So I'm building an MSNP (windows live messenger) client. And I've got this list of capabilities
public enum UserCapabilities : long
{
None = 0,
MobileOnline = 1 << 0,
MSN8User = 1 << 1,
RendersGif = 1 << 2,
....
MsgrVersion7 = 1 << 30,
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
}
full list here http://paste.pocoo.org/show/383240/
The server sends each users capabilities to the client as a long integer, which I take and cast it to UserCapabilities
capabilities = Int64.Parse(e.Command.Args[3]);
user._capabilities = (UserCapabilities)capabilities;
This is fine, and with atleast one user (with a capability value of 1879474220), I can do
Debug.WriteLine(_msgr.GetUser(usr).Capabilities);
and this will output
RendersGif, RendersIsf, SupportsChunking, IsBot, SupportsSChannel, SupportsSipInvite, MsgrVersion5, MsgrVersion6, MsgrVersion7
But with another user, who has the capability value of (3055849760), when I do the same, I just get the same number outputted
3055849760
What I would like to be seeing is a list of capabilities, as it is with the other user.
I'm sure there is a very valid reason for this happening, but no matter how hard I try to phrase the question to Google, I am not finding an answer.
Please help me :)
A flagged enum can be used to efficiently send and store a collection of boolean values. In a flagged enum, each value of the enum is assigned to a bit value. These must be bit values because each combination possible will be unique.
The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.
A Flags is an attribute that allows us to represent an enum as a collection of values rather than a single value. So, let's see how we can implement the Flags attribute on enumeration: [Flags] public enum UserType.
Enum Flags Attribute The idea of Enum Flags is to take an enumeration variable and allow it hold multiple values. It should be used whenever the enum represents a collection of flags, rather than representing a single value. Such enumeration collections are usually manipulated using bitwise operators.
The definition of the shift operators means that only the 5 least significant bits are used for 32-bit numbers and only the first 6 bits for 64-bit; meaning:
1 << 5
is identical to
1 << 37
(both are 32
)
By making it:
MsgrVersion9 = 1L << 32
you make it a 64-bit number, which is why @leppie's fix works; otherwise the <<
is considered first (and note that 1<<32
is identical to 1<<0
, i.e. 1
), and then the resulting 1
is converted to a long
; so it is still 1
.
From §14.8 in the ECMA spec:
For the predefined operators, the number of bits to shift is computed as follows:
- When the type of x is
int
oruint
, the shift count is given by the low-order five bits of count. In other words, the shift count is computed fromcount & 0x1F
.- When the type of x is
long
orulong
, the shift count is given by the low-order six bits of count. In other words, the shift count is computed fromcount & 0x3F
.If the resulting shift count is zero, the shift operators simply return the value of x.
Shift operations never cause overflows and produce the same results in checked and unchecked context
The problem could be with arithmetic overflow.
Specifically at:
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
I suggest you make it:
MsgrVersion8 = 1L << 31,
MsgrVersion9 = 1L << 32,
To prevent accidental overflow.
Update:
Seems likely as the smaller number on 'touches' 31 bits, while the bigger one 'touches' 32 bits.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With