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