2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
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
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.
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
23 #ifndef __NGMime_NGMimePartParser_H__
24 #define __NGMime_NGMimePartParser_H__
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>
36 This is an abstract class for parsing MIME parts.
39 NGMimeMessageParser (parses RFC 822 MIME messages)
40 NGMimeBodyPartParser (parses the parts contained in a multipart structure)
41 NGHttpMessageParser (parses HTTP messages)
44 @class NSString, NSData;
45 @class NGMutableHashMap, NGHashMap;
48 typedef struct _NGMimeHeaderNames {
50 NSString *acceptLanguage;
51 NSString *acceptEncoding;
52 NSString *acceptCharset;
53 NSString *cacheControl;
56 NSString *contentDisposition;
57 NSString *contentLength;
58 NSString *contentTransferEncoding;
59 NSString *contentType;
66 NSString *mimeVersion;
67 NSString *organization;
78 @interface NGMimePartParser : NSObject /* abstract */
81 NSData *sourceData; /* for parsing with imutable data */
82 const char *sourceBytes;
83 int dataIdx; /* data parsing index */
86 NGByteBuffer *source; // for parsing with LA
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);
94 /* buffer-capacity and LA (has to be at least 4) */
98 is set to the value of content-length header field
99 if contentLength == -1 -> read until EOF
102 BOOL useContentLength; // should be set in subclasses
103 NSString *contentTransferEncoding;
105 id delegate; // not retained to avoid retain cycles
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;
124 + (NSStringEncoding)defaultHeaderFieldEncoding;
125 + (NGMimeHeaderNames *)headerFieldNames;
127 /* setting the delegate */
129 - (void)setDelegate:(id)_delegate;
132 /* parsing the whole part */
134 - (id<NGMimePart>)parsePartFromStream:(id<NGStream>)_stream;
135 - (id<NGMimePart>)parsePartFromData:(NSData *)_data;
137 /* header field parsing */
139 - (id<NGMimeHeaderFieldParser>)parserForHeaderField:(NSString *)_name;
141 /* perform further parsing of the header value */
143 - (id)valueOfHeaderField:(NSString *)_name data:(id)_data;
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;
152 - (id<NGMimePart>)producePartWithHeader:(NGHashMap *)_header;
154 - (NSData *)decodeBody:(NSData *)_data ofPart:(id<NGMimePart>)_part;
156 - (id<NGMimeBodyParser>)
157 parserForBodyOfPart:(id<NGMimePart>)_part data:(NSData *)_dt;
159 - (NGMimeType *)defaultContentTypeForPart:(id<NGMimePart>)_part;
161 - (void)parseBodyOfPart:(id<NGMimePart>)_part;
163 /* hooks for subclasses */
165 - (BOOL)parsePrefix; // returns NO to abort parsing
167 - (BOOL)prepareForParsingFromStream:(id<NGStream>)_stream;
168 - (void)finishParsingOfPart:(id<NGMimePart>)_part;
172 - (void)setUseContentLength:(BOOL)_use;
173 - (BOOL)doesUseContentLength;
175 - (NSData *)applyTransferEncoding:(NSString *)_encoding onData:(NSData *)_data;
177 @end /* NGMimePartParser */
179 @interface NSObject(NGMimePartParserDelegate)
182 Called before the parsing of the headers begins. The delegate can return NO to
183 stop parsing or YES to continue parsing.
185 - (BOOL)parserWillParseHeader:(NGMimePartParser *)_parser;
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.
191 - (void)parser:(NGMimePartParser *)_parser didParseHeader:(NGHashMap *)_headers;
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
201 - (id)parser:(NGMimePartParser *)_parser
202 parseHeaderField:(NSString *)_name
203 data:(NSData *)_data;
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.
210 - (BOOL)parser:(NGMimePartParser *)_parser
211 keepHeaderField:(NSString *)_name
212 data:(NSData *)_value;
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
222 - (BOOL)parser:(NGMimePartParser *)_parser
223 keepHeaderField:(NSString *)_name
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.
230 - (void)parser:(NGMimePartParser *)_parser
231 foundComment:(NSString *)_comment // can be nil, if keepComments==NO
232 inHeaderField:(NSString *)_name;
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.
238 - (NSData *)parser:(NGMimePartParser *)_parser
239 decodeBody:(NSData *)_body
240 ofPart:(id<NGMimePart>)_part;
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.
249 - (BOOL)parser:(NGMimePartParser *)_parser
250 willParseBodyOfPart:(id<NGMimePart>)_part;
253 The parser successfully read in the body of the part.
255 - (void)parser:(NGMimePartParser *)_parser
256 didParseBodyOfPart:(id<NGMimePart>)_part;
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.
266 - (BOOL)parser:(NGMimePartParser *)_parser
267 parseRawBodyData:(NSData *)_data
268 ofPart:(id<NGMimePart>)_part;
271 If the delegate does not parse the body itself, it can still select an
272 appropriate body parser using this method.
274 - (id<NGMimeBodyParser>)parser:(NGMimePartParser *)_parser
275 bodyParserForPart:(id<NGMimePart>)_part;
277 @end /* NSObject(NGMimePartParserDelegate) */
279 @interface NSObject(NGMimePartParser)
281 - (void)parser:(NGMimePartParser *)_parser
282 setOriginalHeaderFieldName:(NSString *)_name;
286 #endif /* __NGMime_NGMimePartParser_H__ */