/*
- Copyright (C) 2000-2004 SKYRIX Software AG
+ Copyright (C) 2000-2005 SKYRIX Software AG
- This file is part of OpenGroupware.org.
+ This file is part of SOPE.
- OGo is free software; you can redistribute it and/or modify it under
+ SOPE is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING. If not, write to the
+ License along with SOPE; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#include "NGMimeMessageParser.h"
#include "NGMimeMessage.h"
#include "common.h"
-
-
+#include <string.h>
@interface NGMimeMessageParserDelegate : NSObject
@end
@implementation NGMimeMessageParserDelegate
-static int UseFoundationStringEncodingForMimeHeader = -1;
-static Class NGMimeMessageParserClass = NULL;
+static Class NGMimeMessageParserClass = Nil;
+ (void)initialize {
- if (UseFoundationStringEncodingForMimeHeader == -1) {
- UseFoundationStringEncodingForMimeHeader
- = [[NSUserDefaults standardUserDefaults]
- boolForKey:@"UseFoundationStringEncodingForMimeHeader"]
- ? 1 : 0;
- }
- if (NGMimeMessageParserClass == NULL) {
+ if (NGMimeMessageParserClass == Nil)
NGMimeMessageParserClass = [NGMimeMessageParser class];
- }
}
-- (id)parser:(id)_parser parseHeaderField:(NSString *)_field data:(NSData *)_data
+- (id)parser:(NGMimePartParser *)_p parseHeaderField:(NSString *)_field
+ data:(NSData *)_data
{
- id v = nil;
-
- if ([_parser isKindOfClass:NGMimeMessageParserClass] == NO) {
- NGMimeMessageParser *parser = nil;
+ NGMimeMessageParser *parser = nil;
+ id v;
- parser = [[NGMimeMessageParserClass alloc] init];
- v = [parser valueOfHeaderField:_field data:_data];
- [parser release]; parser = nil;
- }
+ if ([_p isKindOfClass:NGMimeMessageParserClass])
+ return nil;
+
+ parser = [[NGMimeMessageParserClass alloc] init];
+ v = [parser valueOfHeaderField:_field data:_data];
+ [parser release]; parser = nil;
return v;
}
- (id<NGMimeBodyParser>)parser:(NGMimePartParser *)_parser
bodyParserForPart:(id<NGMimePart>)_part
{
- id ctype;
- NGMimeType *contentType;
+ id ctype;
+ NGMimeType *contentType;
ctype = [_part contentType];
@end /* NGMimeMessageParser */
-@implementation NSData(MimeQPHeaderFieldDecoding)
-
-- (id)decodeQuotedPrintableValueOfMIMEHeaderField:(NSString *)_name {
- // check data for 8-bit headerfields (RFC 2047 (MIME PART III))
- static Class NGMimeTypeClass = Nil;
- enum {
- NGMimeMessageParser_quoted_start = 1,
- NGMimeMessageParser_quoted_charSet = 2,
- NGMimeMessageParser_quoted_qpData = 3,
- NGMimeMessageParser_quoted_end = 4
- } status = NGMimeMessageParser_quoted_start;
- unsigned int length;
- const unsigned char *bytes, *firstEq;
- BOOL foundQP = NO;
-
- if (NSStringClass == Nil) NSStringClass = [NSString class];
- if (NGMimeTypeClass == Nil) NGMimeTypeClass = [NGMimeType class];
-
- length = [self length];
-
- /* check whether the string is long enough to be quoted etc */
- if (length <= 6)
- return self;
-
- /* check whether the string contains QP tokens ... */
- bytes = [self bytes];
-
- if ((firstEq = memchr(bytes, '=', length)) == NULL)
- return self;
-
- /* process data ... (quoting etc) */
- {
- unichar *buffer;
- unsigned int bufLen, maxBufLen;
- NSString *charset;
- BOOL appendLC;
- int cnt, tmp;
- unsigned char encoding;
-
- buffer = calloc(length + 13, sizeof(unichar));
-
- maxBufLen = length + 3;
- buffer[maxBufLen - 1] = '\0';
- bufLen = 0;
-
- encoding = 0;
- tmp = -1;
- appendLC = YES;
- charset = nil;
- status = NGMimeMessageParser_quoted_start;
-
- /* copy data up to first '=' sign */
- if ((cnt = (firstEq - bytes)) > 0) {
- for (; bufLen < cnt; bufLen++)
- buffer[bufLen] = bytes[bufLen];
- }
-
- for (; cnt < (length-1); cnt++) {
- appendLC = YES;
-
- if (status == NGMimeMessageParser_quoted_start) {
- if ((bytes[cnt] == '=') && (bytes[cnt + 1] == '?')) { // found begin
- cnt++;
- status = NGMimeMessageParser_quoted_charSet;
- }
- else { // other char
- if (bytes[cnt + 1] != '=') {
- buffer[bufLen++] = bytes[cnt];
- buffer[bufLen++] = bytes[cnt+1];
- cnt++;
- if (cnt >= length - 1)
- appendLC = NO;
- }
- else {
- buffer[bufLen++] = bytes[cnt];
- }
- }
- }
- else if (status == NGMimeMessageParser_quoted_charSet) {
- if (tmp == -1)
- tmp = cnt;
-
- if (bytes[cnt] == '?') {
- charset =
- [NSStringClass stringWithCString:(bytes + tmp) length:cnt - tmp];
- tmp = -1;
-
- if ((length - cnt) > 2) {
- // set encoding (eg 'q' for quoted printable)
- cnt++; // skip '?'
- encoding = bytes[cnt];
- cnt++; // skip encoding
- status = NGMimeMessageParser_quoted_qpData;
- }
- else { // unexpected end
- NSLog(@"WARNING: unexpected end of header");
- appendLC = NO;
- break;
- }
- }
- }
- else if (status == NGMimeMessageParser_quoted_qpData) {
- if (tmp == -1)
- tmp = cnt;
-
- if ((bytes[cnt] == '?') && (bytes[cnt + 1] == '=')) {
- NSData *tmpData;
- NSString *tmpStr;
- unsigned int tmpLen;
-
- tmpData = _rfc2047Decoding(encoding, bytes + tmp, cnt - tmp);
- foundQP = YES;
-
- /*
- create a temporary string for charset conversion ...
- Note: the headerfield is currently held in ISO Latin 1
- */
- tmpStr = nil;
-
- if (!UseFoundationStringEncodingForMimeHeader) {
- tmpStr = [NSStringClass stringWithData:tmpData
- usingEncodingNamed:charset];
- }
- if (tmpStr == nil) {
- NSStringEncoding enc;
-
- enc = [NGMimeTypeClass stringEncodingForCharset:charset];
- tmpStr = [[[NSStringClass alloc] initWithData:tmpData encoding:enc]
- autorelease];
- }
- tmpLen = [tmpStr length];
-
- if ((tmpLen + bufLen) < maxBufLen) {
- [tmpStr getCharacters:(buffer + bufLen)];
- bufLen += tmpLen;
- }
- else {
- NSLog(@"ERROR[%s]: quoted data to large --> ignored %@",
- __PRETTY_FUNCTION__, tmpStr);
- }
- tmp = -1;
- cnt++;
- appendLC = YES;
- status = NGMimeMessageParser_quoted_start;
- }
- }
- }
- if (appendLC == YES) {
- if (cnt < length) {
- buffer[bufLen] = bytes[cnt];
- bufLen++;
- }
- }
- buffer[bufLen] = '\0';
- {
- id data;
-
- data = nil;
-
- if (buffer && foundQP) {
- data = [[[NSString alloc] initWithCharacters:buffer length:bufLen]
- autorelease];
- if (data == nil) {
- NSLog(@"%s: got no string for buffer '%s', length '%i' !",
- __PRETTY_FUNCTION__,
- buffer, bufLen);
- }
- }
- if (!data) {
- data = self;
- }
- free(buffer); buffer = NULL;
- return data;
- }
- }
- return self;
-}
-@end /* NSData(MimeQPHeaderFieldDecoding) */
@implementation NGMimeRfc822BodyParser