1 | /* |
2 | * Copyright (c) 2000-2019 Apple Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License |
8 | * Version 2.0 (the 'License'). You may not use this file except in |
9 | * compliance with the License. The rights granted to you under the License |
10 | * may not be used to create, or enable the creation or redistribution of, |
11 | * unlawful or unlicensed copies of an Apple operating system, or to |
12 | * circumvent, violate, or enable the circumvention or violation of, any |
13 | * terms of an Apple operating system software license agreement. |
14 | * |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
17 | * |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and |
24 | * limitations under the License. |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | /* OSSerialize.h created by rsulack on Wen 25-Nov-1998 */ |
29 | |
30 | #ifndef _OS_OSSERIALIZE_H |
31 | #define _OS_OSSERIALIZE_H |
32 | |
33 | #include <libkern/c++/OSObject.h> |
34 | #include <libkern/c++/OSPtr.h> |
35 | |
36 | class OSCollection; |
37 | class OSSet; |
38 | class OSDictionary; |
39 | class OSArray; |
40 | class OSData; |
41 | |
42 | class OSSerializer; |
43 | typedef OSSerializer* OSSerializerPtr; |
44 | |
45 | class OSSerialize; |
46 | typedef OSSerialize* OSSerializePtr; |
47 | |
48 | /*! |
49 | * @header |
50 | * |
51 | * @abstract |
52 | * This header declares the OSSerialize class. |
53 | */ |
54 | |
55 | OSObjectPtr |
56 | OSUnserializeBinary(const void *buffer, size_t bufferSize); |
57 | |
58 | /*! |
59 | * @class OSSerialize |
60 | * |
61 | * @abstract |
62 | * OSSerialize coordinates serialization of Libkern C++ objects |
63 | * into an XML stream. |
64 | * |
65 | * @discussion |
66 | * This class is for the most part internal to the OSContainer classes, |
67 | * used for transferring property tables between the kernel and user space. |
68 | * It should not be used directly. |
69 | * Classes that participate in serialization |
70 | * override the |
71 | * <code>@link |
72 | * //apple_ref/cpp/instm/OSObject/serialize/virtualbool/(OSSerialize*) |
73 | * OSObject::serialize@/link</code> . |
74 | * function. |
75 | * |
76 | * <b>Use Restrictions</b> |
77 | * |
78 | * With very few exceptions in the I/O Kit, all Libkern-based C++ |
79 | * classes, functions, and macros are <b>unsafe</b> |
80 | * to use in a primary interrupt context. |
81 | * Consult the I/O Kit documentation related to primary interrupts |
82 | * for more information. |
83 | * |
84 | * OSSerialize provides no concurrency protection; |
85 | * it's up to the usage context to provide any protection necessary. |
86 | * Some portions of the I/O Kit, such as |
87 | * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link, |
88 | * handle synchronization via defined member functions |
89 | * for serializing properties. |
90 | */ |
91 | |
92 | class OSSerialize : public OSObject |
93 | { |
94 | OSDeclareDefaultStructors(OSSerialize); |
95 | friend class OSBoolean; |
96 | |
97 | private: |
98 | char * data; // container for serialized data |
99 | unsigned int length; // of serialized data (counting NULL) |
100 | unsigned int capacity; // of container |
101 | unsigned int capacityIncrement;// of container |
102 | |
103 | OSPtr<OSArray> tags; // tags for all objects seen |
104 | |
105 | #ifdef XNU_KERNEL_PRIVATE |
106 | public: |
107 | typedef const OSMetaClassBase * (*Editor)(void * reference, |
108 | OSSerialize * s, |
109 | OSCollection * container, |
110 | const OSSymbol * name, |
111 | const OSMetaClassBase * value); |
112 | #else |
113 | typedef void * Editor; |
114 | #endif |
115 | |
116 | bool binary; |
117 | bool endCollection; |
118 | Editor editor; |
119 | void * editRef; |
120 | OSPtr<OSData> indexData; |
121 | |
122 | bool binarySerialize(const OSMetaClassBase *o); |
123 | bool binarySerializeInternal(const OSMetaClassBase *o); |
124 | bool addBinary(const void * data, size_t size); |
125 | bool addBinaryObject(const OSMetaClassBase * o, uint32_t key, const void * _bits, uint32_t size, |
126 | uint32_t * startCollection); |
127 | void endBinaryCollection(uint32_t startCollection); |
128 | |
129 | public: |
130 | |
131 | /*! |
132 | * @function withCapacity |
133 | * |
134 | * @abstract |
135 | * Creates and initializes an empty OSSerialize object. |
136 | * |
137 | * @param capacity The initial size of the XML buffer. |
138 | * |
139 | * @result |
140 | * A new instance of OSSerialize |
141 | * with a retain count of 1; |
142 | * <code>NULL</code> on failure. |
143 | * |
144 | * @discussion |
145 | * The serializer will grow as needed to accommodate more data. |
146 | */ |
147 | static OSPtr<OSSerialize> withCapacity(unsigned int capacity); |
148 | |
149 | static OSPtr<OSSerialize> binaryWithCapacity(unsigned int inCapacity, Editor editor = NULL, void * reference = NULL); |
150 | void setIndexed(bool index); |
151 | |
152 | /*! |
153 | * @function text |
154 | * |
155 | * @abstract |
156 | * Returns the XML text serialized so far. |
157 | * |
158 | * @result |
159 | * The nul-terminated XML data serialized so far. |
160 | */ |
161 | virtual char * text() const; |
162 | |
163 | |
164 | /*! |
165 | * @function clearText |
166 | * |
167 | * @abstract |
168 | * Resets the OSSerialize object. |
169 | * |
170 | * @discussion |
171 | * This function is a useful optimization if you are serializing |
172 | * the same object repeatedly. |
173 | */ |
174 | virtual void clearText(); |
175 | |
176 | // stuff to serialize your object |
177 | |
178 | /*! |
179 | * @function previouslySerialized |
180 | * |
181 | * @abstract |
182 | * Checks whether the object has already been serialized |
183 | * into the XML stream, emitting a reference if it has. |
184 | * |
185 | * @param object The object to check. |
186 | * |
187 | * @result |
188 | * <code>true</code> if <code>object</code> has already been serialized |
189 | * by this OSSerialize object and a reference |
190 | * to it is successfully added to the XML stream, |
191 | * <code>false</code> otherwise. |
192 | * |
193 | * |
194 | * @discussion |
195 | * This function both reduces the size of generated XML |
196 | * by emitting shorter references to existing objects with the same |
197 | * value (particularly for OSString, OSSymbol, and OSData), |
198 | * and also preserves instance references |
199 | * so that the user-space I/O Kit library can reconstruct |
200 | * an identical graph of object relationships. |
201 | * |
202 | * All classes that override |
203 | * <code>@link |
204 | * //apple_ref/cpp/instm/OSObject/serialize/virtualbool/(OSSerialize*) |
205 | * OSObject::serialize@/link</code>. |
206 | * should call this function before doing any actual serialization; |
207 | * if it returns <code>true</code>, the <code>serialize</code> implementation |
208 | * can immediately return <code>true</code>. |
209 | */ |
210 | virtual bool previouslySerialized(const OSMetaClassBase * object); |
211 | |
212 | |
213 | /*! |
214 | * @function addXMLStartTag |
215 | * |
216 | * @abstract |
217 | * Appends an XML start tag to the XML stream. |
218 | * |
219 | * @param object The object being serialized. |
220 | * @param tagString The name of the XML tag to emit; for example, "string". |
221 | * |
222 | * @result |
223 | * <code>true</code> if an XML start tag for <code>tagString</code> |
224 | * is successfully added to the XML stream, <code>false</code> otherwise. |
225 | * |
226 | * @discussion |
227 | * This function emits the named tag, |
228 | * enclosed within a pair of angle brackets. |
229 | * |
230 | * A class that implements serialization should call this function |
231 | * with the name of the XML tag that best represents the serialized |
232 | * contents of the object. |
233 | * A limited number of tags are supported by the user-space |
234 | * I/O Kit library: |
235 | * <ul> |
236 | * <li>array</li> |
237 | * <li>dict</li> |
238 | * <li>integer</li> |
239 | * <li>key</li> |
240 | * <li>set</li> |
241 | * <li>string</li> |
242 | * </ul> |
243 | * |
244 | * A call to this function must be balanced with one to |
245 | * <code>@link addXMLEndTag addXMLEndTag@/link</code> |
246 | * using the same <code>tagString</code>. |
247 | */ |
248 | virtual bool addXMLStartTag( |
249 | const OSMetaClassBase * object, |
250 | const char * tagString); |
251 | |
252 | |
253 | /*! |
254 | * @function addXMLEndTag |
255 | * |
256 | * @abstract |
257 | * Appends an XML end tag to the XML stream. |
258 | * |
259 | * @param tagString The name of the XML tag to emit; for example, "string". |
260 | * |
261 | * @result |
262 | * <code>true</code> if an XML end tag for <code>tagString</code> |
263 | * is successfully added to the XML stream, <code>false</code> otherwise. |
264 | * |
265 | * @discussion |
266 | * This function emits the named tag, |
267 | * preceded by a slash character to indicate the closing of an entity, |
268 | * all enclosed within a pair of angle brackets. |
269 | * |
270 | * A call to this function must balance an earlier call to |
271 | * <code>@link addXMLStartTag addXMLStartTag@/link</code> |
272 | * using the same <code>tagString</code>. |
273 | */ |
274 | virtual bool addXMLEndTag(const char * tagString); |
275 | |
276 | |
277 | /*! |
278 | * @function addChar |
279 | * |
280 | * @abstract |
281 | * Appends a single character to the XML stream. |
282 | * |
283 | * @param aChar The character to append to the XML stream. |
284 | * |
285 | * @result |
286 | * <code>true</code> if <code>char</code> |
287 | * is successfully added to the XML stream, <code>false</code> otherwise. |
288 | */ |
289 | virtual bool addChar(const char aChar); |
290 | |
291 | |
292 | /*! |
293 | * @function addString |
294 | * |
295 | * @abstract |
296 | * Appends a C string to the XML stream. |
297 | * |
298 | * @param cString The C string to append to the XML stream. |
299 | * |
300 | * @result |
301 | * <code>true</code> if <code>cString</code> |
302 | * is successfully added to the XML stream, <code>false</code> otherwise. |
303 | */ |
304 | virtual bool addString(const char * cString); |
305 | |
306 | // stuff you should never have to use (in theory) |
307 | |
308 | virtual bool initWithCapacity(unsigned int inCapacity); |
309 | virtual unsigned int getLength() const; |
310 | virtual unsigned int getCapacity() const; |
311 | virtual unsigned int getCapacityIncrement() const; |
312 | virtual unsigned int setCapacityIncrement(unsigned increment); |
313 | virtual unsigned int ensureCapacity(unsigned int newCapacity); |
314 | virtual void free() APPLE_KEXT_OVERRIDE; |
315 | |
316 | OSMetaClassDeclareReservedUnused(OSSerialize, 0); |
317 | OSMetaClassDeclareReservedUnused(OSSerialize, 1); |
318 | OSMetaClassDeclareReservedUnused(OSSerialize, 2); |
319 | OSMetaClassDeclareReservedUnused(OSSerialize, 3); |
320 | OSMetaClassDeclareReservedUnused(OSSerialize, 4); |
321 | OSMetaClassDeclareReservedUnused(OSSerialize, 5); |
322 | OSMetaClassDeclareReservedUnused(OSSerialize, 6); |
323 | OSMetaClassDeclareReservedUnused(OSSerialize, 7); |
324 | }; |
325 | |
326 | |
327 | typedef bool (*OSSerializerCallback)(void * target, void * ref, |
328 | OSSerialize * serializer); |
329 | |
330 | #ifdef __BLOCKS__ |
331 | typedef bool (^OSSerializerBlock)(OSSerialize * serializer); |
332 | #endif /* __BLOCKS__ */ |
333 | |
334 | |
335 | class OSSerializer : public OSObject |
336 | { |
337 | OSDeclareDefaultStructors(OSSerializer); |
338 | |
339 | void * target; |
340 | void * ref; |
341 | OSSerializerCallback callback; |
342 | |
343 | public: |
344 | |
345 | static OSPtr<OSSerializer> forTarget( |
346 | void * target, |
347 | OSSerializerCallback callback, |
348 | void * ref = NULL); |
349 | |
350 | #ifdef __BLOCKS__ |
351 | static OSPtr<OSSerializer> withBlock( |
352 | OSSerializerBlock callback); |
353 | #endif |
354 | |
355 | virtual void free( void ) APPLE_KEXT_OVERRIDE; |
356 | |
357 | #if XNU_KERNEL_PRIVATE |
358 | static bool callbackToBlock(void * target, void * ref, |
359 | OSSerialize * serializer); |
360 | #endif /* XNU_KERNEL_PRIVATE */ |
361 | |
362 | virtual bool serialize(OSSerialize * serializer) const APPLE_KEXT_OVERRIDE; |
363 | }; |
364 | |
365 | #endif /* _OS_OSSERIALIZE_H */ |
366 | |