1 /*  --------------------------------------------------------------------
2  *  Filename:
3  *    src/parsers/mime/mime.h
4  *
5  *  Description:
6  *    Declaration of main mime parser components
7  *  --------------------------------------------------------------------
8  *  Copyright 2002-2005 Andreas Aardal Hanssen
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  *  --------------------------------------------------------------------
24  */
25 #ifndef mime_h_included
26 #define mime_h_included
27 
28 #include <string>
29 #include <vector>
30 #include <map>
31 #include <stdio.h>
32 
33 namespace Binc {
34 
35 class MimeInputSource;
36 
37 
38 //----------------------------------------------------------------------
39 class HeaderItem {
40 private:
41     mutable std::string key;
42     mutable std::string value;
43 
44 public:
getKey(void)45     inline const std::string &getKey(void) const { return key; }
getValue(void)46     inline const std::string &getValue(void) const { return value; }
47 
48     //--
49     HeaderItem(void);
50     HeaderItem(const std::string &key, const std::string &value);
51 };
52 
53 //----------------------------------------------------------------------
54 class Header {
55 private:
56     mutable std::vector<HeaderItem> content;
57 
58 public:
59     bool getFirstHeader(const std::string &key, HeaderItem &dest) const;
60     bool getAllHeaders(const std::string &key, std::vector<HeaderItem> &dest)
61         const;
62     void add(const std::string &name, const std::string &content);
63     void clear(void);
64 
65     //--
66     Header(void);
67     ~Header(void);
68 };
69 
70 //----------------------------------------------------------------------
71 class IODevice;
72 class MimeDocument;
73 class MimePart {
74 protected:
75 public:
76     mutable bool multipart;
77     mutable bool messagerfc822;
78     mutable std::string subtype;
79     mutable std::string boundary;
80 
81     mutable unsigned int headerstartoffsetcrlf;
82     mutable unsigned int headerlength;
83 
84     mutable unsigned int bodystartoffsetcrlf;
85     mutable unsigned int bodylength;
86     mutable unsigned int nlines;
87     mutable unsigned int nbodylines;
88     mutable unsigned int size;
89 
90 public:
91     enum FetchType {
92         FetchBody,
93         FetchHeader,
94         FetchMime
95     };
96 
97     mutable Header h;
98 
99     mutable std::vector<MimePart> members;
100 
getSubType(void)101     inline const std::string &getSubType(void) const { return subtype; }
isMultipart(void)102     inline bool isMultipart(void) const { return multipart; }
isMessageRFC822(void)103     inline bool isMessageRFC822(void) const { return messagerfc822; }
getSize(void)104     inline unsigned int getSize(void) const { return bodylength; }
getNofLines(void)105     inline unsigned int getNofLines(void) const { return nlines; }
getNofBodyLines(void)106     inline unsigned int getNofBodyLines(void) const { return nbodylines; }
getBodyLength(void)107     inline unsigned int getBodyLength(void) const { return bodylength; }
getBodyStartOffset(void)108     inline unsigned int getBodyStartOffset(void) const {
109         return bodystartoffsetcrlf; }
110 
111     void printBody(Binc::IODevice &output, unsigned int startoffset,
112                    unsigned int length) const;
113     void getBody(std::string& s, unsigned int startoffset, unsigned int length)
114         const;
115     virtual void clear(void);
116 
117     virtual int doParseOnlyHeader(MimeInputSource *ms);
118     virtual int doParseFull(MimeInputSource *ms,
119                             const std::string &toboundary, int &boundarysize);
120 
121     MimePart(void);
122     virtual ~MimePart(void);
123 
124 private:
125     MimeInputSource *mimeSource;
126 
127     bool parseOneHeaderLine(Binc::Header *header, unsigned int *nlines);
128 
129     bool skipUntilBoundary(const std::string &delimiter,
130                            unsigned int *nlines, bool *eof);
131     inline void postBoundaryProcessing(bool *eof,
132                                        unsigned int *nlines,
133                                        int *boundarysize,
134                                        bool *foundendofpart);
135     void parseMultipart(const std::string &boundary,
136                         const std::string &toboundary,
137                         bool *eof,
138                         unsigned int *nlines,
139                         int *boundarysize,
140                         bool *foundendofpart,
141                         unsigned int *bodylength,
142                         std::vector<Binc::MimePart> *members);
143     void parseSinglePart(const std::string &toboundary,
144                          int *boundarysize,
145                          unsigned int *nbodylines,
146                          unsigned int *nlines,
147                          bool *eof, bool *foundendofpart,
148                          unsigned int *bodylength);
149     void parseHeader(Binc::Header *header, unsigned int *nlines);
150     void analyzeHeader(Binc::Header *header, bool *multipart,
151                        bool *messagerfc822, std::string *subtype,
152                        std::string *boundary);
153     void parseMessageRFC822(std::vector<Binc::MimePart> *members,
154                             bool *foundendofpart,
155                             unsigned int *bodylength,
156                             unsigned int *nbodylines,
157                             const std::string &toboundary);
158 };
159 
160 //----------------------------------------------------------------------
161 class MimeDocument : public MimePart {
162 public:
163     MimeDocument(void);
164     ~MimeDocument(void);
165 
166     void parseOnlyHeader(int fd);
167     void parseFull(int fd);
168     void parseOnlyHeader(std::istream& s);
169     void parseFull(std::istream& s);
170 
171     void clear(void);
172 
isHeaderParsed(void)173     bool isHeaderParsed(void) const {
174             return headerIsParsed;
175         }
isAllParsed(void)176     bool isAllParsed(void) const {
177             return allIsParsed;
178         }
179 
180 private:
181     bool headerIsParsed;
182     bool allIsParsed;
183     MimeInputSource *doc_mimeSource;
184 };
185 
186 };
187 
188 #endif
189