Monotone-Parent: 430f5637e275bb6a780f5be502428ee3c01c1d98
Monotone-Revision: 4b4728f355bbb34bff8025c45fdf5a359fe6387a Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-07-19T21:31:16 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
parent
2e5a3f44db
commit
e82423d4e2
|
@ -1,5 +1,11 @@
|
||||||
2011-07-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2011-07-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* OpenChange/MAPIStoreMailMessage.m (-_setupBodyData): new
|
||||||
|
centralized method that performs the common operations required to
|
||||||
|
fetch the message body.
|
||||||
|
(-getPrHtml:inMemCtx,-getPrBody:inMemCtx:): make use of the above
|
||||||
|
method.
|
||||||
|
|
||||||
* SoObjects/SOGo/NSString+Utilities.m
|
* SoObjects/SOGo/NSString+Utilities.m
|
||||||
(-countOccurrencesOfString:): new self-explicit method.
|
(-countOccurrencesOfString:): new self-explicit method.
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,16 @@
|
||||||
|
|
||||||
#import "MAPIStoreMessage.h"
|
#import "MAPIStoreMessage.h"
|
||||||
|
|
||||||
|
@class NSData;
|
||||||
|
@class NSString;
|
||||||
|
|
||||||
@interface MAPIStoreMailMessage : MAPIStoreMessage
|
@interface MAPIStoreMailMessage : MAPIStoreMessage
|
||||||
{
|
{
|
||||||
BOOL fetchedAttachments;
|
BOOL fetchedAttachments;
|
||||||
|
BOOL bodySetup;
|
||||||
|
NSData *bodyContent;
|
||||||
|
NSString *bodyMimeType;
|
||||||
|
NSString *bodyCharset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#import <Foundation/NSException.h>
|
#import <Foundation/NSException.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
#import <SOGo/NSArray+Utilities.h>
|
#import <SOGo/NSArray+Utilities.h>
|
||||||
|
#import <SOGo/NSString+Utilities.h>
|
||||||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||||
#import <Mailer/NSData+Mail.h>
|
#import <Mailer/NSData+Mail.h>
|
||||||
#import <Mailer/SOGoMailBodyPart.h>
|
#import <Mailer/SOGoMailBodyPart.h>
|
||||||
|
@ -88,11 +89,25 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
fetchedAttachments = NO;
|
{
|
||||||
|
bodySetup = NO;
|
||||||
|
bodyContent = nil;
|
||||||
|
bodyMimeType = nil;
|
||||||
|
bodyCharset = nil;
|
||||||
|
fetchedAttachments = NO;
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[bodyContent release];
|
||||||
|
[bodyMimeType release];
|
||||||
|
[bodyCharset release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
- (int) getPrIconIndex: (void **) data
|
- (int) getPrIconIndex: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
|
@ -494,53 +509,108 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||||
return MAPISTORE_SUCCESS;
|
return MAPISTORE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NSComparisonResult
|
||||||
|
_compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
||||||
|
{
|
||||||
|
NSComparisonResult result;
|
||||||
|
NSArray *keys;
|
||||||
|
NSString *data1, *data2;
|
||||||
|
NSUInteger count1, count2;
|
||||||
|
|
||||||
|
keys = data;
|
||||||
|
|
||||||
|
data1 = [entry1 objectForKey: @"mimeType"];
|
||||||
|
count1 = [keys indexOfObject: data1];
|
||||||
|
data2 = [entry2 objectForKey: @"mimeType"];
|
||||||
|
count2 = [keys indexOfObject: data2];
|
||||||
|
|
||||||
|
if (count1 == count2)
|
||||||
|
{
|
||||||
|
data1 = [entry1 objectForKey: @"key"];
|
||||||
|
count1 = [data1 countOccurrencesOfString: @"."];
|
||||||
|
data2 = [entry2 objectForKey: @"key"];
|
||||||
|
count2 = [data2 countOccurrencesOfString: @"."];
|
||||||
|
if (count1 == count2)
|
||||||
|
{
|
||||||
|
data1 = [data1 _strippedBodyKey];
|
||||||
|
count1 = [data1 intValue];
|
||||||
|
data2 = [data2 _strippedBodyKey];
|
||||||
|
count2 = [data2 intValue];
|
||||||
|
if (count1 == count2)
|
||||||
|
result = NSOrderedSame;
|
||||||
|
else if (count1 < count2)
|
||||||
|
result = NSOrderedAscending;
|
||||||
|
else
|
||||||
|
result = NSOrderedDescending;
|
||||||
|
}
|
||||||
|
else if (count1 < count2)
|
||||||
|
result = NSOrderedAscending;
|
||||||
|
else
|
||||||
|
result = NSOrderedDescending;
|
||||||
|
}
|
||||||
|
else if (count1 < count2)
|
||||||
|
result = NSOrderedAscending;
|
||||||
|
else
|
||||||
|
result = NSOrderedDescending;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _setupBodyData
|
||||||
|
{
|
||||||
|
NSMutableArray *keys;
|
||||||
|
NSArray *acceptedTypes;
|
||||||
|
NSDictionary *messageData, *partHeaderData;
|
||||||
|
NSString *messageKey, *encoding;
|
||||||
|
NSData *rawContent;
|
||||||
|
id result;
|
||||||
|
|
||||||
|
acceptedTypes = [NSArray arrayWithObjects: // @"text/calendar",
|
||||||
|
// @"application/ics",
|
||||||
|
@"text/html",
|
||||||
|
@"text/plain", nil];
|
||||||
|
keys = [NSMutableArray array];
|
||||||
|
[sogoObject addRequiredKeysOfStructure: [sogoObject bodyStructure]
|
||||||
|
path: @"" toArray: keys
|
||||||
|
acceptedTypes: acceptedTypes];
|
||||||
|
[keys sortUsingFunction: _compareBodyKeysByPriority context: acceptedTypes];
|
||||||
|
if ([keys count] > 0)
|
||||||
|
{
|
||||||
|
messageData = [keys objectAtIndex: 0];
|
||||||
|
ASSIGN (bodyMimeType, [messageData objectForKey: @"mimeType"]);
|
||||||
|
messageKey = [messageData objectForKey: @"key"];
|
||||||
|
result = [sogoObject fetchParts: [NSArray arrayWithObject: messageKey]];
|
||||||
|
result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"];
|
||||||
|
rawContent = [[result objectForKey: messageKey] objectForKey: @"data"];
|
||||||
|
partHeaderData = [sogoObject
|
||||||
|
lookupInfoForBodyPart: [messageKey _strippedBodyKey]];
|
||||||
|
encoding = [partHeaderData objectForKey: @"encoding"];
|
||||||
|
ASSIGN (bodyContent, [rawContent bodyDataFromEncoding: encoding]);
|
||||||
|
ASSIGN (bodyCharset, [[partHeaderData objectForKey: @"parameterList"]
|
||||||
|
objectForKey: @"charset"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bodySetup = YES;
|
||||||
|
}
|
||||||
|
|
||||||
- (int) getPrBody: (void **) data
|
- (int) getPrBody: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
NSMutableArray *keys;
|
NSString *stringValue;
|
||||||
id result;
|
|
||||||
NSData *content;
|
|
||||||
NSDictionary *partHeaderData;
|
|
||||||
NSString *partKey, *encoding, *charset, *stringValue;
|
|
||||||
int rc = MAPISTORE_SUCCESS;
|
int rc = MAPISTORE_SUCCESS;
|
||||||
|
|
||||||
keys = [NSMutableArray array];
|
if (!bodySetup)
|
||||||
[sogoObject addRequiredKeysOfStructure: [sogoObject bodyStructure]
|
[self _setupBodyData];
|
||||||
path: @"" toArray: keys
|
|
||||||
acceptedTypes: [NSArray arrayWithObject:
|
if ([bodyMimeType isEqualToString: @"text/plain"])
|
||||||
@"text/html"]];
|
|
||||||
if ([keys count] > 0)
|
|
||||||
{
|
{
|
||||||
*data = NULL;
|
stringValue = [bodyContent bodyStringFromCharset: bodyCharset];
|
||||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[keys removeAllObjects];
|
*data = NULL;
|
||||||
[sogoObject addRequiredKeysOfStructure: [sogoObject bodyStructure]
|
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||||
path: @"" toArray: keys
|
|
||||||
acceptedTypes: [NSArray arrayWithObject:
|
|
||||||
@"text/plain"]];
|
|
||||||
if ([keys count] > 0)
|
|
||||||
{
|
|
||||||
result = [sogoObject fetchParts: [keys objectsForKey: @"key"
|
|
||||||
notFoundMarker: nil]];
|
|
||||||
result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"];
|
|
||||||
partKey = [[keys objectAtIndex: 0] objectForKey: @"key"];
|
|
||||||
content = [[result objectForKey: partKey] objectForKey: @"data"];
|
|
||||||
|
|
||||||
partHeaderData
|
|
||||||
= [sogoObject lookupInfoForBodyPart: [partKey _strippedBodyKey]];
|
|
||||||
encoding = [partHeaderData objectForKey: @"encoding"];
|
|
||||||
charset = [[partHeaderData objectForKey: @"parameterList"]
|
|
||||||
objectForKey: @"charset"];
|
|
||||||
stringValue = [[content bodyDataFromEncoding: encoding]
|
|
||||||
bodyStringFromCharset: charset];
|
|
||||||
|
|
||||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -549,64 +619,19 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK;
|
||||||
- (int) getPrHtml: (void **) data
|
- (int) getPrHtml: (void **) data
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
id result;
|
|
||||||
NSData *content;
|
|
||||||
NSDictionary *partHeaderData;
|
|
||||||
NSString *key, *encoding;
|
|
||||||
char *oldBytes, *newBytes;
|
|
||||||
NSUInteger c, newC, max, newMax;
|
|
||||||
NSMutableArray *keys;
|
|
||||||
NSArray *acceptedTypes;
|
|
||||||
int rc = MAPISTORE_SUCCESS;
|
int rc = MAPISTORE_SUCCESS;
|
||||||
|
|
||||||
acceptedTypes = [NSArray arrayWithObject: @"text/html"];
|
if (!bodySetup)
|
||||||
keys = [NSMutableArray array];
|
[self _setupBodyData];
|
||||||
[sogoObject addRequiredKeysOfStructure: [sogoObject bodyStructure]
|
|
||||||
path: @"" toArray: keys
|
if ([bodyMimeType isEqualToString: @"text/html"])
|
||||||
acceptedTypes: acceptedTypes];
|
*data = [bodyContent asBinaryInMemCtx: memCtx];
|
||||||
if ([keys count] > 0)
|
|
||||||
{
|
|
||||||
result = [sogoObject fetchParts: [keys objectsForKey: @"key"
|
|
||||||
notFoundMarker: nil]];
|
|
||||||
result = [[result valueForKey: @"RawResponse"] objectForKey:
|
|
||||||
@"fetch"];
|
|
||||||
key = [[keys objectAtIndex: 0] objectForKey: @"key"];
|
|
||||||
content = [[result objectForKey: key] objectForKey: @"data"];
|
|
||||||
|
|
||||||
max = [content length];
|
|
||||||
newMax = max;
|
|
||||||
oldBytes = malloc (max);
|
|
||||||
newBytes = malloc (max * 2);
|
|
||||||
[content getBytes: oldBytes];
|
|
||||||
newC = 0;
|
|
||||||
for (c = 0; c < max; c++)
|
|
||||||
{
|
|
||||||
if (*(oldBytes + c) == '\n')
|
|
||||||
{
|
|
||||||
*(newBytes + newC) = '\r';
|
|
||||||
newC++;
|
|
||||||
newMax++;
|
|
||||||
}
|
|
||||||
*(newBytes + newC) = *(oldBytes + c);
|
|
||||||
newC++;
|
|
||||||
}
|
|
||||||
content = [[NSData alloc] initWithBytesNoCopy: newBytes
|
|
||||||
length: newMax];;
|
|
||||||
[content autorelease];
|
|
||||||
free(oldBytes);
|
|
||||||
|
|
||||||
partHeaderData
|
|
||||||
= [sogoObject lookupInfoForBodyPart: [key _strippedBodyKey]];
|
|
||||||
encoding = [partHeaderData objectForKey: @"encoding"];
|
|
||||||
content = [content bodyDataFromEncoding: encoding];
|
|
||||||
*data = [content asBinaryInMemCtx: memCtx];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*data = NULL;
|
*data = NULL;
|
||||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue