From ed2c4777aa3df9ab131c9b624c1b02ebdd503845 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Mon, 7 Mar 2011 19:15:16 +0000 Subject: [PATCH] Monotone-Parent: 482fb2f36da6ff311c3c19eb3752da985fdae5cd Monotone-Revision: 8fcaef79630a50f01c6aba0e5fdc0744c274cba6 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-03-07T19:15:16 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 42 +++++ OpenChange/GNUmakefile | 3 + OpenChange/MAPIStoreCalendarFolder.m | 6 +- OpenChange/MAPIStoreContactsFolder.m | 6 +- OpenChange/MAPIStoreContactsMessage.m | 7 +- OpenChange/MAPIStoreContactsMessageTable.m | 2 + OpenChange/MAPIStoreContext.h | 6 + OpenChange/MAPIStoreContext.m | 170 ++++++++++++++++++--- OpenChange/MAPIStoreDraftsMessage.m | 8 +- OpenChange/MAPIStoreFAIMessageTable.h | 31 ++++ OpenChange/MAPIStoreFAIMessageTable.m | 40 +++++ OpenChange/MAPIStoreFSFolder.m | 7 +- OpenChange/MAPIStoreFolder.h | 15 +- OpenChange/MAPIStoreFolder.m | 101 ++++++++---- OpenChange/MAPIStoreFolderTable.m | 10 ++ OpenChange/MAPIStoreMailFolder.m | 6 +- OpenChange/MAPIStoreMailMessage.m | 19 +-- OpenChange/MAPIStoreMessage.h | 2 +- OpenChange/MAPIStoreMessage.m | 14 +- OpenChange/MAPIStoreObject.h | 8 + OpenChange/MAPIStoreObject.m | 26 ++++ OpenChange/MAPIStoreSOGo.m | 103 +++++++++++++ OpenChange/MAPIStoreTable.h | 8 + OpenChange/MAPIStoreTable.m | 73 ++++++++- OpenChange/MAPIStoreTasksFolder.m | 6 +- OpenChange/MAPIStoreTasksMessage.m | 5 +- OpenChange/MAPIStoreTypes.h | 4 +- 27 files changed, 624 insertions(+), 104 deletions(-) create mode 100644 OpenChange/MAPIStoreFAIMessageTable.h create mode 100644 OpenChange/MAPIStoreFAIMessageTable.m diff --git a/ChangeLog b/ChangeLog index 2d714f007..3d95262ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,47 @@ 2011-03-07 Wolfgang Sourdeau + * OpenChange/MAPIStoreFAIMessageTable.[hm]: restored class module + in order to reenable proper class testing during notifications. + + * OpenChange/MAPIStoreTypes.h (MAPIPropertyKey): we now make use + of the full property tag again since the modified properties need + to be reported during notifications. + + * OpenChange/MAPIStoreSOGo.m (sogo_pocop_open_table) + (sogo_pocop_set_table_restrictions) + (sogo_pocop_set_table_sort_order): new poc methods. + (sogo_pocop_release): invoke -deactivate on the released object if + it responds to it. + + * OpenChange/MAPIStoreContext.m (-setRestrictions:withFID:andTableType:getTableStatus:): + (-setSortOrder:withFID:andTableType:getTableStatus:): + (-getTableProperty:withTag:atPosition:withTableType:andQueryType:inFID:): + adversise methods as obsolete in the log for debugging purposes. + (_saveOrSubmitChangesInMessageWithMID:andFlags:save:): added code + to push the relevant folder, message and table notifications. + (-deleteMessageWithMID:inFID:withFlags:): same as above. + (-getTable:andRowCount:withFID:tableType:andHandleId:): new pocop + helper method to instantiate tables. + + * OpenChange/MAPIStoreTable.m (-notifyChangesForChild:): new + method that pushes an appropriate table notification with regards + to the child passed as parameters. + (-deactivate): new helper method that enables the table to + unregister itself from its container prior to be released. + (-setHandleId): new helper accessor enabling reporting the table + handle during notifications. + + * OpenChange/MAPIStoreObject.m (-addActiveTable:) + (-removeActiveTable:): new methods to add or remove tables from + the active table arrays, used later for notifications. + (-resetNewProperties): new method to empty the "newProperties" + dictionary once a "save changes" or a "submit" happened. + + * OpenChange/MAPIStore*Folder.m (-messageTable, -messageFAITable, + -folderTable) + * OpenChange/MAPIStore*Message.m (-attachmentTable): no longer + cache the resulting table. + * SoObjects/SOGo/SOGoCache.m (-unregisterObjectWithName:inContainer:): same as below. diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile index 3aa7767a5..c78e28e27 100644 --- a/OpenChange/GNUmakefile +++ b/OpenChange/GNUmakefile @@ -47,6 +47,9 @@ $(SOGOBACKEND)_OBJC_FILES += \ MAPIStoreFSMessage.m \ MAPIStoreFSMessageTable.m \ \ + MAPIStoreFAIMessage.m \ + MAPIStoreFAIMessageTable.m \ + \ MAPIStoreGCSBaseContext.m \ MAPIStoreGCSFolder.m \ MAPIStoreGCSMessage.m \ diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m index 0be936e40..8b6eb771b 100644 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ b/OpenChange/MAPIStoreCalendarFolder.m @@ -83,11 +83,7 @@ static Class MAPIStoreCalendarMessageK; - (MAPIStoreMessageTable *) messageTable { - if (!messageTable) - ASSIGN (messageTable, - [MAPIStoreCalendarMessageTable tableForContainer: self]); - - return messageTable; + return [MAPIStoreCalendarMessageTable tableForContainer: self]; } - (EOQualifier *) componentQualifier diff --git a/OpenChange/MAPIStoreContactsFolder.m b/OpenChange/MAPIStoreContactsFolder.m index 0c6c3b162..df6f5ed36 100644 --- a/OpenChange/MAPIStoreContactsFolder.m +++ b/OpenChange/MAPIStoreContactsFolder.m @@ -85,11 +85,7 @@ static Class MAPIStoreContactsMessageK; - (MAPIStoreMessageTable *) messageTable { - if (!messageTable) - ASSIGN (messageTable, - [MAPIStoreContactsMessageTable tableForContainer: self]); - - return messageTable; + return [MAPIStoreContactsMessageTable tableForContainer: self]; } - (EOQualifier *) componentQualifier diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 5602b2dc8..f4b0f1877 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -41,6 +41,7 @@ #include #include #include +#include #include @implementation MAPIStoreContactsMessage @@ -80,7 +81,7 @@ NGVCard *vCard; enum MAPISTATUS rc; - rc = MAPI_E_SUCCESS; + rc = MAPISTORE_SUCCESS; switch (proptag) { case PR_ICON_INDEX: // TODO @@ -161,6 +162,8 @@ case PR_CONTACT_EMAIL_ADDRESSES_UNICODE: stringValue = [[sogoObject vCard] preferredEMail]; + if (!stringValue) + stringValue = @""; *data = [[NSArray arrayWithObject: stringValue] asArrayOfUnicodeStringsInCtx: memCtx]; break; @@ -490,7 +493,7 @@ *data = [dateValue asFileTimeInMemCtx: memCtx]; } else - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; } break; diff --git a/OpenChange/MAPIStoreContactsMessageTable.m b/OpenChange/MAPIStoreContactsMessageTable.m index 549b8cb05..a6f3a5ea5 100644 --- a/OpenChange/MAPIStoreContactsMessageTable.m +++ b/OpenChange/MAPIStoreContactsMessageTable.m @@ -108,6 +108,8 @@ knownProperties = [NSMutableDictionary new]; [knownProperties setObject: @"c_cn" forKey: MAPIPropertyKey (PidLidFileUnder)]; + [knownProperties setObject: @"c_cn" + forKey: MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE)]; } return [knownProperties objectForKey: MAPIPropertyKey (property)]; diff --git a/OpenChange/MAPIStoreContext.h b/OpenChange/MAPIStoreContext.h index e0a6f2191..c2c4c3539 100644 --- a/OpenChange/MAPIStoreContext.h +++ b/OpenChange/MAPIStoreContext.h @@ -160,6 +160,12 @@ - (void) setupBaseFolder: (NSURL *) newURL; /* proof of concept */ +- (int) getTable: (void **) table + andRowCount: (uint32_t *) count + withFID: (uint64_t) fid + tableType: (uint8_t) tableType + andHandleId: (uint32_t) handleId; + - (int) getAttachmentTable: (void **) table andRowCount: (uint32_t *) count withMID: (uint64_t) mid; diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 7e90c614d..b001421c3 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -43,7 +43,8 @@ #import "MAPIStoreMapping.h" #import "MAPIStoreMessage.h" #import "MAPIStoreMessageTable.h" -#import "MAPIStoreFSMessageTable.h" +#import "MAPIStoreFAIMessage.h" +#import "MAPIStoreFAIMessageTable.h" #import "MAPIStoreTypes.h" #import "NSArray+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -66,7 +67,7 @@ /* sogo://username:password@{contacts,calendar,tasks,journal,notes,mail}/dossier/id */ -static Class NSDataK, NSStringK; +static Class NSDataK, NSStringK, MAPIStoreFAIMessageK; static MAPIStoreMapping *mapping; static NSMutableDictionary *contextClassMapping; @@ -82,6 +83,7 @@ static void *ldbCtx = NULL; NSDataK = [NSData class]; NSStringK = [NSString class]; + MAPIStoreFAIMessageK = [MAPIStoreFAIMessage class]; mapping = [MAPIStoreMapping sharedMapping]; @@ -405,21 +407,11 @@ _prepareContextClass (struct mapistore_context *newMemCtx, MAPIStoreFolder *folder; int rc; + /* WARNING: make sure this method is no longer invoked for counting + table elements */ [self logWithFormat: @"METHOD '%s' (%d) -- tableType: %d", __FUNCTION__, __LINE__, tableType]; - // [self logWithFormat: @"context restriction state is: %@", - // MAPIStringForRestrictionState (restrictionState)]; - // if (restriction) - // [self logWithFormat: @" active qualifier: %@", restriction]; - - // if (restrictionState == MAPIRestrictionStateAlwaysFalse) - // { - // *rowCount = 0; - // rc = MAPI_E_SUCCESS; - // } - // else - // { url = [mapping urlFromID: fid]; if (url) { @@ -469,6 +461,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx, { MAPIStoreTable *table; + [self errorWithFormat: @"%s: obsolete method", __FUNCTION__]; + table = [self _tableForFID: fid andTableType: tableType]; [table setRestrictions: res]; // FIXME: we should not flush the caches if the restrictions matches @@ -483,6 +477,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx, { MAPIStoreTable *table; + [self errorWithFormat: @"%s: obsolete method", __FUNCTION__]; + table = [self _tableForFID: fid andTableType: type]; [table setSortOrder: set]; [table cleanupCaches]; @@ -503,6 +499,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx, const char *propName; int rc; + [self errorWithFormat: @"%s: obsolete method", __FUNCTION__]; + // [self logWithFormat: @"METHOD '%s' (%d) -- proptag: %s (0x%.8x), pos: %.8x," // @" tableType: %d, queryType: %d, fid: %.16x", // __FUNCTION__, __LINE__, propName, proptag, pos, tableType, queryType, fid]; @@ -577,7 +575,6 @@ _prepareContextClass (struct mapistore_context *newMemCtx, if (message) { [message openMessage: msg]; - [message setMAPIRetainCount: [message mapiRetainCount] + 1]; [messages setObject: message forKey: midKey]; rc = MAPISTORE_SUCCESS; } @@ -646,18 +643,83 @@ _prepareContextClass (struct mapistore_context *newMemCtx, { int rc; MAPIStoreMessage *message; + MAPIStoreFolder *folder; NSNumber *midKey; + NSArray *activeTables; + NSUInteger count, max; + // NSArray *propKeys; + struct mapistore_object_notification_parameters *notif_parameters; + // uint16_t count, max; + uint64_t folderId; midKey = [NSNumber numberWithUnsignedLongLong: mid]; message = [messages objectForKey: midKey]; if (message) { rc = MAPISTORE_SUCCESS; + folder = (MAPIStoreFolder *) [message container]; if (isSave) - [message save]; + { + /* notifications */ + folderId = [folder objectId]; + + /* folder modified */ + notif_parameters + = talloc_zero(memCtx, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = folderId; + if ([message 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 = [[folder messageKeys] count] + 1; + } + mapistore_push_notification (MAPISTORE_FOLDER, + MAPISTORE_OBJECT_MODIFIED, + notif_parameters); + + /* message created */ + if ([message isNew]) + { + notif_parameters + = talloc_zero(memCtx, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = [message objectId]; + notif_parameters->folder_id = folderId; + + notif_parameters->tag_count = 0xffff; + mapistore_push_notification (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 */ + activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] + ? [folder activeFAIMessageTables] + : [folder activeMessageTables]); + max = [activeTables count]; + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] restrictedChildKeys]; + + [message save]; + + /* table modified */ + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] + notifyChangesForChild: message]; + } else [message submit]; - [[message container] cleanupCaches]; + [message setIsNew: NO]; + [message resetNewProperties]; + [folder cleanupCaches]; } else rc = MAPISTORE_ERROR; @@ -1095,6 +1157,9 @@ _prepareContextClass (struct mapistore_context *newMemCtx, NSString *childURL, *folderURL, *childKey; MAPIStoreFolder *folder; MAPIStoreMessage *message; + NSArray *activeTables; + NSUInteger count, max; + struct mapistore_object_notification_parameters *notif_parameters; int rc; [self logWithFormat: @"-deleteMessageWithMID: mid: 0x%.16x flags: %d", mid, flags]; @@ -1110,15 +1175,67 @@ _prepareContextClass (struct mapistore_context *newMemCtx, message = [folder lookupChild: childKey]; if (message) { + /* we ensure the table caches are loaded so that old and new state + can be compared */ + /* we ensure the table caches are loaded so that old and new state + can be compared */ + activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] + ? [folder activeFAIMessageTables] + : [folder activeMessageTables]); + max = [activeTables count]; + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] restrictedChildKeys]; + if ([[message sogoObject] delete]) { rc = MAPISTORE_ERROR; [self logWithFormat: @"ERROR deleting object at URL: %@", childURL]; } - else + else { + if (![message isNew]) + { + /* folder notification */ + notif_parameters + = talloc_zero(memCtx, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = fid; + notif_parameters->tag_count = 5; + notif_parameters->tags = talloc_array (notif_parameters, + enum MAPITAGS, 5); + notif_parameters->tags[0] = PR_CONTENT_COUNT; + notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; + notif_parameters->tags[2] = PR_MESSAGE_SIZE; + notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; + notif_parameters->tags[4] = PR_DELETED_MSG_COUNT; + notif_parameters->new_message_count = true; + notif_parameters->message_count = [[folder messageKeys] + count] - 1; + mapistore_push_notification (MAPISTORE_FOLDER, + MAPISTORE_OBJECT_MODIFIED, + notif_parameters); + talloc_free(notif_parameters); + + /* message notification */ + notif_parameters + = talloc_zero(memCtx, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = mid; + notif_parameters->folder_id = fid; + /* Exchange sends a fnevObjectCreated!! */ + mapistore_push_notification (MAPISTORE_MESSAGE, + MAPISTORE_OBJECT_CREATED, + notif_parameters); + talloc_free(notif_parameters); + + /* table notification */ + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] + notifyChangesForChild: message]; + } [self logWithFormat: @"sucessfully deleted object at URL: %@", childURL]; [mapping unregisterURLWithID: mid]; + [folder cleanupCaches]; rc = MAPISTORE_SUCCESS; } } @@ -1280,6 +1397,23 @@ _prepareContextClass (struct mapistore_context *newMemCtx, } /* proof of concept */ +- (int) getTable: (void **) tablePtr + andRowCount: (uint32_t *) countPtr + withFID: (uint64_t) fid + tableType: (uint8_t) tableType + andHandleId: (uint32_t) handleId +{ + MAPIStoreTable *table; + + table = [self _tableForFID: fid andTableType: tableType]; + [table retain]; + [table setHandleId: handleId]; + *countPtr = [[table childKeys] count]; + *tablePtr = table; + + return MAPISTORE_SUCCESS; +} + - (int) getAttachmentTable: (void **) tablePtr andRowCount: (uint32_t *) count withMID: (uint64_t) mid diff --git a/OpenChange/MAPIStoreDraftsMessage.m b/OpenChange/MAPIStoreDraftsMessage.m index 60e89b203..57d0a598b 100644 --- a/OpenChange/MAPIStoreDraftsMessage.m +++ b/OpenChange/MAPIStoreDraftsMessage.m @@ -167,13 +167,7 @@ e) - (MAPIStoreAttachmentTable *) attachmentTable { - if (!attachmentTable) - { - attachmentTable = [MAPIStoreAttachmentTable tableForContainer: self]; - [attachmentTable retain]; - } - - return attachmentTable; + return [MAPIStoreAttachmentTable tableForContainer: self]; } - (MAPIStoreAttachment *) createAttachment diff --git a/OpenChange/MAPIStoreFAIMessageTable.h b/OpenChange/MAPIStoreFAIMessageTable.h new file mode 100644 index 000000000..70e12f43f --- /dev/null +++ b/OpenChange/MAPIStoreFAIMessageTable.h @@ -0,0 +1,31 @@ +/* MAPIStoreFAIMessageTable.h - this file is part of SOGo + * + * Copyright (C) 2011 Inverse inc + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef MAPISTOREFAIMESSAGETABLE_H +#define MAPISTOREFAIMESSAGETABLE_H + +#import "MAPIStoreFSMessageTable.h" + +@interface MAPIStoreFAIMessageTable : MAPIStoreFSMessageTable +@end + +#endif /* MAPISTOREFAIMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreFAIMessageTable.m b/OpenChange/MAPIStoreFAIMessageTable.m new file mode 100644 index 000000000..956be332a --- /dev/null +++ b/OpenChange/MAPIStoreFAIMessageTable.m @@ -0,0 +1,40 @@ +/* MAPIStoreFAIMessageTable.m - this file is part of SOGo + * + * Copyright (C) 2011 Inverse inc + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import "MAPIStoreFAIMessageTable.h" + +#undef DEBUG +#include + +@implementation MAPIStoreFAIMessageTable + +- (id) init +{ + if ((self = [super init])) + { + tableType = MAPISTORE_FAI_TABLE; + } + + return self; +} + +@end diff --git a/OpenChange/MAPIStoreFSFolder.m b/OpenChange/MAPIStoreFSFolder.m index 4ce217935..47ad71dcd 100644 --- a/OpenChange/MAPIStoreFSFolder.m +++ b/OpenChange/MAPIStoreFSFolder.m @@ -26,6 +26,7 @@ #import "EOQualifier+MAPIFS.h" #import "MAPIStoreFSMessage.h" +#import "MAPIStoreFSMessageTable.h" #import "SOGoMAPIFSFolder.h" #import "SOGoMAPIFSMessage.h" @@ -62,11 +63,7 @@ static Class MAPIStoreFSMessageK; - (MAPIStoreMessageTable *) messageTable { - if (!messageTable) - ASSIGN (messageTable, - [MAPIStoreFSMessageTable tableForContainer: self]); - - return messageTable; + return [MAPIStoreFSMessageTable tableForContainer: self]; } - (Class) messageClass diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h index 16a5a6d15..4b854b31e 100644 --- a/OpenChange/MAPIStoreFolder.h +++ b/OpenChange/MAPIStoreFolder.h @@ -34,7 +34,7 @@ @class MAPIStoreContext; @class MAPIStoreMessage; -@class MAPIStoreFSMessageTable; +@class MAPIStoreFAIMessageTable; @class MAPIStoreFolderTable; @class MAPIStoreMessageTable; @class SOGoMAPIFSFolder; @@ -45,14 +45,15 @@ { NSURL *folderURL; MAPIStoreContext *context; - MAPIStoreMessageTable *messageTable; NSArray *messageKeys; - MAPIStoreFSMessageTable *faiMessageTable; NSArray *faiMessageKeys; - MAPIStoreFolderTable *folderTable; NSMutableArray *folderKeys; SOGoMAPIFSFolder *faiFolder; + + NSMutableArray *activeMessageTables; + NSMutableArray *activeFAIMessageTables; + NSMutableArray *activeFolderTables; } + (id) baseFolderWithURL: (NSURL *) newURL @@ -60,10 +61,14 @@ - (id) initWithURL: (NSURL *) newURL inContext: (MAPIStoreContext *) newContext; +- (NSArray *) activeMessageTables; +- (NSArray *) activeFAIMessageTables; +- (NSArray *) activeFolderTables; + - (MAPIStoreMessageTable *) messageTable; - (NSArray *) messageKeys; -- (MAPIStoreFSMessageTable *) faiMessageTable; +- (MAPIStoreFAIMessageTable *) faiMessageTable; - (NSArray *) faiMessageKeys; - (MAPIStoreFolderTable *) folderTable; diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index dcd8baac9..d2093eb34 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -30,8 +30,8 @@ #import #import "MAPIStoreContext.h" -#import "MAPIStoreFSMessage.h" -#import "MAPIStoreFSMessageTable.h" +#import "MAPIStoreFAIMessage.h" +#import "MAPIStoreFAIMessageTable.h" #import "MAPIStoreFolder.h" #import "MAPIStoreMessage.h" #import "MAPIStoreTypes.h" @@ -46,13 +46,16 @@ #include // #include -Class NSExceptionK; +Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStoreFolderTableK; @implementation MAPIStoreFolder + (void) initialize { NSExceptionK = [NSException class]; + MAPIStoreMessageTableK = [MAPIStoreMessageTable class]; + MAPIStoreFAIMessageTableK = [MAPIStoreFAIMessageTable class]; + MAPIStoreFolderTableK = [MAPIStoreFolderTable class]; } + (id) baseFolderWithURL: (NSURL *) newURL @@ -70,15 +73,16 @@ Class NSExceptionK; { if ((self = [super init])) { - messageTable = nil; messageKeys = nil; - faiMessageTable = nil; faiMessageKeys = nil; - folderTable = nil; folderKeys = nil; faiFolder = nil; folderURL = nil; context = nil; + + activeMessageTables = [NSMutableArray new]; + activeFAIMessageTables = [NSMutableArray new]; + activeFolderTables = [NSMutableArray new]; } return self; @@ -102,13 +106,14 @@ Class NSExceptionK; - (void) dealloc { [folderURL release]; - [messageTable release]; [messageKeys release]; - [faiMessageTable release]; [faiMessageKeys release]; - [folderTable release]; [folderKeys release]; [faiFolder release]; + [activeMessageTables release]; + [activeFAIMessageTables release]; + [activeFolderTables release]; + [super dealloc]; } @@ -132,15 +137,9 @@ Class NSExceptionK; return messageKeys; } -- (MAPIStoreFSMessageTable *) faiMessageTable +- (MAPIStoreFAIMessageTable *) faiMessageTable { - if (!faiMessageTable) - { - faiMessageTable = [MAPIStoreFSMessageTable tableForContainer: self]; - [faiMessageTable retain]; - } - - return faiMessageTable; + return [MAPIStoreFAIMessageTable tableForContainer: self]; } - (NSArray *) faiMessageKeys @@ -161,21 +160,68 @@ Class NSExceptionK; - (NSArray *) folderKeys { - if (!faiMessageKeys) - faiMessageKeys = [NSArray new]; + return nil; +} - return faiMessageKeys; +- (NSArray *) activeMessageTables +{ + return activeMessageTables; +} + +- (NSArray *) activeFAIMessageTables +{ + return activeFAIMessageTables; +} + +- (NSArray *) activeFolderTables +{ + return activeFolderTables; +} + +- (NSMutableArray *) _arrayForActiveTable: (MAPIStoreTable *) activeTable +{ + NSMutableArray *tablesArray; + + if ([activeTable isKindOfClass: MAPIStoreFAIMessageTableK]) + tablesArray = activeMessageTables; + else if ([activeTable isKindOfClass: MAPIStoreMessageTableK]) + tablesArray = activeMessageTables; + else if ([activeTable isKindOfClass: MAPIStoreFolderTableK]) + tablesArray = activeMessageTables; + else + tablesArray = nil; + + return tablesArray; +} + +- (void) addActiveTable: (MAPIStoreTable *) activeTable +{ + [[self _arrayForActiveTable: activeTable] addObject: activeTable]; +} + +- (void) removeActiveTable: (MAPIStoreTable *) activeTable +{ + [[self _arrayForActiveTable: activeTable] removeObject: activeTable]; +} + +- (void) _cleanupTableCaches: (NSArray *) activeTables +{ + NSUInteger count, max; + + max = [activeTables count]; + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] cleanupCaches]; } - (void) cleanupCaches { - [faiMessageTable cleanupCaches]; + [self _cleanupTableCaches: activeMessageTables]; + [self _cleanupTableCaches: activeFAIMessageTables]; + [self _cleanupTableCaches: activeFolderTables]; [faiMessageKeys release]; faiMessageKeys = nil; - [messageTable cleanupCaches]; [messageKeys release]; messageKeys = nil; - [folderTable cleanupCaches]; [folderKeys release]; folderKeys = nil; } @@ -194,8 +240,8 @@ Class NSExceptionK; inContext: nil acquire: NO]; newChild - = [MAPIStoreFSMessage mapiStoreObjectWithSOGoObject: msgObject - inContainer: self]; + = [MAPIStoreFAIMessage mapiStoreObjectWithSOGoObject: msgObject + inContainer: self]; } else { @@ -274,8 +320,8 @@ Class NSExceptionK; newKey = [NSString stringWithFormat: @"%@.plist", [SOGoObject globallyUniqueObjectId]]; fsObject = [SOGoMAPIFSMessage objectWithName: newKey inContainer: faiFolder]; - newMessage = [MAPIStoreFSMessage mapiStoreObjectWithSOGoObject: fsObject - inContainer: self]; + newMessage = [MAPIStoreFAIMessage mapiStoreObjectWithSOGoObject: fsObject + inContainer: self]; return newMessage; @@ -289,6 +335,7 @@ Class NSExceptionK; newMessage = [self _createAssociatedMessage]; else newMessage = [self createMessage]; + [newMessage setIsNew: YES]; return newMessage; } diff --git a/OpenChange/MAPIStoreFolderTable.m b/OpenChange/MAPIStoreFolderTable.m index 8beeada1b..b34b07015 100644 --- a/OpenChange/MAPIStoreFolderTable.m +++ b/OpenChange/MAPIStoreFolderTable.m @@ -42,6 +42,16 @@ static MAPIStoreMapping *mapping; mapping = [MAPIStoreMapping sharedMapping]; } +- (id) init +{ + if ((self = [super init])) + { + tableType = MAPISTORE_FOLDER_TABLE; + } + + return self; +} + - (NSArray *) childKeys { return [(MAPIStoreFolder *) container folderKeys]; diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index d549a005e..7ffe40ca2 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -111,11 +111,7 @@ static Class MAPIStoreMailMessageK; - (MAPIStoreMessageTable *) messageTable { - if (!messageTable) - ASSIGN (messageTable, - [MAPIStoreMailMessageTable tableForContainer: self]); - - return messageTable; + return [MAPIStoreMailMessageTable tableForContainer: self]; } - (Class) messageClass diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 2010a369d..c6271a851 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -44,6 +44,7 @@ #include #include #include +#include #include static Class NSExceptionK; @@ -84,13 +85,7 @@ static Class NSExceptionK; - (MAPIStoreAttachmentTable *) attachmentTable { - if (!attachmentTable) - { - attachmentTable = [MAPIStoreAttachmentTable tableForContainer: self]; - [attachmentTable retain]; - } - - return attachmentTable; + return [MAPIStoreAttachmentTable tableForContainer: self]; } - (enum MAPISTATUS) getProperty: (void **) data @@ -101,7 +96,7 @@ static Class NSExceptionK; uint32_t intValue; enum MAPISTATUS rc; - rc = MAPI_E_SUCCESS; + rc = MAPISTORE_SUCCESS; switch (propTag) { case PR_ICON_INDEX: @@ -330,7 +325,7 @@ static Class NSExceptionK; if ([keys count] > 0) { *data = NULL; - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; } else { @@ -373,7 +368,7 @@ static Class NSExceptionK; } } else - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; } } break; @@ -457,7 +452,7 @@ static Class NSExceptionK; else { *data = NULL; - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; } } break; @@ -465,7 +460,7 @@ static Class NSExceptionK; /* We don't handle any RTF content. */ case PR_RTF_COMPRESSED: *data = NULL; - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; break; case PR_RTF_IN_SYNC: *data = MAPIBoolValue (memCtx, NO); diff --git a/OpenChange/MAPIStoreMessage.h b/OpenChange/MAPIStoreMessage.h index e34def722..0bed90bbc 100644 --- a/OpenChange/MAPIStoreMessage.h +++ b/OpenChange/MAPIStoreMessage.h @@ -38,7 +38,7 @@ { NSMutableArray *attachmentKeys; NSMutableDictionary *attachmentParts; - MAPIStoreAttachmentTable *attachmentTable; + NSMutableArray *activeTables; uint32_t mapiRetainCount; } diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index 1bcee1f86..fec1b98ba 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -54,7 +54,7 @@ mapiRetainCount = 0; attachmentKeys = nil; attachmentParts = nil; - attachmentTable = nil; + activeTables = [NSMutableArray new]; } return self; @@ -64,7 +64,7 @@ { [attachmentKeys release]; [attachmentParts release]; - [attachmentTable release]; + [activeTables release]; [super dealloc]; } @@ -285,4 +285,14 @@ return nil; } +- (void) addActiveTable: (MAPIStoreTable *) activeTable +{ + [activeTables addObject: activeTable]; +} + +- (void) removeActiveTable: (MAPIStoreTable *) activeTable +{ + [activeTables removeObject: activeTable]; +} + @end diff --git a/OpenChange/MAPIStoreObject.h b/OpenChange/MAPIStoreObject.h index 0583fe05e..3a9f061ca 100644 --- a/OpenChange/MAPIStoreObject.h +++ b/OpenChange/MAPIStoreObject.h @@ -32,6 +32,7 @@ @class EOQualifier; @class MAPIStoreFolder; +@class MAPIStoreTable; @interface MAPIStoreObject : NSObject { @@ -40,6 +41,7 @@ id sogoObject; NSMutableDictionary *newProperties; void *memCtx; + BOOL isNew; } + (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject @@ -47,6 +49,8 @@ - (id) initWithSOGoObject: (id) newSOGoObject inContainer: (MAPIStoreObject *) newFolder; +- (void) setIsNew: (BOOL) newIsNew; +- (BOOL) isNew; - (NSString *) nameInContainer; @@ -60,10 +64,14 @@ - (uint64_t) objectId; - (NSString *) url; +- (void) addActiveTable: (MAPIStoreTable *) activeTable; +- (void) removeActiveTable: (MAPIStoreTable *) activeTable; + /* properties */ - (void) addNewProperties: (NSDictionary *) newNewProperties; - (NSDictionary *) newProperties; +- (void) resetNewProperties; /* ops */ - (int) getProperties: (struct mapistore_property_data *) data diff --git a/OpenChange/MAPIStoreObject.m b/OpenChange/MAPIStoreObject.m index 717238061..4b763f263 100644 --- a/OpenChange/MAPIStoreObject.m +++ b/OpenChange/MAPIStoreObject.m @@ -69,6 +69,7 @@ static Class NSExceptionK, MAPIStoreFolderK; sogoObject = nil; newProperties = [NSMutableDictionary new]; memCtx = talloc_size (NULL, 0); + isNew = NO; } return self; @@ -96,6 +97,16 @@ static Class NSExceptionK, MAPIStoreFolderK; [super dealloc]; } +- (void) setIsNew: (BOOL) newIsNew +{ + isNew = newIsNew; +} + +- (BOOL) isNew +{ + return isNew; +} + - (id) sogoObject { return sogoObject; @@ -151,6 +162,16 @@ static Class NSExceptionK, MAPIStoreFolderK; containerURL, [sogoObject nameInContainer]]; } +- (void) addActiveTable: (MAPIStoreTable *) activeTable +{ + [self subclassResponsibility: _cmd]; +} + +- (void) removeActiveTable: (MAPIStoreTable *) activeTable +{ + [self subclassResponsibility: _cmd]; +} + - (void) addNewProperties: (NSDictionary *) newNewProperties { [newProperties addEntriesFromDictionary: newNewProperties]; @@ -161,6 +182,11 @@ static Class NSExceptionK, MAPIStoreFolderK; return newProperties; } +- (void) resetNewProperties +{ + [newProperties removeAllObjects]; +} + - (int) getProperty: (void **) data withTag: (enum MAPITAGS) propTag { diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index d6f8f38c9..c46b21e8c 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -44,6 +44,12 @@ #include #include +@interface MAPIStoreObject (MAPIStoreObjectProtocol) + +- (void) deactivate; + +@end + /** \details Initialize sogo mapistore backend @@ -839,6 +845,42 @@ sogo_op_set_sort_order (void *private_data, uint64_t fid, uint8_t type, /** proof of concept */ +static int +sogo_pocop_open_table(void *private_data, uint64_t fid, uint8_t table_type, + uint32_t handle_id, + void **table_object, uint32_t *row_count) +{ + NSAutoreleasePool *pool; + sogo_context *cContext; + MAPIStoreContext *context; + int rc; + + DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); + + pool = [NSAutoreleasePool new]; + + cContext = private_data; + context = cContext->objcContext; + if (context) + { + [context setupRequest]; + rc = [context getTable: table_object + andRowCount: row_count + withFID: fid + tableType: table_type + andHandleId: handle_id]; + [context tearDownRequest]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO CONTEXT"); + rc = MAPI_E_NOT_FOUND; + } + + return rc; +} + static int sogo_pocop_get_attachment_table (void *private_data, uint64_t mid, void **table_object, uint32_t *row_count) { @@ -957,6 +999,62 @@ sogo_pocop_set_table_columns (void *table_object, uint16_t count, enum MAPITAGS return rc; } +static int +sogo_pocop_set_table_restrictions (void *table_object, struct mapi_SRestriction *restrictions, uint8_t *table_status) +{ + NSAutoreleasePool *pool; + MAPIStoreTable *table; + int rc; + + DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); + + table = table_object; + if (table) + { + pool = [NSAutoreleasePool new]; + [table setRestrictions: restrictions]; + [table cleanupCaches]; + rc = MAPISTORE_SUCCESS; + *table_status = TBLSTAT_COMPLETE; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO DATA"); + rc = MAPI_E_NOT_FOUND; + } + + return rc; +} + +static int +sogo_pocop_set_table_sort_order (void *table_object, struct SSortOrderSet *sort_order, uint8_t *table_status) +{ + NSAutoreleasePool *pool; + MAPIStoreTable *table; + int rc; + + DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); + + table = table_object; + if (table) + { + pool = [NSAutoreleasePool new]; + [table setSortOrder: sort_order]; + [table cleanupCaches]; + rc = MAPISTORE_SUCCESS; + *table_status = TBLSTAT_COMPLETE; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO DATA"); + rc = MAPI_E_NOT_FOUND; + } + + return rc; +} + static int sogo_pocop_get_table_row (void *table_object, enum table_query_type query_type, uint32_t row_id, struct mapistore_property_data *data) { @@ -1047,6 +1145,8 @@ sogo_pocop_release (void *object) if (propObject) { pool = [NSAutoreleasePool new]; + if ([propObject respondsToSelector: @selector (deactivate)]) + [propObject deactivate]; [propObject release]; [pool release]; rc = MAPI_E_SUCCESS; @@ -1114,9 +1214,12 @@ int mapistore_init_backend(void) backend.op_get_property_into_fd = sogo_op_get_property_into_fd; /* proof of concept */ + backend.folder.open_table = sogo_pocop_open_table; backend.message.get_attachment_table = sogo_pocop_get_attachment_table; backend.message.get_attachment = sogo_pocop_get_attachment; backend.message.create_attachment = sogo_pocop_create_attachment; + backend.table.set_restrictions = sogo_pocop_set_table_restrictions; + backend.table.set_sort_order = sogo_pocop_set_table_sort_order; backend.table.set_columns = sogo_pocop_set_table_columns; backend.table.get_row = sogo_pocop_get_table_row; backend.properties.get_properties = sogo_pocop_get_properties; diff --git a/OpenChange/MAPIStoreTable.h b/OpenChange/MAPIStoreTable.h index 4e01df33c..7774c3196 100644 --- a/OpenChange/MAPIStoreTable.h +++ b/OpenChange/MAPIStoreTable.h @@ -48,6 +48,8 @@ typedef enum { { MAPIStoreObject *container; + uint32_t handleId; /* hack for identifying tables during notifications */ + NSArray *childKeys; NSArray *restrictedChildKeys; @@ -58,6 +60,8 @@ typedef enum { uint32_t currentRow; MAPIStoreObject *currentChild; + uint16_t tableType; /* mapistore */ + /* proof of concept */ uint16_t columnsCount; enum MAPITAGS *columns; @@ -67,6 +71,8 @@ typedef enum { - (id) initForContainer: (MAPIStoreObject *) newContainer; +- (void) setHandleId: (uint32_t) newHandleId; + - (NSArray *) childKeys; - (NSArray *) restrictedChildKeys; @@ -82,6 +88,8 @@ typedef enum { withRowID: (uint32_t) rowId andQueryType: (enum table_query_type) queryType; +- (void) notifyChangesForChild: (MAPIStoreObject *) child; + /* helpers */ - (void) warnUnhandledProperty: (enum MAPITAGS) property diff --git a/OpenChange/MAPIStoreTable.m b/OpenChange/MAPIStoreTable.m index d1225131a..5ca73ec03 100644 --- a/OpenChange/MAPIStoreTable.m +++ b/OpenChange/MAPIStoreTable.m @@ -263,6 +263,9 @@ static Class NSDataK, NSStringK; { if ((self = [super init])) { + tableType = MAPISTORE_MESSAGE_TABLE; + handleId = -1; + container = nil; childKeys = nil; @@ -284,11 +287,17 @@ static Class NSDataK, NSStringK; if ((self = [self init])) { container = newContainer; + [container addActiveTable: self]; } return self; } +- (void) deactivate +{ + [container removeActiveTable: self]; +} + - (void) dealloc { [currentChild release]; @@ -298,6 +307,12 @@ static Class NSDataK, NSStringK; [super dealloc]; } +- (void) setHandleId: (uint32_t) newHandleId +{ + handleId = newHandleId; + [self logWithFormat: @"new table handle: %d", handleId]; +} + - (NSArray *) childKeys { if (!childKeys) @@ -727,6 +742,7 @@ static Class NSDataK, NSStringK; child = currentChild; else { + [currentChild release]; child = nil; if (queryType == MAPISTORE_PREFILTERED_QUERY) @@ -751,7 +767,11 @@ static Class NSDataK, NSStringK; currentChild = child; [currentChild retain]; - currentRow = rowId; + + if (child) + currentRow = rowId; + else + currentRow = (uint32_t) -1; } return child; @@ -780,6 +800,57 @@ static Class NSDataK, NSStringK; return rc; } +- (void) notifyChangesForChild: (MAPIStoreObject *) child +{ + NSUInteger currentChildRow, newChildRow; + NSArray *list; + NSString *childName; + struct mapistore_table_notification_parameters notif_parameters; + + notif_parameters.table_type = tableType; + notif_parameters.handle = handleId; + notif_parameters.folder_id = [container objectId]; + notif_parameters.object_id = [child objectId]; + notif_parameters.instance_id = 0; /* TODO: always 0 ? */ + + [self logWithFormat: @"table notification handle: %d", handleId]; + + childName = [child nameInContainer]; + list = [self restrictedChildKeys]; + currentChildRow = [list indexOfObject: childName]; + notif_parameters.row_id = currentChildRow; + + [self cleanupCaches]; + list = [self restrictedChildKeys]; + newChildRow = [list indexOfObject: childName]; + + if (currentChildRow == NSNotFound) + { + if (newChildRow != NSNotFound) + { + notif_parameters.row_id = newChildRow; + mapistore_push_notification (MAPISTORE_TABLE, + MAPISTORE_OBJECT_CREATED, + ¬if_parameters); + } + } + else + { + if (newChildRow == NSNotFound) + mapistore_push_notification (MAPISTORE_TABLE, + MAPISTORE_OBJECT_DELETED, + ¬if_parameters); + else + { + /* the fact that the row order has changed has no impact here */ + notif_parameters.row_id = newChildRow; + mapistore_push_notification (MAPISTORE_TABLE, + MAPISTORE_OBJECT_MODIFIED, + ¬if_parameters); + } + } +} + /* subclasses */ - (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property { diff --git a/OpenChange/MAPIStoreTasksFolder.m b/OpenChange/MAPIStoreTasksFolder.m index d717d746e..511ccf80b 100644 --- a/OpenChange/MAPIStoreTasksFolder.m +++ b/OpenChange/MAPIStoreTasksFolder.m @@ -83,11 +83,7 @@ static Class MAPIStoreTasksMessageK; - (MAPIStoreMessageTable *) messageTable { - if (!messageTable) - ASSIGN (messageTable, - [MAPIStoreTasksMessageTable tableForContainer: self]); - - return messageTable; + return [MAPIStoreTasksMessageTable tableForContainer: self]; } - (EOQualifier *) componentQualifier diff --git a/OpenChange/MAPIStoreTasksMessage.m b/OpenChange/MAPIStoreTasksMessage.m index 720a6450e..d774b4915 100644 --- a/OpenChange/MAPIStoreTasksMessage.m +++ b/OpenChange/MAPIStoreTasksMessage.m @@ -44,6 +44,7 @@ #include #include #include +#include #include @implementation MAPIStoreTasksMessage @@ -116,7 +117,7 @@ if (dateValue) *data = [dateValue asFileTimeInMemCtx: memCtx]; else - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; break; // http://msdn.microsoft.com/en-us/library/cc765590.aspx // It's important to have a proper value for PidLidTaskState @@ -146,7 +147,7 @@ if (dateValue) *data = [dateValue asFileTimeInMemCtx: memCtx]; else - rc = MAPI_E_NOT_FOUND; + rc = MAPISTORE_ERR_NOT_FOUND; break; case PR_CREATION_TIME: diff --git a/OpenChange/MAPIStoreTypes.h b/OpenChange/MAPIStoreTypes.h index fc2aa964a..b6fd47bb2 100644 --- a/OpenChange/MAPIStoreTypes.h +++ b/OpenChange/MAPIStoreTypes.h @@ -44,9 +44,9 @@ static inline NSNumber * MAPIPropertyKey (enum MAPITAGS propTag) { #if (GS_SIZEOF_LONG == 4) - return [NSNumber numberWithUnsignedLong: (propTag & 0xffff0000) >> 16]; + return [NSNumber numberWithUnsignedLong: propTag]; #elif (GS_SIZEOF_INT == 4) - return [NSNumber numberWithUnsignedInt: (propTag & 0xffff0000) >> 16]; + return [NSNumber numberWithUnsignedInt: propTag]; #else #error No suitable type for 4 bytes integers #endif