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