sogo/UI/MailerUI/UIxSubjectFormatter.m
Wolfgang Sourdeau c2729f8b87 Monotone-Parent: c5cc88dd452d75edebb6730bdb60d21a0facec48
Monotone-Revision: 5409e94f78704f474807523b11be4df984918299

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2007-07-27T17:30:37
Monotone-Branch: ca.inverse.sogo
2007-07-27 17:30:37 +00:00

156 lines
4 KiB
Objective-C

/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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
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
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGMail/NGMimeMessageParser.h>
#import "UIxMailFormatter.h"
@implementation UIxSubjectFormatter
static Class StrClass = Nil;
static Class DataClass = Nil;
+ (void)initialize {
StrClass = [NSString class];
DataClass = [NSData class];
}
- (id)init {
if ((self = [super init])) {
self->maxLength = 64;
}
return self;
}
/* configuration */
- (unsigned int)maxLength {
return self->maxLength;
}
- (BOOL)shouldDecodeQP {
return YES;
}
/* labels */
- (NSString *)missingSubjectLabel {
return [self labelForKey:@"no_subject"];
}
/* specific formatters */
- (NSString *)stringForStringValue:(NSString *)_subject {
NSString *s;
/* quoted printable */
if ([self shouldDecodeQP] && [_subject hasPrefix:@"=?"]) {
/*
Now this is interesting. An NSString should not contain QP markers since
it is already 'charset decoded'. This is also why the NGMime parser
expects an NSData.
Sample:
=?iso-8859-1?q?Yannick=20DAmboise?=
Note: -stringByDecodingQuotedPrintable only expands =D0 like charcodes!
*/
NSData *data;
/* header field data should always be ASCII */
data = [_subject dataUsingEncoding:NSUTF8StringEncoding];
return [self stringForDataValue:data];
}
if ([_subject length] == 0)
return [self missingSubjectLabel];
if ([_subject length] <= [self maxLength])
return _subject;
s = [_subject substringToIndex:([self maxLength] - 3)];
return [s stringByAppendingString:@"..."];
}
- (NSString *)stringForDataValue:(NSData *)_subject {
NSString *s, *r;
unsigned len;
if ((len = [_subject length]) == 0)
return [self missingSubjectLabel];
/* check for quoted printable */
if (len > 6 && [self shouldDecodeQP]) {
const unsigned char *b;
b = [_subject bytes];
if (b[0] == '=' && b[1] == '?') {
/* eg: '=?iso-8859-1?q?Yannick=20DAmboise?=' */
id t;
t = [_subject decodeQuotedPrintableValueOfMIMEHeaderField:@"subject"];
if ([t isNotNull])
return [self stringForObjectValue:t];
else
[self warnWithFormat:@"decoding QP failed: '%@'", t];
}
}
/* continue NSData processing */
[self warnWithFormat:@"NSData subject, using UTF-8 to decode."];
// TODO: exception handler?
s = [[NSString alloc] initWithData:_subject encoding:NSUTF8StringEncoding];
if (s == nil) {
[self errorWithFormat:@"could do not decode NSData subject!"];
return [self labelForKey:@"Error_CouldNotDecodeSubject"];
}
if ([s hasPrefix:@"=?"]) { // TODO: this should never happen?
[self warnWithFormat:@"subject still has QP signature: '%@'", s];
r = [s copy];
}
else
r = [[self stringForStringValue:s] copy];
[s release];
return [r autorelease];
}
/* formatter entry function */
- (NSString *)stringForObjectValue:(id)_subject {
if (![_subject isNotNull])
return [self missingSubjectLabel];
if ([_subject isKindOfClass:StrClass])
return [self stringForStringValue:_subject];
if ([_subject isKindOfClass:DataClass])
return [self stringForDataValue:_subject];
return [self stringForStringValue:[_subject stringValue]];
}
@end /* UIxSubjectFormatter */