00001
00002
00003
00004
00005
00006
00007 #ifndef _MIMETIC_RFC822_HEADER_H_
00008 #define _MIMETIC_RFC822_HEADER_H_
00009 #include <string>
00010 #include <deque>
00011 #include <cassert>
00012 #include <functional>
00013 #include <iostream>
00014 #include <mimetic/strutils.h>
00015 #include <mimetic/utils.h>
00016 #include <mimetic/rfc822/field.h>
00017 #include <mimetic/rfc822/mailbox.h>
00018 #include <mimetic/rfc822/messageid.h>
00019 #include <mimetic/rfc822/mailboxlist.h>
00020 #include <mimetic/rfc822/addresslist.h>
00021
00022 namespace mimetic
00023 {
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 class Rfc822Header: public std::deque<Field>
00034 {
00035 public:
00036 struct find_by_name:
00037 public std::unary_function<const Field, bool>
00038 {
00039 find_by_name(const std::string&);
00040 bool operator()(const Field&) const;
00041 private:
00042 const istring m_name;
00043 };
00044
00045 bool hasField(const std::string&) const;
00046
00047 const Field& field(const std::string&) const;
00048 Field& field(const std::string&);
00049
00050 const Mailbox& sender() const;
00051 Mailbox& sender();
00052 void sender(const Mailbox&);
00053
00054 const MailboxList& from() const;
00055 MailboxList& from();
00056 void from(const MailboxList&);
00057
00058 const AddressList& to() const;
00059 AddressList& to();
00060 void to(const AddressList&);
00061
00062 const std::string& subject() const;
00063 std::string& subject();
00064 void subject(const std::string&);
00065
00066 const AddressList& replyto() const;
00067 AddressList& replyto();
00068 void replyto(const AddressList&);
00069
00070 const AddressList& cc() const;
00071 AddressList& cc();
00072 void cc(const AddressList&);
00073
00074 const AddressList& bcc() const;
00075 AddressList& bcc();
00076 void bcc(const AddressList&);
00077
00078 const MessageId& messageid() const;
00079 MessageId& messageid();
00080 void messageid(const MessageId&);
00081 protected:
00082 template<typename T>
00083 const T& getField(const std::string&) const;
00084 template<typename T>
00085 T& getField(const std::string&);
00086 template<typename T>
00087 void setField(const std::string&, const T&);
00088 };
00089
00090
00091
00092 template<typename T>
00093 const T& Rfc822Header::getField(const std::string& name) const
00094 {
00095 const_iterator it;
00096 it = find_if(begin(), end(), find_by_name(name));
00097 if(it != end())
00098 {
00099
00100 Field& f = const_cast<Field&>(*it);
00101
00102 FieldValue* pFv = f.m_pValue;
00103 if(!pFv->typeChecked())
00104 {
00105 std::string val = pFv->str();
00106 delete pFv;
00107 pFv = new T(val);
00108 f.m_pValue = pFv;
00109 }
00110 return static_cast<const T&>(*pFv);
00111 } else {
00112 static const T null;
00113 return null;
00114 }
00115 }
00116 template<typename T>
00117 T& Rfc822Header::getField(const std::string& name)
00118 {
00119 iterator it;
00120 it = find_if(begin(), end(), find_by_name(name));
00121 if(it != end())
00122 {
00123 FieldValue* pFv = it->m_pValue;
00124 if(pFv == 0)
00125 {
00126 pFv = new T;
00127 assert(pFv);
00128 it->m_pValue = pFv;
00129 }
00130
00131 else if(!pFv->typeChecked())
00132 {
00133 std::string val = pFv->str();
00134 delete pFv;
00135 pFv = new T(val);
00136 it->m_pValue = pFv;
00137 }
00138 return static_cast<T&>(*pFv);
00139 } else {
00140
00141
00142 Field f;
00143 it = insert(end(), f);
00144 it->name(name);
00145 T* pT = new T;
00146 assert(pT);
00147 it->m_pValue = pT;
00148 assert(it->m_pValue->typeChecked());
00149 return *pT;
00150 }
00151 }
00152
00153 template<typename T>
00154 void Rfc822Header::setField(const std::string& name, const T& obj)
00155 {
00156
00157 iterator bit = begin(), eit = end();
00158 iterator found = find_if(bit, eit, find_by_name(name));
00159 if(found != eit)
00160 erase(found);
00161
00162 Field f;
00163 iterator it;
00164 it = insert(end(), f);
00165 it->name(name);
00166 it->m_pValue = new T(obj);
00167 }
00168
00169 }
00170
00171 #endif