Search code examples
c#.netenum-flags

FlagsAttribute Enum problems


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 :)


Solution

  • 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 or uint, the shift count is given by the low-order five bits of count. In other words, the shift count is computed from count & 0x1F.
    • When the type of x is long or ulong, the shift count is given by the low-order six bits of count. In other words, the shift count is computed from count & 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