haiku/headers/os/support/Archivable.h
Ingo Weinhold b137ab3eb3 Patch by Alex Wilson (minor changes by myself) related to the new archiving
features:
* Some cosmetic adjustments of the API, like using references instead of
  pointers, argument order, method names, etc.
* Added convenience template methods for archiving and unarchiving to BArchiver
  and BUnarchiver.
* BUnarchiver (respectively the private BUnarchiveManager) explicitly deals with
  object ownership, now. This is necessary since an error while unarchiving
  could leave an already unarchived object without owning object, which would
  result in it being leaked. The BUnarchiver::{Get,Find}Object() methods do now
  have an optional parameter to specify whether object ownership shall be
  transferred.
* Fixed incorrect header guard in headers/private/binary_compatibility/Global.h.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37538 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-07-16 16:49:42 +00:00

310 lines
6.7 KiB
C++

/*
* Copyright 2001-2010, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _ARCHIVABLE_H
#define _ARCHIVABLE_H
#include <image.h>
#include <Message.h>
#include <SupportDefs.h>
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<class T>
inline status_t GetObject(int32 token, T*& object);
template<class T>
status_t GetObject(int32 token, ownership_policy owning,
T*& object);
template<class T>
inline status_t FindObject(const char* name, T*& object);
template<class T>
inline status_t FindObject(const char* name,
ownership_policy owning,
T*& object);
template<class T>
inline status_t FindObject(const char* name,
int32 index, T*& object);
template<class T>
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(BMessage* archive);
static BMessage* PrepareArchive(BMessage*& archive);
template<class T>
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<BArchivable>(const char* name, int32 index,
ownership_policy owning, BArchivable*& archivable);
template<class T>
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<T*>(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<BArchivable>(int32 token,
ownership_policy owning, BArchivable*& object);
template<class T>
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<T*>(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<class T>
status_t
BUnarchiver::GetObject(int32 token, T*& object)
{
return GetObject<T>(token, B_ASSUME_OWNERSHIP, object);
}
template<class T>
status_t
BUnarchiver::FindObject(const char* name, ownership_policy owning, T*& object)
{
return FindObject(name, 0, owning, object);
}
template<class T>
status_t
BUnarchiver::FindObject(const char* name, T*& object)
{
return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object);
}
template<class T>
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<BArchivable>(BMessage* from,
BArchivable*& object);
template<class T>
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<T*>(interim);
if (object == NULL) {
delete interim;
return B_BAD_TYPE;
}
return B_OK;
}
#endif // _ARCHIVABLE_H