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
36class OSCollection;
37class OSSet;
38class OSDictionary;
39class OSArray;
40class OSData;
41
42class OSSerializer;
43typedef OSSerializer* OSSerializerPtr;
44
45class OSSerialize;
46typedef OSSerialize* OSSerializePtr;
47
48/*!
49 * @header
50 *
51 * @abstract
52 * This header declares the OSSerialize class.
53 */
54
55OSObjectPtr
56OSUnserializeBinary(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
92class OSSerialize : public OSObject
93{
94 OSDeclareDefaultStructors(OSSerialize);
95 friend class OSBoolean;
96
97private:
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
106public:
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
129public:
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
327typedef bool (*OSSerializerCallback)(void * target, void * ref,
328 OSSerialize * serializer);
329
330#ifdef __BLOCKS__
331typedef bool (^OSSerializerBlock)(OSSerialize * serializer);
332#endif /* __BLOCKS__ */
333
334
335class OSSerializer : public OSObject
336{
337 OSDeclareDefaultStructors(OSSerializer);
338
339 void * target;
340 void * ref;
341 OSSerializerCallback callback;
342
343public:
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