1 /* 2 * Copyright 2010 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _ARCHIVING_MANAGERS_H 6 #define _ARCHIVING_MANAGERS_H 7 8 9 #include <map> 10 11 #include <String.h> 12 #include <ObjectList.h> 13 #include <MessagePrivate.h> 14 15 #include <Archivable.h> 16 17 18 #define NULL_TOKEN -42 19 20 21 namespace BPrivate { 22 namespace Archiving { 23 24 extern const char* kManagedField; 25 26 27 class BManagerBase { 28 public: 29 enum manager_type { 30 ARCHIVE_MANAGER, 31 UNARCHIVE_MANAGER 32 }; 33 34 BManagerBase(BMessage* topLevelArchive, manager_type type) 35 : 36 fTopLevelArchive(topLevelArchive), 37 fType(type) 38 { 39 MarkArchive(topLevelArchive); 40 } 41 42 43 static BManagerBase* 44 ManagerPointer(const BMessage* constArchive) 45 { 46 if (!constArchive) 47 return NULL; 48 49 BMessage* archive = const_cast<BMessage*>(constArchive); 50 51 return static_cast<BManagerBase*>( 52 BMessage::Private(archive).ArchivingPointer()); 53 } 54 55 56 static void 57 SetManagerPointer(BMessage* archive, BManagerBase* manager) 58 { 59 BMessage::Private(archive).SetArchivingPointer(manager); 60 } 61 62 63 void 64 MarkArchive(BMessage* archive) 65 { 66 BManagerBase* manager = ManagerPointer(archive); 67 if (manager != NULL) 68 debugger("Overlapping managed archiving/unarchiving sessions!"); 69 70 SetManagerPointer(archive, this); 71 } 72 73 74 void 75 UnmarkArchive(BMessage* archive) 76 { 77 BManagerBase* manager = ManagerPointer(archive); 78 if (manager == this) 79 SetManagerPointer(archive, NULL); 80 else 81 debugger("Overlapping managed archiving/unarchiving sessions!"); 82 } 83 84 85 static BArchiveManager* ArchiveManager(const BMessage* archive); 86 static BUnarchiveManager* UnarchiveManager(const BMessage* archive); 87 88 protected: 89 ~BManagerBase() 90 { 91 UnmarkArchive(fTopLevelArchive); 92 } 93 94 protected: 95 BMessage* fTopLevelArchive; 96 manager_type fType; 97 }; 98 99 100 class BArchiveManager: public BManagerBase { 101 public: 102 BArchiveManager(const BArchiver* creator); 103 104 status_t GetTokenForArchivable(BArchivable* archivable, 105 int32& _token); 106 107 status_t ArchiveObject(BArchivable* archivable, 108 bool deep, int32& _token); 109 110 bool IsArchived(BArchivable* archivable); 111 112 status_t ArchiverLeaving(const BArchiver* archiver, 113 status_t err); 114 115 void Acquire(); 116 void RegisterArchivable( 117 const BArchivable* archivable); 118 119 private: 120 ~BArchiveManager(); 121 122 struct ArchiveInfo; 123 typedef std::map<const BArchivable*, ArchiveInfo> TokenMap; 124 125 TokenMap fTokenMap; 126 const BArchiver* fCreator; 127 status_t fError; 128 }; 129 130 131 132 133 class BUnarchiveManager: public BManagerBase { 134 public: 135 BUnarchiveManager(BMessage* topLevelArchive); 136 137 status_t GetArchivableForToken(int32 token, 138 BUnarchiver::ownership_policy owning, 139 BArchivable*& _archivable); 140 141 bool IsInstantiated(int32 token); 142 143 void RegisterArchivable(BArchivable* archivable); 144 status_t UnarchiverLeaving(const BUnarchiver* archiver, 145 status_t err); 146 void Acquire(); 147 148 void RelinquishOwnership(BArchivable* archivable); 149 void AssumeOwnership(BArchivable* archivable); 150 private: 151 ~BUnarchiveManager(); 152 153 status_t _ExtractArchiveAt(int32 index); 154 155 struct ArchiveInfo; 156 157 ArchiveInfo* fObjects; 158 int32 fObjectCount; 159 int32 fTokenInProgress; 160 int32 fRefCount; 161 status_t fError; 162 }; 163 164 165 } // namespace Archiving 166 } // namespace BPrivate 167 168 169 #endif // _ARCHIVING_MANAGERS_H 170