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
This commit is contained in:
Ingo Weinhold
2010-07-16 16:49:42 +00:00
parent 6a78d35e85
commit b137ab3eb3
8 changed files with 421 additions and 190 deletions
+188 -13
View File
@@ -7,11 +7,13 @@
#include <image.h>
#include <Message.h>
#include <SupportDefs.h>
class BMessage;
namespace BPrivate {
namespace Archiving {
class BArchiveManager;
@@ -38,9 +40,12 @@ public:
virtual status_t AllArchived(BMessage* archive) const;
private:
friend class BUnarchiveManager;
virtual void _ReservedArchivable3();
uint32 _reserved[2];
int32 fArchivingToken;
uint32 _reserved;
};
@@ -52,11 +57,13 @@ public:
status_t AddArchivable(const char* name,
BArchivable* archivable, bool deep = true);
inline status_t GetTokenForArchivable(BArchivable* archivable,
int32& _token);
status_t GetTokenForArchivable(BArchivable* archivable,
int32& _token, bool deep = true);
bool deep, int32& _token);
bool IsArchived(BArchivable* archivable);
status_t Finish();
status_t Finish(status_t err = B_OK);
BMessage* ArchiveMessage() const;
private:
@@ -71,37 +78,64 @@ private:
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();
status_t GetArchivable(int32 token,
BArchivable** archivable);
template<class T>
inline status_t GetObject(int32 token, T*& object);
status_t FindArchivable(const char* name,
BArchivable** archivable);
template<class T>
status_t GetObject(int32 token, ownership_policy owning,
T*& object);
status_t FindArchivable(const char* name, int32 index,
BArchivable** archivable);
template<class T>
inline status_t FindObject(const char* name, T*& object);
status_t EnsureUnarchived(const char* name,
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);
status_t EnsureUnarchived(int32 token);
inline status_t EnsureUnarchived(int32 token);
bool IsInstantiated(int32 token);
bool IsInstantiated(const char* name,
int32 index = 0);
status_t Finish();
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;
@@ -110,11 +144,12 @@ private:
void RegisterArchivable(BArchivable* archivable);
void _CallDebuggerIfManagerNull();
inline void _CallDebuggerIfManagerNull();
BUnarchiveManager* fManager;
const BMessage* fArchive;
bool fFinished;
uint32 _reserved[2];
};
@@ -131,4 +166,144 @@ instantiation_func find_instantiation_func(const char* className,
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