Main Page   Class Hierarchy   Alphabetical List   Compound List   Examples  

rfc822/header.h

00001 /***************************************************************************
00002     copyright            : (C) 2002-2005 by Stefano Barbato
00003     email                : [email protected]
00004 
00005     $Id: rfc822_2header_8h-source.html,v 1.4 2006-03-12 12:28:31 tat Exp $
00006  ***************************************************************************/
00007 
00008 /***************************************************************************
00009  *                                                                         *
00010  *   This program is free software; you can redistribute it and/or modify  *
00011  *   it under the terms of the GNU General Public License as published by  *
00012  *   the Free Software Foundation; either version 2 of the License, or     *
00013  *   (at your option) any later version.                                   *
00014  *                                                                         *
00015  ***************************************************************************/
00016 #ifndef _MIMETIC_RFC822_HEADER_H_
00017 #define _MIMETIC_RFC822_HEADER_H_
00018 #include <string>
00019 #include <deque>
00020 #include <cassert>
00021 #include <functional>
00022 #include <iostream>
00023 #include <mimetic/strutils.h>
00024 #include <mimetic/utils.h>
00025 #include <mimetic/rfc822/field.h>
00026 #include <mimetic/rfc822/mailbox.h>
00027 #include <mimetic/rfc822/messageid.h>
00028 #include <mimetic/rfc822/mailboxlist.h>
00029 #include <mimetic/rfc822/addresslist.h>
00030 
00031 namespace mimetic
00032 {
00033 
00034 
00035 /// RFC822 header class object
00036 /*!
00037     Use this class to build or parse message header fields.
00038     This is a STL container so you can browse fields using iterators(see ex. below).
00039 
00040     \sa <a href="../RFC/rfc822.txt">RFC822</a>
00041  */
00042 class Rfc822Header: public std::deque<Field>
00043 {
00044 public:
00045     struct find_by_name: 
00046         public std::unary_function<const Field, bool>
00047     {
00048         find_by_name(const std::string&);
00049         bool operator()(const Field&) const;
00050     private:
00051         const istring m_name;
00052     };
00053 
00054     bool hasField(const std::string&) const;
00055     
00056     const Field& field(const std::string&) const;
00057     Field& field(const std::string&);
00058 
00059     const Mailbox& sender() const;
00060     Mailbox& sender();
00061     void sender(const Mailbox&);
00062 
00063     const MailboxList& from() const;
00064     MailboxList& from();
00065     void from(const MailboxList&);
00066 
00067     const AddressList& to() const;
00068     AddressList& to();
00069     void to(const AddressList&);
00070 
00071     const std::string& subject() const;
00072     std::string& subject();
00073     void subject(const std::string&);
00074 
00075     const AddressList& replyto() const;
00076     AddressList& replyto();
00077     void replyto(const AddressList&);
00078 
00079     const AddressList& cc() const;
00080     AddressList& cc();
00081     void cc(const AddressList&);
00082 
00083     const AddressList& bcc() const;
00084     AddressList& bcc();
00085     void bcc(const AddressList&);
00086 
00087     const MessageId& messageid() const;
00088     MessageId& messageid();
00089     void messageid(const MessageId&);
00090 protected:
00091     template<typename T>
00092     const T& getField(const std::string&) const;
00093     template<typename T>
00094     T& getField(const std::string&);
00095     template<typename T>
00096     void setField(const std::string&, const T&);
00097 };
00098 
00099 
00100 // template member functions
00101 template<typename T>
00102 const T& Rfc822Header::getField(const std::string& name) const
00103 {
00104     const_iterator it;
00105     it = find_if(begin(), end(), find_by_name(name));
00106     if(it != end())
00107     {
00108         // cast away constness
00109         Field& f = const_cast<Field&>(*it);
00110         // to be sure that it's the correct type
00111         FieldValue* pFv = f.m_pValue;
00112         if(!pFv->typeChecked())
00113         {
00114             std::string val = pFv->str();
00115             delete pFv;
00116             pFv = new T(val);
00117             f.m_pValue = pFv;
00118         }
00119         return static_cast<const T&>(*pFv);
00120     } else {
00121         static const T null;
00122         return null;
00123     }
00124 }
00125 template<typename T>
00126 T& Rfc822Header::getField(const std::string& name)
00127 {    
00128     iterator it;
00129     it = find_if(begin(), end(), find_by_name(name));
00130     if(it != end())
00131     {
00132         FieldValue* pFv = it->m_pValue;
00133         if(pFv == 0)
00134         {
00135             pFv = new T;
00136             assert(pFv);
00137             it->m_pValue = pFv;
00138         }
00139         // be sure that it's the correct type
00140         else if(!pFv->typeChecked())
00141         {
00142             std::string val = pFv->str();
00143             delete pFv;
00144             pFv = new T(val);
00145             it->m_pValue = pFv;
00146         }
00147         return static_cast<T&>(*pFv);
00148     } else {
00149         // insert and get the reference of the actual 
00150         // obj in the container, then modify its fields
00151         Field f;
00152         it = insert(end(), f);
00153         it->name(name);
00154         T* pT = new T;
00155         assert(pT);
00156         it->m_pValue = pT;
00157         assert(it->m_pValue->typeChecked());
00158         return *pT;
00159     }
00160 }
00161 
00162 template<typename T>
00163 void Rfc822Header::setField(const std::string& name, const T& obj) 
00164 {
00165     // remove if already exists
00166     iterator bit = begin(), eit = end();
00167     iterator found = find_if(bit, eit, find_by_name(name));
00168     if(found != eit)
00169         erase(found);
00170     // add field
00171     Field f;
00172     iterator it;
00173     it = insert(end(), f);
00174     it->name(name);
00175     it->m_pValue = new T(obj);
00176 }
00177 
00178 }
00179 
00180 #endif