]>
git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSData.cpp
a48142d2c0513f3886f0df87b707357a69203196
   2  * Copyright (c) 2000 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 /* IOData.m created by rsulack on Thu 25-Sep-1997 */ 
  32 #include <libkern/c++/OSData.h> 
  33 #include <libkern/c++/OSSerialize.h> 
  34 #include <libkern/c++/OSLib.h> 
  35 #include <libkern/c++/OSString.h> 
  38 #define super OSObject 
  40 OSDefineMetaClassAndStructors(OSData
, OSObject
) 
  41 OSMetaClassDefineReservedUsed(OSData
, 0);    // setDeallocFunction 
  42 OSMetaClassDefineReservedUnused(OSData
, 1); 
  43 OSMetaClassDefineReservedUnused(OSData
, 2); 
  44 OSMetaClassDefineReservedUnused(OSData
, 3); 
  45 OSMetaClassDefineReservedUnused(OSData
, 4); 
  46 OSMetaClassDefineReservedUnused(OSData
, 5); 
  47 OSMetaClassDefineReservedUnused(OSData
, 6); 
  48 OSMetaClassDefineReservedUnused(OSData
, 7); 
  50 #define EXTERNAL ((unsigned int) -1) 
  52 bool OSData::initWithCapacity(unsigned int inCapacity
) 
  56         OSCONTAINER_ACCUMSIZE(-((size_t)capacity
)); 
  57         if (!inCapacity 
|| (capacity 
< inCapacity
)) 
  59             // clean out old data's storage if it isn't big enough 
  60             kfree(data
, capacity
); 
  69     if (inCapacity 
&& !data
) { 
  70         data 
= (void *) kalloc_container(inCapacity
); 
  73         capacity 
= inCapacity
; 
  75     OSCONTAINER_ACCUMSIZE(capacity
); 
  79         capacityIncrement 
= 16; 
  81         capacityIncrement 
= inCapacity
; 
  86 bool OSData::initWithBytes(const void *bytes
, unsigned int inLength
) 
  88     if ((inLength 
&& !bytes
) || !initWithCapacity(inLength
)) 
  92         bcopy(bytes
, data
, inLength
); 
  98 bool OSData::initWithBytesNoCopy(void *bytes
, unsigned int inLength
) 
 110 bool OSData::initWithData(const OSData 
*inData
) 
 112     return initWithBytes(inData
->data
, inData
->length
); 
 115 bool OSData::initWithData(const OSData 
*inData
, 
 116                           unsigned int start
, unsigned int inLength
) 
 118     const void *localData 
= inData
->getBytesNoCopy(start
, inLength
); 
 121         return initWithBytes(localData
, inLength
); 
 126 OSData 
*OSData::withCapacity(unsigned int inCapacity
) 
 128     OSData 
*me 
= new OSData
; 
 130     if (me 
&& !me
->initWithCapacity(inCapacity
)) { 
 138 OSData 
*OSData::withBytes(const void *bytes
, unsigned int inLength
) 
 140     OSData 
*me 
= new OSData
; 
 142     if (me 
&& !me
->initWithBytes(bytes
, inLength
)) { 
 149 OSData 
*OSData::withBytesNoCopy(void *bytes
, unsigned int inLength
) 
 151     OSData 
*me 
= new OSData
; 
 153     if (me 
&& !me
->initWithBytesNoCopy(bytes
, inLength
)) { 
 161 OSData 
*OSData::withData(const OSData 
*inData
) 
 163     OSData 
*me 
= new OSData
; 
 165     if (me 
&& !me
->initWithData(inData
)) { 
 173 OSData 
*OSData::withData(const OSData 
*inData
, 
 174                          unsigned int start
, unsigned int inLength
) 
 176     OSData 
*me 
= new OSData
; 
 178     if (me 
&& !me
->initWithData(inData
, start
, inLength
)) { 
 188     if (capacity 
!= EXTERNAL 
&& data 
&& capacity
) { 
 189         kfree(data
, capacity
); 
 190         OSCONTAINER_ACCUMSIZE( -((size_t)capacity
) ); 
 191     } else if (capacity 
== EXTERNAL
) { 
 192         DeallocFunction freemem 
= reserved 
? reserved
->deallocFunction 
: NULL
; 
 193         if (freemem 
&& data 
&& length
) { 
 194                 freemem(data
, length
); 
 197     if (reserved
) kfree(reserved
, sizeof(ExpansionData
)); 
 201 unsigned int OSData::getLength() const { return length
; } 
 202 unsigned int OSData::getCapacity() const { return capacity
; } 
 204 unsigned int OSData::getCapacityIncrement() const  
 206     return capacityIncrement
;  
 209 unsigned int OSData::setCapacityIncrement(unsigned increment
)  
 211     return capacityIncrement 
= increment
;  
 214 // xx-review: does not check for capacity == EXTERNAL 
 216 unsigned int OSData::ensureCapacity(unsigned int newCapacity
) 
 218     unsigned char * newData
; 
 219     unsigned int finalCapacity
; 
 221     if (newCapacity 
<= capacity
) 
 224     finalCapacity 
= (((newCapacity 
- 1) / capacityIncrement
) + 1) 
 227     // integer overflow check 
 228     if (finalCapacity 
< newCapacity
) 
 231     newData 
= (unsigned char *) kalloc_container(finalCapacity
); 
 234         bzero(newData 
+ capacity
, finalCapacity 
- capacity
); 
 236             bcopy(data
, newData
, capacity
); 
 237             kfree(data
, capacity
); 
 239         OSCONTAINER_ACCUMSIZE( ((size_t)finalCapacity
) - ((size_t)capacity
) ); 
 240         data 
= (void *) newData
; 
 241         capacity 
= finalCapacity
; 
 247 bool OSData::appendBytes(const void *bytes
, unsigned int inLength
) 
 249     unsigned int newSize
; 
 254     if (capacity 
== EXTERNAL
) 
 257     newSize 
= length 
+ inLength
; 
 258     if ( (newSize 
> capacity
) && newSize 
> ensureCapacity(newSize
) ) 
 262         bcopy(bytes
, &((unsigned char *)data
)[length
], inLength
); 
 264         bzero(&((unsigned char *)data
)[length
], inLength
); 
 271 bool OSData::appendByte(unsigned char byte
, unsigned int inLength
) 
 273     unsigned int newSize
; 
 278     if (capacity 
== EXTERNAL
) 
 281     newSize 
= length 
+ inLength
; 
 282     if ( (newSize 
> capacity
) && newSize 
> ensureCapacity(newSize
) ) 
 285     memset(&((unsigned char *)data
)[length
], byte
, inLength
); 
 291 bool OSData::appendBytes(const OSData 
*other
) 
 293     return appendBytes(other
->data
, other
->length
); 
 296 const void *OSData::getBytesNoCopy() const 
 304 const void *OSData::getBytesNoCopy(unsigned int start
, 
 305                                    unsigned int inLength
) const 
 307     const void *outData 
= 0; 
 311     && (start 
+ inLength
) <= length
) 
 312         outData 
= (const void *) ((char *) data 
+ start
); 
 317 bool OSData::isEqualTo(const OSData 
*aData
) const 
 325     return isEqualTo(aData
->data
, len
); 
 328 bool OSData::isEqualTo(const void *someData
, unsigned int inLength
) const 
 330     return (length 
>= inLength
) && (bcmp(data
, someData
, inLength
) == 0); 
 333 bool OSData::isEqualTo(const OSMetaClassBase 
*obj
) const 
 338     if ((otherData 
= OSDynamicCast(OSData
, obj
))) 
 339         return isEqualTo(otherData
); 
 340     else if ((str 
= OSDynamicCast (OSString
, obj
))) 
 341         return isEqualTo(str
); 
 346 bool OSData::isEqualTo(const OSString 
*obj
) const 
 348     const char * aCString
; 
 350     unsigned int checkLen 
= length
; 
 351     unsigned int stringLen
; 
 356     stringLen 
= obj
->getLength (); 
 358     dataPtr 
= (char *)data
; 
 360     if (stringLen 
!= checkLen
) { 
 362       // check for the fact that OSData may be a buffer that 
 363       // that includes a termination byte and will thus have 
 364       // a length of the actual string length PLUS 1. In this 
 365       // case we verify that the additional byte is a terminator 
 366       // and if so count the two lengths as being the same. 
 368       if ( (checkLen 
- stringLen
) == 1) { 
 369         if (dataPtr
[checkLen
-1] != 0) // non-zero means not a terminator and thus not likely the same 
 377     aCString 
= obj
->getCStringNoCopy (); 
 379     for ( unsigned int i
=0; i 
< checkLen
; i
++ ) { 
 380       if ( *dataPtr
++ != aCString
[i
] )  
 387 //this was taken from CFPropertyList.c  
 388 static const char __CFPLDataEncodeTable
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
 390 bool OSData::serialize(OSSerialize 
*s
) const 
 393     const unsigned char *p
; 
 395     unsigned int serializeLength
; 
 397     if (s
->previouslySerialized(this)) return true; 
 399     if (!s
->addXMLStartTag(this, "data")) return false; 
 401     serializeLength 
= length
; 
 402     if (reserved 
&& reserved
->disableSerialization
) serializeLength 
= 0; 
 404     for (i 
= 0, p 
= (unsigned char *)data
; i 
< serializeLength
; i
++, p
++) { 
 405         /* 3 bytes are encoded as 4 */ 
 408                 c 
= __CFPLDataEncodeTable 
[ ((p
[0] >> 2) & 0x3f)]; 
 409                 if (!s
->addChar(c
)) return false; 
 412                 c 
= __CFPLDataEncodeTable 
[ ((((p
[-1] << 8) | p
[0]) >> 4) & 0x3f)]; 
 413                 if (!s
->addChar(c
)) return false; 
 416                 c 
= __CFPLDataEncodeTable 
[ ((((p
[-1] << 8) | p
[0]) >> 6) & 0x3f)]; 
 417                 if (!s
->addChar(c
)) return false; 
 418                 c 
= __CFPLDataEncodeTable 
[ (p
[0] & 0x3f)]; 
 419                 if (!s
->addChar(c
)) return false; 
 427             c 
= __CFPLDataEncodeTable 
[ ((p
[-1] << 4) & 0x30)]; 
 428             if (!s
->addChar(c
)) return false; 
 429             if (!s
->addChar('=')) return false; 
 430             if (!s
->addChar('=')) return false; 
 433             c 
= __CFPLDataEncodeTable 
[ ((p
[-1] << 2) & 0x3c)]; 
 434             if (!s
->addChar(c
)) return false; 
 435             if (!s
->addChar('=')) return false; 
 439     return s
->addXMLEndTag("data"); 
 442 void OSData::setDeallocFunction(DeallocFunction func
) 
 446         reserved 
= (typeof(reserved
)) kalloc_container(sizeof(ExpansionData
)); 
 447         if (!reserved
) return; 
 448         bzero(reserved
, sizeof(ExpansionData
)); 
 450     reserved
->deallocFunction 
= func
; 
 453 void OSData::setSerializable(bool serializable
) 
 457         reserved 
= (typeof(reserved
)) kalloc_container(sizeof(ExpansionData
)); 
 458         if (!reserved
) return; 
 459         bzero(reserved
, sizeof(ExpansionData
)); 
 461     reserved
->disableSerialization 
= (!serializable
);