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
GetTokenForArchivable(BArchivable * archivable,int32 & _token)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
FindObject(const char * name,int32 index,ownership_policy owning,T * & object)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
GetObject(int32 token,ownership_policy owning,T * & object)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
GetObject(int32 token,T * & object)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
FindObject(const char * name,ownership_policy owning,T * & object)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
FindObject(const char * name,T * & object)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
FindObject(const char * name,int32 index,T * & object)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
EnsureUnarchived(int32 token)267 BUnarchiver::EnsureUnarchived(int32 token)
268 {
269 BArchivable* dummy;
270 return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy);
271 }
272
273
274 status_t
EnsureUnarchived(const char * name,int32 index)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
InstantiateObject(BMessage * archive,T * & object)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