xref: /xnu-11215.1.10/libkern/libkern/c++/OSSerialize.h (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
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