Changeset e7bbf3c6b857df8ad33c4d39396d693b48a48461

Show
Ignore:
Timestamp:
09/02/10 22:19:15 (17 months ago)
Author:
Antti-Juhani Kaijanaho <antti-juhani@…>
Children:
1a970cd0640f976f152341597a5249ec22acbba7
Parents:
c504199e7e127458fff243397776ee854e62b7a3
git-committer:
Antti-Juhani Kaijanaho <antti-juhani@…> (09/02/10 22:19:15)
Message:

Add support for message/rfc822

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

Files:
5 added
4 modified

Legend:

Unmodified
Added
Removed
  • msg/entity.cc

    rc504199 re7bbf3c  
    2020#include "content_type.hh" 
    2121#include "entity.hh" 
    22 #include "format_violation.hh" 
     22#include "message_entity.hh" 
    2323#include "multipart.hh" 
    2424#include "text_plain.hh" 
     
    8181        void entity::parse_headers(std::string msgstr) 
    8282        { 
    83                 typedef format_violation fv; 
    84  
    8583                size_t inx = 0; 
    8684                size_t name_start = 0; 
     
    9088        FIELD_NAME: 
    9189                if (inx >= msgstr.length()) 
    92                         throw fv("message ends in the middle of a header name"); 
     90                { 
     91                        errors += 
     92                                "message ends in the middle of a header name\n"; 
     93                        goto HEADER_END; 
     94                } 
     95 
    9396                if (is_ftext(msgstr[inx])) 
    9497                { 
     
    9699                        goto FIELD_NAME; 
    97100                } 
    98                 if (msgstr[inx] != ':') { 
    99                         throw fv(boost::str(boost::format 
    100                                             ("invalid character (0x%02x) " 
    101                                              "in header field name") 
    102                                             % (unsigned)msgstr[inx])); 
     101                if (msgstr[inx] != ':') 
     102                { 
     103                        errors += boost::str(boost::format 
     104                                             ("invalid character (0x%02x) " 
     105                                              "in header field name\n") 
     106                                             % (unsigned)msgstr[inx]); 
    103107                } 
    104108                field_name = msgstr.substr(name_start, inx - name_start); 
    105109                inx++; 
    106110                if (inx >= msgstr.length() || msgstr[inx] != ' ') 
    107                         throw fv("header field '" + field_name + "' " 
    108                                  "is missing the mandatory space after colon"); 
     111                { 
     112                        errors += "header field '" + field_name + "' " 
     113                                "is missing the mandatory space after colon\n"; 
     114                } 
    109115                inx++; 
    110116                body_start = inx; 
     
    113119        FIELD_BODY: 
    114120                if (inx >= msgstr.length()) 
    115                         throw fv("header field '" + field_name + "' " 
    116                                  "terminates abruptly"); 
     121                { 
     122                        errors += "header field '" + field_name + "' " 
     123                                "terminates abruptly\n"; 
     124                        goto HEADER_END; 
     125                } 
    117126                if (is_vchar(msgstr[inx]) || is_wsp(msgstr[inx])) 
    118127                { 
     
    121130                } 
    122131                if (msgstr[inx] != '\r')  
    123                         throw fv("header field '" + field_name + "' " 
    124                                  "contains a character that is not allowed"); 
     132                { 
     133                        errors += "header field '" + field_name + "' " 
     134                                "contains a character that is not allowed\n"; 
     135                } 
    125136                inx++; 
    126137                if (inx >= msgstr.length() || msgstr[inx] != '\n')  
    127                         throw fv("header field '" + field_name + "' " 
    128                                  "contains a stray CR"); 
     138                { 
     139                        errors += "header field '" + field_name + "' " 
     140                                "contains a stray CR\n"; 
     141                } 
    129142                assert(inx  < msgstr.length()); 
    130                 assert(msgstr[inx] == '\n'); 
    131143                inx++; 
    132144                if (inx < msgstr.length() && is_wsp(msgstr[inx])) 
     
    244256                switch (ct.get_type()) 
    245257                { 
     258                case content_type::MESSAGE: 
     259                        rv.reset(new message_entity(*this)); 
     260                        break; 
    246261                case content_type::MULTIPART: 
    247262                        rv.reset(new multipart(*this)); 
  • msg/entity.hh

    rc504199 re7bbf3c  
    2121#define GUARD_MSG_ENTITY_HH 
    2222 
     23#include "format_violation.hh" 
    2324#include <boost/algorithm/string/case_conv.hpp> 
    2425#include <boost/shared_ptr.hpp> 
     
    3435        class entity 
    3536        { 
     37                std::string errors; 
     38 
    3639        public: 
    3740                typedef boost::shared_ptr<entity> ptr; 
     
    4447 
    4548                virtual ~entity() {} 
     49 
     50                void validate_format() { 
     51                        if (!errors.empty()) throw format_violation(errors); 
     52                } 
    4653 
    4754                field_iterator fields_begin() const { 
  • msg/msg.cc

    r9948114 re7bbf3c  
    215215        void msg::validate_imf()  
    216216        { 
     217                validate_format(); 
    217218                check_present("From");                 
    218219                check_present("Date");                 
  • tlate/msg_value.cc

    r563ece2 re7bbf3c  
    2121#include "empty_value.hh" 
    2222#include "group_value.hh" 
     23#include "header_value.hh" 
    2324#include "lazy_structured_value.hh" 
    2425#include "list_value.hh" 
     
    9899        }; 
    99100 
    100         class fld_value : public structured_value 
    101         { 
    102                 std::string fld; 
    103                 db::user::const_ptr u; 
    104         public: 
    105                 fld_value(std::string fld, db::user::const_ptr u) 
    106                         : fld(fld), u(u) 
    107                         {} 
    108                 value::const_ptr get(std::string var) const { 
    109                         size_t col = fld.find(':'); 
    110                         value::ptr rv; 
    111                         /**/ if (var == "name") 
    112                                 rv.reset(new string_value 
    113                                          (quote(fld.substr(0,col), false))); 
    114                         else if (var == "body") 
    115                         { 
    116                                 std::string s = fld.substr(col+1); 
    117                                 s = decode_unstructured(s); 
    118                                 rv.reset(new string_value(quote(s, !u))); 
    119                         } 
    120                         return rv; 
    121                 } 
    122         }; 
    123  
    124         class hdr_seq : public sequential_value 
    125         { 
    126                 msg::msg::const_ptr m; 
    127                 db::user::const_ptr u; 
    128  
    129                 class vit : public virtual_iterator 
    130                 { 
    131                         msg::msg::field_iterator it; 
    132                         mutable value::const_ptr cur; 
    133                         db::user::const_ptr u; 
    134   
    135                         vit(msg::msg::field_iterator it, value::const_ptr cur, 
    136                             db::user::const_ptr u) 
    137                                 : it(it) 
    138                                 , cur(cur) 
    139                                 , u(u) 
    140                                 {} 
    141                public: 
    142                         vit(msg::msg::field_iterator it, db::user::const_ptr u) 
    143                                 : it(it) 
    144                                 , u(u) 
    145                                 {} 
    146                         virtual_iterator *clone() const { 
    147                                 return new vit(it, cur, u); 
    148                         } 
    149                         value::const_ptr get() const { 
    150                                 if (!cur) cur.reset(new fld_value(*it, u)); 
    151                                 return cur; 
    152                         } 
    153                         void next() { 
    154                                 it++; 
    155                                 cur.reset(); 
    156                         } 
    157                         bool eq(const virtual_iterator &o_) const { 
    158                                 const vit *o = dynamic_cast<const vit *>(&o_); 
    159                                 return o ? it == o->it : false; 
    160                         } 
    161                 }; 
    162  
    163         public: 
    164                 hdr_seq(msg::msg::const_ptr m, db::user::const_ptr u) 
    165                         : m(m) 
    166                         , u(u) 
    167                         {} 
    168                 const_iterator begin() const { 
    169                         return const_iterator 
    170                                 (new vit(m->fields_begin(), u)); 
    171                 } 
    172                 const_iterator end() const { 
    173                         return const_iterator 
    174                                 (new vit(m->fields_end(), u)); 
    175                 } 
    176         }; 
    177101 
    178102        value::ptr mk_msg_value(db::thread_node::const_ptr tr, 
     
    246170                                                 
    247171                else if (rauthz && m && var == "header") 
    248                         rv.reset(new hdr_seq(m,u)); // FIXME -> seqval 
     172                        rv.reset(new header_value(m,!u)); 
    249173                else if (rauthz && m && var == "body") 
    250174                {