xref: /haiku/src/kits/support/ArchivingManagers.h (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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 
21 namespace BPrivate {
22 namespace Archiving {
23 
24 extern const char* kManagedField;
25 
26 
27 class BManagerBase {
28 public:
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 
88 protected:
89 	~BManagerBase()
90 	{
91 		UnmarkArchive(fTopLevelArchive);
92 	}
93 
94 protected:
95 			BMessage*			fTopLevelArchive;
96 			manager_type		fType;
97 };
98 
99 
100 class BArchiveManager: public BManagerBase {
101 public:
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 
119 private:
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 
133 class BUnarchiveManager: public BManagerBase {
134 public:
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);
150 private:
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