summaryrefslogtreecommitdiffstats
path: root/libmail/headers.C
diff options
context:
space:
mode:
Diffstat (limited to 'libmail/headers.C')
-rw-r--r--libmail/headers.C319
1 files changed, 319 insertions, 0 deletions
diff --git a/libmail/headers.C b/libmail/headers.C
new file mode 100644
index 0000000..813056c
--- /dev/null
+++ b/libmail/headers.C
@@ -0,0 +1,319 @@
+/*
+** Copyright 2004, Double Precision Inc.
+**
+** See COPYING for distribution information.
+*/
+#include "libmail_config.h"
+#include "rfcaddr.H"
+#include "headers.H"
+#include "rfc2047encode.H"
+#include "rfc2047decode.H"
+#include "rfc2045/rfc2045.h"
+#include <errno.h>
+
+using namespace std;
+
+mail::Header::~Header()
+{
+}
+
+string mail::Header::wrap(string s) const
+{
+ string ws=name + ": ";
+ size_t init_offset=ws.size();
+ size_t offset=init_offset;
+ string::iterator b=s.begin(), e=s.end();
+ bool first=true;
+
+ while (b != e)
+ {
+ string::iterator c=b;
+
+ while (c != e)
+ {
+ if (*c != ' ' && *c != '\t')
+ break;
+ ++c;
+ }
+
+ while (c != e)
+ {
+ if (*c == ' ' || *c == '\t')
+ break;
+ ++c;
+ }
+
+ if (c-b + offset > 76 && !first)
+ {
+ while (b != c && (*b == ' ' || *b == '\t'))
+ ++b;
+ if (b == e)
+ break;
+
+ ws += "\n";
+ ws.insert(ws.end(), init_offset, ' ');
+ offset=init_offset;
+ }
+ ws.insert(ws.end(), b, c);
+ offset += c-b;
+ b=c;
+ first=false;
+ }
+ return ws;
+}
+
+mail::Header::plain::~plain()
+{
+}
+
+mail::Header *mail::Header::plain::clone() const
+{
+ mail::Header::plain *c=new plain(name, text);
+
+ if (!c)
+ throw strerror(errno);
+ return c;
+}
+
+string mail::Header::plain::toString() const
+{
+ return wrap(text);
+}
+
+string mail::Header::encoded::encode(string text, string charset, string lang)
+{
+ if (lang.size() > 0)
+ charset += "*" + lang;
+
+ return mail::rfc2047::encode(text, charset);
+}
+
+mail::Header::encoded::encoded(string name,
+ string text, string charset, string lang)
+ : Header::plain(name, encode(text, charset, lang))
+{
+}
+
+mail::Header::encoded::~encoded()
+{
+}
+
+mail::Header::addresslist::addresslist(string name)
+ : mail::Header(name)
+{
+}
+
+mail::Header::addresslist::addresslist(string name,
+ const std::vector<mail::emailAddress>
+ &addressesArg)
+ : mail::Header(name), addresses(addressesArg)
+{
+}
+
+mail::Header::addresslist::~addresslist()
+{
+}
+
+mail::Header *mail::Header::addresslist::clone() const
+{
+ mail::Header::addresslist *c=new addresslist(name, addresses);
+
+ if (!c)
+ throw strerror(errno);
+ return c;
+}
+
+std::string mail::Header::addresslist::toString() const
+{
+ return mail::address::toString(name + ": ",
+ addresses);
+}
+
+mail::Header::mime::mime(string name)
+ : mail::Header(name)
+{
+}
+
+mail::Header::mime::mime(string name, string valueArg)
+ : mail::Header(name), value(valueArg)
+{
+}
+
+mail::Header::mime mail::Header::mime::fromString(string header)
+{
+ size_t n=header.find(':');
+
+ if (n != std::string::npos)
+ ++n;
+ else
+ n=header.size();
+
+ mime m(header.substr(0, n));
+
+ header=header.substr(n);
+
+ rfc2045_parse_mime_header(header.c_str(), cb_type, cb_param, &m);
+ return m;
+}
+
+void mail::Header::mime::cb_type(const char *t, void *void_arg)
+{
+ mail::Header::mime *a=(mail::Header::mime *)void_arg;
+
+ a->value=t;
+ mail::upper(a->value);
+}
+
+void mail::Header::mime::cb_param(const char *name,
+ const char *value,
+ void *void_arg)
+{
+ mail::Header::mime *a=(mail::Header::mime *)void_arg;
+
+ string n=name;
+
+ mail::upper(n);
+
+ if (!a->parameters.exists(name))
+ a->parameters.set_simple(name, value);
+}
+
+mail::Header::mime::~mime()
+{
+}
+
+string mail::Header::mime::toString() const
+{
+ string h=name + ": " + value;
+ size_t init_offset=name.size()+2;
+
+ const_parameter_iterator b=begin();
+ const_parameter_iterator e=end();
+
+ size_t offset=h.size();
+
+ while (b != e)
+ {
+ string w=b->first;
+ string s=b->second;
+
+ string::iterator sb=s.begin(), se=s.end();
+
+ if (sb != se)
+ w += "=";
+
+ while (sb != se)
+ {
+ if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?*+-/=_", *sb))
+ break;
+ ++sb;
+ }
+
+ if (sb == se)
+ {
+ w += s;
+ }
+ else
+ {
+ w += "\"";
+
+ string::iterator p=s.begin();
+
+ for (sb=p; sb != se; sb++)
+ {
+ if (*sb == '\\' || *sb == '"')
+ {
+ w += string(p, sb) + "\\";
+ w += *sb;
+ p=sb+1;
+ }
+ }
+ w += string(p, sb);
+ w += "\"";
+ }
+
+ if (offset + w.size() > 74)
+ {
+ h += ";\n";
+ h.insert(h.end(), init_offset, ' ');
+ offset=init_offset;
+ }
+ else
+ {
+ h += "; ";
+ offset += 2;
+ }
+ h += w;
+ offset += w.size();
+ ++b;
+ }
+ return h;
+}
+
+mail::Header *mail::Header::mime::clone() const
+{
+ mail::Header::mime *c=new mime(name, value);
+
+ if (!c)
+ throw strerror(errno);
+ c->parameters=parameters;
+ return c;
+}
+
+mail::Header::listitem::listitem(const listitem &hArg)
+ : h(hArg.h->clone())
+{
+}
+
+mail::Header::listitem::listitem(const mail::Header &hArg)
+ : h(hArg.clone())
+{
+}
+
+mail::Header::listitem::~listitem()
+{
+ delete h;
+}
+
+mail::Header::listitem &mail::Header::listitem::operator=(const listitem &hArg)
+{
+ Header *p=hArg.h->clone();
+
+ delete h;
+ h=p;
+ return *this;
+}
+
+mail::Header::listitem &mail::Header::listitem::operator=(const Header &hArg)
+{
+ Header *p=hArg.clone();
+
+ delete h;
+ h=p;
+ return *this;
+}
+
+mail::Header::list::list()
+{
+}
+
+mail::Header::list::~list()
+{
+}
+
+mail::Header::list::operator string() const
+{
+ string h;
+
+ const_iterator b=begin();
+ const_iterator e=end();
+
+ while (b != e)
+ {
+ const Header &hh= *b;
+ h += hh.toString();
+ h += "\n";
+ ++b;
+ }
+ return h;
+}