using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace Nexi { public class Packet { /// /// How interesting is this packet? Between 0 and 1. /// public double Interest; public string TextContents; public static Packet FromText(TextReader src) { Reader rdr = new Reader(src); rdr.ReadHeaders(); rdr.ReadBody(); return rdr.Packet; } private class Reader { private readonly TextReader _src; private Packet pack = new Packet(); public Packet Packet { get { return pack; } } private string _contentType; public Reader(TextReader src) { _src = src; } public void ReadHeaders() { while (true) { string line = _src.ReadLine(); if (line == "") // end of headers return; if (line.StartsWith(" ") || line.StartsWith("\t")) // we don't handle continued headers yet throw new NotImplementedException("Continued headers aren't supported"); int colonpos = line.IndexOf(':'); if (colonpos == -1) throw new ArgumentException(String.Format("Bad header '{0}': missing colon", line)); string header = line.Substring(0, colonpos).ToLowerInvariant().Trim(); string value = line.Substring(colonpos + 1).Trim(); if (header == "interest") pack.Interest = double.Parse(value); else if (header == "content-type") _contentType = value; else // eventually we should ignore unknown headers throw new ArgumentException(String.Format("Unknown header {0}", header)); } } public void ReadBody() { StringBuilder bob = new StringBuilder(); while (true) { string line = _src.ReadLine(); if (line == null) { // end of text assignBody(bob.ToString()); return; } bob.AppendLine(line); } } private void assignBody(string p) { if (_contentType == "text/plain") { pack.TextContents = p; } else { throw new ArgumentException(string.Format("Unknown content type {0}", _contentType)); } } } } }