From 911b170f32c911daebfec863bd8fa0b16c1c1086 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:39:51 +0000 Subject: [PATCH 01/14] Monotone-Parent: 7fc3840c26038b9a53ac374b2e5b17f2ceeb99ab Monotone-Revision: 6458b9280ffad02762e0cb2a3067126b205997d6 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:39:51 Monotone-Branch: ca.inverse.sogo --- OpenChange/MAPIStoreCalendarFolder.m | 1 - 1 file changed, 1 deletion(-) 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 From 38e085ae8f4499cf5ca2a3d97e718682bcbdb8b4 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:41:52 +0000 Subject: [PATCH 02/14] Monotone-Parent: ae2a845cc86e684e944e2ffbb629f7bd634d985f Monotone-Revision: 0d1809a8a5fbb980e78d197e8f5c0c634b960a2e Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:41:52 Monotone-Branch: ca.inverse.sogo --- Tests/Integration/test-webdavsync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 3ad93f3257d8c0a1b8ca4056b0b00d58554be7a0 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:51:51 +0000 Subject: [PATCH 03/14] Monotone-Parent: 0d1809a8a5fbb980e78d197e8f5c0c634b960a2e Monotone-Revision: cd4c34d79c62c8b6a1f9ccfb14ea9a79442034c6 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:51:51 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 6 ++++++ OpenChange/MAPIStoreGCSFolder.m | 19 ++----------------- OpenChange/MAPIStoreMailFolder.m | 19 ++----------------- OpenChange/NSData+MAPIStore.h | 3 +++ OpenChange/NSData+MAPIStore.m | 17 +++++++++++++++++ 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61fc3d51a..88eb73a8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-03-16 Wolfgang Sourdeau + + * 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/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index b27e0a24f..74c784c93 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -497,21 +497,6 @@ static Class NSNumberK; [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 +510,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; @@ -554,7 +539,7 @@ static Class NSNumberK; { guid = [keys objectAtIndex: count]; globCnt = [changeListDict objectForKey: guid]; - changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt]; + changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; [changeKeys appendUInt8: [changeKey length]]; [changeKeys appendData: changeKey]; } diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 23c55ec97..93fe1aee8 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -686,21 +686,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 +701,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; @@ -747,7 +732,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) { guid = [keys objectAtIndex: count]; globCnt = [changeListDict objectForKey: guid]; - changeKey = [self _dataFromChangeKeyGUID: guid andCnt: globCnt]; + changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; [changeKeys appendUInt8: [changeKey length]]; [changeKeys appendData: changeKey]; } 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) From 5b424d69690f7e05650ec94b318f3ff2e2a1aa11 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:53:04 +0000 Subject: [PATCH 04/14] Monotone-Parent: cd4c34d79c62c8b6a1f9ccfb14ea9a79442034c6 Monotone-Revision: ff50144aaefa18bc1bf88723bc25f1f6b4962451 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:53:04 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 4 ++++ OpenChange/MAPIStoreSOGo.m | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ChangeLog b/ChangeLog index 88eb73a8a..2036b55f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2012-03-16 Wolfgang Sourdeau + * 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. 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]; From 23ab567d6edd9d22bb6c92b1cdaa0e42816854d1 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:53:51 +0000 Subject: [PATCH 05/14] Monotone-Parent: ff50144aaefa18bc1bf88723bc25f1f6b4962451 Monotone-Revision: 28f447e944f764132e7461e3945a83c23938d406 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:53:51 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 3 +++ OpenChange/MAPIStoreMessage.m | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2036b55f7..c5ee2f89f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2012-03-16 Wolfgang Sourdeau + * 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. 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 { From baafa421ab46205e79e3830b82734c7491598786 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:56:01 +0000 Subject: [PATCH 06/14] Monotone-Parent: 28f447e944f764132e7461e3945a83c23938d406 Monotone-Revision: 284725383e8970e66810d4b8facf4af043b77fe2 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:56:01 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 12 ++++++++++++ OpenChange/MAPIStoreContactsFolder.m | 10 ++++++++++ OpenChange/MAPIStoreFolder.m | 8 ++++++++ OpenChange/MAPIStoreNotesFolder.m | 12 +++++++++++- OpenChange/MAPIStoreTasksFolder.m | 10 ++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c5ee2f89f..94ed06ca5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2012-03-16 Wolfgang Sourdeau + * 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. 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/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/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/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 From a8cc7409a11225d466b19eb359bc8571798b5e66 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 20:57:35 +0000 Subject: [PATCH 07/14] Monotone-Parent: 284725383e8970e66810d4b8facf4af043b77fe2 Monotone-Revision: 34a0500cef031e53eda3a1a6c3b2f626ce8f76dc Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T20:57:35 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 8 ++++++++ OpenChange/MAPIStoreGCSBaseContext.m | 3 +++ OpenChange/MAPIStoreMailContext.m | 3 +++ 3 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index 94ed06ca5..862cd95fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2012-03-16 Wolfgang Sourdeau + * 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. 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/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; } From 26701b7c719243b8b09873b7b40c110ffa8ee8b5 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:05:41 +0000 Subject: [PATCH 08/14] Monotone-Parent: 34a0500cef031e53eda3a1a6c3b2f626ce8f76dc Monotone-Revision: f4e8a715d67a12fea729843b1401f636ce05ed66 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:05:41 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 10 ++++++++++ OpenChange/MAPIStoreCalendarMessage.m | 7 +------ OpenChange/MAPIStoreContactsMessage.m | 7 ++----- OpenChange/MAPIStoreGCSFolder.h | 2 ++ OpenChange/MAPIStoreGCSFolder.m | 11 ++++++++++- OpenChange/MAPIStoreGCSMessage.h | 3 +++ OpenChange/MAPIStoreGCSMessage.m | 12 ++++++++++++ OpenChange/MAPIStoreTasksMessage.m | 7 ++----- 8 files changed, 42 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 862cd95fb..0d67ba961 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2012-03-16 Wolfgang Sourdeau + * OpenChange/MAPIStoreGCSFolder.m + (-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/MAPIStoreGCSMessage.m (-updateVersions): new proxy + method for -[MAPIStoreGCSFolder + updateVersionsForMessageWithKey:withChangeKey:]. + * OpenChange/MAPIStoreGCSBaseContext.m (+createRootSecondaryFolderWithFID:andName:forUser:): setup the userContext in the MAPIApp object. 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/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/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 74c784c93..57cb9b123 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 { 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/MAPIStoreTasksMessage.m b/OpenChange/MAPIStoreTasksMessage.m index 28d690b74..5e123fab7 100644 --- a/OpenChange/MAPIStoreTasksMessage.m +++ b/OpenChange/MAPIStoreTasksMessage.m @@ -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 From ff26754291e0ab24467fe5037c7176b88e57d80e Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:09:10 +0000 Subject: [PATCH 09/14] 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) { From 36ded79755e630edb57cd7803c968028634eef3b Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:10:33 +0000 Subject: [PATCH 10/14] Monotone-Parent: 86ef6adf2b0443af39cafaac0b9a9d66fb753576 Monotone-Revision: 3f20830a3de3ff870541d0f05c25b39079b08e65 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:10:33 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 4 ++++ OpenChange/MAPIStoreMailFolder.m | 10 +--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5bb792d7f..119d33f1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2012-03-16 Wolfgang Sourdeau + * OpenChange/MAPIStoreMailFolder.m + (-getPidTagMessageClass:inMemCtx:): removed method, as folders are + not supposed to return a PidTagMessageClass attribute. + * OpenChange/MAPIStoreGCSFolder.m (-predecessorChangeListForMessageWithKey:): same as below. diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index e1db52f07..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; From 7144a0fddb5e31d56c4384f233c0b938f9382170 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:10:48 +0000 Subject: [PATCH 11/14] Monotone-Parent: 3f20830a3de3ff870541d0f05c25b39079b08e65 Monotone-Revision: 9d9059c535146bcefa1a378020e4c39b33d901e2 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:10:48 Monotone-Branch: ca.inverse.sogo --- OpenChange/MAPIStoreTasksMessage.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenChange/MAPIStoreTasksMessage.m b/OpenChange/MAPIStoreTasksMessage.m index 5e123fab7..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]]; From 57fc5197bea2ca55e2d795731ebbed2052bc9c3a Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:12:12 +0000 Subject: [PATCH 12/14] Monotone-Parent: 9d9059c535146bcefa1a378020e4c39b33d901e2 Monotone-Revision: 256c88e136b95ffb79c997058df4ad39e9e33821 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:12:12 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 4 ++++ OpenChange/MAPIStoreGCSFolder.m | 4 ++-- OpenChange/MAPIStoreTypes.h | 2 +- OpenChange/MAPIStoreTypes.m | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 119d33f1f..df6518426 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2012-03-16 Wolfgang Sourdeau + * OpenChange/MAPIStoreTypes.m (MAPICNCompare): added as void * + parameter so that the function can be used as a comparator + function in NSArray sort methods. + * OpenChange/MAPIStoreMailFolder.m (-getPidTagMessageClass:inMemCtx:): removed method, as folders are not supposed to return a PidTagMessageClass attribute. diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index cf777ca3c..0464b5b97 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -631,11 +631,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/MAPIStoreTypes.h b/OpenChange/MAPIStoreTypes.h index 5a8e3fb42..1fec6a6a7 100644 --- a/OpenChange/MAPIStoreTypes.h +++ b/OpenChange/MAPIStoreTypes.h @@ -42,7 +42,7 @@ 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 * diff --git a/OpenChange/MAPIStoreTypes.m b/OpenChange/MAPIStoreTypes.m index b7cd9bb98..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; From 18cd217b63d7743eaded8aaee991c40654979cfc Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:13:16 +0000 Subject: [PATCH 13/14] Monotone-Parent: 256c88e136b95ffb79c997058df4ad39e9e33821 Monotone-Revision: df7bf24308030f46878403591ecefe2986dc350b Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:13:16 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 2 ++ OpenChange/MAPIStoreGCSFolder.m | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index df6518426..4e8222a18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,8 @@ * OpenChange/MAPIStoreGCSFolder.m (-predecessorChangeListForMessageWithKey:): same as below. + (-setChangeKey:forMessageWithKey:): synchronise the version cache + if the message entry is not found. * OpenChange/MAPIStoreMailFolder.m (-predecessorChangeListForMessageWithKey:): the returned list must diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index 0464b5b97..e5f6bbd65 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -500,7 +500,12 @@ 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]; From cf97dee428848ae04b177887b787edf5dc7667b4 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 16 Mar 2012 21:14:38 +0000 Subject: [PATCH 14/14] Monotone-Parent: df7bf24308030f46878403591ecefe2986dc350b Monotone-Revision: a080c16a5e48751ac225497ff7300f2a67b4721f Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-16T21:14:38 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e8222a18..504f620cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,31 +1,26 @@ 2012-03-16 Wolfgang Sourdeau - * OpenChange/MAPIStoreTypes.m (MAPICNCompare): added as void * - parameter so that the function can be used as a comparator - function in NSArray sort methods. - - * OpenChange/MAPIStoreMailFolder.m - (-getPidTagMessageClass:inMemCtx:): removed method, as folders are - not supposed to return a PidTagMessageClass attribute. - * 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 (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 - insert the PidTagChangeKey provided by the client during the save - operations. + * 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