Pergunta

My question is mostly about how interpret a typedef enum, but here is the background:

I am using MailCore2, and I am trying to figure out how to read the flags off of an individual email object that I am fetching.

Each MCOIMAPMessage *email that I fetch has a property on it called 'flags.' Flags is of type MCOMessageFlag. When I look up the definition of MCOMessageFlag, I find that it is a typedef enum:

typedef enum {
    MCOMessageFlagNone          = 0,
    /** Seen/Read flag.*/
    MCOMessageFlagSeen          = 1 << 0,
    /** Replied/Answered flag.*/
   MCOMessageFlagAnswered      = 1 << 1,
    /** Flagged/Starred flag.*/
    MCOMessageFlagFlagged       = 1 << 2,
    /** Deleted flag.*/
    MCOMessageFlagDeleted       = 1 << 3,
    /** Draft flag.*/
    MCOMessageFlagDraft         = 1 << 4,
    /** $MDNSent flag.*/
    MCOMessageFlagMDNSent       = 1 << 5,
    /** $Forwarded flag.*/
    MCOMessageFlagForwarded     = 1 << 6,
    /** $SubmitPending flag.*/
    MCOMessageFlagSubmitPending = 1 << 7,
    /** $Submitted flag.*/
    MCOMessageFlagSubmitted     = 1 << 8,
} MCOMessageFlag;

Since I do not know how typedef enums really work - particularly this one with the '= 1 << 8' type components, I am a little lost about how to read the emails' flags property.

For example, I have an email message that has both an MCOMessageFlagSeen and an MCOMessageFlagFlagged on the server. I'd like to find out from the email.flags property whether or not the fetched email has one, both or neither of these flags (if possible). However, in the debugger when I print 'email.flags' for an email that has both of the above flags, I get back just the number 5. I don't see how that relates to the typedef enum definitions above.

Ultimately, I want to set a BOOL value based on whether or not the flag is present. In other words, I'd like to do something like:

BOOL wasSeen = email.flags == MCOMessageFlagSeen;
BOOL isFlagged = email.flags == MCOMessageFlagFlagged;

Of course this doesn't work, but this is the idea. Can anyone suggest how I might accomplish this and/or how to understand the typedef enum?

Foi útil?

Solução

These flags are used as in a bitmask.

This allows to store multiple on/off flags in a single numeric type (let it be an unsigned char or an unsigned int). Basically if a flag is set then its corresponding bit is set too.

For example:

MCOMessageFlagMDNSent       = 1 << 5

1<<5 means 1 shifted to the left by 5 bits, so in binary:

00000001 << 5 = 00100000

This works only if no flag overlaps with other flags, which is typically achieved by starting with 1 and shifting it to the left by a different amount for every flag.

Then to check if a flag is set you check if the corresponding bit is set, eg:

if (flags & MCOMessageFlagMDNSent)

result will be true if the bitwise AND result is different from zero, this can happen only if the corresponding bit is set.

You can set a flag easily with OR:

flags |= MCOMessageFlagMDNSent;

or reset it with AND:

flags &= ~MCOMessageFlagMDNSent;

Outras dicas

The values of the enum represent the individual bits, so you need bitwise operations to check for flags:

BOOL wasSeen = ( email.flags & MCOMessageFlagSeen ); // check if a bit was set

BTW: You code seems to suggest this is C, not C++. Tagging a question is both is almost always wrong, I suggest you pick the language you are using and remove the other tag.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top