1/*
2 * Copyright 2010 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _ARCHIVING_MANAGERS_H
6#define _ARCHIVING_MANAGERS_H
7
8
9#include <map>
10
11#include <String.h>
12#include <ObjectList.h>
13#include <MessagePrivate.h>
14
15#include <Archivable.h>
16
17
18#define NULL_TOKEN -42
19
20
21namespace BPrivate {
22namespace Archiving {
23
24extern const char* kManagedField;
25
26
27class BManagerBase {
28public:
29	enum manager_type {
30		ARCHIVE_MANAGER,
31		UNARCHIVE_MANAGER
32	};
33
34	BManagerBase(BMessage* topLevelArchive, manager_type type)
35		:
36		fTopLevelArchive(topLevelArchive),
37		fType(type)
38	{
39		MarkArchive(topLevelArchive);
40	}
41
42
43	static BManagerBase*
44	ManagerPointer(const BMessage* constArchive)
45	{
46		if (!constArchive)
47			return NULL;
48
49		BMessage* archive = const_cast<BMessage*>(constArchive);
50
51		return static_cast<BManagerBase*>(
52			BMessage::Private(archive).ArchivingPointer());
53	}
54
55
56	static void
57	SetManagerPointer(BMessage* archive, BManagerBase* manager)
58	{
59		BMessage::Private(archive).SetArchivingPointer(manager);
60	}
61
62
63	void
64	MarkArchive(BMessage* archive)
65	{
66		BManagerBase* manager = ManagerPointer(archive);
67		if (manager != NULL)
68			debugger("Overlapping managed archiving/unarchiving sessions!");
69
70		SetManagerPointer(archive, this);
71	}
72
73
74	void
75	UnmarkArchive(BMessage* archive)
76	{
77		BManagerBase* manager = ManagerPointer(archive);
78		if (manager == this)
79			SetManagerPointer(archive, NULL);
80		else
81			debugger("Overlapping managed archiving/unarchiving sessions!");
82	}
83
84
85	static	BArchiveManager*	ArchiveManager(const BMessage* archive);
86	static 	BUnarchiveManager*	UnarchiveManager(const BMessage* archive);
87
88protected:
89	~BManagerBase()
90	{
91		UnmarkArchive(fTopLevelArchive);
92	}
93
94protected:
95			BMessage*			fTopLevelArchive;
96			manager_type		fType;
97};
98
99
100class BArchiveManager: public BManagerBase {
101public:
102								BArchiveManager(const BArchiver* creator);
103
104			status_t			GetTokenForArchivable(BArchivable* archivable,
105									int32& _token);
106
107			status_t			ArchiveObject(BArchivable* archivable,
108									bool deep, int32& _token);
109
110			bool				IsArchived(BArchivable* archivable);
111
112			status_t			ArchiverLeaving(const BArchiver* archiver,
113									status_t err);
114
115			void				Acquire();
116			void				RegisterArchivable(
117									const BArchivable* archivable);
118
119private:
120								~BArchiveManager();
121
122			struct ArchiveInfo;
123			typedef std::map<const BArchivable*, ArchiveInfo> TokenMap;
124
125			TokenMap			fTokenMap;
126			const BArchiver*	fCreator;
127			status_t			fError;
128};
129
130
131
132
133class BUnarchiveManager: public BManagerBase {
134public:
135								BUnarchiveManager(BMessage* topLevelArchive);
136
137			status_t			GetArchivableForToken(int32 token,
138									BUnarchiver::ownership_policy owning,
139									BArchivable*& _archivable);
140
141			bool				IsInstantiated(int32 token);
142
143			void				RegisterArchivable(BArchivable* archivable);
144			status_t			UnarchiverLeaving(const BUnarchiver* archiver,
145									status_t err);
146			void				Acquire();
147
148			void				RelinquishOwnership(BArchivable* archivable);
149			void				AssumeOwnership(BArchivable* archivable);
150private:
151								~BUnarchiveManager();
152
153			status_t			_ExtractArchiveAt(int32 index);
154
155			struct ArchiveInfo;
156
157			ArchiveInfo*		fObjects;
158			int32				fObjectCount;
159			int32				fTokenInProgress;
160			int32				fRefCount;
161			status_t			fError;
162};
163
164
165} // namespace Archiving
166} // namespace BPrivate
167
168
169#endif	// _ARCHIVING_MANAGERS_H
170