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