/* * Copyright 2010 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _ARCHIVING_MANAGERS_H #define _ARCHIVING_MANAGERS_H #include #include #include #include #include #define NULL_TOKEN -42 namespace BPrivate { namespace Archiving { extern const char* kManagedField; class BManagerBase { public: enum manager_type { ARCHIVE_MANAGER, UNARCHIVE_MANAGER }; BManagerBase(BMessage* topLevelArchive, manager_type type) : fTopLevelArchive(topLevelArchive), fType(type) { MarkArchive(topLevelArchive); } static BManagerBase* ManagerPointer(const BMessage* constArchive) { if (!constArchive) return NULL; BMessage* archive = const_cast(constArchive); return static_cast( BMessage::Private(archive).ArchivingPointer()); } static void SetManagerPointer(BMessage* archive, BManagerBase* manager) { BMessage::Private(archive).SetArchivingPointer(manager); } void MarkArchive(BMessage* archive) { BManagerBase* manager = ManagerPointer(archive); if (manager != NULL) debugger("Overlapping managed archiving/unarchiving sessions!"); SetManagerPointer(archive, this); } void UnmarkArchive(BMessage* archive) { BManagerBase* manager = ManagerPointer(archive); if (manager == this) SetManagerPointer(archive, NULL); else debugger("Overlapping managed archiving/unarchiving sessions!"); } static BArchiveManager* ArchiveManager(const BMessage* archive); static BUnarchiveManager* UnarchiveManager(const BMessage* archive); protected: ~BManagerBase() { UnmarkArchive(fTopLevelArchive); } protected: BMessage* fTopLevelArchive; manager_type fType; }; class BArchiveManager: public BManagerBase { public: BArchiveManager(const BArchiver* creator); status_t GetTokenForArchivable(BArchivable* archivable, int32& _token); status_t ArchiveObject(BArchivable* archivable, bool deep, int32& _token); bool IsArchived(BArchivable* archivable); status_t ArchiverLeaving(const BArchiver* archiver, status_t err); void Acquire(); void RegisterArchivable( const BArchivable* archivable); private: ~BArchiveManager(); struct ArchiveInfo; typedef std::map TokenMap; TokenMap fTokenMap; const BArchiver* fCreator; status_t fError; }; class BUnarchiveManager: public BManagerBase { public: BUnarchiveManager(BMessage* topLevelArchive); status_t GetArchivableForToken(int32 token, BUnarchiver::ownership_policy owning, BArchivable*& _archivable); bool IsInstantiated(int32 token); void RegisterArchivable(BArchivable* archivable); status_t UnarchiverLeaving(const BUnarchiver* archiver, status_t err); void Acquire(); void RelinquishOwnership(BArchivable* archivable); void AssumeOwnership(BArchivable* archivable); private: ~BUnarchiveManager(); status_t _ExtractArchiveAt(int32 index); struct ArchiveInfo; ArchiveInfo* fObjects; int32 fObjectCount; int32 fTokenInProgress; int32 fRefCount; status_t fError; }; } // namespace Archiving } // namespace BPrivate #endif // _ARCHIVING_MANAGERS_H