1 /* 2 * Copyright 2001-2010 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _ARCHIVABLE_H 6 #define _ARCHIVABLE_H 7 8 9 #include <image.h> 10 #include <Message.h> 11 #include <SupportDefs.h> 12 13 14 class BMessage; 15 16 17 namespace BPrivate { 18 namespace Archiving { 19 class BArchiveManager; 20 class BUnarchiveManager; 21 } 22 } 23 24 using ::BPrivate::Archiving::BArchiveManager; 25 using ::BPrivate::Archiving::BUnarchiveManager; 26 27 28 class BArchivable { 29 public: 30 BArchivable(BMessage* from); 31 BArchivable(); 32 virtual ~BArchivable(); 33 34 virtual status_t Archive(BMessage* into, bool deep = true) const; 35 static BArchivable* Instantiate(BMessage* archive); 36 37 virtual status_t Perform(perform_code d, void* arg); 38 39 virtual status_t AllUnarchived(const BMessage* archive); 40 virtual status_t AllArchived(BMessage* archive) const; 41 42 private: 43 friend class BUnarchiveManager; 44 45 virtual void _ReservedArchivable3(); 46 47 int32 fArchivingToken; 48 uint32 _reserved; 49 }; 50 51 52 class BArchiver { 53 public: 54 BArchiver(BMessage* archive); 55 ~BArchiver(); 56 57 status_t AddArchivable(const char* name, 58 BArchivable* archivable, bool deep = true); 59 60 inline status_t GetTokenForArchivable(BArchivable* archivable, 61 int32& _token); 62 status_t GetTokenForArchivable(BArchivable* archivable, 63 bool deep, int32& _token); 64 65 bool IsArchived(BArchivable* archivable); 66 status_t Finish(status_t err = B_OK); 67 BMessage* ArchiveMessage() const; 68 69 private: 70 friend class BArchivable; 71 72 BArchiver(); // not defined 73 BArchiver(const BArchiver&); // not defined 74 75 void RegisterArchivable( 76 const BArchivable* archivable); 77 78 BArchiveManager* fManager; 79 BMessage* fArchive; 80 bool fFinished; 81 uint32 _reserved[2]; 82 }; 83 84 85 class BUnarchiver { 86 public: 87 enum ownership_policy { 88 B_ASSUME_OWNERSHIP, 89 B_DONT_ASSUME_OWNERSHIP 90 }; 91 92 BUnarchiver(const BMessage* archive); 93 ~BUnarchiver(); 94 95 template<class T> 96 inline status_t GetObject(int32 token, T*& object); 97 98 template<class T> 99 status_t GetObject(int32 token, ownership_policy owning, 100 T*& object); 101 102 template<class T> 103 inline status_t FindObject(const char* name, T*& object); 104 105 template<class T> 106 inline status_t FindObject(const char* name, 107 ownership_policy owning, 108 T*& object); 109 110 template<class T> 111 inline status_t FindObject(const char* name, 112 int32 index, T*& object); 113 114 template<class T> 115 status_t FindObject(const char* name, int32 index, 116 ownership_policy owning, T*& object); 117 118 inline status_t EnsureUnarchived(const char* name, 119 int32 index = 0); 120 inline status_t EnsureUnarchived(int32 token); 121 122 bool IsInstantiated(int32 token); 123 bool IsInstantiated(const char* name, 124 int32 index = 0); 125 126 status_t Finish(status_t err = B_OK); 127 const BMessage* ArchiveMessage() const; 128 129 void AssumeOwnership(BArchivable* archivable); 130 void RelinquishOwnership(BArchivable* archivable); 131 132 static bool IsArchiveManaged(const BMessage* archive); 133 static BMessage* PrepareArchive(BMessage*& archive); 134 135 template<class T> 136 static status_t InstantiateObject(BMessage* archive, 137 T*& object); 138 139 private: 140 friend class BArchivable; 141 142 BUnarchiver(); // not defined 143 BUnarchiver(const BUnarchiver&); // not defined 144 145 void RegisterArchivable(BArchivable* archivable); 146 147 inline void _CallDebuggerIfManagerNull(); 148 149 BUnarchiveManager* fManager; 150 const BMessage* fArchive; 151 bool fFinished; 152 uint32 _reserved[2]; 153 }; 154 155 156 // global functions 157 158 typedef BArchivable* (*instantiation_func)(BMessage*); 159 160 BArchivable* instantiate_object(BMessage* from, image_id* id); 161 BArchivable* instantiate_object(BMessage* from); 162 bool validate_instantiation(BMessage* from, const char* className); 163 164 instantiation_func find_instantiation_func(const char* className, 165 const char* signature); 166 instantiation_func find_instantiation_func(const char* className); 167 instantiation_func find_instantiation_func(BMessage* archive); 168 169 170 status_t 171 BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token) 172 { 173 return GetTokenForArchivable(archivable, true, _token); 174 } 175 176 177 template<> 178 status_t BUnarchiver::FindObject<BArchivable>(const char* name, int32 index, 179 ownership_policy owning, BArchivable*& archivable); 180 181 182 template<class T> 183 status_t 184 BUnarchiver::FindObject(const char* name, int32 index, 185 ownership_policy owning, T*& object) 186 { 187 object = NULL; 188 189 BArchivable* interim; 190 status_t err = FindObject(name, index, owning, interim); 191 192 if (err == B_OK && interim) { 193 object = dynamic_cast<T*>(interim); 194 if (!object) { 195 err = B_BAD_TYPE; 196 // we will not be deleting this item, but it must be deleted 197 if (owning == B_ASSUME_OWNERSHIP) 198 RelinquishOwnership(interim); 199 } 200 } 201 return err; 202 } 203 204 205 template<> 206 status_t 207 BUnarchiver::GetObject<BArchivable>(int32 token, 208 ownership_policy owning, BArchivable*& object); 209 210 211 template<class T> 212 status_t 213 BUnarchiver::GetObject(int32 token, ownership_policy owning, T*& object) 214 { 215 object = NULL; 216 217 BArchivable* interim; 218 status_t err = GetObject(token, owning, interim); 219 220 if (err == B_OK && interim) { 221 object = dynamic_cast<T*>(interim); 222 if (!object) { 223 err = B_BAD_TYPE; 224 // we will not be deleting this item, but it must be deleted 225 if (owning == B_ASSUME_OWNERSHIP) 226 RelinquishOwnership(interim); 227 } 228 } 229 return err; 230 } 231 232 233 template<class T> 234 status_t 235 BUnarchiver::GetObject(int32 token, T*& object) 236 { 237 return GetObject<T>(token, B_ASSUME_OWNERSHIP, object); 238 } 239 240 241 template<class T> 242 status_t 243 BUnarchiver::FindObject(const char* name, ownership_policy owning, T*& object) 244 { 245 return FindObject(name, 0, owning, object); 246 } 247 248 249 template<class T> 250 status_t 251 BUnarchiver::FindObject(const char* name, T*& object) 252 { 253 return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object); 254 } 255 256 257 template<class T> 258 status_t 259 BUnarchiver::FindObject(const char* name, 260 int32 index, T*& object) 261 { 262 return FindObject(name, index, B_ASSUME_OWNERSHIP, object); 263 } 264 265 266 status_t 267 BUnarchiver::EnsureUnarchived(int32 token) 268 { 269 BArchivable* dummy; 270 return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy); 271 } 272 273 274 status_t 275 BUnarchiver::EnsureUnarchived(const char* name, int32 index) 276 { 277 BArchivable* dummy; 278 return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy); 279 } 280 281 282 template<> 283 status_t 284 BUnarchiver::InstantiateObject<BArchivable>(BMessage* from, 285 BArchivable*& object); 286 287 288 template<class T> 289 status_t 290 BUnarchiver::InstantiateObject(BMessage* archive, T*& object) 291 { 292 object = NULL; 293 294 BArchivable* interim; 295 status_t err = InstantiateObject(archive, interim); 296 if (err != B_OK || interim == NULL) 297 return err; 298 299 object = dynamic_cast<T*>(interim); 300 if (object == NULL) { 301 delete interim; 302 return B_BAD_TYPE; 303 } 304 305 return B_OK; 306 } 307 308 309 #endif // _ARCHIVABLE_H 310