diff --git a/ChangeLog b/ChangeLog index 61fc3d51a..504f620cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,62 @@ +2012-03-16 Wolfgang Sourdeau + + * OpenChange/MAPIStoreGCSFolder.m + (-predecessorChangeListForMessageWithKey:): same as below. + (-setChangeKey:forMessageWithKey:): synchronise the version cache + if the message entry is not found. + (-updateVersionsForMessageWithKey:withChangeKey:): new method, + common to all GCS messages, that updates the folder cache and + insert the PidTagChangeKey provided by the client during the save + operations. + + * OpenChange/MAPIStoreMailFolder.m + (-predecessorChangeListForMessageWithKey:): the returned list must + be binary ordered by GUID (as specified in the SPEC). We now do so + using the new function below. + (-getPidTagMessageClass:inMemCtx:): removed method, as folders are + not supposed to return a PidTagMessageClass attribute. + + * OpenChange/MAPIStoreTypes.m (MAPICNCompare): added as void * + parameter so that the function can be used as a comparator + function in NSArray sort methods. + (MAPIChangeKeyGUIDCompare): new comparator function to compare the + GUID of two change key streams. + + * OpenChange/MAPIStoreGCSMessage.m (-updateVersions): new proxy + method for -[MAPIStoreGCSFolder + updateVersionsForMessageWithKey:withChangeKey:]. + + * OpenChange/MAPIStoreGCSBaseContext.m + (+createRootSecondaryFolderWithFID:andName:forUser:): setup the + userContext in the MAPIApp object. + + * OpenChange/MAPIStoreMailContext.m + (+createRootSecondaryFolderWithFID:andName:forUser:): setup the + userContext in the MAPIApp object. + + * OpenChange/MAPIStoreContactsFolder.m + (-getPidTagDefaultPostMessageClass:inMemCtx:): new getter. + + * OpenChange/MAPIStoreCalendarFolder.m + (-getPidTagDefaultPostMessageClass:inMemCtx:): new getter. + + * OpenChange/MAPIStoreTasksFolder.m + (-getPidTagDefaultPostMessageClass:inMemCtx:): new getter. + + * OpenChange/MAPIStoreFolder.m + (-getPidTagDefaultPostMessageClass:inMemCtx:): new getter. + + * OpenChange/MAPIStoreMessage.m + (-getPidTagMessageStatus:inMemCtx:): removed useless getter. + + * OpenChange/MAPIStoreSOGo.m (sogo_backend_init): check for + "SOGoDebugLeaks" in the user defaults and activate GSDebug + allocation utilities. + + * OpenChange/NSData+MAPIStore.m (+dataWithChangeKeyGUID:andCnt:): + new method replacing _dataFromChangeKeyGUID:andCnt: from + MAPIStore{GCS,Mail}Folder. + 2012-03-16 Jean Raby * sogo.spec debian/sogo.postint: upon installation, update timestamp diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m index f50b0358c..71dcddb4e 100644 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ b/OpenChange/MAPIStoreCalendarFolder.m @@ -172,5 +172,4 @@ return MAPISTORE_SUCCESS; } - @end diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index bd299eb35..3c657b47d 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -1064,12 +1064,7 @@ if (newParticipationStatus) [sogoObject changeParticipationStatus: newParticipationStatus withDelegate: nil]; - - [(MAPIStoreCalendarFolder *) container synchroniseCache]; - value = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; - if (value) - [(MAPIStoreCalendarFolder *) container - setChangeKey: value forMessageWithKey: [self nameInContainer]]; + [self updateVersions]; } - (id) lookupAttachment: (NSString *) childKey diff --git a/OpenChange/MAPIStoreContactsFolder.m b/OpenChange/MAPIStoreContactsFolder.m index 49c26df90..3e7fe71c5 100644 --- a/OpenChange/MAPIStoreContactsFolder.m +++ b/OpenChange/MAPIStoreContactsFolder.m @@ -31,11 +31,13 @@ #import "MAPIStoreContactsContext.h" #import "MAPIStoreContactsMessage.h" #import "MAPIStoreContactsMessageTable.h" +#import "NSString+MAPIStore.h" #import "MAPIStoreContactsFolder.h" #include #include +#include @implementation MAPIStoreContactsFolder @@ -112,4 +114,12 @@ return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer]; } +- (int) getPidTagDefaultPostMessageClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"IPM.Contact" asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + @end diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index d1bdebadc..c8af5c05b 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -1157,11 +1157,8 @@ fromProperties: (NSDictionary *) attachmentProps // we save the new/modified card // [sogoObject saveContentString: [newCard versitString]]; - [(MAPIStoreContactsFolder *) container synchroniseCache]; - value = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; - if (value) - [(MAPIStoreContactsFolder *) container - setChangeKey: value forMessageWithKey: [self nameInContainer]]; + + [self updateVersions]; } @end diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 9565288fe..c6702c76c 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -1278,6 +1278,14 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe return rc; } +- (int) getPidTagDefaultPostMessageClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"IPM.Note" asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + - (int) getProperty: (void **) data withTag: (enum MAPITAGS) propTag inMemCtx: (TALLOC_CTX *) memCtx diff --git a/OpenChange/MAPIStoreGCSBaseContext.m b/OpenChange/MAPIStoreGCSBaseContext.m index d13e6bc58..296479251 100644 --- a/OpenChange/MAPIStoreGCSBaseContext.m +++ b/OpenChange/MAPIStoreGCSBaseContext.m @@ -27,6 +27,7 @@ #import #import +#import "MAPIApplication.h" #import "MAPIStoreUserContext.h" #import "NSString+MAPIStore.h" @@ -118,6 +119,7 @@ userContext = [MAPIStoreUserContext userContextWithUsername: userName andTDBIndexing: NULL]; + [MAPIApp setUserContext: userContext]; moduleName = [self MAPIModuleName]; parentFolder = [[userContext rootFolders] objectForKey: moduleName]; if (![parentFolder newFolderWithName: folderName @@ -126,6 +128,7 @@ userName, moduleName, nameInContainer]; else mapistoreURI = nil; + [MAPIApp setUserContext: nil]; return mapistoreURI; } diff --git a/OpenChange/MAPIStoreGCSFolder.h b/OpenChange/MAPIStoreGCSFolder.h index d87c9c63c..0d0c1e6df 100644 --- a/OpenChange/MAPIStoreGCSFolder.h +++ b/OpenChange/MAPIStoreGCSFolder.h @@ -41,6 +41,8 @@ /* synchronisation */ - (BOOL) synchroniseCache; +- (void) updateVersionsForMessageWithKey: (NSString *) messageKey + withChangeKey: (NSData *) newChangeKey; - (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum; - (NSNumber *) changeNumberForMessageWithKey: (NSString *) messageKey; diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index b27e0a24f..e5f6bbd65 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -252,7 +252,7 @@ static Class NSNumberK; ... }; VersionMapping = { - Version = MessageKey; + Version = last-modified; ... } } @@ -458,6 +458,15 @@ static Class NSNumberK; return rc; } + +- (void) updateVersionsForMessageWithKey: (NSString *) messageKey + withChangeKey: (NSData *) newChangeKey +{ + [self synchroniseCache]; + + if (newChangeKey) + [self setChangeKey: newChangeKey forMessageWithKey: messageKey]; +} - (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum { @@ -491,27 +500,17 @@ static Class NSNumberK; messages = [[versionsMessage properties] objectForKey: @"Messages"]; messageEntry = [messages objectForKey: messageKey]; if (!messageEntry) - abort (); + { + [self synchroniseCache]; + messageEntry = [messages objectForKey: messageKey]; + if (!messageEntry) + abort (); + } [self _setChangeKey: changeKey forMessageEntry: messageEntry]; [versionsMessage save]; } -- (NSData *) _dataFromChangeKeyGUID: (NSString *) guidString - andCnt: (NSData *) globCnt -{ - NSMutableData *changeKey; - struct GUID guid; - - changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]]; - - [guidString extractGUID: &guid]; - [changeKey appendData: [NSData dataWithGUID: &guid]]; - [changeKey appendData: globCnt]; - - return changeKey; -} - - (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey { NSDictionary *messages, *changeKeyDict; @@ -525,7 +524,7 @@ static Class NSNumberK; { guid = [changeKeyDict objectForKey: @"GUID"]; globCnt = [changeKeyDict objectForKey: @"LocalId"]; - changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt]; + changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; } return changeKey; @@ -533,9 +532,10 @@ static Class NSNumberK; - (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey { - NSMutableData *changeKeys = nil; + NSMutableData *list = nil; NSDictionary *messages, *changeListDict; NSArray *keys; + NSMutableArray *changeKeys; NSUInteger count, max; NSData *changeKey; NSString *guid; @@ -546,21 +546,30 @@ static Class NSNumberK; objectForKey: @"PredecessorChangeList"]; if (changeListDict) { - changeKeys = [NSMutableData data]; keys = [changeListDict allKeys]; max = [keys count]; + changeKeys = [NSMutableArray arrayWithCapacity: max]; for (count = 0; count < max; count++) { guid = [keys objectAtIndex: count]; globCnt = [changeListDict objectForKey: guid]; - changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt]; - [changeKeys appendUInt8: [changeKey length]]; - [changeKeys appendData: changeKey]; + changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; + [changeKeys addObject: changeKey]; + } + [changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare + context: nil]; + + list = [NSMutableData data]; + for (count = 0; count < max; count++) + { + changeKey = [changeKeys objectAtIndex: count]; + [list appendUInt8: [changeKey length]]; + [list appendData: changeKey]; } } - return changeKeys; + return list; } - (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum @@ -627,11 +636,11 @@ static Class NSNumberK; currentChangeNum = [[messageEntry objectForKey: @"version"] unsignedLongLongValue]; - if (MAPICNCompare (changeNum, currentChangeNum) + if (MAPICNCompare (changeNum, currentChangeNum, NULL) == NSOrderedAscending) { [(NSMutableArray *) deletedKeys addObject: cName]; - if (MAPICNCompare (maxChangeNum, currentChangeNum) + if (MAPICNCompare (maxChangeNum, currentChangeNum, NULL) == NSOrderedAscending) maxChangeNum = currentChangeNum; } diff --git a/OpenChange/MAPIStoreGCSMessage.h b/OpenChange/MAPIStoreGCSMessage.h index 883923e5f..5ada9290b 100644 --- a/OpenChange/MAPIStoreGCSMessage.h +++ b/OpenChange/MAPIStoreGCSMessage.h @@ -29,6 +29,9 @@ { } +/* subclass helpers */ +- (void) updateVersions; + @end #endif /* MAPISTOREGCSMESSAGE_H */ diff --git a/OpenChange/MAPIStoreGCSMessage.m b/OpenChange/MAPIStoreGCSMessage.m index 4d7ea0c07..c62f87990 100644 --- a/OpenChange/MAPIStoreGCSMessage.m +++ b/OpenChange/MAPIStoreGCSMessage.m @@ -21,6 +21,7 @@ */ #import +#import #import #import #import @@ -204,4 +205,15 @@ return version; } +- (void) updateVersions +{ + NSData *newChangeKey; + + newChangeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; + + [(MAPIStoreGCSFolder *) container + updateVersionsForMessageWithKey: [self nameInContainer] + withChangeKey: newChangeKey]; +} + @end diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m index f42f331c9..d91d76514 100644 --- a/OpenChange/MAPIStoreMailContext.m +++ b/OpenChange/MAPIStoreMailContext.m @@ -32,6 +32,7 @@ #import "NSString+MAPIStore.h" #import +#import "MAPIApplication.h" #import "MAPIStoreMailContext.h" #include @@ -176,6 +177,7 @@ MakeDisplayFolderName (NSString *folderName) userContext = [MAPIStoreUserContext userContextWithUsername: userName andTDBIndexing: NULL]; + [MAPIApp setUserContext: userContext]; accountFolder = [[userContext rootFolders] objectForKey: @"mail"]; folderName = [NSString stringWithFormat: @"folder%@", [newFolderName asCSSIdentifier]]; @@ -186,6 +188,7 @@ MakeDisplayFolderName (NSString *folderName) userName, userName, folderName]; else mapistoreURI = nil; + [MAPIApp setUserContext: nil]; return mapistoreURI; } diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 23c55ec97..f5cfe3340 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -218,21 +218,13 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK; } - (int) getPidTagContainerClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx + inMemCtx: (TALLOC_CTX *) memCtx { *data = [@"IPF.Note" asUnicodeInMemCtx: memCtx]; return MAPISTORE_SUCCESS; } -- (int) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Note" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - - (EOQualifier *) nonDeletedQualifier { static EOQualifier *nonDeletedQualifier = nil; @@ -686,21 +678,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) [versionsMessage save]; } -- (NSData *) _dataFromChangeKeyGUID: (NSString *) guidString - andCnt: (NSData *) globCnt -{ - NSMutableData *changeKey; - struct GUID guid; - - changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]]; - - [guidString extractGUID: &guid]; - [changeKey appendData: [NSData dataWithGUID: &guid]]; - [changeKey appendData: globCnt]; - - return changeKey; -} - - (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey { NSDictionary *messages, *changeKeyDict; @@ -716,7 +693,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) { guid = [changeKeyDict objectForKey: @"GUID"]; globCnt = [changeKeyDict objectForKey: @"LocalId"]; - changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt]; + changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; } return changeKey; @@ -724,9 +701,10 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) - (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey { - NSMutableData *changeKeys = nil; + NSMutableData *list = nil; NSDictionary *messages, *changeListDict; NSArray *keys; + NSMutableArray *changeKeys; NSUInteger count, max; NSData *changeKey; NSString *guid; @@ -739,21 +717,30 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) objectForKey: @"PredecessorChangeList"]; if (changeListDict) { - changeKeys = [NSMutableData data]; keys = [changeListDict allKeys]; max = [keys count]; + changeKeys = [NSMutableArray arrayWithCapacity: max]; for (count = 0; count < max; count++) { guid = [keys objectAtIndex: count]; globCnt = [changeListDict objectForKey: guid]; - changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt]; - [changeKeys appendUInt8: [changeKey length]]; - [changeKeys appendData: changeKey]; + changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; + [changeKeys addObject: changeKey]; + } + [changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare + context: nil]; + + list = [NSMutableData data]; + for (count = 0; count < max; count++) + { + changeKey = [changeKeys objectAtIndex: count]; + [list appendUInt8: [changeKey length]]; + [list appendData: changeKey]; } } - return changeKeys; + return list; } - (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index 2bc1dedaa..35ea1036d 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -685,12 +685,6 @@ rtf2html (NSData *compressedRTF) return MAPISTORE_SUCCESS; } -- (int) getPidTagMessageStatus: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - - (int) getPidTagImportance: (void **) data // TODO -> subclass? inMemCtx: (TALLOC_CTX *) memCtx { diff --git a/OpenChange/MAPIStoreNotesFolder.m b/OpenChange/MAPIStoreNotesFolder.m index aafa79f51..bac783bd2 100644 --- a/OpenChange/MAPIStoreNotesFolder.m +++ b/OpenChange/MAPIStoreNotesFolder.m @@ -21,11 +21,21 @@ */ #import "MAPIStoreNotesFolder.h" - #import "MAPIStoreNotesMessage.h" +#import "NSString+MAPIStore.h" + +#include #import "MAPIStoreNotesFolder.h" @implementation MAPIStoreNotesFolder +- (int) getPidTagDefaultPostMessageClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"IPM.StickyNote" asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + @end diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index 69df2ffc5..f2b6a807e 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -23,6 +23,7 @@ /* OpenChange SOGo storage backend */ #import +#import #import #import #import @@ -48,6 +49,7 @@ #include static Class MAPIStoreContextK = Nil; +static BOOL leakDebugging = NO; static enum mapistore_error sogo_backend_unexpected_error() @@ -57,6 +59,16 @@ sogo_backend_unexpected_error() return MAPISTORE_SUCCESS; } +static void +sogo_backend_atexit (void) +{ + NSAutoreleasePool *pool; + + pool = [NSAutoreleasePool new]; + NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES)); + [pool release]; +} + /** \details Initialize sogo mapistore backend @@ -89,6 +101,14 @@ sogo_backend_init (void) ud = [NSUserDefaults standardUserDefaults]; [ud registerDefaults: [ud persistentDomainForName: @"sogod"]]; + if (!leakDebugging && [ud boolForKey: @"SOGoDebugLeaks"]) + { + NSLog (@" leak debugging on"); + GSDebugAllocationActive (YES); + atexit (sogo_backend_atexit); + leakDebugging = YES; + } + registry = [SoProductRegistry sharedProductRegistry]; [registry scanForProductsInDirectory: SOGO_BUNDLES_DIR]; diff --git a/OpenChange/MAPIStoreTasksFolder.m b/OpenChange/MAPIStoreTasksFolder.m index 888daf2a8..bfc0698e8 100644 --- a/OpenChange/MAPIStoreTasksFolder.m +++ b/OpenChange/MAPIStoreTasksFolder.m @@ -34,11 +34,13 @@ #import "MAPIStoreTasksContext.h" #import "MAPIStoreTasksMessage.h" #import "MAPIStoreTasksMessageTable.h" +#import "NSString+MAPIStore.h" #import "MAPIStoreTasksFolder.h" #include #include +#include @implementation MAPIStoreTasksFolder @@ -124,4 +126,12 @@ [(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]]; } +- (int) getPidTagDefaultPostMessageClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"IPM.Task" asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + @end diff --git a/OpenChange/MAPIStoreTasksMessage.m b/OpenChange/MAPIStoreTasksMessage.m index 28d690b74..658817650 100644 --- a/OpenChange/MAPIStoreTasksMessage.m +++ b/OpenChange/MAPIStoreTasksMessage.m @@ -450,7 +450,7 @@ // percent complete // NOTE: this does not seem to work on Outlook 2003. PidLidPercentComplete's value // is always set to 0, no matter what value is set in Outlook - value = [properties objectForKey: MAPIPropertyKey(PidLidPercentComplete)]; + value = [properties objectForKey: MAPIPropertyKey (PidLidPercentComplete)]; if (value) [vToDo setPercentComplete: [value stringValue]]; @@ -462,11 +462,8 @@ [vToDo setTimeStampAsDate: now]; [sogoObject saveContentString: [vCalendar versitString]]; - [(MAPIStoreTasksFolder *) container synchroniseCache]; - value = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; - if (value) - [(MAPIStoreTasksFolder *) container - setChangeKey: value forMessageWithKey: [self nameInContainer]]; + + [self updateVersions]; } @end diff --git a/OpenChange/MAPIStoreTypes.h b/OpenChange/MAPIStoreTypes.h index c630b1e15..1fec6a6a7 100644 --- a/OpenChange/MAPIStoreTypes.h +++ b/OpenChange/MAPIStoreTypes.h @@ -42,7 +42,8 @@ id NSObjectFromSPropValue (const struct SPropValue *); id NSObjectFromMAPISPropValue (const struct mapi_SPropValue *); id NSObjectFromValuePointer (enum MAPITAGS, const void *); -NSComparisonResult MAPICNCompare (uint64_t cn1, uint64_t cn2); +NSComparisonResult MAPICNCompare (uint64_t cn1, uint64_t cn2, void *); +NSComparisonResult MAPIChangeKeyGUIDCompare (NSData *ck1, NSData *ck2, void *); static inline NSNumber * MAPIPropertyKey (enum MAPITAGS propTag) diff --git a/OpenChange/MAPIStoreTypes.m b/OpenChange/MAPIStoreTypes.m index 24dbac860..c294dd429 100644 --- a/OpenChange/MAPIStoreTypes.m +++ b/OpenChange/MAPIStoreTypes.m @@ -284,7 +284,7 @@ _reverseCN (uint64_t cn) } NSComparisonResult -MAPICNCompare (uint64_t cn1, uint64_t cn2) +MAPICNCompare (uint64_t cn1, uint64_t cn2, void *unused) { NSComparisonResult result; @@ -298,6 +298,41 @@ MAPICNCompare (uint64_t cn1, uint64_t cn2) return result; } +NSComparisonResult MAPIChangeKeyGUIDCompare (NSData *ck1, NSData *ck2, void *unused) +{ + NSUInteger count; + const unsigned char *ptr1, *ptr2; + NSComparisonResult result = NSOrderedSame; + + if ([ck1 length] < 16) + { + NSLog (@"ck1 has a length < 16"); + abort (); + } + if ([ck2 length] < 16) + { + NSLog (@"ck2 has a length < 16"); + abort (); + } + + ptr1 = [ck1 bytes]; + ptr2 = [ck2 bytes]; + for (count = 0; result == NSOrderedSame && count < 16; count++) + { + if (*ptr1 < *ptr2) + result = NSOrderedAscending; + else if (*ptr1 > *ptr2) + result = NSOrderedDescending; + else + { + ptr1++; + ptr2++; + } + } + + return result; +} + void MAPIStoreDumpMessageProperties (NSDictionary *properties) { diff --git a/OpenChange/NSData+MAPIStore.h b/OpenChange/NSData+MAPIStore.h index fd56f0389..20409c1ac 100644 --- a/OpenChange/NSData+MAPIStore.h +++ b/OpenChange/NSData+MAPIStore.h @@ -42,6 +42,9 @@ + (id) dataWithXID: (const struct XID *) xid; - (struct XID *) asXIDInMemCtx: (void *) memCtx; ++ (id) dataWithChangeKeyGUID: (NSString *) guidString + andCnt: (NSData *) globCnt; + @end @interface NSMutableData (MAPIStoreDataTypes) diff --git a/OpenChange/NSData+MAPIStore.m b/OpenChange/NSData+MAPIStore.m index e9fe04076..b0143dc1b 100644 --- a/OpenChange/NSData+MAPIStore.m +++ b/OpenChange/NSData+MAPIStore.m @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#import "NSString+MAPIStore.h" + #import "NSData+MAPIStore.h" #undef DEBUG @@ -168,6 +170,21 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID * return xid; } ++ (id) dataWithChangeKeyGUID: (NSString *) guidString + andCnt: (NSData *) globCnt; +{ + NSMutableData *changeKey; + struct GUID guid; + + changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]]; + + [guidString extractGUID: &guid]; + [changeKey appendData: [NSData dataWithGUID: &guid]]; + [changeKey appendData: globCnt]; + + return changeKey; +} + @end @implementation NSMutableData (MAPIStoreDataTypes) diff --git a/Tests/Integration/test-webdavsync.py b/Tests/Integration/test-webdavsync.py index d6dc34fca..e28048ddc 100755 --- a/Tests/Integration/test-webdavsync.py +++ b/Tests/Integration/test-webdavsync.py @@ -54,7 +54,7 @@ class WebdavSyncTest(unittest.TestCase): self.assertTrue(token > 0) query1EndTime = int(math.ceil(query1.start + query1.duration)) self.assertTrue(token <= query1EndTime, - "token = %d > query1EndTime = %d" % (token, query1EndTime)) + "token = %d > query1EndTime = %d" % (token, query1EndTime)) # we make sure that any token is accepted when the collection is # empty, but that the returned token differs