--- /dev/null
+/* $Id$
+
+This file is part of libmsphttp
+Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Distributed under the LGPL
+*/
+
+#include <cstdlib>
+#include <msp/strings/formatter.h>
+#include <msp/strings/utils.h>
+#include "message.h"
+
+using namespace std;
+
+#include <iostream>
+
+namespace Msp {
+namespace Http {
+
+void Message::set_header(const string &hdr, const string &val)
+{
+ headers[tolower(hdr)]=val;
+}
+
+const string &Message::get_header(const string &hdr) const
+{
+ HeaderMap::const_iterator i=headers.find(hdr);
+ if(i==headers.end())
+ throw KeyError(format("Header %s is not defined", hdr));
+
+ return i->second;
+}
+
+void Message::add_data(const string &d)
+{
+ data+=d;
+ if(headers.count("content-type")==0)
+ set_header("content-type", "text/plain");
+ set_header("content-length", lexical_cast(data.size()));
+}
+
+unsigned Message::parse_data(const string &d)
+{
+ if(complete)
+ return 0;
+
+ HeaderMap::const_iterator i=headers.find("content-length");
+ if(i!=headers.end())
+ {
+ unsigned needed=lexical_cast<unsigned>(i->second)-data.size();
+ unsigned len=min(needed, d.size());
+
+ data.append(d, 0, len);
+
+ if(len==needed)
+ complete=true;
+
+ return len;
+ }
+
+ i=headers.find("transfer-encoding");
+ if(i!=headers.end() && strcasecmp(i->second, "chunked")==0)
+ {
+ unsigned pos=0;
+ while(!complete && pos<d.size())
+ {
+ if(chunk_length==0)
+ {
+ unsigned lf=d.find('\n', pos);
+ if(lf==string::npos)
+ return pos;
+ // XXX strtoul
+ chunk_length=strtoul(strip(d.substr(pos, lf-pos)).c_str(), 0, 16);
+ if(chunk_length==0)
+ complete=true;
+ pos=lf+1;
+ }
+ else
+ {
+ unsigned len=min(chunk_length, d.size()-pos);
+ data.append(d, pos, len);
+ chunk_length-=len;
+ if((pos=d.find('\n', pos+len))!=string::npos)
+ ++pos;
+ }
+ }
+
+ return pos;
+ }
+
+ return 0;
+}
+
+Message::Message():
+ http_version(0x11),
+ chunk_length(0),
+ complete(false)
+{ }
+
+string Message::str_common() const
+{
+ string result;
+
+ for(HeaderMap::const_iterator i=headers.begin(); i!=headers.end(); ++i)
+ result+=format("%s: %s\r\n", i->first, i->second);
+ result+="\r\n";
+ result+=data;
+
+ return result;
+}
+
+} // namespace Http
+} // namespace Msp