public object Parse(string value, object argument) { var index = value.IndexOf(Characters.Colon); value = value.Substring(index + 1).Trim(); return(TransferEncoder.DecodeHeaderIfNecessary(value)); }
public string Serialize() { using (var writer = new StringWriter()) { foreach (var literals in Headers.Select(headerField => headerField.Serialize())) { writer.WriteLine(literals); } var isSingleView = CheckSingleView(); if (isSingleView) { var child = Children.First(); writer.WriteLine(string.Empty); writer.WriteLine(child.Text); return(writer.ToString()); } var isMultipart = CheckMultipart(); if (isMultipart) { writer.WriteLine(string.Empty); writer.WriteLine("This is a multi-part message in MIME format."); foreach (var child in Children) { writer.WriteLine(string.Empty); writer.WriteLine("--" + ContentTypeHeaderField.BoundaryName); var part = child.Serialize(); writer.WriteLine(part); } writer.WriteLine("--" + ContentTypeHeaderField.BoundaryName + "--"); } else { var encoding = DetermineEncoding(); var contentType = DetermineContentType(); switch (contentType) { case ContentTypes.MessageRfc822: encoding = ContentTransferEncodings.None; break; } var charset = DetermineCharset(); var encodedBody = !string.IsNullOrEmpty(Text) ? TransferEncoder.Encode(Text, encoding, charset) // is text, needs encoding : Bytes != null?Convert.ToBase64String(Bytes).ToBlockText(76) : string.Empty; // is binary stream, needs no encoding writer.Write(Environment.NewLine); writer.Write(encodedBody); } return(writer.ToString()); } }
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); }
public virtual string Serialize() { if (Parameters.Count > 0) { var parameters = Parameters.Serialize(); return(string.Format("{0}: {1};{2} {3}", Name, Value, Environment.NewLine, parameters)); } // encode if necessary var value = TransferEncoder.EncodeHeaderIfNecessary(Value, HeaderEncoding); return(string.Format("{0}: {1}", Name, value)); }
/// <summary> /// Fetches a single view from the requested message. /// </summary> /// <param name="info">The associated info object, this token can be obtained from the messages body structure.</param> /// <returns>The requested view.</returns> public View FetchView2(ViewInfo info) { var text = FetchEntityBody(info); if (string.IsNullOrEmpty(text)) { return(null); } var paramDictionary = ((IDictionary <string, string>)info.Parameters); var hasValidCharset = paramDictionary.ContainsKey("charset"); var charset = hasValidCharset ? paramDictionary["charset"] : Charsets.Utf8; var decoded = TransferEncoder.Decode(text, info.ContentTransferEncoding, charset); return(new View { MediaType = info.MediaType, Text = decoded }); }
public BoundaryTy readBody(TextReader rr, EML_Media parent) { mlBody = null; mlBinary = null; string major = mlContentType.major; string boundary = parent.mlContentType.boundary; bool binaryMedia = !major.Equals("text"); string charSet = mlContentType.charSet; CharsetEncoder charSet_enc = charSetEnc.getEncoding(charSet); if (charSet_enc == null) { throw new ArgumentException("不明な文字コード", charSet); } string transferEncoding = parent.mlContentTransferEncoding.major; TransferEncoder transfer_enc = transferEnc.getEncoding(transferEncoding); if (transfer_enc == null) { throw new ArgumentException("不明な変換コード", transferEncoding); } mlBody = new StringBuilder(); mlBinary = new MemoryStream(); String boundaryPass = (boundary != null) ? "--" + boundary : null ; String boundaryTerm = (boundary != null) ? "--" + boundary + "--" : null ; MemoryStream tempText = new MemoryStream(); bool preserveCRLF = transfer_enc.preserveCRLF; ArrayList alDEBUG = new ArrayList(); BoundaryTy bty = BoundaryTy.Pass; while (true) { string lin = rr.ReadLine(); if (lin == null) { break; } alDEBUG.Add(lin); if (boundaryTerm != null && lin.Equals(boundaryTerm)) { bty = BoundaryTy.Term; break; } if (boundaryPass != null && lin.Equals(boundaryPass)) { break; } byte[] bin = transfer_enc.decodeBinary(lin); if (binaryMedia) { mlBinary.Write(bin, 0, bin.Length); if (preserveCRLF) { mlBinary.WriteByte((byte)'\r'); mlBinary.WriteByte((byte)'\n'); } continue; } tempText.Write(bin, 0, bin.Length); if (preserveCRLF) { tempText.WriteByte((byte)'\r'); tempText.WriteByte((byte)'\n'); } } if (!binaryMedia) { string text = charSet_enc.decodeText(tempText.ToArray()); mlBody.Append(text); } return(bty); }
public void writeTo(TextWriter wr) { if (mlTo != null) { wr.WriteLine("{0}: {1}", "To", mlTo.ToString()); } if (mlCC != null) { wr.WriteLine("{0}: {1}", "CC", mlCC.ToString()); } if (mlFrom != null) { wr.WriteLine("{0}: {1}", "From", mlFrom.ToString()); } if (mlReturnPath != null) { wr.WriteLine("{0}: {1}", "ReturnPath", mlReturnPath.ToString()); } if (mlReferences != null) { wr.WriteLine("{0}: {1}", "References", mlReferences.ToString()); } if (mlInReplyTo != null) { wr.WriteLine("{0}: {1}", "InReplyTo", mlInReplyTo.ToString()); } if (mlMessageID != null) { wr.WriteLine("{0}: {1}", "MessageID", mlMessageID.ToString()); } if (mlSubject != null) { wr.WriteLine("{0}: {1}", "Subject", SubjectEncode.current.encode(mlSubject)); } if (mlDate != null) { wr.WriteLine("{0}: {1}", "Date", mlDate); } if (mlContentType != null) { wr.WriteLine("{0}: {1}", "Content-Type", mlContentType); } if (mlContentTransferEncoding != null) { wr.WriteLine("{0}: {1}", "Content-Transfer-Encoding", mlContentTransferEncoding); } if (mlContentDisposition != null) { wr.WriteLine("{0}: {1}", "Content-Disposition", mlContentDisposition); } wr.WriteLine("{0}: {1}", "MIME-Version", "1.0"); wr.WriteLine("{0}: {1}", "X-Mailer", "HDD LibEML 1.0"); string transferEncoding = mlContentTransferEncoding.major; TransferEncoder transfer_enc = transferEnc.getEncoding(transferEncoding); string charSet = mlContentType.charSet; CharsetEncoder charSet_enc = charSetEnc.getEncoding(charSet); wr.WriteLine(); if (mlBody != null) { byte[] bin = charSet_enc.encodeText(mlBody.ToString()); if (transfer_enc == null) { throw new ArgumentException("不明な変換コード", transferEncoding); } wr.Write(transfer_enc.encodeBinary(bin)); } else { if (transfer_enc == null) { throw new ArgumentException("不明な変換コード", transferEncoding); } mlBinary.Position = 0; wr.Write(transfer_enc.encodeBinary(mlBinary.ToArray())); } }
public void Deserialize(string literals) { var isBeginning = true; LineInfo?last = null; using (var reader = new StringReader(literals)) { while (true) { var line = reader.ReadLine(); if (line == null) { break; } // darn new lines if (line == string.Empty && isBeginning) { continue; } isBeginning = false; var current = new LineInfo(line); if (current.IsField) { if (last.HasValue) { CommitHeaderField(last.Value); } last = current; continue; } if (current.IsContinuation) { if (last.HasValue) { last = last.Value.Merge(current); } continue; } if (!current.IsBoundaryStart && IsBoundaryExpected) { continue; } // process final field if (last.HasValue) { CommitHeaderField(last.Value); last = null; } if (!IsBoundaryExpected) { var charset = DetermineCharset(); var encoding = DetermineEncoding(); var content = reader.ReadToEnd() ?? string.Empty; content.Trim(); if (!string.IsNullOrEmpty(content)) { if (HasContentType) { var contentType = ContentTypeHeaderField.MediaType; if (encoding == ContentTransferEncodings.Base64 && !contentType.StartsWith("text")) { Bytes = string.IsNullOrEmpty(content) ? new byte[0] : Convert.FromBase64String(content); } else { Text = TransferEncoder.Decode(content, encoding, charset); } } else { Text = TransferEncoder.Decode(content, encoding, charset); } } break; } if (current.IsBoundaryStart && IsExpectedBoundary(current)) { var parts = ReadBoundaryBlocks(current.BoundaryName, reader); foreach (var part in parts) { var entity = new Entity(); entity.Deserialize(part); Children.Add(entity); } } } } }
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); }
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()); } } }