2  * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  28 /* OSSerialize.cpp created by rsulack on Wen 25-Nov-1998 */ 
  30 #define IOKIT_ENABLE_SHARED_PTR 
  32 #include <sys/cdefs.h> 
  35 #include <vm/vm_kern.h> 
  38 #include <libkern/c++/OSContainers.h> 
  39 #include <libkern/c++/OSLib.h> 
  40 #include <libkern/c++/OSDictionary.h> 
  41 #include <libkern/c++/OSSharedPtr.h> 
  42 #include <libkern/OSSerializeBinary.h> 
  43 #include <libkern/Block.h> 
  44 #include <IOKit/IOLib.h> 
  46 #define super OSObject 
  48 OSDefineMetaClassAndStructors(OSSerialize
, OSObject
) 
  49 OSMetaClassDefineReservedUnused(OSSerialize
, 0); 
  50 OSMetaClassDefineReservedUnused(OSSerialize
, 1); 
  51 OSMetaClassDefineReservedUnused(OSSerialize
, 2); 
  52 OSMetaClassDefineReservedUnused(OSSerialize
, 3); 
  53 OSMetaClassDefineReservedUnused(OSSerialize
, 4); 
  54 OSMetaClassDefineReservedUnused(OSSerialize
, 5); 
  55 OSMetaClassDefineReservedUnused(OSSerialize
, 6); 
  56 OSMetaClassDefineReservedUnused(OSSerialize
, 7); 
  60 OSSerialize::text() const 
  66 OSSerialize::clearText() 
  69                 length 
= sizeof(kOSSerializeBinarySignature
); 
  70                 bzero(&data
[length
], capacity 
- length
); 
  73                 bzero((void *)data
, capacity
); 
  76         tags
->flushCollection(); 
  80 OSSerialize::previouslySerialized(const OSMetaClassBase 
*o
) 
  86                 return binarySerialize(o
); 
  90         tagIdx 
= tags
->getNextIndexOfObject(o
, 0); 
  92 // xx-review: no error checking here for addString calls! 
  95                 addString("<reference IDREF=\""); 
  96                 snprintf(temp
, sizeof(temp
), "%u", tagIdx
); 
 103         tags
->setObject(o
);// XXX check return 
 109 OSSerialize::addXMLStartTag(const OSMetaClassBase 
*o
, const char *tagString
) 
 115                 printf("class %s: xml serialize\n", o
->getMetaClass()->getClassName()); 
 122         if (!addString(tagString
)) { 
 125         if (!addString(" ID=\"")) { 
 128         tagIdx 
= tags
->getNextIndexOfObject(o
, 0); 
 129         assert(tagIdx 
!= -1U); 
 130         snprintf(temp
, sizeof(temp
), "%u", tagIdx
); 
 131         if (!addString(temp
)) { 
 134         if (!addChar('\"')) { 
 144 OSSerialize::addXMLEndTag(const char *tagString
) 
 152         if (!addString(tagString
)) { 
 162 OSSerialize::addChar(const char c
) 
 165                 printf("xml serialize\n"); 
 169         // add char, possibly extending our capacity 
 170         if (length 
>= capacity 
&& length 
>= ensureCapacity(capacity 
+ capacityIncrement
)) { 
 174         data
[length 
- 1] = c
; 
 181 OSSerialize::addString(const char *s
) 
 185         while (*s 
&& (rc 
= addChar(*s
++))) { 
 193 OSSerialize::initWithCapacity(unsigned int inCapacity
) 
 195         if (!super::init()) { 
 199         tags 
= OSArray::withCapacity(256); 
 209         if (round_page_overflow(inCapacity
, &capacity
)) { 
 214         capacityIncrement 
= capacity
; 
 216         // allocate from the kernel map so that we can safely map this data 
 217         // into user space (the primary use of the OSSerialize object) 
 219         kern_return_t rc 
= kmem_alloc(kernel_map
, (vm_offset_t 
*)&data
, capacity
, IOMemoryTag(kernel_map
)); 
 223         bzero((void *)data
, capacity
); 
 226         OSCONTAINER_ACCUMSIZE(capacity
); 
 231 OSSharedPtr
<OSSerialize
> 
 232 OSSerialize::withCapacity(unsigned int inCapacity
) 
 234         OSSharedPtr
<OSSerialize
> me 
= OSMakeShared
<OSSerialize
>(); 
 236         if (me 
&& !me
->initWithCapacity(inCapacity
)) { 
 244 OSSerialize::getLength() const 
 249 OSSerialize::getCapacity() const 
 254 OSSerialize::getCapacityIncrement() const 
 256         return capacityIncrement
; 
 259 OSSerialize::setCapacityIncrement(unsigned int increment
) 
 261         capacityIncrement 
= (increment
)? increment 
: 256; 
 262         return capacityIncrement
; 
 266 OSSerialize::ensureCapacity(unsigned int newCapacity
) 
 270         if (newCapacity 
<= capacity
) { 
 274         if (round_page_overflow(newCapacity
, &newCapacity
)) { 
 278         kern_return_t rc 
= kmem_realloc(kernel_map
, 
 281             (vm_offset_t 
*)&newData
, 
 283             VM_KERN_MEMORY_IOKIT
); 
 285                 OSCONTAINER_ACCUMSIZE(newCapacity
); 
 287                 // kmem realloc does not free the old address range 
 288                 kmem_free(kernel_map
, (vm_offset_t
)data
, capacity
); 
 289                 OSCONTAINER_ACCUMSIZE(-((size_t)capacity
)); 
 291                 // kmem realloc does not zero out the new memory 
 292                 // and this could end up going to user land 
 293                 bzero(&newData
[capacity
], newCapacity 
- capacity
); 
 296                 capacity 
= newCapacity
; 
 306                 kmem_free(kernel_map
, (vm_offset_t
)data
, capacity
); 
 307                 OSCONTAINER_ACCUMSIZE( -((size_t)capacity
)); 
 313 OSDefineMetaClassAndStructors(OSSerializer
, OSObject
) 
 315 OSSharedPtr
<OSSerializer
> 
 316 OSSerializer::forTarget( void * target
, 
 317     OSSerializerCallback callback
, void * ref 
) 
 319         OSSharedPtr
<OSSerializer
> thing 
= OSMakeShared
<OSSerializer
>(); 
 321         if (thing 
&& !thing
->init()) { 
 326                 thing
->target   
= target
; 
 328                 thing
->callback 
= callback
; 
 334 OSSerializer::callbackToBlock(void * target __unused
, void * ref
, 
 335     OSSerialize 
* serializer
) 
 337         return ((OSSerializerBlock
)ref
)(serializer
); 
 340 OSSharedPtr
<OSSerializer
> 
 341 OSSerializer::withBlock( 
 342         OSSerializerBlock callback
) 
 344         OSSharedPtr
<OSSerializer
> serializer
; 
 345         OSSerializerBlock block
; 
 347         block 
= Block_copy(callback
); 
 352         serializer 
= (OSSerializer::forTarget(NULL
, &OSSerializer::callbackToBlock
, block
)); 
 355                 Block_release(block
); 
 362 OSSerializer::free(void) 
 364         if (callback 
== &callbackToBlock
) { 
 372 OSSerializer::serialize( OSSerialize 
* s 
) const 
 374         return (*callback
)(target
, ref
, s
);