Monotone-Parent: 79dc6e23f29ab39ef98de2d45f1c37249b3c4152

Monotone-Revision: 5b4c993653702d15ad66f63a1c94781ddd2e36aa

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-07-13T21:41:58
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2011-07-13 21:41:58 +00:00
parent 78e8ffe78f
commit 53d65fddb8
16 changed files with 565 additions and 642 deletions

View File

@@ -21,13 +21,18 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoObject.h>
#import <SOGo/SOGoUser.h>
#import "MAPIStoreActiveTables.h"
#import "MAPIStoreAttachment.h"
#import "MAPIStoreAttachmentTable.h"
#import "MAPIStoreContext.h"
#import "MAPIStoreFolder.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSString+MAPIStore.h"
@@ -70,8 +75,8 @@
[super dealloc];
}
- (void) openMessage: (struct mapistore_message *) msg
inMemCtx: (TALLOC_CTX *) memCtx
- (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx
{
static enum MAPITAGS tags[] = { PR_SUBJECT_PREFIX_UNICODE,
PR_NORMALIZED_SUBJECT_UNICODE };
@@ -80,23 +85,26 @@
NSInteger count, max;
const char *propName;
void *propValue;
struct mapistore_message *msgData;
// [self logWithFormat: @"INCOMPLETE METHOD '%s' (%d): no recipient handling",
// __FUNCTION__, __LINE__];
recipients = talloc_zero (memCtx, struct SRowSet);
msgData = talloc_zero (memCtx, struct mapistore_message);
recipients = talloc_zero (msgData, struct SRowSet);
recipients->cRows = 0;
recipients->aRow = NULL;
msg->recipients = recipients;
msgData->recipients = recipients;
max = 2;
properties = talloc_zero (memCtx, struct SRow);
properties = talloc_zero (msgData, struct SRow);
properties->cValues = 0;
properties->ulAdrEntryPad = 0;
properties->lpProps = talloc_array (properties, struct SPropValue, max);
for (count = 0; count < max; count++)
{
if ([self getProperty: &propValue withTag: tags[count] inMemCtx: memCtx]
if ([self getProperty: &propValue withTag: tags[count] inMemCtx: msgData]
== MAPI_E_SUCCESS)
{
if (propValue == NULL)
@@ -117,7 +125,246 @@
}
}
}
msg->properties = properties;
msgData->properties = properties;
*dataPtr = msgData;
}
- (NSDictionary *) _convertRecipientFromRow: (struct RecipientRow *) row
{
NSMutableDictionary *recipient;
NSString *value;
SOGoUser *recipientUser;
recipient = [NSMutableDictionary dictionaryWithCapacity: 5];
if ((row->RecipientFlags & 0x07) == 1)
{
value = [NSString stringWithUTF8String: row->X500DN.recipient_x500name];
[recipient setObject: value forKey: @"x500dn"];
recipientUser = [SOGoUser userWithLogin: [value lowercaseString]];
if (recipientUser)
{
value = [recipientUser cn];
if ([value length] > 0)
[recipient setObject: value forKey: @"fullName"];
value = [[recipientUser allEmails] objectAtIndex: 0];
if ([value length] > 0)
[recipient setObject: value forKey: @"email"];
}
}
else
{
switch ((row->RecipientFlags & 0x208))
{
case 0x08:
// TODO: we cheat
value = [NSString stringWithUTF8String: row->EmailAddress.lpszA];
break;
case 0x208:
value = [NSString stringWithUTF8String: row->EmailAddress.lpszW];
break;
default:
value = nil;
}
if (value)
[recipient setObject: value forKey: @"email"];
switch ((row->RecipientFlags & 0x210))
{
case 0x10:
// TODO: we cheat
value = [NSString stringWithUTF8String: row->DisplayName.lpszA];
break;
case 0x210:
value = [NSString stringWithUTF8String: row->DisplayName.lpszW];
break;
default:
value = nil;
}
if (value)
[recipient setObject: value forKey: @"fullName"];
}
return recipient;
}
- (int) modifyRecipientsWithRows: (struct ModifyRecipientRow *) rows
andCount: (NSUInteger) max
{
static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
NSDictionary *recipientProperties;
NSMutableDictionary *recipients;
NSMutableArray *list;
NSString *recType;
struct ModifyRecipientRow *currentRow;
NSUInteger count;
[self logWithFormat: @"METHOD '%s'", __FUNCTION__];
recipients = [NSMutableDictionary new];
recipientProperties = [NSDictionary dictionaryWithObject: recipients
forKey: @"recipients"];
[recipients release];
for (count = 0; count < max; count++)
{
currentRow = rows + count;
if (currentRow->RecipClass >= MAPI_ORIG
&& currentRow->RecipClass < MAPI_BCC)
{
recType = recTypes[currentRow->RecipClass];
list = [recipients objectForKey: recType];
if (!list)
{
list = [NSMutableArray new];
[recipients setObject: list forKey: recType];
[list release];
}
[list addObject: [self _convertRecipientFromRow:
&(currentRow->RecipientRow)]];
}
}
[self addNewProperties: recipientProperties];
return MAPISTORE_SUCCESS;
}
- (int) createAttachment: (MAPIStoreAttachment **) attachmentPtr
inAID: (uint32_t *) aidPtr
{
MAPIStoreAttachment *attachment;
int rc = MAPISTORE_SUCCESS;
attachment = [self createAttachment];
if (attachment)
{
*attachmentPtr = attachment;
*aidPtr = [attachment AID];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) getAttachment: (MAPIStoreAttachment **) attachmentPtr
withAID: (uint32_t) aid
{
MAPIStoreAttachment *attachment;
NSArray *keys;
int rc = MAPISTORE_ERR_NOT_FOUND;
keys = [self childKeysMatchingQualifier: nil
andSortOrderings: nil];
if (aid < [keys count])
{
attachment = [self lookupChild: [keys objectAtIndex: aid]];
if (attachment)
{
*attachmentPtr = attachment;
rc = MAPISTORE_SUCCESS;
}
}
return rc;
}
- (int) getAttachmentTable: (MAPIStoreAttachmentTable **) tablePtr
andRowCount: (uint32_t *) countPtr
{
MAPIStoreAttachmentTable *attTable;
int rc = MAPISTORE_SUCCESS;
attTable = [self attachmentTable];
if (attTable)
{
*tablePtr = attTable;
*countPtr = [[self childKeysMatchingQualifier: nil
andSortOrderings: nil]
count];
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (NSArray *) activeContainerMessageTables
{
return [[MAPIStoreActiveTables activeTables]
activeTablesForFMID: [container objectId]
andType: MAPISTORE_MESSAGE_TABLE];
}
- (int) saveMessage
{
NSArray *containerTables;
NSUInteger count, max;
struct mapistore_object_notification_parameters *notif_parameters;
uint64_t folderId;
struct mapistore_context *mstoreCtx;
/* notifications */
folderId = [(MAPIStoreFolder *) container objectId];
mstoreCtx = [[self context] connectionInfo]->mstore_ctx;
/* folder modified */
notif_parameters
= talloc_zero(NULL, struct mapistore_object_notification_parameters);
notif_parameters->object_id = folderId;
if (isNew)
{
notif_parameters->tag_count = 3;
notif_parameters->tags = talloc_array (notif_parameters,
enum MAPITAGS, 3);
notif_parameters->tags[0] = PR_CONTENT_COUNT;
notif_parameters->tags[1] = PR_MESSAGE_SIZE;
notif_parameters->tags[2] = PR_NORMAL_MESSAGE_SIZE;
notif_parameters->new_message_count = true;
notif_parameters->message_count
= [[(MAPIStoreFolder *) container messageKeys] count] + 1;
}
mapistore_push_notification (mstoreCtx,
MAPISTORE_FOLDER, MAPISTORE_OBJECT_MODIFIED,
notif_parameters);
talloc_free (notif_parameters);
/* message created */
if (isNew)
{
notif_parameters
= talloc_zero(NULL,
struct mapistore_object_notification_parameters);
notif_parameters->object_id = [self objectId];
notif_parameters->folder_id = folderId;
notif_parameters->tag_count = 0xffff;
mapistore_push_notification (mstoreCtx,
MAPISTORE_MESSAGE, MAPISTORE_OBJECT_CREATED,
notif_parameters);
talloc_free (notif_parameters);
}
/* we ensure the table caches are loaded so that old and new state
can be compared */
containerTables = [self activeContainerMessageTables];
max = [containerTables count];
for (count = 0; count < max; count++)
[[containerTables objectAtIndex: count] restrictedChildKeys];
[self save];
/* table modified */
for (count = 0; count < max; count++)
[[containerTables objectAtIndex: count]
notifyChangesForChild: self];
[self setIsNew: NO];
[self resetNewProperties];
[container cleanupCaches];
return MAPISTORE_SUCCESS;
}
/* helper getters */
@@ -361,7 +608,7 @@
{
NSURL *contextUrl;
contextUrl = [[self context] url];
contextUrl = (NSURL *) [[self context] url];
*data = [[contextUrl user] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
@@ -402,11 +649,6 @@
[self subclassResponsibility: _cmd];
}
- (void) submit
{
[self subclassResponsibility: _cmd];
}
- (MAPIStoreAttachment *) createAttachment
{
[self subclassResponsibility: _cmd];