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:
@@ -54,11 +54,11 @@ public:
|
|||||||
|
|
||||||
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
||||||
virtual status_t AllUnarchived(const BMessage* from);
|
virtual status_t AllUnarchived(const BMessage* from);
|
||||||
virtual status_t ArchiveLayoutData(BMessage* into,
|
|
||||||
const BLayoutItem* of) const;
|
|
||||||
virtual status_t RestoreItemAndData(const BMessage* from,
|
|
||||||
BLayoutItem* item);
|
|
||||||
|
|
||||||
|
virtual status_t ItemArchived(BMessage* into, BLayoutItem* item,
|
||||||
|
int32 index) const;
|
||||||
|
virtual status_t ItemUnarchived(const BMessage* from,
|
||||||
|
BLayoutItem* item, int32 index);
|
||||||
protected:
|
protected:
|
||||||
// TODO: Since memory allocations can fail, we should return a bool and
|
// TODO: Since memory allocations can fail, we should return a bool and
|
||||||
// undo the addition, if false.
|
// undo the addition, if false.
|
||||||
|
|||||||
+188
-13
@@ -7,11 +7,13 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include <Message.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
class BMessage;
|
class BMessage;
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Archiving {
|
namespace Archiving {
|
||||||
class BArchiveManager;
|
class BArchiveManager;
|
||||||
@@ -38,9 +40,12 @@ public:
|
|||||||
virtual status_t AllArchived(BMessage* archive) const;
|
virtual status_t AllArchived(BMessage* archive) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class BUnarchiveManager;
|
||||||
|
|
||||||
virtual void _ReservedArchivable3();
|
virtual void _ReservedArchivable3();
|
||||||
|
|
||||||
uint32 _reserved[2];
|
int32 fArchivingToken;
|
||||||
|
uint32 _reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -52,11 +57,13 @@ public:
|
|||||||
status_t AddArchivable(const char* name,
|
status_t AddArchivable(const char* name,
|
||||||
BArchivable* archivable, bool deep = true);
|
BArchivable* archivable, bool deep = true);
|
||||||
|
|
||||||
|
inline status_t GetTokenForArchivable(BArchivable* archivable,
|
||||||
|
int32& _token);
|
||||||
status_t GetTokenForArchivable(BArchivable* archivable,
|
status_t GetTokenForArchivable(BArchivable* archivable,
|
||||||
int32& _token, bool deep = true);
|
bool deep, int32& _token);
|
||||||
|
|
||||||
bool IsArchived(BArchivable* archivable);
|
bool IsArchived(BArchivable* archivable);
|
||||||
status_t Finish();
|
status_t Finish(status_t err = B_OK);
|
||||||
BMessage* ArchiveMessage() const;
|
BMessage* ArchiveMessage() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -71,37 +78,64 @@ private:
|
|||||||
BArchiveManager* fManager;
|
BArchiveManager* fManager;
|
||||||
BMessage* fArchive;
|
BMessage* fArchive;
|
||||||
bool fFinished;
|
bool fFinished;
|
||||||
|
uint32 _reserved[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BUnarchiver {
|
class BUnarchiver {
|
||||||
public:
|
public:
|
||||||
|
enum ownership_policy {
|
||||||
|
B_ASSUME_OWNERSHIP,
|
||||||
|
B_DONT_ASSUME_OWNERSHIP
|
||||||
|
};
|
||||||
|
|
||||||
BUnarchiver(const BMessage* archive);
|
BUnarchiver(const BMessage* archive);
|
||||||
~BUnarchiver();
|
~BUnarchiver();
|
||||||
|
|
||||||
status_t GetArchivable(int32 token,
|
template<class T>
|
||||||
BArchivable** archivable);
|
inline status_t GetObject(int32 token, T*& object);
|
||||||
|
|
||||||
status_t FindArchivable(const char* name,
|
template<class T>
|
||||||
BArchivable** archivable);
|
status_t GetObject(int32 token, ownership_policy owning,
|
||||||
|
T*& object);
|
||||||
|
|
||||||
status_t FindArchivable(const char* name, int32 index,
|
template<class T>
|
||||||
BArchivable** archivable);
|
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);
|
int32 index = 0);
|
||||||
status_t EnsureUnarchived(int32 token);
|
inline status_t EnsureUnarchived(int32 token);
|
||||||
|
|
||||||
bool IsInstantiated(int32 token);
|
bool IsInstantiated(int32 token);
|
||||||
bool IsInstantiated(const char* name,
|
bool IsInstantiated(const char* name,
|
||||||
int32 index = 0);
|
int32 index = 0);
|
||||||
|
|
||||||
status_t Finish();
|
status_t Finish(status_t err = B_OK);
|
||||||
const BMessage* ArchiveMessage() const;
|
const BMessage* ArchiveMessage() const;
|
||||||
|
|
||||||
|
void AssumeOwnership(BArchivable* archivable);
|
||||||
|
void RelinquishOwnership(BArchivable* archivable);
|
||||||
|
|
||||||
static bool IsArchiveManaged(BMessage* archive);
|
static bool IsArchiveManaged(BMessage* archive);
|
||||||
static BMessage* PrepareArchive(BMessage*& archive);
|
static BMessage* PrepareArchive(BMessage*& archive);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static status_t InstantiateObject(BMessage* archive,
|
||||||
|
T*& object);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BArchivable;
|
friend class BArchivable;
|
||||||
|
|
||||||
@@ -110,11 +144,12 @@ private:
|
|||||||
|
|
||||||
void RegisterArchivable(BArchivable* archivable);
|
void RegisterArchivable(BArchivable* archivable);
|
||||||
|
|
||||||
void _CallDebuggerIfManagerNull();
|
inline void _CallDebuggerIfManagerNull();
|
||||||
|
|
||||||
BUnarchiveManager* fManager;
|
BUnarchiveManager* fManager;
|
||||||
const BMessage* fArchive;
|
const BMessage* fArchive;
|
||||||
bool fFinished;
|
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(const char* className);
|
||||||
instantiation_func find_instantiation_func(BMessage* archive);
|
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
|
#endif // _ARCHIVABLE_H
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _BINARY_COMPATIBILITY_GLOBAL_H_
|
#ifndef _BINARY_COMPATIBILITY_GLOBAL_H_
|
||||||
#define _BINARY_COMPATIBILITY__GLOBAL_H_
|
#define _BINARY_COMPATIBILITY_GLOBAL_H_
|
||||||
|
|
||||||
|
|
||||||
// method codes
|
// method codes
|
||||||
@@ -24,7 +24,6 @@ enum {
|
|||||||
PERFORM_CODE_GET_TOOL_TIP_AT = 1009,
|
PERFORM_CODE_GET_TOOL_TIP_AT = 1009,
|
||||||
|
|
||||||
// support kit
|
// support kit
|
||||||
|
|
||||||
PERFORM_CODE_ALL_ARCHIVED = 1010,
|
PERFORM_CODE_ALL_ARCHIVED = 1010,
|
||||||
PERFORM_CODE_ALL_UNARCHIVED = 1011
|
PERFORM_CODE_ALL_UNARCHIVED = 1011
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
* Copyright 2010, Haiku, Inc.
|
* Copyright 2010, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _BINARY_COMPATIBILITY_SUPPORT_H
|
#ifndef _BINARY_COMPATIBILITY_SUPPORT_H_
|
||||||
#define _BINARY_COMPATIBILITY_SUPPORT_H
|
#define _BINARY_COMPATIBILITY_SUPPORT_H_
|
||||||
|
|
||||||
|
|
||||||
#include <binary_compatibility/Global.h>
|
#include <binary_compatibility/Global.h>
|
||||||
@@ -20,4 +20,4 @@ struct perform_data_all_archived {
|
|||||||
status_t return_value;
|
status_t return_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _BINARY_COMPATIBILITY_INTERFACE_H_ */
|
#endif /* _BINARY_COMPATIBILITY_SUPPORT_H_ */
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <Layout.h>
|
#include <Layout.h>
|
||||||
|
|
||||||
|
#include <syslog.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
@@ -19,11 +20,9 @@ using std::nothrow;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char* kLayoutItemField = "BLayout:_items";
|
const char* kLayoutItemField = "BLayout:_items";
|
||||||
const char* kLayoutDataField = "BLayout:_data";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
BLayout::BLayout()
|
BLayout::BLayout()
|
||||||
:
|
:
|
||||||
fView(NULL),
|
fView(NULL),
|
||||||
@@ -211,77 +210,64 @@ BLayout::Archive(BMessage* into, bool deep) const
|
|||||||
BArchiver archiver(into);
|
BArchiver archiver(into);
|
||||||
status_t err = BArchivable::Archive(into, deep);
|
status_t err = BArchivable::Archive(into, deep);
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (deep) {
|
if (deep) {
|
||||||
int32 count = CountItems();
|
int32 count = CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count && err == B_OK; i++) {
|
||||||
err = archiver.AddArchivable(kLayoutItemField, ItemAt(i), deep);
|
BLayoutItem* item = ItemAt(i);
|
||||||
|
err = archiver.AddArchivable(kLayoutItemField, item, deep);
|
||||||
|
|
||||||
if (err == B_OK) {
|
if (err == B_OK) {
|
||||||
BMessage data;
|
err = ItemArchived(into, item, i);
|
||||||
err = ArchiveLayoutData(&data, ItemAt(i));
|
if (err != B_OK)
|
||||||
if (err == B_OK)
|
syslog(LOG_ERR, "ItemArchived() failed at index: %d.", i);
|
||||||
err = into->AddMessage(kLayoutDataField, &data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return archiver.Finish();
|
return archiver.Finish(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BLayout::AllUnarchived(const BMessage* from)
|
BLayout::AllUnarchived(const BMessage* from)
|
||||||
{
|
{
|
||||||
status_t err = BArchivable::AllUnarchived(from);
|
|
||||||
BUnarchiver unarchiver(from);
|
BUnarchiver unarchiver(from);
|
||||||
|
status_t err = BArchivable::AllUnarchived(from);
|
||||||
|
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
for (int32 i = 0; ; i++) {
|
int32 itemCount;
|
||||||
BArchivable* retriever;
|
unarchiver.ArchiveMessage()->GetInfo(kLayoutItemField, NULL, &itemCount);
|
||||||
err = unarchiver.FindArchivable(kLayoutItemField, i, &retriever);
|
for (int32 i = 0; i < itemCount && err == B_OK; i++) {
|
||||||
|
BLayoutItem* item;
|
||||||
|
err = unarchiver.FindObject(kLayoutItemField, i, item);
|
||||||
|
|
||||||
if (err == B_BAD_INDEX)
|
if (err == B_OK && item) {
|
||||||
break;
|
if (fItems.AddItem(item)) {
|
||||||
|
ItemAdded(item);
|
||||||
if (err == B_OK) {
|
item->SetLayout(this);
|
||||||
BMessage layoutData;
|
err = ItemUnarchived(from, item, i);
|
||||||
err = from->FindMessage(kLayoutDataField, i, &layoutData);
|
} else
|
||||||
|
err = B_NO_MEMORY;
|
||||||
if (err == B_OK) {
|
|
||||||
BLayoutItem* item = dynamic_cast<BLayoutItem*>(retriever);
|
|
||||||
err = RestoreItemAndData(&layoutData, item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != B_OK)
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BLayout::ArchiveLayoutData(BMessage* into, const BLayoutItem* of) const
|
BLayout::ItemArchived(BMessage* into, BLayoutItem* of, int32 index) const
|
||||||
{
|
{
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BLayout::RestoreItemAndData(const BMessage* from, BLayoutItem* item)
|
BLayout::ItemUnarchived(const BMessage* from, BLayoutItem* item, int32 index)
|
||||||
{
|
{
|
||||||
if (item && AddItem(item))
|
return B_OK;
|
||||||
return B_OK;
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -210,11 +210,15 @@ check_signature(const char* signature, image_info& info)
|
|||||||
|
|
||||||
|
|
||||||
BArchivable::BArchivable()
|
BArchivable::BArchivable()
|
||||||
|
:
|
||||||
|
fArchivingToken(NULL_TOKEN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BArchivable::BArchivable(BMessage* from)
|
BArchivable::BArchivable(BMessage* from)
|
||||||
|
:
|
||||||
|
fArchivingToken(NULL_TOKEN)
|
||||||
{
|
{
|
||||||
if (BUnarchiver::IsArchiveManaged(from)) {
|
if (BUnarchiver::IsArchiveManaged(from)) {
|
||||||
BUnarchiver::PrepareArchive(from);
|
BUnarchiver::PrepareArchive(from);
|
||||||
@@ -313,7 +317,7 @@ BArchiver::BArchiver(BMessage* archive)
|
|||||||
BArchiver::~BArchiver()
|
BArchiver::~BArchiver()
|
||||||
{
|
{
|
||||||
if (!fFinished)
|
if (!fFinished)
|
||||||
fManager->ArchiverLeaving(this);
|
fManager->ArchiverLeaving(this, B_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -321,7 +325,7 @@ status_t
|
|||||||
BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep)
|
BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep)
|
||||||
{
|
{
|
||||||
int32 token;
|
int32 token;
|
||||||
status_t err = GetTokenForArchivable(archivable, token, deep);
|
status_t err = GetTokenForArchivable(archivable, deep, token);
|
||||||
|
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
@@ -332,17 +336,9 @@ BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
BArchiver::GetTokenForArchivable(BArchivable* archivable,
|
BArchiver::GetTokenForArchivable(BArchivable* archivable,
|
||||||
int32& _token, bool deep)
|
bool deep, int32& _token)
|
||||||
{
|
{
|
||||||
status_t err = B_OK;
|
return fManager->ArchiveObject(archivable, deep, _token);
|
||||||
|
|
||||||
if (!IsArchived(archivable))
|
|
||||||
err = fManager->ArchiveObject(archivable, deep);
|
|
||||||
|
|
||||||
if (err == B_OK)
|
|
||||||
return fManager->GetTokenForArchivable(archivable, _token);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -354,13 +350,14 @@ BArchiver::IsArchived(BArchivable* archivable)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BArchiver::Finish()
|
BArchiver::Finish(status_t err)
|
||||||
{
|
{
|
||||||
if (fFinished)
|
if (fFinished)
|
||||||
debugger("Finish() called multiple times on same BArchiver.");
|
debugger("Finish() called multiple times on same BArchiver.");
|
||||||
|
|
||||||
fFinished = true;
|
fFinished = true;
|
||||||
return fManager->ArchiverLeaving(this);
|
|
||||||
|
return fManager->ArchiverLeaving(this, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -393,56 +390,32 @@ BUnarchiver::BUnarchiver(const BMessage* archive)
|
|||||||
BUnarchiver::~BUnarchiver()
|
BUnarchiver::~BUnarchiver()
|
||||||
{
|
{
|
||||||
if (!fFinished && fManager)
|
if (!fFinished && fManager)
|
||||||
fManager->UnarchiverLeaving(this);
|
fManager->UnarchiverLeaving(this, B_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
status_t
|
status_t
|
||||||
BUnarchiver::GetArchivable(int32 token, BArchivable** archivable)
|
BUnarchiver::GetObject<BArchivable>(int32 token,
|
||||||
|
ownership_policy owning, BArchivable*& object)
|
||||||
{
|
{
|
||||||
_CallDebuggerIfManagerNull();
|
_CallDebuggerIfManagerNull();
|
||||||
|
return fManager->GetArchivableForToken(token, owning, object);
|
||||||
if (archivable == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
return fManager->ArchivableForToken(archivable, token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
status_t
|
status_t
|
||||||
BUnarchiver::FindArchivable(const char* name, BArchivable** archivable)
|
BUnarchiver::FindObject<BArchivable>(const char* name,
|
||||||
|
int32 index, ownership_policy owning, BArchivable*& archivable)
|
||||||
{
|
{
|
||||||
return FindArchivable(name, 0, archivable);
|
archivable = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUnarchiver::FindArchivable(const char* name,
|
|
||||||
int32 index, BArchivable** archivable)
|
|
||||||
{
|
|
||||||
|
|
||||||
int32 token;
|
int32 token;
|
||||||
status_t err = fArchive->FindInt32(name, index, &token);
|
status_t err = fArchive->FindInt32(name, index, &token);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return GetArchivable(token, archivable);
|
return GetObject(token, owning, archivable);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUnarchiver::EnsureUnarchived(const char* name, int32 index)
|
|
||||||
{
|
|
||||||
BArchivable* dummy;
|
|
||||||
return FindArchivable(name, index, &dummy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUnarchiver::EnsureUnarchived(int32 token)
|
|
||||||
{
|
|
||||||
BArchivable* dummy;
|
|
||||||
return GetArchivable(token, &dummy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -452,6 +425,7 @@ BUnarchiver::IsInstantiated(int32 token)
|
|||||||
return fManager->IsInstantiated(token);
|
return fManager->IsInstantiated(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUnarchiver::IsInstantiated(const char* field, int32 index)
|
BUnarchiver::IsInstantiated(const char* field, int32 index)
|
||||||
{
|
{
|
||||||
@@ -461,14 +435,18 @@ BUnarchiver::IsInstantiated(const char* field, int32 index)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUnarchiver::Finish()
|
BUnarchiver::Finish(status_t err)
|
||||||
{
|
{
|
||||||
if (fFinished)
|
if (fFinished)
|
||||||
debugger("Finish() called multiple times on same BArchiver.");
|
debugger("Finish() called multiple times on same BArchiver.");
|
||||||
|
|
||||||
fFinished = true;
|
fFinished = true;
|
||||||
return fManager->UnarchiverLeaving(this);
|
if (fManager)
|
||||||
|
return fManager->UnarchiverLeaving(this, err);
|
||||||
|
else
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -479,6 +457,22 @@ BUnarchiver::ArchiveMessage() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUnarchiver::AssumeOwnership(BArchivable* archivable)
|
||||||
|
{
|
||||||
|
_CallDebuggerIfManagerNull();
|
||||||
|
fManager->AssumeOwnership(archivable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUnarchiver::RelinquishOwnership(BArchivable* archivable)
|
||||||
|
{
|
||||||
|
_CallDebuggerIfManagerNull();
|
||||||
|
fManager->RelinquishOwnership(archivable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUnarchiver::IsArchiveManaged(BMessage* archive)
|
BUnarchiver::IsArchiveManaged(BMessage* archive)
|
||||||
{
|
{
|
||||||
@@ -487,14 +481,25 @@ BUnarchiver::IsArchiveManaged(BMessage* archive)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// managed top level archives return here
|
// managed top level archives return here
|
||||||
int32 dummy;
|
bool dummy;
|
||||||
if (archive->FindInt32(kArchiveCountField, &dummy) == B_OK)
|
if (archive->FindBool(kManagedField, &dummy) == B_OK)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
status_t
|
||||||
|
BUnarchiver::InstantiateObject<BArchivable>(BMessage* from,
|
||||||
|
BArchivable*& object)
|
||||||
|
{
|
||||||
|
BUnarchiver unarchiver(BUnarchiver::PrepareArchive(from));
|
||||||
|
object = instantiate_object(from);
|
||||||
|
return unarchiver.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BMessage*
|
BMessage*
|
||||||
BUnarchiver::PrepareArchive(BMessage*& archive)
|
BUnarchiver::PrepareArchive(BMessage*& archive)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,18 +6,16 @@
|
|||||||
* Alex Wilson ([email protected])
|
* Alex Wilson ([email protected])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ArchivingManagers.h"
|
||||||
|
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
#include "ArchivingManagers.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Archiving {
|
namespace Archiving {
|
||||||
const char* kArchiveCountField = "_managed_archive_count";
|
|
||||||
const char* kArchivableField = "_managed_archivable";
|
const char* kArchivableField = "_managed_archivable";
|
||||||
const char* kTokenField = "_managed_token";
|
const char* kManagedField = "_managed_archive";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +48,7 @@ BManagerBase::UnarchiveManager(const BMessage* archive)
|
|||||||
if (manager->fType == UNARCHIVE_MANAGER)
|
if (manager->fType == UNARCHIVE_MANAGER)
|
||||||
return static_cast<BUnarchiveManager*>(manager);
|
return static_cast<BUnarchiveManager*>(manager);
|
||||||
|
|
||||||
debugger("More calls to BUnarchiver::PrepareMessage()"
|
debugger("More calls to BUnarchiver::PrepareArchive()"
|
||||||
" than BUnarchivers created.");
|
" than BUnarchivers created.");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -84,14 +82,15 @@ BArchiveManager::BArchiveManager(const BArchiver* creator)
|
|||||||
:
|
:
|
||||||
BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER),
|
BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER),
|
||||||
fTokenMap(),
|
fTokenMap(),
|
||||||
fCreator(creator)
|
fCreator(creator),
|
||||||
|
fError(B_OK)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BArchiveManager::~BArchiveManager()
|
BArchiveManager::~BArchiveManager()
|
||||||
{
|
{
|
||||||
fTopLevelArchive->AddInt32(kArchiveCountField, fTokenMap.size());
|
fTopLevelArchive->AddBool(kManagedField, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -99,7 +98,7 @@ status_t
|
|||||||
BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token)
|
BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token)
|
||||||
{
|
{
|
||||||
if (!archivable) {
|
if (!archivable) {
|
||||||
_token = -42;
|
_token = NULL_TOKEN;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,25 +113,32 @@ BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BArchiveManager::ArchiveObject(BArchivable* archivable, bool deep)
|
BArchiveManager::ArchiveObject(BArchivable* archivable,
|
||||||
|
bool deep, int32& _token)
|
||||||
{
|
{
|
||||||
if (IsArchived(archivable)){
|
if (!archivable) {
|
||||||
debugger("BArchivable requested to be archived"
|
_token = NULL_TOKEN;
|
||||||
" was previously archived.");
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiveInfo& info = fTokenMap[archivable];
|
ArchiveInfo& info = fTokenMap[archivable];
|
||||||
|
|
||||||
info.archive = new BMessage();
|
status_t err = B_OK;
|
||||||
info.token = fTokenMap.size() - 1;
|
|
||||||
|
|
||||||
MarkArchive(info.archive);
|
if (!info.archive) {
|
||||||
status_t err = archivable->Archive(info.archive, deep);
|
info.archive = new BMessage();
|
||||||
|
info.token = fTokenMap.size() - 1;
|
||||||
|
|
||||||
|
MarkArchive(info.archive);
|
||||||
|
err = archivable->Archive(info.archive, deep);
|
||||||
|
}
|
||||||
|
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
fTokenMap.erase(archivable);
|
fTokenMap.erase(archivable);
|
||||||
// info.archive gets deleted here
|
// info.archive gets deleted here
|
||||||
}
|
_token = NULL_TOKEN;
|
||||||
|
} else
|
||||||
|
_token = info.token;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -149,9 +155,12 @@ BArchiveManager::IsArchived(BArchivable* archivable)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BArchiveManager::ArchiverLeaving(const BArchiver* archiver)
|
BArchiveManager::ArchiverLeaving(const BArchiver* archiver, status_t err)
|
||||||
{
|
{
|
||||||
if (archiver == fCreator) {
|
if (fError == B_OK)
|
||||||
|
fError = err;
|
||||||
|
|
||||||
|
if (archiver == fCreator && fError == B_OK) {
|
||||||
// first, we must sort the objects into the order they were archived in
|
// first, we must sort the objects into the order they were archived in
|
||||||
typedef std::pair<BMessage*, const BArchivable*> ArchivePair;
|
typedef std::pair<BMessage*, const BArchivable*> ArchivePair;
|
||||||
ArchivePair pairs[fTokenMap.size()];
|
ArchivePair pairs[fTokenMap.size()];
|
||||||
@@ -167,29 +176,28 @@ BArchiveManager::ArchiverLeaving(const BArchiver* archiver)
|
|||||||
info.archive = NULL;
|
info.archive = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t err = B_ERROR;
|
|
||||||
int32 count = fTokenMap.size();
|
int32 count = fTokenMap.size();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
const ArchivePair& pair = pairs[i];
|
const ArchivePair& pair = pairs[i];
|
||||||
err = pair.second->AllArchived(pair.first);
|
fError = pair.second->AllArchived(pair.first);
|
||||||
|
|
||||||
if (err == B_OK && i > 0) {
|
if (fError == B_OK && i > 0) {
|
||||||
err = fTopLevelArchive->AddMessage(kArchivableField,
|
fError = fTopLevelArchive->AddMessage(kArchivableField,
|
||||||
pair.first);
|
pair.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != B_OK) {
|
if (fError != B_OK) {
|
||||||
syslog(LOG_ERR, "AllArchived failed for object of type %s.",
|
syslog(LOG_ERR, "AllArchived failed for object of type %s.",
|
||||||
typeid(*pairs[i].second).name());
|
typeid(*pairs[i].second).name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this;
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
if (archiver == fCreator)
|
||||||
|
delete this;
|
||||||
|
|
||||||
|
return fError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -211,7 +219,8 @@ struct BUnarchiveManager::ArchiveInfo {
|
|||||||
ArchiveInfo()
|
ArchiveInfo()
|
||||||
:
|
:
|
||||||
archivable(NULL),
|
archivable(NULL),
|
||||||
archive()
|
archive(),
|
||||||
|
adopted(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +232,7 @@ struct BUnarchiveManager::ArchiveInfo {
|
|||||||
|
|
||||||
BArchivable* archivable;
|
BArchivable* archivable;
|
||||||
BMessage archive;
|
BMessage archive;
|
||||||
|
bool adopted;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -235,9 +245,12 @@ BUnarchiveManager::BUnarchiveManager(BMessage* archive)
|
|||||||
fObjects(NULL),
|
fObjects(NULL),
|
||||||
fObjectCount(0),
|
fObjectCount(0),
|
||||||
fTokenInProgress(0),
|
fTokenInProgress(0),
|
||||||
fRefCount(0)
|
fRefCount(0),
|
||||||
|
fError(B_OK)
|
||||||
{
|
{
|
||||||
archive->FindInt32(kArchiveCountField, &fObjectCount);
|
archive->GetInfo(kArchivableField, NULL, &fObjectCount);
|
||||||
|
fObjectCount++;
|
||||||
|
// root object needs a spot too
|
||||||
fObjects = new ArchiveInfo[fObjectCount];
|
fObjects = new ArchiveInfo[fObjectCount];
|
||||||
|
|
||||||
// fObjects[0] is a placeholder for the object that started
|
// fObjects[0] is a placeholder for the object that started
|
||||||
@@ -260,28 +273,37 @@ BUnarchiveManager::~BUnarchiveManager()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUnarchiveManager::ArchivableForToken(BArchivable** _archivable, int32 token)
|
BUnarchiveManager::GetArchivableForToken(int32 token,
|
||||||
|
BUnarchiver::ownership_policy owning, BArchivable*& _archivable)
|
||||||
{
|
{
|
||||||
if (!_archivable || token > fObjectCount)
|
if (token >= fObjectCount)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (token < 0) {
|
if (token < 0) {
|
||||||
*_archivable = NULL;
|
_archivable = NULL;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t err = B_OK;
|
status_t err = B_OK;
|
||||||
if (!fObjects[token].archivable) {
|
ArchiveInfo& info = fObjects[token];
|
||||||
if (fRefCount > 0)
|
if (!info.archivable) {
|
||||||
err = _InstantiateObjectForToken(token);
|
if (fRefCount > 0) {
|
||||||
else {
|
fTokenInProgress = token;
|
||||||
|
if(!instantiate_object(&info.archive))
|
||||||
|
err = B_ERROR;
|
||||||
|
} else {
|
||||||
syslog(LOG_ERR, "Object requested from AllUnarchived()"
|
syslog(LOG_ERR, "Object requested from AllUnarchived()"
|
||||||
" was not previously instantiated");
|
" was not previously instantiated");
|
||||||
err = B_ERROR;
|
err = B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*_archivable = fObjects[token].archivable;
|
if (!info.adopted && owning == BUnarchiver::B_ASSUME_OWNERSHIP)
|
||||||
|
info.adopted = true;
|
||||||
|
else if (info.adopted && owning == BUnarchiver::B_ASSUME_OWNERSHIP)
|
||||||
|
debugger("Cannot assume ownership of an object that is already owned");
|
||||||
|
|
||||||
|
_archivable = info.archivable;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,37 +324,84 @@ BUnarchiveManager::RegisterArchivable(BArchivable* archivable)
|
|||||||
debugger("Cannot register NULL pointer");
|
debugger("Cannot register NULL pointer");
|
||||||
|
|
||||||
fObjects[fTokenInProgress].archivable = archivable;
|
fObjects[fTokenInProgress].archivable = archivable;
|
||||||
|
archivable->fArchivingToken = fTokenInProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver)
|
BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver,
|
||||||
|
status_t err)
|
||||||
{
|
{
|
||||||
if (--fRefCount == 0) {
|
if (--fRefCount >= 0 && fError == B_OK)
|
||||||
fRefCount = -1;
|
fError = err;
|
||||||
// make sure we de not end up here again!
|
|
||||||
|
|
||||||
|
if (fRefCount != 0)
|
||||||
|
return fError;
|
||||||
|
|
||||||
|
if (fError == B_OK) {
|
||||||
BArchivable* archivable = fObjects[0].archivable;
|
BArchivable* archivable = fObjects[0].archivable;
|
||||||
status_t err = archivable->AllUnarchived(fTopLevelArchive);
|
if (archivable) {
|
||||||
|
fError = archivable->AllUnarchived(fTopLevelArchive);
|
||||||
for (int32 i = 1; i < fObjectCount; i++) {
|
archivable->fArchivingToken = NULL_TOKEN;
|
||||||
if (err != B_OK)
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
|
for (int32 i = 1; i < fObjectCount && fError == B_OK; i++) {
|
||||||
archivable = fObjects[i].archivable;
|
archivable = fObjects[i].archivable;
|
||||||
err = archivable->AllUnarchived(&fObjects[i].archive);
|
if (archivable) {
|
||||||
|
fError = archivable->AllUnarchived(&fObjects[i].archive);
|
||||||
|
archivable->fArchivingToken = NULL_TOKEN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (fError != B_OK) {
|
||||||
if (err != B_OK) {
|
syslog(LOG_ERR, "Error in AllUnarchived"
|
||||||
syslog(LOG_ERR, "AllUnarchived failed for object of type %s.",
|
" method of object of type %s", typeid(*archivable).name());
|
||||||
typeid(*archivable).name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this;
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
if (fError != B_OK) {
|
||||||
|
syslog(LOG_ERR, "An error occured during unarchival, cleaning up.");
|
||||||
|
for (int32 i = 1; i < fObjectCount; i++) {
|
||||||
|
if (!fObjects[i].adopted)
|
||||||
|
delete fObjects[i].archivable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
return fError;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUnarchiveManager::RelinquishOwnership(BArchivable* archivable)
|
||||||
|
{
|
||||||
|
int32 token = NULL_TOKEN;
|
||||||
|
if (archivable)
|
||||||
|
token = archivable->fArchivingToken;
|
||||||
|
|
||||||
|
if (token < 0 || token >= fObjectCount
|
||||||
|
|| fObjects[token].archivable != archivable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fObjects[token].adopted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUnarchiveManager::AssumeOwnership(BArchivable* archivable)
|
||||||
|
{
|
||||||
|
int32 token = NULL_TOKEN;
|
||||||
|
if (archivable)
|
||||||
|
token = archivable->fArchivingToken;
|
||||||
|
|
||||||
|
if (token < 0 || token >= fObjectCount
|
||||||
|
|| fObjects[token].archivable != archivable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!fObjects[token].adopted)
|
||||||
|
fObjects[token].adopted = true;
|
||||||
|
else {
|
||||||
|
debugger("Cannot assume ownership of an object that is already owned");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -342,14 +411,3 @@ BUnarchiveManager::Acquire()
|
|||||||
if (fRefCount >= 0)
|
if (fRefCount >= 0)
|
||||||
fRefCount++;
|
fRefCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUnarchiveManager::_InstantiateObjectForToken(int32 token)
|
|
||||||
{
|
|
||||||
fTokenInProgress = token;
|
|
||||||
if(!instantiate_object(&fObjects[token].archive))
|
|
||||||
return B_ERROR;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,13 @@
|
|||||||
#include <Archivable.h>
|
#include <Archivable.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define NULL_TOKEN -42
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Archiving {
|
namespace Archiving {
|
||||||
|
|
||||||
extern const char* kArchiveCountField;
|
extern const char* kManagedField;
|
||||||
extern const char* kArchivableField;
|
|
||||||
extern const char* kTokenField;
|
|
||||||
|
|
||||||
|
|
||||||
class BManagerBase {
|
class BManagerBase {
|
||||||
@@ -101,11 +102,13 @@ public:
|
|||||||
int32& _token);
|
int32& _token);
|
||||||
|
|
||||||
status_t ArchiveObject(BArchivable* archivable,
|
status_t ArchiveObject(BArchivable* archivable,
|
||||||
bool deep);
|
bool deep, int32& _token);
|
||||||
|
|
||||||
bool IsArchived(BArchivable* archivable);
|
bool IsArchived(BArchivable* archivable);
|
||||||
|
|
||||||
status_t ArchiverLeaving(const BArchiver* archiver);
|
status_t ArchiverLeaving(const BArchiver* archiver,
|
||||||
|
status_t err);
|
||||||
|
|
||||||
void Acquire();
|
void Acquire();
|
||||||
void RegisterArchivable(
|
void RegisterArchivable(
|
||||||
const BArchivable* archivable);
|
const BArchivable* archivable);
|
||||||
@@ -118,6 +121,7 @@ private:
|
|||||||
|
|
||||||
TokenMap fTokenMap;
|
TokenMap fTokenMap;
|
||||||
const BArchiver* fCreator;
|
const BArchiver* fCreator;
|
||||||
|
status_t fError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -127,20 +131,23 @@ class BUnarchiveManager: public BManagerBase {
|
|||||||
public:
|
public:
|
||||||
BUnarchiveManager(BMessage* topLevelArchive);
|
BUnarchiveManager(BMessage* topLevelArchive);
|
||||||
|
|
||||||
status_t ArchivableForToken(BArchivable** archivable,
|
status_t GetArchivableForToken(int32 token,
|
||||||
int32 token);
|
BUnarchiver::ownership_policy owning,
|
||||||
|
BArchivable*& _archivable);
|
||||||
|
|
||||||
bool IsInstantiated(int32 token);
|
bool IsInstantiated(int32 token);
|
||||||
|
|
||||||
void RegisterArchivable(BArchivable* archivable);
|
void RegisterArchivable(BArchivable* archivable);
|
||||||
status_t UnarchiverLeaving(const BUnarchiver* archiver);
|
status_t UnarchiverLeaving(const BUnarchiver* archiver,
|
||||||
|
status_t err);
|
||||||
void Acquire();
|
void Acquire();
|
||||||
|
|
||||||
|
void RelinquishOwnership(BArchivable* archivable);
|
||||||
|
void AssumeOwnership(BArchivable* archivable);
|
||||||
private:
|
private:
|
||||||
~BUnarchiveManager();
|
~BUnarchiveManager();
|
||||||
|
|
||||||
status_t _ExtractArchiveAt(int32 index);
|
status_t _ExtractArchiveAt(int32 index);
|
||||||
status_t _InstantiateObjectForToken(int32 token);
|
|
||||||
|
|
||||||
struct ArchiveInfo;
|
struct ArchiveInfo;
|
||||||
|
|
||||||
@@ -148,6 +155,7 @@ private:
|
|||||||
int32 fObjectCount;
|
int32 fObjectCount;
|
||||||
int32 fTokenInProgress;
|
int32 fTokenInProgress;
|
||||||
int32 fRefCount;
|
int32 fRefCount;
|
||||||
|
status_t fError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user