Создание Windows-приложений на основе Visual C#

         

Основной класс сообщения. Common.cs


Листинг 3.14.

(html, txt)


// конвертируем строки в массив байтов Encoding enc = Encoding.ASCII; byte [] b = enc.GetBytes(message); cs.Write(b, 0, b.Length);

cs.Close(); string t = Utils.GetEncoding(Charset).GetString(tf.ToArray()); tf.Close(); return t; } /// <summary> /// Конструктор. /// </summary> /// <param name="parent">Родительский провайдер.</param> /// <param name="message">Текст, содержащий сообщение.</param> internal Common(Provider parent, string message) { if (parent == null) { throw new ArgumentNullException("parent"); } if (message == String.Empty) { throw new ArgumentException("empty string", "message"); }

int end = FillHeaders(message); _size = message.Length;

// исключаем заголовок из тела сообщения _message = message.Substring(end); _pop3 = parent; }

/// <summary> /// Выбираем все заголовки и заполняем массив. /// </summary> /// <returns></returns> internal int FillHeaders(string message) { int start = 0; //message.IndexOf(CRLF) + CRLF.Length; //пропускаем 2 байта int headerend = message.IndexOf(DCRLF); string headers = message.Substring(start, headerend - start); GetHeaders(headers);

// пропускаем секцию заголовков headerend += DCRLF.Length;

return headerend; }

/// <summary> /// Заполнение <see cref="Mime"/> массива. /// </summary> /// <returns></returns> protected bool MultipartMixed() { string b = GetBoundary(); if (b == String.Empty) return false;

int s = _message.IndexOf(b); if (s < 0) { throw new ParseException("Can't find beginning MIME boundary: " + b); }

ArrayList tmimes = new ArrayList();

while(true) { s += b.Length + CRLF.Length;

int e = _message.IndexOf(b, s); if (e < 0) { if (_message.IndexOf(MIMEE, s - CRLF.Length, MIMEE.Length) < 0) { throw new ParseException("Неправильный MIME"); }

break; }



tmimes.Add(new Mime(_pop3, _message.Substring(s, e - s - CRLF.Length))); s = e; }



ChildMimes = (Mime [])tmimes.ToArray(typeof(Mime));

return true; }

/// <summary> /// Попытка извлечения значения 'boundary' из <see cref="ContentType"/>. /// </summary> /// <returns></returns> protected string GetBoundary() { Regex r = new Regex("boundary=[\\\"]?([^\\r\\\"]+)"); if (ContentType == null) { return String.Empty; }

Match m = r.Match(ContentType); if (m.Success) { return "--" + m.Groups[1].ToString(); } else { return String.Empty; } }

/// <summary> /// Все заголовки в нижнем регистре. /// </summary> /// <param name="top">Заголовок</param> void GetHeaders(string top) { Regex line = new Regex(@"\r\n(?![\t\x20])"); string [] col = line.Split(top); foreach (string s in col) { string [] fields = s.Split(new Char[] {':'}, 2); // Console.WriteLine(fields[0] + "}={" + fields[1] + "}"); if (fields.Length < 2) continue; fields[0] = fields[0].ToLower(); // перевод в нижний регистр fields[1] = fields[1].TrimStart(' '); // удаление ненужных пробелов

if (Headers.ContainsKey(fields[0])) { object oldv = Headers[fields[0]]; ArrayList al = oldv as ArrayList; if (al == null) { al = new ArrayList(); al.Add(oldv); Headers[fields[0]] = al; }

al.Add(fields[1]); } else { Headers.Add(fields[0].ToLower(), fields[1]); } } }

# region Common headers public string Charset { get { Regex r = new Regex(@"charset=[""'\s]([^""'\s]+)"); Match m = r.Match(ContentType); if (m.Success) return m.Groups[1].Value; else return ""; } }

protected string TransferEncoding { get { return ((string)Headers["content-transfer-encoding"]).ToLower(); } }

/// <summary> /// Содержит тип текущей <see cref="Mime"/> секции или <see cref="Message"/>. /// </summary> public string ContentType { get { return (string)Headers["content-type"]; } } #endregion } }

Листинг 3.14.


Содержание раздела