From ff26754291e0ab24467fe5037c7176b88e57d80e Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:09:10 +0000 Subject: [PATCH] Monotone-Parent: f4e8a715d67a12fea729843b1401f636ce05ed66 Monotone-Revision: 86ef6adf2b0443af39cafaac0b9a9d66fb753576 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:09:10 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 11 ++++++++++ OpenChange/MAPIStoreGCSFolder.m | 20 +++++++++++++----- OpenChange/MAPIStoreMailFolder.m | 20 +++++++++++++----- OpenChange/MAPIStoreTypes.h | 1 + OpenChange/MAPIStoreTypes.m | 35 ++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d67ba961..5bb792d7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2012-03-16 Wolfgang Sourdeau + * OpenChange/MAPIStoreGCSFolder.m + (-predecessorChangeListForMessageWithKey:): same as below. + + * 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. + + * OpenChange/MAPIStoreTypes.m (MAPIChangeKeyGUIDCompare): new + comparator function to compare the GUID of two change key streams. + * OpenChange/MAPIStoreGCSFolder.m (-updateVersionsForMessageWithKey:withChangeKey:): new method, common to all GCS messages, that updates the folder cache and diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index 57cb9b123..cf777ca3c 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -527,9 +527,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; @@ -540,21 +541,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 = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; - [changeKeys appendUInt8: [changeKey length]]; - [changeKeys appendData: changeKey]; + [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/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 93fe1aee8..e1db52f07 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -709,9 +709,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; @@ -724,21 +725,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 = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; - [changeKeys appendUInt8: [changeKey length]]; - [changeKeys appendData: changeKey]; + [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/MAPIStoreTypes.h b/OpenChange/MAPIStoreTypes.h index c630b1e15..5a8e3fb42 100644 --- a/OpenChange/MAPIStoreTypes.h +++ b/OpenChange/MAPIStoreTypes.h @@ -43,6 +43,7 @@ id NSObjectFromMAPISPropValue (const struct mapi_SPropValue *); id NSObjectFromValuePointer (enum MAPITAGS, const void *); NSComparisonResult MAPICNCompare (uint64_t cn1, uint64_t cn2); +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..b7cd9bb98 100644 --- a/OpenChange/MAPIStoreTypes.m +++ b/OpenChange/MAPIStoreTypes.m @@ -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) {