Ejemplo n.º 1
0
        void MessageFlagsChanged(object sender, MessageFlagsChangedEventArgs e)
        {
            if (e.Index < messages.Count)
            {
                var info = messages[e.Index];
                var node = map[info];

                info.Flags = e.Flags;

                UpdateMessageNode(node);
            }
        }
Ejemplo n.º 2
0
        private void ServerFolder_MessageFlagsChanged(object sender, MessageFlagsChangedEventArgs e)
        {
            done?.Cancel();

            NewLogMessage?.Invoke(this, $"{DateTime.Now}: Message Number: {e.Index} flags changed.");
            if (sender is IMailFolder rootMailFolder)
            {
                UpdateForm(this, new Action(() =>
                {
                    CreateOrUppdate(rootMailFolder).ContinueWith((t) => ReadMails(t.Result));
                }));
            }
        }
Ejemplo n.º 3
0
        public void TestMessageFlagsChangedEventArgs()
        {
            var keywords = new HashSet <string> (new [] { "custom1", "custom2" });
            MessageFlagsChangedEventArgs args;
            var   uid    = new UniqueId(5);
            ulong modseq = 724;

            args = new MessageFlagsChangedEventArgs(0);
            Assert.AreEqual(0, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.None, args.Flags);
            Assert.IsFalse(args.UniqueId.HasValue);
            Assert.IsFalse(args.ModSeq.HasValue);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, MessageFlags.Answered);
            Assert.AreEqual(0, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.IsFalse(args.UniqueId.HasValue);
            Assert.IsFalse(args.ModSeq.HasValue);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, MessageFlags.Answered, modseq);
            Assert.AreEqual(0, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.IsFalse(args.UniqueId.HasValue);
            Assert.AreEqual(modseq, args.ModSeq);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, MessageFlags.Answered, keywords);
            Assert.AreEqual(keywords.Count, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.IsFalse(args.UniqueId.HasValue);
            Assert.IsFalse(args.ModSeq.HasValue);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, MessageFlags.Answered, keywords, modseq);
            Assert.AreEqual(keywords.Count, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.IsFalse(args.UniqueId.HasValue);
            Assert.AreEqual(modseq, args.ModSeq);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, uid, MessageFlags.Answered);
            Assert.AreEqual(0, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.AreEqual(uid, args.UniqueId);
            Assert.IsFalse(args.ModSeq.HasValue);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, uid, MessageFlags.Answered, modseq);
            Assert.AreEqual(0, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.AreEqual(uid, args.UniqueId);
            Assert.AreEqual(modseq, args.ModSeq);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, uid, MessageFlags.Answered, keywords);
            Assert.AreEqual(keywords.Count, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.AreEqual(uid, args.UniqueId);
            Assert.IsFalse(args.ModSeq.HasValue);
            Assert.AreEqual(0, args.Index);

            args = new MessageFlagsChangedEventArgs(0, uid, MessageFlags.Answered, keywords, modseq);
            Assert.AreEqual(keywords.Count, args.UserFlags.Count);
            Assert.AreEqual(MessageFlags.Answered, args.Flags);
            Assert.AreEqual(uid, args.UniqueId);
            Assert.AreEqual(modseq, args.ModSeq);
            Assert.AreEqual(0, args.Index);

            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, MessageFlags.Answered));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, MessageFlags.Answered, modseq));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, MessageFlags.Answered, keywords));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, MessageFlags.Answered, keywords, modseq));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, uid, MessageFlags.Answered));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, uid, MessageFlags.Answered, modseq));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, uid, MessageFlags.Answered, keywords));
            Assert.Throws <ArgumentOutOfRangeException> (() => new MessageFlagsChangedEventArgs(-1, uid, MessageFlags.Answered, keywords, modseq));

            Assert.Throws <ArgumentNullException> (() => new MessageFlagsChangedEventArgs(0, MessageFlags.Answered, null));
            Assert.Throws <ArgumentNullException> (() => new MessageFlagsChangedEventArgs(0, MessageFlags.Answered, null, modseq));
            Assert.Throws <ArgumentNullException> (() => new MessageFlagsChangedEventArgs(0, uid, MessageFlags.Answered, null));
            Assert.Throws <ArgumentNullException> (() => new MessageFlagsChangedEventArgs(0, uid, MessageFlags.Answered, null, modseq));
        }
Ejemplo n.º 4
0
		internal void OnFetch (ImapEngine engine, int index, CancellationToken cancellationToken)
		{
			var labels = new MessageLabelsChangedEventArgs (index);
			var flags = new MessageFlagsChangedEventArgs (index);
			var token = engine.ReadToken (cancellationToken);
			bool labelsChanged = false;
			bool flagsChanged = false;

			if (token.Type != ImapTokenType.OpenParen)
				throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);

			do {
				token = engine.ReadToken (cancellationToken);

				if (token.Type == ImapTokenType.CloseParen || token.Type == ImapTokenType.Eoln)
					break;

				if (token.Type != ImapTokenType.Atom)
					throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);

				var atom = (string) token.Value;
				ulong modseq;
				uint uid;

				switch (atom) {
				case "MODSEQ":
					token = engine.ReadToken (cancellationToken);

					if (token.Type != ImapTokenType.OpenParen)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					token = engine.ReadToken (cancellationToken);

					if (token.Type != ImapTokenType.Atom || !ulong.TryParse ((string) token.Value, out modseq))
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					token = engine.ReadToken (cancellationToken);

					if (token.Type != ImapTokenType.CloseParen)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					labels.ModSeq = modseq;
					flags.ModSeq = modseq;
					break;
				case "UID":
					token = engine.ReadToken (cancellationToken);

					if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid) || uid == 0)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					labels.UniqueId = new UniqueId (UidValidity, uid);
					flags.UniqueId = new UniqueId (UidValidity, uid);
					break;
				case "FLAGS":
					flags.Flags = ImapUtils.ParseFlagsList (engine, atom, flags.UserFlags, cancellationToken);
					flagsChanged = true;
					break;
				case "X-GM-LABELS":
					labels.Labels = ImapUtils.ParseLabelsList (engine, cancellationToken);
					labelsChanged = true;
					break;
				default:
					throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);
				}
			} while (true);

			if (token.Type != ImapTokenType.CloseParen)
				throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);

			if (flagsChanged)
				OnMessageFlagsChanged (flags);

			if (labelsChanged)
				OnMessageLabelsChanged (labels);
		}
Ejemplo n.º 5
0
		void FetchStream (ImapEngine engine, ImapCommand ic, int index)
		{
			var token = engine.ReadToken (ic.CancellationToken);
			var labels = new MessageLabelsChangedEventArgs (index);
			var flags = new MessageFlagsChangedEventArgs (index);
			var ctx = (FetchStreamContext) ic.UserData;
			var section = new StringBuilder ();
			bool labelsChanged = false;
			bool flagsChanged = false;
			var buf = new byte[4096];
			long nread = 0, size = 0;
			UniqueId? uid = null;
			Stream stream;
			int n;

			if (token.Type != ImapTokenType.OpenParen)
				throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);

			do {
				token = engine.ReadToken (ic.CancellationToken);

				if (token.Type == ImapTokenType.CloseParen || token.Type == ImapTokenType.Eoln)
					break;

				if (token.Type != ImapTokenType.Atom)
					throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);

				var atom = (string) token.Value;
				int offset = 0, length;
				ulong modseq;
				uint value;

				switch (atom) {
				case "BODY":
					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type != ImapTokenType.OpenBracket)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					section.Clear ();

					do {
						token = engine.ReadToken (ic.CancellationToken);

						if (token.Type == ImapTokenType.CloseBracket)
							break;

						if (token.Type == ImapTokenType.OpenParen) {
							section.Append (" (");

							do {
								token = engine.ReadToken (ic.CancellationToken);

								if (token.Type == ImapTokenType.CloseParen)
									break;

								// the header field names will generally be atoms or qstrings but may also be literals
								switch (token.Type) {
								case ImapTokenType.Literal:
									section.Append (engine.ReadLiteral (ic.CancellationToken));
									section.Append (' ');
									break;
								case ImapTokenType.QString:
								case ImapTokenType.Atom:
									section.Append ((string) token.Value);
									break;
								default:
									throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);
								}
							} while (true);

							if (section[section.Length - 1] == ' ')
								section.Length--;

							section.Append (')');
						} else if (token.Type != ImapTokenType.Atom) {
							throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);
						} else {
							section.Append ((string) token.Value);
						}
					} while (true);

					if (token.Type != ImapTokenType.CloseBracket)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type == ImapTokenType.Atom) {
						// this might be a region ("<###>")
						var expr = (string) token.Value;

						if (expr.Length > 2 && expr[0] == '<' && expr[expr.Length - 1] == '>') {
							var region = expr.Substring (1, expr.Length - 2);
							int.TryParse (region, out offset);

							token = engine.ReadToken (ic.CancellationToken);
						}
					}

					switch (token.Type) {
					case ImapTokenType.Literal:
						length = (int) token.Value;
						size += length;

						stream = CreateStream (uid, section.ToString (), offset, length);

						try {
							while ((n = engine.Stream.Read (buf, 0, buf.Length, ic.CancellationToken)) > 0) {
								stream.Write (buf, 0, n);
								nread += n;

								ctx.Report (nread, size);
							}

							stream.Position = 0;
						} catch {
							stream.Dispose ();
							throw;
						}
						break;
					case ImapTokenType.QString:
					case ImapTokenType.Atom:
						var buffer = Encoding.UTF8.GetBytes ((string) token.Value);
						length = buffer.Length;
						nread += length;
						size += length;

						stream = CreateStream (uid, section.ToString (), offset, length);

						try {
							stream.Write (buffer, 0, length);
							ctx.Report (nread, size);
							stream.Position = 0;
						} catch {
							stream.Dispose ();
							throw;
						}
						break;
					case ImapTokenType.Nil:
						stream = CreateStream (uid, section.ToString (), offset, 0);
						break;
					default:
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);
					}

					if (uid.HasValue)
						ctx.Sections[section.ToString ()] = CommitStream (stream, uid.Value);
					else
						ctx.Sections[section.ToString ()] = stream;

					break;
				case "UID":
					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out value) || value == 0)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					uid = new UniqueId (UidValidity, value);

					foreach (var key in ctx.Sections.Keys.ToArray ())
						ctx.Sections[key] = CommitStream (ctx.Sections[key], uid.Value);

					labels.UniqueId = uid.Value;
					flags.UniqueId = uid.Value;
					break;
				case "MODSEQ":
					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type != ImapTokenType.OpenParen)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type != ImapTokenType.Atom || !ulong.TryParse ((string) token.Value, out modseq))
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type != ImapTokenType.CloseParen)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);

					labels.ModSeq = modseq;
					flags.ModSeq = modseq;
					break;
				case "FLAGS":
					// even though we didn't request this piece of information, the IMAP server
					// may send it if another client has recently modified the message flags.
					flags.Flags = ImapUtils.ParseFlagsList (engine, atom, flags.UserFlags, ic.CancellationToken);
					flagsChanged = true;
					break;
				case "X-GM-LABELS":
					// even though we didn't request this piece of information, the IMAP server
					// may send it if another client has recently modified the message labels.
					labels.Labels = ImapUtils.ParseLabelsList (engine, ic.CancellationToken);
					labelsChanged = true;
					break;
				default:
					throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);
				}
			} while (true);

			if (token.Type != ImapTokenType.CloseParen)
				throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "FETCH", token);

			if (flagsChanged)
				ic.Folder.OnMessageFlagsChanged (flags);

			if (labelsChanged)
				ic.Folder.OnMessageLabelsChanged (labels);
		}
Ejemplo n.º 6
0
        void OnMessageFlagsChanged(object sender, MessageFlagsChangedEventArgs e)
        {
            var folder = (ImapFolder)sender;

            Console.WriteLine("{0}: flags have changed for message #{1} ({2}).", folder, e.Index, e.Flags);
        }
Ejemplo n.º 7
0
        void OnFlagsChanged(MessageFlagsChangedEventArgs args)
        {
            var handler = MessageFlagsChanged;

            if (handler != null)
                handler (this, args);
        }
Ejemplo n.º 8
0
        static void FetchMessageBody(ImapEngine engine, ImapCommand ic, int index, ImapToken tok)
        {
            var token = engine.ReadToken (ic.CancellationToken);
            var args = new MessageFlagsChangedEventArgs (index);
            var type = FetchReturnType.MimeMessage;
            bool emit = false;

            if (token.Type != ImapTokenType.OpenParen)
                throw ImapEngine.UnexpectedToken (token, false);

            do {
                token = engine.ReadToken (ic.CancellationToken);

                if (token.Type == ImapTokenType.CloseParen || token.Type == ImapTokenType.Eoln)
                    break;

                if (token.Type != ImapTokenType.Atom)
                    throw ImapEngine.UnexpectedToken (token, false);

                var atom = (string) token.Value;
                ulong modseq;
                uint uid;

                switch (atom) {
                case "BODY":
                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.OpenBracket)
                        throw ImapEngine.UnexpectedToken (token, false);

                    do {
                        token = engine.ReadToken (ic.CancellationToken);

                        if (token.Type == ImapTokenType.CloseBracket)
                            break;

                        if (token.Type == ImapTokenType.OpenParen) {
                            type = FetchReturnType.Stream;

                            do {
                                token = engine.ReadToken (ic.CancellationToken);

                                if (token.Type == ImapTokenType.CloseParen)
                                    break;

                                if (token.Type != ImapTokenType.Atom)
                                    throw ImapEngine.UnexpectedToken (token, false);
                            } while (true);
                        } else if (token.Type != ImapTokenType.Atom) {
                            throw ImapEngine.UnexpectedToken (token, false);
                        } else {
                            type = FetchReturnType.MimeEntity;
                        }
                    } while (true);

                    if (token.Type != ImapTokenType.CloseBracket)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type == ImapTokenType.Atom) {
                        var region = (string) token.Value;

                        if (region[0] != '<' || region[region.Length - 1] != '>')
                            throw ImapEngine.UnexpectedToken (token, false);

                        token = engine.ReadToken (ic.CancellationToken);

                        type = FetchReturnType.Stream;
                    }

                    if (token.Type != ImapTokenType.Literal)
                        throw ImapEngine.UnexpectedToken (token, false);

                    switch (type) {
                    case FetchReturnType.MimeMessage:
                        ic.UserData = MimeMessage.Load (engine.Stream, ic.CancellationToken);
                        break;
                    case FetchReturnType.MimeEntity:
                        ic.UserData = MimeEntity.Load (engine.Stream, ic.CancellationToken);
                        break;
                    default:
                        var stream = new MemoryBlockStream ();
                        var buf = new byte[4096];
                        int nread;

                        ic.CancellationToken.ThrowIfCancellationRequested ();
                        while ((nread = engine.Stream.Read (buf, 0, buf.Length)) > 0) {
                            ic.CancellationToken.ThrowIfCancellationRequested ();
                            stream.Write (buf, 0, nread);
                        }

                        ic.UserData = stream;
                        break;
                    }

                    break;
                case "UID":
                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid) || uid == 0)
                        throw ImapEngine.UnexpectedToken (token, false);

                    args.Uid = new UniqueId (uid);
                    break;
                case "MODSEQ":
                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.OpenParen)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.Atom || !ulong.TryParse ((string) token.Value, out modseq) || modseq == 0)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.CloseParen)
                        throw ImapEngine.UnexpectedToken (token, false);

                    args.ModSeq = modseq;
                    break;
                case "FLAGS":
                    // even though we didn't request this piece of information, the IMAP server
                    // may send it if another client has recently modified the message flags.
                    args.Flags = ImapUtils.ParseFlagsList (engine, ic.CancellationToken);
                    emit = true;
                    break;
                default:
                    throw ImapEngine.UnexpectedToken (token, false);
                }
            } while (true);

            if (token.Type != ImapTokenType.CloseParen)
                throw ImapEngine.UnexpectedToken (token, false);

            if (emit)
                ic.Folder.OnFlagsChanged (args);
        }
Ejemplo n.º 9
0
        internal void OnFetch(ImapEngine engine, int index, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken (cancellationToken);
            var args = new MessageFlagsChangedEventArgs (index);

            if (token.Type != ImapTokenType.OpenParen)
                throw ImapEngine.UnexpectedToken (token, false);

            do {
                token = engine.ReadToken (cancellationToken);

                if (token.Type == ImapTokenType.CloseParen || token.Type == ImapTokenType.Eoln)
                    break;

                if (token.Type != ImapTokenType.Atom)
                    throw ImapEngine.UnexpectedToken (token, false);

                var atom = (string) token.Value;
                ulong modseq;
                uint uid;

                switch (atom) {
                case "MODSEQ":
                    token = engine.ReadToken (cancellationToken);

                    if (token.Type != ImapTokenType.OpenParen)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (cancellationToken);

                    if (token.Type != ImapTokenType.Atom || !ulong.TryParse ((string) token.Value, out modseq) || modseq == 0)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (cancellationToken);

                    if (token.Type != ImapTokenType.CloseParen)
                        throw ImapEngine.UnexpectedToken (token, false);

                    args.ModSeq = modseq;
                    break;
                case "UID":
                    token = engine.ReadToken (cancellationToken);

                    if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid) || uid == 0)
                        throw ImapEngine.UnexpectedToken (token, false);

                    args.Uid = new UniqueId (uid);
                    break;
                case "FLAGS":
                    args.Flags = ImapUtils.ParseFlagsList (engine, cancellationToken);
                    break;
                default:
                    throw ImapEngine.UnexpectedToken (token, false);
                }
            } while (true);

            if (token.Type != ImapTokenType.CloseParen)
                throw ImapEngine.UnexpectedToken (token, false);

            OnFlagsChanged (args);
        }
Ejemplo n.º 10
0
 void MessageFlagsChanged_TaskThread(object sender, MessageFlagsChangedEventArgs e)
 {
     // proxy back to the main thread
     Invoke(new EventHandler <MessageFlagsChangedEventArgs> (MessageFlagsChanged), sender, e);
 }
Ejemplo n.º 11
0
        static void FetchMessageBody(ImapEngine engine, ImapCommand ic, int index)
        {
            var streams = (Dictionary<string, Stream>) ic.UserData;
            var token = engine.ReadToken (ic.CancellationToken);
            var labels = new MessageLabelsChangedEventArgs (index);
            var flags = new MessageFlagsChangedEventArgs (index);
            bool labelsChanged = false;
            bool flagsChanged = false;
            var buf = new byte[4096];
            string specifier;
            Stream stream;
            int nread;

            if (token.Type != ImapTokenType.OpenParen)
                throw ImapEngine.UnexpectedToken (token, false);

            do {
                token = engine.ReadToken (ic.CancellationToken);

                if (token.Type == ImapTokenType.CloseParen || token.Type == ImapTokenType.Eoln)
                    break;

                if (token.Type != ImapTokenType.Atom)
                    throw ImapEngine.UnexpectedToken (token, false);

                var atom = (string) token.Value;
                ulong modseq;
                uint uid;

                switch (atom) {
                case "BODY":
                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.OpenBracket)
                        throw ImapEngine.UnexpectedToken (token, false);

                    specifier = string.Empty;

                    do {
                        token = engine.ReadToken (ic.CancellationToken);

                        if (token.Type == ImapTokenType.CloseBracket)
                            break;

                        if (token.Type == ImapTokenType.OpenParen) {
                            do {
                                token = engine.ReadToken (ic.CancellationToken);

                                if (token.Type == ImapTokenType.CloseParen)
                                    break;

                                if (token.Type != ImapTokenType.Atom)
                                    throw ImapEngine.UnexpectedToken (token, false);
                            } while (true);
                        } else if (token.Type != ImapTokenType.Atom) {
                            throw ImapEngine.UnexpectedToken (token, false);
                        } else {
                            specifier += (string) token.Value;
                        }
                    } while (true);

                    if (token.Type != ImapTokenType.CloseBracket)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type == ImapTokenType.Atom) {
                        var region = (string) token.Value;

                        if (region[0] != '<' || region[region.Length - 1] != '>')
                            throw ImapEngine.UnexpectedToken (token, false);

                        token = engine.ReadToken (ic.CancellationToken);
                    }

                    switch (token.Type) {
                    case ImapTokenType.Literal:
                        stream = new MemoryBlockStream ();

                        while ((nread = engine.Stream.Read (buf, 0, buf.Length, ic.CancellationToken)) > 0)
                            stream.Write (buf, 0, nread);

                        streams[specifier] = stream;
                        stream.Position = 0;
                        break;
                    case ImapTokenType.QString:
                    case ImapTokenType.Atom:
                        stream = new MemoryStream (Encoding.UTF8.GetBytes ((string) token.Value), false);
                        break;
                    default:
                        throw ImapEngine.UnexpectedToken (token, false);
                    }

                    break;
                case "UID":
                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid) || uid == 0)
                        throw ImapEngine.UnexpectedToken (token, false);

                    labels.UniqueId = new UniqueId (uid);
                    flags.UniqueId = new UniqueId (uid);
                    break;
                case "MODSEQ":
                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.OpenParen)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.Atom || !ulong.TryParse ((string) token.Value, out modseq) || modseq == 0)
                        throw ImapEngine.UnexpectedToken (token, false);

                    token = engine.ReadToken (ic.CancellationToken);

                    if (token.Type != ImapTokenType.CloseParen)
                        throw ImapEngine.UnexpectedToken (token, false);

                    labels.ModSeq = modseq;
                    flags.ModSeq = modseq;
                    break;
                case "FLAGS":
                    // even though we didn't request this piece of information, the IMAP server
                    // may send it if another client has recently modified the message flags.
                    flags.Flags = ImapUtils.ParseFlagsList (engine, flags.UserFlags, ic.CancellationToken);
                    flagsChanged = true;
                    break;
                case "X-GM-LABELS":
                    // even though we didn't request this piece of information, the IMAP server
                    // may send it if another client has recently modified the message labels.
                    labels.Labels = ImapUtils.ParseLabelsList (engine, ic.CancellationToken);
                    labelsChanged = true;
                    break;
                default:
                    throw ImapEngine.UnexpectedToken (token, false);
                }
            } while (true);

            if (token.Type != ImapTokenType.CloseParen)
                throw ImapEngine.UnexpectedToken (token, false);

            if (flagsChanged)
                ic.Folder.OnMessageFlagsChanged (flags);

            if (labelsChanged)
                ic.Folder.OnMessageLabelsChanged (labels);
        }
Ejemplo n.º 12
0
 /// <summary>
 /// when message flag change
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void OnMessageFlagsChanged(object sender, MessageFlagsChangedEventArgs e)
 {
 }
Ejemplo n.º 13
0
 private void Inbox_MessageFlagsChanged(object sender, MessageFlagsChangedEventArgs e)
 {
     _logger.LogTrace("{id}: Message flags have changed: #{id} -> {flags}",
                      Identifier, e.Index, e.Flags);
 }
Ejemplo n.º 14
0
 private void ServerFolder_MessageFlagsChanged(object sender, MessageFlagsChangedEventArgs e)
 {
     throw new NotImplementedException();
 }