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
35class OSCollection;
36class OSSet;
37class OSDictionary;
38class OSArray;
39
40/*!
41 * @header
42 *
43 * @abstract
44 * This header declares the OSSerialize class.
45 */
46
47OSObject *
48OSUnserializeBinary(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
84class OSSerialize : public OSObject
85{
86 OSDeclareDefaultStructors(OSSerialize)
87 friend class OSBoolean;
88
89private:
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
98public:
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
117public:
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
314typedef bool (*OSSerializerCallback)(void * target, void * ref,
315 OSSerialize * serializer);
316
317#ifdef __BLOCKS__
318typedef bool (^OSSerializerBlock)(OSSerialize * serializer);
319#endif /* __BLOCKS__ */
320
321
322class OSSerializer : public OSObject
323{
324 OSDeclareDefaultStructors(OSSerializer)
325
326 void * target;
327 void * ref;
328 OSSerializerCallback callback;
329
330public:
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