/* * Copyright 2001-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _ARCHIVABLE_H #define _ARCHIVABLE_H #include #include #include class BMessage; namespace BPrivate { namespace Archiving { class BArchiveManager; class BUnarchiveManager; } } using ::BPrivate::Archiving::BArchiveManager; using ::BPrivate::Archiving::BUnarchiveManager; class BArchivable { public: BArchivable(BMessage* from); BArchivable(); virtual ~BArchivable(); virtual status_t Archive(BMessage* into, bool deep = true) const; static BArchivable* Instantiate(BMessage* archive); virtual status_t Perform(perform_code d, void* arg); virtual status_t AllUnarchived(const BMessage* archive); virtual status_t AllArchived(BMessage* archive) const; private: friend class BUnarchiveManager; virtual void _ReservedArchivable3(); int32 fArchivingToken; uint32 _reserved; }; class BArchiver { public: BArchiver(BMessage* archive); ~BArchiver(); status_t AddArchivable(const char* name, BArchivable* archivable, bool deep = true); inline status_t GetTokenForArchivable(BArchivable* archivable, int32& _token); status_t GetTokenForArchivable(BArchivable* archivable, bool deep, int32& _token); bool IsArchived(BArchivable* archivable); status_t Finish(status_t err = B_OK); BMessage* ArchiveMessage() const; private: friend class BArchivable; BArchiver(); // not defined BArchiver(const BArchiver&); // not defined void RegisterArchivable( const BArchivable* archivable); BArchiveManager* fManager; BMessage* fArchive; bool fFinished; uint32 _reserved[2]; }; class BUnarchiver { public: enum ownership_policy { B_ASSUME_OWNERSHIP, B_DONT_ASSUME_OWNERSHIP }; BUnarchiver(const BMessage* archive); ~BUnarchiver(); template inline status_t GetObject(int32 token, T*& object); template status_t GetObject(int32 token, ownership_policy owning, T*& object); template inline status_t FindObject(const char* name, T*& object); template inline status_t FindObject(const char* name, ownership_policy owning, T*& object); template inline status_t FindObject(const char* name, int32 index, T*& object); template status_t FindObject(const char* name, int32 index, ownership_policy owning, T*& object); inline status_t EnsureUnarchived(const char* name, int32 index = 0); inline status_t EnsureUnarchived(int32 token); bool IsInstantiated(int32 token); bool IsInstantiated(const char* name, int32 index = 0); status_t Finish(status_t err = B_OK); const BMessage* ArchiveMessage() const; void AssumeOwnership(BArchivable* archivable); void RelinquishOwnership(BArchivable* archivable); static bool IsArchiveManaged(const BMessage* archive); static BMessage* PrepareArchive(BMessage*& archive); template static status_t InstantiateObject(BMessage* archive, T*& object); private: friend class BArchivable; BUnarchiver(); // not defined BUnarchiver(const BUnarchiver&); // not defined void RegisterArchivable(BArchivable* archivable); inline void _CallDebuggerIfManagerNull(); BUnarchiveManager* fManager; const BMessage* fArchive; bool fFinished; uint32 _reserved[2]; }; // global functions typedef BArchivable* (*instantiation_func)(BMessage*); BArchivable* instantiate_object(BMessage* from, image_id* id); BArchivable* instantiate_object(BMessage* from); bool validate_instantiation(BMessage* from, const char* className); instantiation_func find_instantiation_func(const char* className, const char* signature); instantiation_func find_instantiation_func(const char* className); instantiation_func find_instantiation_func(BMessage* archive); status_t BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token) { return GetTokenForArchivable(archivable, true, _token); } template<> status_t BUnarchiver::FindObject(const char* name, int32 index, ownership_policy owning, BArchivable*& archivable); template status_t BUnarchiver::FindObject(const char* name, int32 index, ownership_policy owning, T*& object) { object = NULL; BArchivable* interim; status_t err = FindObject(name, index, owning, interim); if (err == B_OK && interim) { object = dynamic_cast(interim); if (!object) { err = B_BAD_TYPE; // we will not be deleting this item, but it must be deleted if (owning == B_ASSUME_OWNERSHIP) RelinquishOwnership(interim); } } return err; } template<> status_t BUnarchiver::GetObject(int32 token, ownership_policy owning, BArchivable*& object); template status_t BUnarchiver::GetObject(int32 token, ownership_policy owning, T*& object) { object = NULL; BArchivable* interim; status_t err = GetObject(token, owning, interim); if (err == B_OK && interim) { object = dynamic_cast(interim); if (!object) { err = B_BAD_TYPE; // we will not be deleting this item, but it must be deleted if (owning == B_ASSUME_OWNERSHIP) RelinquishOwnership(interim); } } return err; } template status_t BUnarchiver::GetObject(int32 token, T*& object) { return GetObject(token, B_ASSUME_OWNERSHIP, object); } template status_t BUnarchiver::FindObject(const char* name, ownership_policy owning, T*& object) { return FindObject(name, 0, owning, object); } template status_t BUnarchiver::FindObject(const char* name, T*& object) { return FindObject(name, 0, B_ASSUME_OWNERSHIP, object); } template status_t BUnarchiver::FindObject(const char* name, int32 index, T*& object) { return FindObject(name, index, B_ASSUME_OWNERSHIP, object); } status_t BUnarchiver::EnsureUnarchived(int32 token) { BArchivable* dummy; return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy); } status_t BUnarchiver::EnsureUnarchived(const char* name, int32 index) { BArchivable* dummy; return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy); } template<> status_t BUnarchiver::InstantiateObject(BMessage* from, BArchivable*& object); template status_t BUnarchiver::InstantiateObject(BMessage* archive, T*& object) { object = NULL; BArchivable* interim; status_t err = InstantiateObject(archive, interim); if (err != B_OK || interim == NULL) return err; object = dynamic_cast(interim); if (object == NULL) { delete interim; return B_BAD_TYPE; } return B_OK; } #endif // _ARCHIVABLE_H