diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 38e54b7af..8c3983f7e 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -802,13 +802,43 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) return YES; } + - (NSNumber *) modseqFromMessageChangeNumber: (NSString *) changeNum { NSDictionary *mapping; NSNumber *modseq; + NSEnumerator *enumerator; + id key; + uint64_t found, target, current, replica_id, current_cn; + NSString *closestChangeNum; mapping = [[versionsMessage properties] objectForKey: @"VersionMapping"]; modseq = [mapping objectForKey: changeNum]; + if (modseq) return modseq; + + // Not found from stored change numbers for this folder. + // Get the closest modseq for the change number given. + // O(n) cost but will be unusual behaviour. + target = exchange_globcnt([changeNum unsignedLongLongValue] >> 16); + replica_id = [changeNum unsignedLongLongValue] & 0xFFFF; + found = 0; + enumerator = [mapping keyEnumerator]; + while ((key = [enumerator nextObject])) + { + current_cn = [(NSString *)key unsignedLongLongValue]; + if ((current_cn & 0xFFFF) != replica_id) + continue; + current = exchange_globcnt(current_cn >> 16); + if (current < target && current > found) + found = current; + } + + if (found) + { + closestChangeNum = [NSString stringWithUnsignedLongLong: + (exchange_globcnt(found) << 16 | replica_id)]; + modseq = [mapping objectForKey: closestChangeNum]; + } return modseq; }