|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* IOData.m created by rsulack on Thu 25-Sep-1997 */ ! 23: ! 24: ! 25: #include <libkern/c++/OSData.h> ! 26: #include <libkern/c++/OSSerialize.h> ! 27: #include <libkern/c++/OSLib.h> ! 28: ! 29: #define super OSObject ! 30: ! 31: OSDefineMetaClassAndStructors(OSData, OSObject) ! 32: ! 33: #define EXTERNAL ((unsigned int) -1) ! 34: ! 35: #ifdef DEBUG ! 36: extern "C" { ! 37: extern int debug_container_malloc_size; ! 38: }; ! 39: #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) ! 40: #else ! 41: #define ACCUMSIZE(s) ! 42: #endif ! 43: ! 44: bool OSData::initWithCapacity(unsigned int inCapacity) ! 45: { ! 46: if (!super::init()) ! 47: return false; ! 48: ! 49: if(inCapacity) { ! 50: data = (void *) kalloc(inCapacity); ! 51: if (!data) ! 52: return false; ! 53: } ! 54: ! 55: length = 0; ! 56: capacity = inCapacity; ! 57: capacityIncrement = capacity; ! 58: ! 59: ACCUMSIZE(capacity); ! 60: ! 61: return true; ! 62: } ! 63: ! 64: bool OSData::initWithBytes(const void *bytes, unsigned int inLength) ! 65: { ! 66: if (!bytes || !initWithCapacity(inLength)) ! 67: return false; ! 68: ! 69: bcopy(bytes, data, inLength); ! 70: length = inLength; ! 71: ! 72: return true; ! 73: } ! 74: ! 75: bool OSData::initWithBytesNoCopy(void *bytes, unsigned int inLength) ! 76: { ! 77: if (!super::init()) ! 78: return false; ! 79: ! 80: length = inLength; ! 81: capacity = EXTERNAL; ! 82: data = bytes; ! 83: ! 84: return true; ! 85: } ! 86: ! 87: bool OSData::initWithData(const OSData *inData) ! 88: { ! 89: return initWithBytes(inData->data, inData->length); ! 90: } ! 91: ! 92: bool OSData::initWithData(const OSData *inData, ! 93: unsigned int start, unsigned int inLength) ! 94: { ! 95: const void *localData = inData->getBytesNoCopy(start, inLength); ! 96: ! 97: if (localData) ! 98: return initWithBytes(localData, inLength); ! 99: else ! 100: return false; ! 101: } ! 102: ! 103: OSData *OSData::withCapacity(unsigned int inCapacity) ! 104: { ! 105: OSData *me = new OSData; ! 106: ! 107: if (me && !me->initWithCapacity(inCapacity)) { ! 108: me->free(); ! 109: return 0; ! 110: } ! 111: ! 112: return me; ! 113: } ! 114: ! 115: OSData *OSData::withBytes(const void *bytes, unsigned int inLength) ! 116: { ! 117: OSData *me = new OSData; ! 118: ! 119: if (me && !me->initWithBytes(bytes, inLength)) { ! 120: me->free(); ! 121: return 0; ! 122: } ! 123: return me; ! 124: } ! 125: ! 126: OSData *OSData::withBytesNoCopy(void *bytes, unsigned int inLength) ! 127: { ! 128: OSData *me = new OSData; ! 129: ! 130: if (me && !me->initWithBytesNoCopy(bytes, inLength)) { ! 131: me->free(); ! 132: return 0; ! 133: } ! 134: ! 135: return me; ! 136: } ! 137: ! 138: OSData *OSData::withData(const OSData *inData) ! 139: { ! 140: OSData *me = new OSData; ! 141: ! 142: if (me && !me->initWithData(inData)) { ! 143: me->free(); ! 144: return 0; ! 145: } ! 146: ! 147: return me; ! 148: } ! 149: ! 150: OSData *OSData::withData(const OSData *inData, ! 151: unsigned int start, unsigned int inLength) ! 152: { ! 153: OSData *me = new OSData; ! 154: ! 155: if (me && !me->initWithData(inData, start, inLength)) { ! 156: me->free(); ! 157: return 0; ! 158: } ! 159: ! 160: return me; ! 161: } ! 162: ! 163: void OSData::free() ! 164: { ! 165: if (capacity != EXTERNAL && data && capacity) { ! 166: kfree((vm_offset_t)data, capacity); ! 167: ACCUMSIZE( -capacity ); ! 168: } ! 169: super::free(); ! 170: } ! 171: ! 172: unsigned int OSData::getLength() const { return length; } ! 173: unsigned int OSData::getCapacity() const { return capacity; } ! 174: ! 175: unsigned int OSData::getCapacityIncrement() const ! 176: { ! 177: return capacityIncrement; ! 178: } ! 179: ! 180: unsigned int OSData::setCapacityIncrement(unsigned increment) ! 181: { ! 182: return capacityIncrement = increment; ! 183: } ! 184: ! 185: unsigned int OSData::ensureCapacity(unsigned int newCapacity) ! 186: { ! 187: unsigned char * newData; ! 188: ! 189: if ( !capacityIncrement || (newCapacity <= capacity) ) ! 190: return capacity; ! 191: ! 192: newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) ! 193: * capacityIncrement; ! 194: ! 195: newData = (unsigned char *) kalloc(newCapacity); ! 196: ! 197: if ( newData ) { ! 198: bcopy(data, newData, capacity); ! 199: bzero(newData + capacity, newCapacity - capacity); ! 200: kfree((vm_offset_t)data, capacity); ! 201: ACCUMSIZE( newCapacity - capacity ); ! 202: data = (void *) newData; ! 203: capacity = newCapacity; ! 204: } ! 205: ! 206: return capacity; ! 207: } ! 208: ! 209: bool OSData::appendBytes(const void *bytes, unsigned int inLength) ! 210: { ! 211: unsigned int newSize; ! 212: ! 213: if (inLength == 0) ! 214: return true; ! 215: ! 216: if (capacity == EXTERNAL) ! 217: return false; ! 218: ! 219: newSize = length + inLength; ! 220: if ( (newSize > capacity) && newSize > ensureCapacity(newSize) ) ! 221: return false; ! 222: ! 223: bcopy(bytes, &((unsigned char *)data)[length], inLength); ! 224: length = newSize; ! 225: ! 226: return true; ! 227: } ! 228: ! 229: bool OSData::appendBytes(const OSData *other) ! 230: { ! 231: return appendBytes(other->data, other->length); ! 232: } ! 233: ! 234: const void *OSData::getBytesNoCopy() const ! 235: { ! 236: if (length == 0) ! 237: return 0; ! 238: else ! 239: return data; ! 240: } ! 241: ! 242: const void *OSData::getBytesNoCopy(unsigned int start, ! 243: unsigned int inLength) const ! 244: { ! 245: const void *outData = 0; ! 246: ! 247: if (length ! 248: && start < length ! 249: && (start + inLength) <= length) ! 250: outData = (const void *) ((char *) data + start); ! 251: ! 252: return outData; ! 253: } ! 254: ! 255: bool OSData::isEqualTo(const OSData *aData) const ! 256: { ! 257: unsigned int len; ! 258: ! 259: len = aData->length; ! 260: if ( length != len ) ! 261: return false; ! 262: ! 263: return isEqualTo(aData->data, len); ! 264: } ! 265: ! 266: bool OSData::isEqualTo(const void *someData, unsigned int inLength) const ! 267: { ! 268: return (length >= inLength) && (bcmp(data, someData, inLength) == 0); ! 269: } ! 270: ! 271: bool OSData::isEqualTo(const OSObject *obj) const ! 272: { ! 273: OSData * data; ! 274: if ((data = OSDynamicCast(OSData, (OSObject *)obj ))) ! 275: return isEqualTo(data); ! 276: else ! 277: return false; ! 278: } ! 279: ! 280: //this was taken from CFPropertyList.c ! 281: static const char __CFPLDataEncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ! 282: ! 283: bool OSData::serialize(OSSerialize *s) const ! 284: { ! 285: unsigned int i; ! 286: const unsigned char *p; ! 287: unsigned char c; ! 288: ! 289: if (s->previouslySerialized(this)) return true; ! 290: ! 291: if (!s->addXMLStartTag(this, "data")) return false; ! 292: ! 293: for (i = 0, p = (unsigned char *)data; i < length; i++, p++) { ! 294: /* 3 bytes are encoded as 4 */ ! 295: switch (i % 3) { ! 296: case 0: ! 297: c = __CFPLDataEncodeTable [ ((p[0] >> 2) & 0x3f)]; ! 298: if (!s->addChar(c)) return false; ! 299: break; ! 300: case 1: ! 301: c = __CFPLDataEncodeTable [ ((((p[-1] << 8) | p[0]) >> 4) & 0x3f)]; ! 302: if (!s->addChar(c)) return false; ! 303: break; ! 304: case 2: ! 305: c = __CFPLDataEncodeTable [ ((((p[-1] << 8) | p[0]) >> 6) & 0x3f)]; ! 306: if (!s->addChar(c)) return false; ! 307: c = __CFPLDataEncodeTable [ (p[0] & 0x3f)]; ! 308: if (!s->addChar(c)) return false; ! 309: break; ! 310: } ! 311: } ! 312: switch (i % 3) { ! 313: case 0: ! 314: break; ! 315: case 1: ! 316: c = __CFPLDataEncodeTable [ ((p[-1] << 4) & 0x30)]; ! 317: if (!s->addChar(c)) return false; ! 318: if (!s->addChar('=')) return false; ! 319: if (!s->addChar('=')) return false; ! 320: break; ! 321: case 2: ! 322: c = __CFPLDataEncodeTable [ ((p[-1] << 2) & 0x3c)]; ! 323: if (!s->addChar(c)) return false; ! 324: if (!s->addChar('=')) return false; ! 325: break; ! 326: } ! 327: ! 328: return s->addXMLEndTag("data"); ! 329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.