xref: /haiku/headers/os/support/Archivable.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 2001-2010 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _ARCHIVABLE_H
6 #define _ARCHIVABLE_H
7 
8 
9 #include <image.h>
10 #include <Message.h>
11 #include <SupportDefs.h>
12 
13 
14 class BMessage;
15 
16 
17 namespace BPrivate {
18 namespace Archiving {
19 	class BArchiveManager;
20 	class BUnarchiveManager;
21 }
22 }
23 
24 using ::BPrivate::Archiving::BArchiveManager;
25 using ::BPrivate::Archiving::BUnarchiveManager;
26 
27 
28 class BArchivable {
29 public:
30 								BArchivable(BMessage* from);
31 								BArchivable();
32 	virtual 					~BArchivable();
33 
34 	virtual	status_t 			Archive(BMessage* into, bool deep = true) const;
35 	static 	BArchivable*		Instantiate(BMessage* archive);
36 
37 	virtual status_t			Perform(perform_code d, void* arg);
38 
39 	virtual	status_t 			AllUnarchived(const BMessage* archive);
40 	virtual	status_t 			AllArchived(BMessage* archive) const;
41 
42 private:
43 	friend 	class BUnarchiveManager;
44 
45 	virtual	void				_ReservedArchivable3();
46 
47 			int32				fArchivingToken;
48 			uint32				_reserved;
49 };
50 
51 
52 class BArchiver {
53 public:
54 								BArchiver(BMessage* archive);
55 								~BArchiver();
56 
57 			status_t			AddArchivable(const char* name,
58 									BArchivable* archivable, bool deep = true);
59 
60 	inline	status_t			GetTokenForArchivable(BArchivable* archivable,
61 									int32& _token);
62 			status_t			GetTokenForArchivable(BArchivable* archivable,
63 									bool deep, int32& _token);
64 
65 			bool				IsArchived(BArchivable* archivable);
66 			status_t			Finish(status_t err = B_OK);
67 			BMessage*			ArchiveMessage() const;
68 
69 private:
70 	friend class BArchivable;
71 
72 								BArchiver(); // not defined
73 								BArchiver(const BArchiver&); // not defined
74 
75 			void				RegisterArchivable(
76 									const BArchivable* archivable);
77 
78 			BArchiveManager*	fManager;
79 			BMessage*			fArchive;
80 			bool				fFinished;
81 			uint32				_reserved[2];
82 };
83 
84 
85 class BUnarchiver {
86 public:
87 			enum ownership_policy {
88 				B_ASSUME_OWNERSHIP,
89 				B_DONT_ASSUME_OWNERSHIP
90 			};
91 
92 								BUnarchiver(const BMessage* archive);
93 								~BUnarchiver();
94 
95 	template<class T>
96 	inline	status_t			GetObject(int32 token, T*& object);
97 
98 	template<class T>
99 			status_t			GetObject(int32 token, ownership_policy owning,
100 									T*& object);
101 
102 	template<class T>
103 	inline	status_t			FindObject(const char* name, T*& object);
104 
105 	template<class T>
106 	inline	status_t			FindObject(const char* name,
107 									ownership_policy owning,
108 									T*& object);
109 
110 	template<class T>
111 	inline	status_t			FindObject(const char* name,
112 									int32 index, T*& object);
113 
114 	template<class T>
115 			status_t			FindObject(const char* name, int32 index,
116 									ownership_policy owning, T*& object);
117 
118 	inline	status_t			EnsureUnarchived(const char* name,
119 									int32 index = 0);
120 	inline	status_t			EnsureUnarchived(int32 token);
121 
122 			bool				IsInstantiated(int32 token);
123 			bool				IsInstantiated(const char* name,
124 									int32 index = 0);
125 
126 			status_t			Finish(status_t err = B_OK);
127 			const BMessage*		ArchiveMessage() const;
128 
129 			void				AssumeOwnership(BArchivable* archivable);
130 			void				RelinquishOwnership(BArchivable* archivable);
131 
132 	static	bool				IsArchiveManaged(const BMessage* archive);
133 	static	BMessage*			PrepareArchive(BMessage*& archive);
134 
135 	template<class T>
136 	static	status_t			InstantiateObject(BMessage* archive,
137 									T*& object);
138 
139 private:
140 	friend class BArchivable;
141 
142 								BUnarchiver(); // not defined
143 								BUnarchiver(const BUnarchiver&); // not defined
144 
145 			void				RegisterArchivable(BArchivable* archivable);
146 
147 	inline	void				_CallDebuggerIfManagerNull();
148 
149 			BUnarchiveManager*	fManager;
150 			const BMessage*		fArchive;
151 			bool				fFinished;
152 			uint32				_reserved[2];
153 };
154 
155 
156 // global functions
157 
158 typedef BArchivable* (*instantiation_func)(BMessage*);
159 
160 BArchivable* instantiate_object(BMessage* from, image_id* id);
161 BArchivable* instantiate_object(BMessage* from);
162 bool validate_instantiation(BMessage* from, const char* className);
163 
164 instantiation_func find_instantiation_func(const char* className,
165 	const char* signature);
166 instantiation_func find_instantiation_func(const char* className);
167 instantiation_func find_instantiation_func(BMessage* archive);
168 
169 
170 status_t
171 BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token)
172 {
173 	return GetTokenForArchivable(archivable, true, _token);
174 }
175 
176 
177 template<>
178 status_t BUnarchiver::FindObject<BArchivable>(const char* name, int32 index,
179 	ownership_policy owning, BArchivable*& archivable);
180 
181 
182 template<class T>
183 status_t
184 BUnarchiver::FindObject(const char* name, int32 index,
185 	ownership_policy owning, T*& object)
186 {
187 	object = NULL;
188 
189 	BArchivable* interim;
190 	status_t err = FindObject(name, index, owning, interim);
191 
192 	if (err == B_OK && interim) {
193 		object = dynamic_cast<T*>(interim);
194 		if (!object) {
195 			err = B_BAD_TYPE;
196 			// we will not be deleting this item, but it must be deleted
197 			if (owning == B_ASSUME_OWNERSHIP)
198 				RelinquishOwnership(interim);
199 		}
200 	}
201 	return err;
202 }
203 
204 
205 template<>
206 status_t
207 BUnarchiver::GetObject<BArchivable>(int32 token,
208 	ownership_policy owning, BArchivable*& object);
209 
210 
211 template<class T>
212 status_t
213 BUnarchiver::GetObject(int32 token, ownership_policy owning, T*& object)
214 {
215 	object = NULL;
216 
217 	BArchivable* interim;
218 	status_t err = GetObject(token, owning, interim);
219 
220 	if (err == B_OK && interim) {
221 		object = dynamic_cast<T*>(interim);
222 		if (!object) {
223 			err = B_BAD_TYPE;
224 			// we will not be deleting this item, but it must be deleted
225 			if (owning == B_ASSUME_OWNERSHIP)
226 				RelinquishOwnership(interim);
227 		}
228 	}
229 	return err;
230 }
231 
232 
233 template<class T>
234 status_t
235 BUnarchiver::GetObject(int32 token, T*& object)
236 {
237 	return GetObject<T>(token, B_ASSUME_OWNERSHIP, object);
238 }
239 
240 
241 template<class T>
242 status_t
243 BUnarchiver::FindObject(const char* name, ownership_policy owning, T*& object)
244 {
245 	return FindObject(name, 0, owning, object);
246 }
247 
248 
249 template<class T>
250 status_t
251 BUnarchiver::FindObject(const char* name, T*& object)
252 {
253 	return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object);
254 }
255 
256 
257 template<class T>
258 status_t
259 BUnarchiver::FindObject(const char* name,
260 	int32 index, T*& object)
261 {
262 	return FindObject(name, index, B_ASSUME_OWNERSHIP, object);
263 }
264 
265 
266 status_t
267 BUnarchiver::EnsureUnarchived(int32 token)
268 {
269 	BArchivable* dummy;
270 	return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy);
271 }
272 
273 
274 status_t
275 BUnarchiver::EnsureUnarchived(const char* name, int32 index)
276 {
277 	BArchivable* dummy;
278 	return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy);
279 }
280 
281 
282 template<>
283 status_t
284 BUnarchiver::InstantiateObject<BArchivable>(BMessage* from,
285 	BArchivable*& object);
286 
287 
288 template<class T>
289 status_t
290 BUnarchiver::InstantiateObject(BMessage* archive, T*& object)
291 {
292 	object = NULL;
293 
294 	BArchivable* interim;
295 	status_t err = InstantiateObject(archive, interim);
296 	if (err != B_OK || interim == NULL)
297 		return err;
298 
299 	object = dynamic_cast<T*>(interim);
300 	if (object == NULL) {
301 		delete interim;
302 		return B_BAD_TYPE;
303 	}
304 
305 	return B_OK;
306 }
307 
308 
309 #endif	// _ARCHIVABLE_H
310