Example #1
0
        public object Parse(string value, object argument)
        {
            var index = value.IndexOf(Characters.Colon);

            value = value.Substring(index + 1).Trim();
            return(TransferEncoder.DecodeHeaderIfNecessary(value));
        }
Example #2
0
        public virtual void Deserialize(string literals)
        {
            var index = literals.IndexOf(":");

            Name = literals.Substring(0, index);

            var tail = literals.Substring(index + 1).Trim();

            var decodedText = TransferEncoder.DecodeHeaderIfNecessary(tail);


            ParseRemainder(decodedText);
        }
Example #3
0
        public object Parse(string text, object argument)
        {
            var envelope = new Envelope();

            // quotes inside the subject can trash the regex results, therefor we will tempararily replace them
            text = text.Replace("\\\"", "&,,4+");

            var matches = Regex.Matches(text, RegexPatterns.EnvelopeResponsePattern);

            if (matches.Count != 10)
            {
                Debug.WriteLine(FailureMessages.UnexpectedItemCountInEnvelopeMessage);
                Debug.WriteLine("Response: " + text);
                return(envelope);
            }

            DateTime date;
            var      normalized = TransferEncoder.DecodeHeaderIfNecessary(matches[0].Value).TrimQuotes().RemoveComments();
            var      success    = DateTime.TryParse(normalized, out date);

            if (success)
            {
                envelope.Date = date;
            }
            else
            {
                Debug.WriteLine(FailureMessages.UnexpectedDateFormatMessage);
                Debug.WriteLine("Date: " + normalized);
            }

            envelope.Subject = matches[1].Value.TrimQuotes();

            // need to insert the previously replaced quotes
            envelope.Subject = envelope.Subject.Replace("&,,4+", "\"");
            envelope.Subject = TransferEncoder.DecodeHeaderIfNecessary(envelope.Subject);

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[2].Value);
                var from  = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.From).AddRange(from);
            }

            {
                var value  = TransferEncoder.DecodeHeaderIfNecessary(matches[3].Value);
                var sender = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.Sender).AddRange(sender);
            }

            {
                var value   = TransferEncoder.DecodeHeaderIfNecessary(matches[4].Value);
                var replyTo = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.ReplyTo).AddRange(replyTo);
            }

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[5].Value);
                var to    = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.To).AddRange(to);
            }

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[6].Value);
                var cc    = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.Cc).AddRange(cc);
            }

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[7].Value);
                var bcc   = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.Bcc).AddRange(bcc);
            }

            var inReplyTo = TransferEncoder.DecodeHeaderIfNecessary(matches[8].Value).TrimQuotes();

            envelope.InReplyTo = inReplyTo.IsNilOrEmpty() ? string.Empty : inReplyTo;

            var messageId = TransferEncoder.DecodeHeaderIfNecessary(matches[9].Value).TrimQuotes();

            envelope.MessageId = messageId.IsNilOrEmpty() ? string.Empty : messageId;

            return(envelope);
        }
Example #4
0
        public string ReadSection(ImapResponseReader reader)
        {
            var text = reader.CurrentLine;
            var sn   = Regex.Match(text, @"\d+").Value;


            using (var sw = new StringWriter()) {
                using (var sr = new StringReader(text)) {
                    var stack = new Stack <char>();

                    var isStarted = false;
                    var index     = text.IndexOf("BODYSTRUCTURE");
                    var buffer    = new char[index + 1];
                    sr.Read(buffer, 0, index);

                    while (true)
                    {
                        if (isStarted)
                        {
                            sw.Write(buffer[0]);
                        }

                        var count = sr.Read(buffer, 0, 1);

                        // end of string
                        if (count == 0)
                        {
                            break;
                        }

                        // matching brace found
                        if (isStarted && stack.Count == 0)
                        {
                            break;
                        }

                        if (buffer[0] == Characters.RoundOpenBracket)
                        {
                            stack.Push(buffer[0]);
                            isStarted = true;
                            continue;
                        }

                        if (buffer[0] == Characters.RoundClosedBracket)
                        {
                            stack.Pop();
                            continue;
                        }
                    }

                    // is a size appended to indicate multilined data? {####}
                    var sizeMatch = Regex.Match(reader.CurrentLine, @"\{\d+\}$");
                    if (sizeMatch.Success)
                    {
                        // need to remove {####} from end of string
                        sw.RemoveLast(sizeMatch.Value.Length);

                        // Usually we could determine the amount of data to read from the size parameter at the end of the line
                        // unfortunately here the number contained seems to be completely arbitrary since it never fits, coming from 1und1 its always 107, no matter what follows.
                        // The 'only' thing I can be sure of when determining the amount of data to append is that it has to end with a closing bracket, no matter what.
                        while (true)
                        {
                            reader.ReadNextLine();
                            var line = reader.CurrentLine;
                            sizeMatch = Regex.Match(reader.CurrentLine, @"\{\d+\}$");

                            // cut trailing {###} expression if necessary
                            var normalizedLine = sizeMatch.Success ? line.Substring(0, line.Length - sizeMatch.Value.Length) : line;

                            // decode line since its usually encoded using QP or Base64
                            normalizedLine = TransferEncoder.DecodeHeaderIfNecessary(normalizedLine);

                            // append line to regular body struct
                            sw.Write(normalizedLine);
                            if (reader.CurrentLine.EndsWith(")"))
                            {
                                break;
                            }
                        }
                    }

                    // we silently append the sequence number to the end of the body structure,
                    // the parser will ignore it, but we can read it later without having to split or change this string
                    sw.Write(Characters.Space);
                    sw.Write(sn);
                    return(sw.ToString());
                }
            }
        }