2 Copyright (C) 2004-2005 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
22 #include "UIxMailFormatter.h"
25 #include <NGMail/NGMimeMessageParser.h>
27 @implementation UIxSubjectFormatter
29 static Class StrClass = Nil;
30 static Class DataClass = Nil;
33 StrClass = [NSString class];
34 DataClass = [NSData class];
38 if ((self = [super init])) {
46 - (unsigned int)maxLength {
47 return self->maxLength;
50 - (BOOL)shouldDecodeQP {
56 - (NSString *)missingSubjectLabel {
57 return [self labelForKey:@"no_subject"];
60 /* specific formatters */
62 - (NSString *)stringForStringValue:(NSString *)_subject {
65 /* quoted printable */
66 if ([self shouldDecodeQP] && [_subject hasPrefix:@"=?"]) {
68 Now this is interesting. An NSString should not contain QP markers since
69 it is already 'charset decoded'. This is also why the NGMime parser
73 =?iso-8859-1?q?Yannick=20DAmboise?=
75 Note: -stringByDecodingQuotedPrintable only expands =D0 like charcodes!
79 /* header field data should always be ASCII */
80 data = [_subject dataUsingEncoding:NSUTF8StringEncoding];
81 return [self stringForDataValue:data];
84 if ([_subject length] == 0)
85 return [self missingSubjectLabel];
87 if ([_subject length] <= [self maxLength])
90 s = [_subject substringToIndex:([self maxLength] - 3)];
91 return [s stringByAppendingString:@"..."];
94 - (NSString *)stringForDataValue:(NSData *)_subject {
98 if ((len = [_subject length]) == 0)
99 return [self missingSubjectLabel];
101 /* check for quoted printable */
103 if (len > 6 && [self shouldDecodeQP]) {
104 const unsigned char *b;
106 b = [_subject bytes];
107 if (b[0] == '=' && b[1] == '?') {
108 /* eg: '=?iso-8859-1?q?Yannick=20DAmboise?=' */
111 t = [_subject decodeQuotedPrintableValueOfMIMEHeaderField:@"subject"];
113 return [self stringForObjectValue:t];
115 [self warnWithFormat:@"decoding QP failed: '%@'", t];
119 /* continue NSData processing */
121 [self warnWithFormat:@"NSData subject, using UTF-8 to decode."];
123 // TODO: exception handler?
124 s = [[NSString alloc] initWithData:_subject encoding:NSUTF8StringEncoding];
126 [self errorWithFormat:@"could do not decode NSData subject!"];
127 return [self labelForKey:@"Error_CouldNotDecodeSubject"];
130 if ([s hasPrefix:@"=?"]) { // TODO: this should never happen?
131 [self warnWithFormat:@"subject still has QP signature: '%@'", s];
135 r = [[self stringForStringValue:s] copy];
137 return [r autorelease];
140 /* formatter entry function */
142 - (NSString *)stringForObjectValue:(id)_subject {
143 if (![_subject isNotNull])
144 return [self missingSubjectLabel];
146 if ([_subject isKindOfClass:StrClass])
147 return [self stringForStringValue:_subject];
148 if ([_subject isKindOfClass:DataClass])
149 return [self stringForDataValue:_subject];
151 return [self stringForStringValue:[_subject stringValue]];
154 @end /* UIxSubjectFormatter */