diff --git a/ChangeLog b/ChangeLog index 179c160b7..0b7c8561a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,8 @@ available, by selecting the first one only. This requires the prior detection of text/html parts in order to exclude the property or not. + Make use of the category methods offered in NSData+Mail to + properly decode the body data for PR_BODY_UNICODE and PR_HTML. 2011-02-11 Wolfgang Sourdeau diff --git a/OpenChange/MAPIStoreMailMessageTable.m b/OpenChange/MAPIStoreMailMessageTable.m index 988c7a9d7..89bf6355c 100644 --- a/OpenChange/MAPIStoreMailMessageTable.m +++ b/OpenChange/MAPIStoreMailMessageTable.m @@ -24,6 +24,7 @@ #import #import #import +#import #import @@ -31,6 +32,7 @@ #import +#import #import #import @@ -46,6 +48,33 @@ #include #include +@interface NSString (MAPIStoreMIME) + +- (NSString *) _strippedBodyKey; + +@end + +@implementation NSString (MAPIStoreMIME) + +- (NSString *) _strippedBodyKey +{ + NSRange bodyRange; + NSString *strippedKey; + + bodyRange = [self rangeOfString: @"body["]; + if (bodyRange.length > 0) + { + strippedKey = [self substringFromIndex: NSMaxRange (bodyRange)]; + strippedKey = [strippedKey substringToIndex: [strippedKey length] - 1]; + } + else + strippedKey = nil; + + return strippedKey; +} + +@end + @implementation MAPIStoreMailMessageTable static Class NSDataK, NSStringK; @@ -355,15 +384,23 @@ static EOQualifier *nonDeletedQualifier = nil; { id result; NSData *content; - NSString *key; - + NSDictionary *partHeaderData; + NSString *key, *encoding, *charset; + result = [child fetchParts: [keys objectsForKey: @"key" notFoundMarker: nil]]; result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"]; key = [[keys objectAtIndex: 0] objectForKey: @"key"]; content = [[result objectForKey: key] objectForKey: @"data"]; - stringValue = [[NSString alloc] initWithData: content - encoding: NSISOLatin1StringEncoding]; + + partHeaderData + = [child lookupInfoForBodyPart: [key _strippedBodyKey]]; + encoding = [partHeaderData objectForKey: @"encoding"]; + charset = [[partHeaderData objectForKey: @"parameterList"] + objectForKey: @"charset"]; + stringValue = [[content bodyDataFromEncoding: encoding] + bodyStringFromCharset: charset]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; if (strlen (*data) > 16384) { @@ -407,8 +444,9 @@ static EOQualifier *nonDeletedQualifier = nil; if ([keys count] > 0) { id result; - NSString *key; NSData *content; + NSDictionary *partHeaderData; + NSString *key, *encoding; result = [child fetchParts: [keys objectsForKey: @"key" notFoundMarker: nil]]; @@ -416,6 +454,12 @@ static EOQualifier *nonDeletedQualifier = nil; @"fetch"]; key = [[keys objectAtIndex: 0] objectForKey: @"key"]; content = [[result objectForKey: key] objectForKey: @"data"]; + + partHeaderData + = [child lookupInfoForBodyPart: [key _strippedBodyKey]]; + encoding = [partHeaderData objectForKey: @"encoding"]; + content = [content bodyDataFromEncoding: encoding]; + if ([content length] > 16384) { [context registerValue: content