/* Copyright (C) 2000-2005 SKYRIX Software AG This file is part of SOPE. 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. 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 SOPE; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "NGMimeMessageGenerator.h" #include "NGMimeMessage.h" #include #include "common.h" @implementation NGMimeMessageGenerator static BOOL debugOn = NO; + (int)version { return 2; } + (void)initialize { NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSAssert2([super version] == 2, @"invalid superclass (%@) version %i !", NSStringFromClass([self superclass]), [super version]); debugOn = [ud boolForKey:@"NGMimeGeneratorDebugEnabled"]; if (debugOn) NSLog(@"WARNING[%@]: NGMimeGeneratorDebugEnabled is enabled!", self); } /* header field specifics */ - (NSData *)generateDataForHeaderField:(NSString *)_headerField value:(id)_value { NSData *data = nil; data = [super generateDataForHeaderField:_headerField value:_value]; { const char *bytes = NULL; unsigned int length = 0; unsigned int desLen = 0; char *des = NULL; unsigned int cnt = 0; BOOL doEnc = NO; NSString *str; #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY str = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; #else str = [[NSString alloc] initWithData:data encoding:NSISOLatin9StringEncoding]; #endif str = [str autorelease]; bytes = [str cString]; length = [str cStringLength]; while (cnt < length) { if ((unsigned char)bytes[cnt] > 127) { doEnc = YES; break; } cnt++; } if (doEnc) { char iso[] = "=?iso-8859-15?q?"; unsigned isoLen = 16; char isoEnd[] = "?="; unsigned isoEndLen = 2; desLen = length * 3 + 20; des = calloc(desLen + 2, sizeof(char)); // memcpy(des, bytes, cnt); memcpy(des, iso, isoLen); desLen = NGEncodeQuotedPrintableMime(bytes, length, des + isoLen, desLen - isoLen); if ((int)desLen != -1) { memcpy(des + isoLen + desLen, isoEnd, isoEndLen); data = [NSData dataWithBytesNoCopy:des length:(isoLen + desLen + isoEndLen)]; } else { NSLog(@"WARNING: An error occour during quoted-printable decoding"); if (des != NULL) free(des); } } } return data; } /* content-transfer-encoding */ - (id)defaultBodyGenerator { NGMimeMessageBodyGenerator *gen; gen = [[NGMimeMessageBodyGenerator alloc] init]; [gen setUseMimeData:self->useMimeData]; return gen; } - (id)generatorForBodyOfPart:(id)_part { /* called by -generateBodyData:? */ id bodyGen; NGMimeType *contentType; NSString *type; Class generatorClass; if (self->delegateRespondsTo.generatorGeneratorForBodyOfPart) { bodyGen = [self->delegate mimePartGenerator:self generatorForBodyOfPart:self->part]; if (bodyGen != nil) return bodyGen; } if ((contentType = [_part contentType]) == nil) contentType = [self defaultContentTypeForPart:_part]; if (contentType == nil) { [self logWithFormat:@"WARNING(%s): missing content-type in part 0x%08X.", __PRETTY_FUNCTION__, _part]; return nil; } type = [contentType type]; generatorClass = Nil; if ([type isEqualToString:NGMimeTypeMultipart]) generatorClass = [NGMimeMessageMultipartBodyGenerator class]; else if ([type isEqualToString:NGMimeTypeText]) generatorClass = [NGMimeMessageTextBodyGenerator class]; else if (([type isEqualToString:NGMimeTypeMessage]) && [[contentType subType] isEqualToString:@"rfc822"]) { generatorClass = [NGMimeMessageRfc822BodyGenerator class]; } if (generatorClass == Nil) { [self debugWithFormat: @"found no body generator class for part with type: %@", contentType]; return nil; } if (debugOn) { [self debugWithFormat:@"using body generator class %@ for part: %@", generatorClass, _part]; } /* allocate generator */ bodyGen = [[[generatorClass alloc] init] autorelease]; [(id)bodyGen setUseMimeData:self->useMimeData]; return bodyGen; } /* debugging */ - (BOOL)isDebuggingEnabled { return debugOn; } @end /* NGMimeMessageGenerator */