2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #ifndef __NGMime_NGMimePartParser_H__
23 #define __NGMime_NGMimePartParser_H__
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>
35 This is an abstract class for parsing MIME parts.
38 NGMimeMessageParser (parses RFC 822 MIME messages)
39 NGMimeBodyPartParser (parses the parts contained in a multipart structure)
40 NGHttpMessageParser (parses HTTP messages)
43 @class NSString, NSData;
44 @class NGMutableHashMap, NGHashMap;
47 typedef struct _NGMimeHeaderNames {
49 NSString *acceptLanguage;
50 NSString *acceptEncoding;
51 NSString *acceptCharset;
52 NSString *cacheControl;
55 NSString *contentDisposition;
56 NSString *contentLength;
57 NSString *contentTransferEncoding;
58 NSString *contentType;
65 NSString *mimeVersion;
66 NSString *organization;
77 @interface NGMimePartParser : NSObject /* abstract */
80 NSData *sourceData; /* for parsing with imutable data */
81 const char *sourceBytes;
82 int dataIdx; /* data parsing index */
85 NGByteBuffer *source; // for parsing with LA
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);
93 /* buffer-capacity and LA (has to be at least 4) */
97 is set to the value of content-length header field
98 if contentLength == -1 -> read until EOF
101 BOOL useContentLength; // should be set in subclasses
102 NSString *contentTransferEncoding;
104 id delegate; // not retained to avoid retain cycles
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;
123 + (NSStringEncoding)defaultHeaderFieldEncoding;
124 + (NGMimeHeaderNames *)headerFieldNames;
126 /* setting the delegate */
128 - (void)setDelegate:(id)_delegate;
131 /* parsing the whole part */
133 - (id<NGMimePart>)parsePartFromStream:(id<NGStream>)_stream;
134 - (id<NGMimePart>)parsePartFromData:(NSData *)_data;
136 /* header field parsing */
138 - (id<NGMimeHeaderFieldParser>)parserForHeaderField:(NSString *)_name;
140 /* perform further parsing of the header value */
142 - (id)valueOfHeaderField:(NSString *)_name data:(id)_data;
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;
151 - (id<NGMimePart>)producePartWithHeader:(NGHashMap *)_header;
153 - (NSData *)decodeBody:(NSData *)_data ofPart:(id<NGMimePart>)_part;
155 - (id<NGMimeBodyParser>)
156 parserForBodyOfPart:(id<NGMimePart>)_part data:(NSData *)_dt;
158 - (NGMimeType *)defaultContentTypeForPart:(id<NGMimePart>)_part;
160 - (void)parseBodyOfPart:(id<NGMimePart>)_part;
162 /* hooks for subclasses */
164 - (BOOL)parsePrefix; // returns NO to abort parsing
166 - (BOOL)prepareForParsingFromStream:(id<NGStream>)_stream;
167 - (void)finishParsingOfPart:(id<NGMimePart>)_part;
171 - (void)setUseContentLength:(BOOL)_use;
172 - (BOOL)doesUseContentLength;
174 - (NSData *)applyTransferEncoding:(NSString *)_encoding onData:(NSData *)_data;
176 @end /* NGMimePartParser */
178 @interface NSObject(NGMimePartParserDelegate)
181 Called before the parsing of the headers begins. The delegate can return NO to
182 stop parsing or YES to continue parsing.
184 - (BOOL)parserWillParseHeader:(NGMimePartParser *)_parser;
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.
190 - (void)parser:(NGMimePartParser *)_parser didParseHeader:(NGHashMap *)_headers;
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
200 - (id)parser:(NGMimePartParser *)_parser
201 parseHeaderField:(NSString *)_name
202 data:(NSData *)_data;
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.
209 - (BOOL)parser:(NGMimePartParser *)_parser
210 keepHeaderField:(NSString *)_name
211 data:(NSData *)_value;
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
221 - (BOOL)parser:(NGMimePartParser *)_parser
222 keepHeaderField:(NSString *)_name
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.
229 - (void)parser:(NGMimePartParser *)_parser
230 foundComment:(NSString *)_comment // can be nil, if keepComments==NO
231 inHeaderField:(NSString *)_name;
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.
237 - (NSData *)parser:(NGMimePartParser *)_parser
238 decodeBody:(NSData *)_body
239 ofPart:(id<NGMimePart>)_part;
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.
248 - (BOOL)parser:(NGMimePartParser *)_parser
249 willParseBodyOfPart:(id<NGMimePart>)_part;
252 The parser successfully read in the body of the part.
254 - (void)parser:(NGMimePartParser *)_parser
255 didParseBodyOfPart:(id<NGMimePart>)_part;
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.
265 - (BOOL)parser:(NGMimePartParser *)_parser
266 parseRawBodyData:(NSData *)_data
267 ofPart:(id<NGMimePart>)_part;
270 If the delegate does not parse the body itself, it can still select an
271 appropriate body parser using this method.
273 - (id<NGMimeBodyParser>)parser:(NGMimePartParser *)_parser
274 bodyParserForPart:(id<NGMimePart>)_part;
276 @end /* NSObject(NGMimePartParserDelegate) */
278 @interface NSObject(NGMimePartParser)
280 - (void)parser:(NGMimePartParser *)_parser
281 setOriginalHeaderFieldName:(NSString *)_name;
285 #endif /* __NGMime_NGMimePartParser_H__ */