]> err.no Git - sope/blob - sope-mime/NGMime/NGMimePartParser.h
new Xcode project
[sope] / sope-mime / NGMime / NGMimePartParser.h
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #ifndef __NGMime_NGMimePartParser_H__
24 #define __NGMime_NGMimePartParser_H__
25
26 #import <Foundation/NSObject.h>
27 #import <Foundation/NSString.h>
28 #import <NGStreams/NGStreamProtocols.h>
29 #include <NGMime/NGPart.h>
30 #include <NGMime/NGMimeHeaderFieldParser.h>
31 #include <NGMime/NGMimeBodyParser.h>
32
33 /*
34   NGMimePartParser
35   
36   This is an abstract class for parsing MIME parts.
37   
38   Known Subclasses:
39     NGMimeMessageParser  (parses RFC 822 MIME messages)
40     NGMimeBodyPartParser (parses the parts contained in a multipart structure)
41     NGHttpMessageParser  (parses HTTP messages)
42 */
43
44 @class NSString, NSData;
45 @class NGMutableHashMap, NGHashMap;
46 @class NGByteBuffer;
47
48 typedef struct _NGMimeHeaderNames {
49   NSString *accept;
50   NSString *acceptLanguage;
51   NSString *acceptEncoding;
52   NSString *acceptCharset;
53   NSString *cacheControl;
54   NSString *cc;
55   NSString *connection;
56   NSString *contentDisposition;
57   NSString *contentLength;
58   NSString *contentTransferEncoding;
59   NSString *contentType;
60   NSString *cookie;
61   NSString *date;
62   NSString *from;
63   NSString *host;
64   NSString *keepAlive;
65   NSString *messageID;
66   NSString *mimeVersion;
67   NSString *organization;
68   NSString *received;
69   NSString *returnPath;
70   NSString *referer;
71   NSString *replyTo;
72   NSString *subject;
73   NSString *to;
74   NSString *userAgent;
75   NSString *xMailer;
76 } NGMimeHeaderNames;
77
78 @interface NGMimePartParser : NSObject /* abstract */
79 {
80 @protected
81   NSData       *sourceData; /* for parsing with imutable data */
82   const char   *sourceBytes;
83   int          dataIdx;     /* data parsing index */
84   int          byteLen;
85   
86   NGByteBuffer *source; // for parsing with LA
87
88   /* cached selectors */
89   int (*readByte)(id, SEL);
90   int (*la)(id, SEL, unsigned);
91   void (*consume)(id, SEL);
92   void (*consumeCnt)(id, SEL, unsigned);
93
94   /* buffer-capacity and LA (has to be at least 4) */
95   int bufLen; 
96
97   /*
98     is set to the value of content-length header field
99     if contentLength == -1 -> read until EOF
100   */
101   int  contentLength;
102   BOOL useContentLength; // should be set in subclasses
103   NSString *contentTransferEncoding;
104   
105   id   delegate; // not retained to avoid retain cycles
106
107   struct {
108     BOOL parserWillParseHeader:1;
109     BOOL parserDidParseHeader:1;
110     BOOL parserKeepHeaderFieldData:1;
111     BOOL parserKeepHeaderFieldValue:1;
112     BOOL parserParseHeaderFieldData:1;
113     BOOL parserFoundCommentInHeaderField:1;
114     BOOL parserWillParseBodyOfPart:1;
115     BOOL parserDidParseBodyOfPart:1;
116     BOOL parserParseRawBodyDataOfPart:1;
117     BOOL parserBodyParserForPart:1;
118     BOOL parserDecodeBodyOfPart:1;
119   } delegateRespondsTo;
120
121   
122 }
123
124 + (NSStringEncoding)defaultHeaderFieldEncoding;
125 + (NGMimeHeaderNames *)headerFieldNames;
126
127 /* setting the delegate */
128
129 - (void)setDelegate:(id)_delegate;
130 - (id)delegate;
131
132 /* parsing the whole part */
133
134 - (id<NGMimePart>)parsePartFromStream:(id<NGStream>)_stream;
135 - (id<NGMimePart>)parsePartFromData:(NSData *)_data;
136
137 /* header field parsing */
138
139 - (id<NGMimeHeaderFieldParser>)parserForHeaderField:(NSString *)_name;
140
141 /* perform further parsing of the header value */
142
143 - (id)valueOfHeaderField:(NSString *)_name data:(id)_data;
144
145 // Parse headers until an empty line is seen, the delegate
146 // can reject header fields from being included in the HashMap
147 // This method can return <nil> to abort the parsing process.
148 - (NGHashMap *)parseHeader;
149
150 /* body parsing */
151
152 - (id<NGMimePart>)producePartWithHeader:(NGHashMap *)_header;
153
154 - (NSData *)decodeBody:(NSData *)_data ofPart:(id<NGMimePart>)_part;
155
156 - (id<NGMimeBodyParser>)
157   parserForBodyOfPart:(id<NGMimePart>)_part data:(NSData *)_dt;
158
159 - (NGMimeType *)defaultContentTypeForPart:(id<NGMimePart>)_part;
160
161 - (void)parseBodyOfPart:(id<NGMimePart>)_part;
162
163 /* hooks for subclasses */
164
165 - (BOOL)parsePrefix; // returns NO to abort parsing
166 - (void)parseSuffix;
167 - (BOOL)prepareForParsingFromStream:(id<NGStream>)_stream;
168 - (void)finishParsingOfPart:(id<NGMimePart>)_part;
169
170 /* accessors */
171
172 - (void)setUseContentLength:(BOOL)_use;
173 - (BOOL)doesUseContentLength;
174
175 - (NSData *)applyTransferEncoding:(NSString *)_encoding onData:(NSData *)_data;
176
177 @end /* NGMimePartParser */
178
179 @interface NSObject(NGMimePartParserDelegate)
180
181 /*
182   Called before the parsing of the headers begins. The delegate can return NO to
183   stop parsing or YES to continue parsing.
184 */
185 - (BOOL)parserWillParseHeader:(NGMimePartParser *)_parser;
186
187 /*
188   This method is invoked when the parser finished parsing the complete header.
189   Those headers are available in the HashMap which is given to the delegate.
190 */
191 - (void)parser:(NGMimePartParser *)_parser didParseHeader:(NGHashMap *)_headers;
192
193 /*
194   This method is invoked when a header field was read in. The field value is
195   as raw data which may be further processed by a field-value-parser. With
196   this method the delegate becomes to opportunity to parse the value itself.
197   When implementing this method the delegate takes over full responsibility
198   for parsing the field-value, no header-parser is invoked by the MIME parser
199   automatically.
200 */
201 - (id)parser:(NGMimePartParser *)_parser
202   parseHeaderField:(NSString *)_name
203   data:(NSData *)_data;
204
205 /*
206   The delegate is asked whether the parser should proceed processing the header
207   field or whether the header field should be thrown away. Throwing away a header
208   field does not stop the parsing, it just ignores this field.
209 */
210 - (BOOL)parser:(NGMimePartParser *)_parser
211   keepHeaderField:(NSString *)_name
212   data:(NSData *)_value;
213   
214 /*
215   The delegate is asked whether the parser should proceed processing the header
216   field or whether the header field should be thrown away. Throwing away a header
217   field does not stop the parsing, it just ignores this field.
218   The value of the header is already parsed (this means in effect that the delegate
219   either didn't implement parser:keepHeader:data: or that it returned YES in this
220   method).
221 */
222 - (BOOL)parser:(NGMimePartParser *)_parser
223   keepHeaderField:(NSString *)_name
224   value:(id)_value;
225
226 /*
227   The parser found a comment in a header field. This comment could be stored for
228   further processing by the delegate. Comment are usually ignored.
229 */
230 - (void)parser:(NGMimePartParser *)_parser
231   foundComment:(NSString *)_comment // can be nil, if keepComments==NO
232   inHeaderField:(NSString *)_name;
233
234 /*
235   When the body of a part is read in appropriate content or content-transfer
236   encodings may need to be applied. Use this method to perform this operation.
237 */
238 - (NSData *)parser:(NGMimePartParser *)_parser
239   decodeBody:(NSData *)_body
240   ofPart:(id<NGMimePart>)_part;
241
242 /*
243   After the headers were parsed the parser creates an NGMimePart object which
244   containes the headers. It will then begin to read in the body of the MIME
245   message, usually first as an NSData object.
246   You can return NO if you want to stop parsing (eg based on some values in the
247   headers or YES if you want to have the parser read in the data of the body.
248 */
249 - (BOOL)parser:(NGMimePartParser *)_parser
250   willParseBodyOfPart:(id<NGMimePart>)_part;
251
252 /*
253   The parser successfully read in the body of the part.
254 */
255 - (void)parser:(NGMimePartParser *)_parser
256   didParseBodyOfPart:(id<NGMimePart>)_part;
257
258 /*
259   After the MIME parser read in the body as an NSData object the delegate can
260   parse the body data and assign the result to the _part.
261   The delegate can return NO if it decides not to parse the body. The builtin
262   parser sequence is applied in this case.
263   Instead of parsing the body itself the delegate can select an appropriate
264   parser for the body using the -parser:bodyParserForPart: delegate method.
265 */
266 - (BOOL)parser:(NGMimePartParser *)_parser
267   parseRawBodyData:(NSData *)_data
268   ofPart:(id<NGMimePart>)_part;
269
270 /*
271   If the delegate does not parse the body itself, it can still select an
272   appropriate body parser using this method.
273 */
274 - (id<NGMimeBodyParser>)parser:(NGMimePartParser *)_parser
275   bodyParserForPart:(id<NGMimePart>)_part;
276
277 @end /* NSObject(NGMimePartParserDelegate) */
278
279 @interface NSObject(NGMimePartParser)
280
281 - (void)parser:(NGMimePartParser *)_parser
282   setOriginalHeaderFieldName:(NSString *)_name;
283
284 @end
285
286 #endif /* __NGMime_NGMimePartParser_H__ */