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