1*a3bb9fccSApple OSS Distributions /* 2*a3bb9fccSApple OSS Distributions * Copyright (c) 2014 Apple Computer, Inc. All rights reserved. 3*a3bb9fccSApple OSS Distributions * 4*a3bb9fccSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*a3bb9fccSApple OSS Distributions * 6*a3bb9fccSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*a3bb9fccSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*a3bb9fccSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*a3bb9fccSApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*a3bb9fccSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*a3bb9fccSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*a3bb9fccSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*a3bb9fccSApple OSS Distributions * terms of an Apple operating system software license agreement. 14*a3bb9fccSApple OSS Distributions * 15*a3bb9fccSApple OSS Distributions * Please obtain a copy of the License at 16*a3bb9fccSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*a3bb9fccSApple OSS Distributions * 18*a3bb9fccSApple OSS Distributions * The Original Code and all software distributed under the License are 19*a3bb9fccSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*a3bb9fccSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*a3bb9fccSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*a3bb9fccSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*a3bb9fccSApple OSS Distributions * Please see the License for the specific language governing rights and 24*a3bb9fccSApple OSS Distributions * limitations under the License. 25*a3bb9fccSApple OSS Distributions * 26*a3bb9fccSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*a3bb9fccSApple OSS Distributions */ 28*a3bb9fccSApple OSS Distributions 29*a3bb9fccSApple OSS Distributions 30*a3bb9fccSApple OSS Distributions #include <libkern/c++/OSContainers.h> 31*a3bb9fccSApple OSS Distributions #include <libkern/c++/OSLib.h> 32*a3bb9fccSApple OSS Distributions #include <libkern/c++/OSDictionary.h> 33*a3bb9fccSApple OSS Distributions #include <libkern/OSSerializeBinary.h> 34*a3bb9fccSApple OSS Distributions 35*a3bb9fccSApple OSS Distributions #include <IOKit/IOLib.h> 36*a3bb9fccSApple OSS Distributions 37*a3bb9fccSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 38*a3bb9fccSApple OSS Distributions 39*a3bb9fccSApple OSS Distributions #if 0 40*a3bb9fccSApple OSS Distributions #define DEBG(fmt, args...) { kprintf(fmt, args); } 41*a3bb9fccSApple OSS Distributions #else 42*a3bb9fccSApple OSS Distributions #define DEBG(fmt, args...) {} 43*a3bb9fccSApple OSS Distributions #endif 44*a3bb9fccSApple OSS Distributions 45*a3bb9fccSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 46*a3bb9fccSApple OSS Distributions 47*a3bb9fccSApple OSS Distributions OSSerialize *OSSerialize::binaryWithCapacity(unsigned int inCapacity, 48*a3bb9fccSApple OSS Distributions Editor editor, void * reference) 49*a3bb9fccSApple OSS Distributions { 50*a3bb9fccSApple OSS Distributions OSSerialize *me; 51*a3bb9fccSApple OSS Distributions 52*a3bb9fccSApple OSS Distributions if (inCapacity < sizeof(uint32_t)) return (0); 53*a3bb9fccSApple OSS Distributions me = OSSerialize::withCapacity(inCapacity); 54*a3bb9fccSApple OSS Distributions if (!me) return (0); 55*a3bb9fccSApple OSS Distributions 56*a3bb9fccSApple OSS Distributions me->binary = true; 57*a3bb9fccSApple OSS Distributions me->endCollection = true; 58*a3bb9fccSApple OSS Distributions me->editor = editor; 59*a3bb9fccSApple OSS Distributions me->editRef = reference; 60*a3bb9fccSApple OSS Distributions 61*a3bb9fccSApple OSS Distributions bcopy(kOSSerializeBinarySignature, &me->data[0], sizeof(kOSSerializeBinarySignature)); 62*a3bb9fccSApple OSS Distributions me->length = sizeof(kOSSerializeBinarySignature); 63*a3bb9fccSApple OSS Distributions 64*a3bb9fccSApple OSS Distributions return (me); 65*a3bb9fccSApple OSS Distributions } 66*a3bb9fccSApple OSS Distributions 67*a3bb9fccSApple OSS Distributions bool OSSerialize::addBinary(const void * bits, size_t size) 68*a3bb9fccSApple OSS Distributions { 69*a3bb9fccSApple OSS Distributions unsigned int newCapacity; 70*a3bb9fccSApple OSS Distributions size_t alignSize; 71*a3bb9fccSApple OSS Distributions 72*a3bb9fccSApple OSS Distributions alignSize = ((size + 3) & ~3L); 73*a3bb9fccSApple OSS Distributions newCapacity = length + alignSize; 74*a3bb9fccSApple OSS Distributions if (newCapacity >= capacity) 75*a3bb9fccSApple OSS Distributions { 76*a3bb9fccSApple OSS Distributions newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement; 77*a3bb9fccSApple OSS Distributions if (newCapacity < ensureCapacity(newCapacity)) return (false); 78*a3bb9fccSApple OSS Distributions } 79*a3bb9fccSApple OSS Distributions 80*a3bb9fccSApple OSS Distributions bcopy(bits, &data[length], size); 81*a3bb9fccSApple OSS Distributions length += alignSize; 82*a3bb9fccSApple OSS Distributions 83*a3bb9fccSApple OSS Distributions return (true); 84*a3bb9fccSApple OSS Distributions } 85*a3bb9fccSApple OSS Distributions 86*a3bb9fccSApple OSS Distributions bool OSSerialize::addBinaryObject(const OSMetaClassBase * o, uint32_t key, 87*a3bb9fccSApple OSS Distributions const void * bits, size_t size) 88*a3bb9fccSApple OSS Distributions { 89*a3bb9fccSApple OSS Distributions unsigned int newCapacity; 90*a3bb9fccSApple OSS Distributions size_t alignSize; 91*a3bb9fccSApple OSS Distributions OSNumber * tagNum; 92*a3bb9fccSApple OSS Distributions 93*a3bb9fccSApple OSS Distributions // build a tag 94*a3bb9fccSApple OSS Distributions tagNum = OSNumber::withNumber(tag, 32); 95*a3bb9fccSApple OSS Distributions tag++; 96*a3bb9fccSApple OSS Distributions // add to tag dictionary 97*a3bb9fccSApple OSS Distributions tags->setObject((const OSSymbol *) o, tagNum); 98*a3bb9fccSApple OSS Distributions tagNum->release(); 99*a3bb9fccSApple OSS Distributions 100*a3bb9fccSApple OSS Distributions alignSize = ((size + sizeof(key) + 3) & ~3L); 101*a3bb9fccSApple OSS Distributions newCapacity = length + alignSize; 102*a3bb9fccSApple OSS Distributions if (newCapacity >= capacity) 103*a3bb9fccSApple OSS Distributions { 104*a3bb9fccSApple OSS Distributions newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement; 105*a3bb9fccSApple OSS Distributions if (newCapacity < ensureCapacity(newCapacity)) return (false); 106*a3bb9fccSApple OSS Distributions } 107*a3bb9fccSApple OSS Distributions 108*a3bb9fccSApple OSS Distributions if (endCollection) 109*a3bb9fccSApple OSS Distributions { 110*a3bb9fccSApple OSS Distributions endCollection = false; 111*a3bb9fccSApple OSS Distributions key |= kOSSerializeEndCollecton; 112*a3bb9fccSApple OSS Distributions } 113*a3bb9fccSApple OSS Distributions 114*a3bb9fccSApple OSS Distributions bcopy(&key, &data[length], sizeof(key)); 115*a3bb9fccSApple OSS Distributions bcopy(bits, &data[length + sizeof(key)], size); 116*a3bb9fccSApple OSS Distributions length += alignSize; 117*a3bb9fccSApple OSS Distributions 118*a3bb9fccSApple OSS Distributions return (true); 119*a3bb9fccSApple OSS Distributions } 120*a3bb9fccSApple OSS Distributions 121*a3bb9fccSApple OSS Distributions bool OSSerialize::binarySerialize(const OSMetaClassBase *o) 122*a3bb9fccSApple OSS Distributions { 123*a3bb9fccSApple OSS Distributions OSDictionary * dict; 124*a3bb9fccSApple OSS Distributions OSArray * array; 125*a3bb9fccSApple OSS Distributions OSSet * set; 126*a3bb9fccSApple OSS Distributions OSNumber * num; 127*a3bb9fccSApple OSS Distributions OSSymbol * sym; 128*a3bb9fccSApple OSS Distributions OSString * str; 129*a3bb9fccSApple OSS Distributions OSData * data; 130*a3bb9fccSApple OSS Distributions OSBoolean * boo; 131*a3bb9fccSApple OSS Distributions 132*a3bb9fccSApple OSS Distributions OSNumber * tagNum; 133*a3bb9fccSApple OSS Distributions uint32_t i, key; 134*a3bb9fccSApple OSS Distributions size_t len; 135*a3bb9fccSApple OSS Distributions bool ok; 136*a3bb9fccSApple OSS Distributions 137*a3bb9fccSApple OSS Distributions tagNum = (OSNumber *)tags->getObject((const OSSymbol *) o); 138*a3bb9fccSApple OSS Distributions // does it exist? 139*a3bb9fccSApple OSS Distributions if (tagNum) 140*a3bb9fccSApple OSS Distributions { 141*a3bb9fccSApple OSS Distributions key = (kOSSerializeObject | tagNum->unsigned32BitValue()); 142*a3bb9fccSApple OSS Distributions if (endCollection) 143*a3bb9fccSApple OSS Distributions { 144*a3bb9fccSApple OSS Distributions endCollection = false; 145*a3bb9fccSApple OSS Distributions key |= kOSSerializeEndCollecton; 146*a3bb9fccSApple OSS Distributions } 147*a3bb9fccSApple OSS Distributions ok = addBinary(&key, sizeof(key)); 148*a3bb9fccSApple OSS Distributions return (ok); 149*a3bb9fccSApple OSS Distributions } 150*a3bb9fccSApple OSS Distributions 151*a3bb9fccSApple OSS Distributions if ((dict = OSDynamicCast(OSDictionary, o))) 152*a3bb9fccSApple OSS Distributions { 153*a3bb9fccSApple OSS Distributions key = (kOSSerializeDictionary | dict->count); 154*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, NULL, 0); 155*a3bb9fccSApple OSS Distributions for (i = 0; ok && (i < dict->count);) 156*a3bb9fccSApple OSS Distributions { 157*a3bb9fccSApple OSS Distributions const OSSymbol * dictKey; 158*a3bb9fccSApple OSS Distributions const OSMetaClassBase * dictValue; 159*a3bb9fccSApple OSS Distributions const OSMetaClassBase * nvalue = 0; 160*a3bb9fccSApple OSS Distributions 161*a3bb9fccSApple OSS Distributions i++; 162*a3bb9fccSApple OSS Distributions dictKey = dict->dictionary[i-1].key; 163*a3bb9fccSApple OSS Distributions dictValue = dict->dictionary[i-1].value; 164*a3bb9fccSApple OSS Distributions if (editor) 165*a3bb9fccSApple OSS Distributions { 166*a3bb9fccSApple OSS Distributions dictValue = nvalue = (*editor)(editRef, this, dict, dictKey, dictValue); 167*a3bb9fccSApple OSS Distributions if (!dictValue) dictValue = dict; 168*a3bb9fccSApple OSS Distributions } 169*a3bb9fccSApple OSS Distributions ok = binarySerialize(dictKey); 170*a3bb9fccSApple OSS Distributions if (!ok) break; 171*a3bb9fccSApple OSS Distributions endCollection = (i == dict->count); 172*a3bb9fccSApple OSS Distributions ok = binarySerialize(dictValue); 173*a3bb9fccSApple OSS Distributions if (!ok) ok = dictValue->serialize(this); 174*a3bb9fccSApple OSS Distributions if (nvalue) nvalue->release(); 175*a3bb9fccSApple OSS Distributions // if (!ok) ok = binarySerialize(kOSBooleanFalse); 176*a3bb9fccSApple OSS Distributions } 177*a3bb9fccSApple OSS Distributions } 178*a3bb9fccSApple OSS Distributions else if ((array = OSDynamicCast(OSArray, o))) 179*a3bb9fccSApple OSS Distributions { 180*a3bb9fccSApple OSS Distributions key = (kOSSerializeArray | array->count); 181*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, NULL, 0); 182*a3bb9fccSApple OSS Distributions for (i = 0; ok && (i < array->count);) 183*a3bb9fccSApple OSS Distributions { 184*a3bb9fccSApple OSS Distributions i++; 185*a3bb9fccSApple OSS Distributions endCollection = (i == array->count); 186*a3bb9fccSApple OSS Distributions ok = binarySerialize(array->array[i-1]); 187*a3bb9fccSApple OSS Distributions if (!ok) ok = array->array[i-1]->serialize(this); 188*a3bb9fccSApple OSS Distributions // if (!ok) ok = binarySerialize(kOSBooleanFalse); 189*a3bb9fccSApple OSS Distributions } 190*a3bb9fccSApple OSS Distributions } 191*a3bb9fccSApple OSS Distributions else if ((set = OSDynamicCast(OSSet, o))) 192*a3bb9fccSApple OSS Distributions { 193*a3bb9fccSApple OSS Distributions key = (kOSSerializeSet | set->members->count); 194*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, NULL, 0); 195*a3bb9fccSApple OSS Distributions for (i = 0; ok && (i < set->members->count);) 196*a3bb9fccSApple OSS Distributions { 197*a3bb9fccSApple OSS Distributions i++; 198*a3bb9fccSApple OSS Distributions endCollection = (i == set->members->count); 199*a3bb9fccSApple OSS Distributions ok = binarySerialize(set->members->array[i-1]); 200*a3bb9fccSApple OSS Distributions if (!ok) ok = set->members->array[i-1]->serialize(this); 201*a3bb9fccSApple OSS Distributions // if (!ok) ok = binarySerialize(kOSBooleanFalse); 202*a3bb9fccSApple OSS Distributions } 203*a3bb9fccSApple OSS Distributions } 204*a3bb9fccSApple OSS Distributions else if ((num = OSDynamicCast(OSNumber, o))) 205*a3bb9fccSApple OSS Distributions { 206*a3bb9fccSApple OSS Distributions key = (kOSSerializeNumber | num->size); 207*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, &num->value, sizeof(num->value)); 208*a3bb9fccSApple OSS Distributions } 209*a3bb9fccSApple OSS Distributions else if ((boo = OSDynamicCast(OSBoolean, o))) 210*a3bb9fccSApple OSS Distributions { 211*a3bb9fccSApple OSS Distributions key = (kOSSerializeBoolean | (kOSBooleanTrue == boo)); 212*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, NULL, 0); 213*a3bb9fccSApple OSS Distributions } 214*a3bb9fccSApple OSS Distributions else if ((sym = OSDynamicCast(OSSymbol, o))) 215*a3bb9fccSApple OSS Distributions { 216*a3bb9fccSApple OSS Distributions len = (sym->getLength() + 1); 217*a3bb9fccSApple OSS Distributions key = (kOSSerializeSymbol | len); 218*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, sym->getCStringNoCopy(), len); 219*a3bb9fccSApple OSS Distributions } 220*a3bb9fccSApple OSS Distributions else if ((str = OSDynamicCast(OSString, o))) 221*a3bb9fccSApple OSS Distributions { 222*a3bb9fccSApple OSS Distributions len = (str->getLength() + 0); 223*a3bb9fccSApple OSS Distributions key = (kOSSerializeString | len); 224*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, str->getCStringNoCopy(), len); 225*a3bb9fccSApple OSS Distributions } 226*a3bb9fccSApple OSS Distributions else if ((data = OSDynamicCast(OSData, o))) 227*a3bb9fccSApple OSS Distributions { 228*a3bb9fccSApple OSS Distributions len = data->getLength(); 229*a3bb9fccSApple OSS Distributions if (data->reserved && data->reserved->disableSerialization) len = 0; 230*a3bb9fccSApple OSS Distributions key = (kOSSerializeData | len); 231*a3bb9fccSApple OSS Distributions ok = addBinaryObject(o, key, data->getBytesNoCopy(), len); 232*a3bb9fccSApple OSS Distributions } 233*a3bb9fccSApple OSS Distributions else return (false); 234*a3bb9fccSApple OSS Distributions 235*a3bb9fccSApple OSS Distributions return (ok); 236*a3bb9fccSApple OSS Distributions } 237*a3bb9fccSApple OSS Distributions 238*a3bb9fccSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 239*a3bb9fccSApple OSS Distributions 240*a3bb9fccSApple OSS Distributions #define setAtIndex(v, idx, o) \ 241*a3bb9fccSApple OSS Distributions if (idx >= v##Capacity) \ 242*a3bb9fccSApple OSS Distributions { \ 243*a3bb9fccSApple OSS Distributions uint32_t ncap = v##Capacity + 64; \ 244*a3bb9fccSApple OSS Distributions typeof(v##Array) nbuf = (typeof(v##Array)) kalloc(ncap * sizeof(o)); \ 245*a3bb9fccSApple OSS Distributions if (!nbuf) ok = false; \ 246*a3bb9fccSApple OSS Distributions if (v##Array) \ 247*a3bb9fccSApple OSS Distributions { \ 248*a3bb9fccSApple OSS Distributions bcopy(v##Array, nbuf, v##Capacity * sizeof(o)); \ 249*a3bb9fccSApple OSS Distributions kfree(v##Array, v##Capacity * sizeof(o)); \ 250*a3bb9fccSApple OSS Distributions } \ 251*a3bb9fccSApple OSS Distributions v##Array = nbuf; \ 252*a3bb9fccSApple OSS Distributions v##Capacity = ncap; \ 253*a3bb9fccSApple OSS Distributions } \ 254*a3bb9fccSApple OSS Distributions if (ok) v##Array[idx] = o; 255*a3bb9fccSApple OSS Distributions 256*a3bb9fccSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 257*a3bb9fccSApple OSS Distributions 258*a3bb9fccSApple OSS Distributions OSObject * 259*a3bb9fccSApple OSS Distributions OSUnserializeBinary(const char *buffer, size_t bufferSize, OSString **errorString) 260*a3bb9fccSApple OSS Distributions { 261*a3bb9fccSApple OSS Distributions OSObject ** objsArray; 262*a3bb9fccSApple OSS Distributions uint32_t objsCapacity; 263*a3bb9fccSApple OSS Distributions uint32_t objsIdx; 264*a3bb9fccSApple OSS Distributions 265*a3bb9fccSApple OSS Distributions OSObject ** stackArray; 266*a3bb9fccSApple OSS Distributions uint32_t stackCapacity; 267*a3bb9fccSApple OSS Distributions uint32_t stackIdx; 268*a3bb9fccSApple OSS Distributions 269*a3bb9fccSApple OSS Distributions OSObject * result; 270*a3bb9fccSApple OSS Distributions OSObject * parent; 271*a3bb9fccSApple OSS Distributions OSDictionary * dict; 272*a3bb9fccSApple OSS Distributions OSArray * array; 273*a3bb9fccSApple OSS Distributions OSSet * set; 274*a3bb9fccSApple OSS Distributions OSDictionary * newDict; 275*a3bb9fccSApple OSS Distributions OSArray * newArray; 276*a3bb9fccSApple OSS Distributions OSSet * newSet; 277*a3bb9fccSApple OSS Distributions OSObject * o; 278*a3bb9fccSApple OSS Distributions OSSymbol * sym; 279*a3bb9fccSApple OSS Distributions 280*a3bb9fccSApple OSS Distributions size_t bufferPos; 281*a3bb9fccSApple OSS Distributions const uint32_t * next; 282*a3bb9fccSApple OSS Distributions uint32_t key, len, wordLen; 283*a3bb9fccSApple OSS Distributions bool end, newCollect, isRef; 284*a3bb9fccSApple OSS Distributions unsigned long long value; 285*a3bb9fccSApple OSS Distributions bool ok; 286*a3bb9fccSApple OSS Distributions 287*a3bb9fccSApple OSS Distributions if (errorString) *errorString = 0; 288*a3bb9fccSApple OSS Distributions if (0 != strcmp(kOSSerializeBinarySignature, buffer)) return (NULL); 289*a3bb9fccSApple OSS Distributions if (3 & ((uintptr_t) buffer)) return (NULL); 290*a3bb9fccSApple OSS Distributions if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (NULL); 291*a3bb9fccSApple OSS Distributions bufferPos = sizeof(kOSSerializeBinarySignature); 292*a3bb9fccSApple OSS Distributions next = (typeof(next)) (((uintptr_t) buffer) + bufferPos); 293*a3bb9fccSApple OSS Distributions 294*a3bb9fccSApple OSS Distributions DEBG("---------OSUnserializeBinary(%p)\n", buffer); 295*a3bb9fccSApple OSS Distributions 296*a3bb9fccSApple OSS Distributions objsArray = stackArray = NULL; 297*a3bb9fccSApple OSS Distributions objsIdx = objsCapacity = 0; 298*a3bb9fccSApple OSS Distributions stackIdx = stackCapacity = 0; 299*a3bb9fccSApple OSS Distributions 300*a3bb9fccSApple OSS Distributions result = 0; 301*a3bb9fccSApple OSS Distributions parent = 0; 302*a3bb9fccSApple OSS Distributions dict = 0; 303*a3bb9fccSApple OSS Distributions array = 0; 304*a3bb9fccSApple OSS Distributions set = 0; 305*a3bb9fccSApple OSS Distributions sym = 0; 306*a3bb9fccSApple OSS Distributions 307*a3bb9fccSApple OSS Distributions ok = true; 308*a3bb9fccSApple OSS Distributions while (ok) 309*a3bb9fccSApple OSS Distributions { 310*a3bb9fccSApple OSS Distributions bufferPos += sizeof(*next); 311*a3bb9fccSApple OSS Distributions if (!(ok = (bufferPos <= bufferSize))) break; 312*a3bb9fccSApple OSS Distributions key = *next++; 313*a3bb9fccSApple OSS Distributions 314*a3bb9fccSApple OSS Distributions len = (key & kOSSerializeDataMask); 315*a3bb9fccSApple OSS Distributions wordLen = (len + 3) >> 2; 316*a3bb9fccSApple OSS Distributions end = (0 != (kOSSerializeEndCollecton & key)); 317*a3bb9fccSApple OSS Distributions DEBG("key 0x%08x: 0x%04x, %d\n", key, len, end); 318*a3bb9fccSApple OSS Distributions 319*a3bb9fccSApple OSS Distributions newCollect = isRef = false; 320*a3bb9fccSApple OSS Distributions o = 0; newDict = 0; newArray = 0; newSet = 0; 321*a3bb9fccSApple OSS Distributions 322*a3bb9fccSApple OSS Distributions switch (kOSSerializeTypeMask & key) 323*a3bb9fccSApple OSS Distributions { 324*a3bb9fccSApple OSS Distributions case kOSSerializeDictionary: 325*a3bb9fccSApple OSS Distributions o = newDict = OSDictionary::withCapacity(len); 326*a3bb9fccSApple OSS Distributions newCollect = (len != 0); 327*a3bb9fccSApple OSS Distributions break; 328*a3bb9fccSApple OSS Distributions case kOSSerializeArray: 329*a3bb9fccSApple OSS Distributions o = newArray = OSArray::withCapacity(len); 330*a3bb9fccSApple OSS Distributions newCollect = (len != 0); 331*a3bb9fccSApple OSS Distributions break; 332*a3bb9fccSApple OSS Distributions case kOSSerializeSet: 333*a3bb9fccSApple OSS Distributions o = newSet = OSSet::withCapacity(len); 334*a3bb9fccSApple OSS Distributions newCollect = (len != 0); 335*a3bb9fccSApple OSS Distributions break; 336*a3bb9fccSApple OSS Distributions 337*a3bb9fccSApple OSS Distributions case kOSSerializeObject: 338*a3bb9fccSApple OSS Distributions if (len >= objsIdx) break; 339*a3bb9fccSApple OSS Distributions o = objsArray[len]; 340*a3bb9fccSApple OSS Distributions o->retain(); 341*a3bb9fccSApple OSS Distributions isRef = true; 342*a3bb9fccSApple OSS Distributions break; 343*a3bb9fccSApple OSS Distributions 344*a3bb9fccSApple OSS Distributions case kOSSerializeNumber: 345*a3bb9fccSApple OSS Distributions bufferPos += sizeof(long long); 346*a3bb9fccSApple OSS Distributions if (bufferPos > bufferSize) break; 347*a3bb9fccSApple OSS Distributions value = next[1]; 348*a3bb9fccSApple OSS Distributions value <<= 32; 349*a3bb9fccSApple OSS Distributions value |= next[0]; 350*a3bb9fccSApple OSS Distributions o = OSNumber::withNumber(value, len); 351*a3bb9fccSApple OSS Distributions next += 2; 352*a3bb9fccSApple OSS Distributions break; 353*a3bb9fccSApple OSS Distributions 354*a3bb9fccSApple OSS Distributions case kOSSerializeSymbol: 355*a3bb9fccSApple OSS Distributions bufferPos += (wordLen * sizeof(uint32_t)); 356*a3bb9fccSApple OSS Distributions if (bufferPos > bufferSize) break; 357*a3bb9fccSApple OSS Distributions if (0 != ((const char *)next)[len-1]) break; 358*a3bb9fccSApple OSS Distributions o = (OSObject *) OSSymbol::withCString((const char *) next); 359*a3bb9fccSApple OSS Distributions next += wordLen; 360*a3bb9fccSApple OSS Distributions break; 361*a3bb9fccSApple OSS Distributions 362*a3bb9fccSApple OSS Distributions case kOSSerializeString: 363*a3bb9fccSApple OSS Distributions bufferPos += (wordLen * sizeof(uint32_t)); 364*a3bb9fccSApple OSS Distributions if (bufferPos > bufferSize) break; 365*a3bb9fccSApple OSS Distributions o = OSString::withStringOfLength((const char *) next, len); 366*a3bb9fccSApple OSS Distributions next += wordLen; 367*a3bb9fccSApple OSS Distributions break; 368*a3bb9fccSApple OSS Distributions 369*a3bb9fccSApple OSS Distributions case kOSSerializeData: 370*a3bb9fccSApple OSS Distributions bufferPos += (wordLen * sizeof(uint32_t)); 371*a3bb9fccSApple OSS Distributions if (bufferPos > bufferSize) break; 372*a3bb9fccSApple OSS Distributions o = OSData::withBytes(next, len); 373*a3bb9fccSApple OSS Distributions next += wordLen; 374*a3bb9fccSApple OSS Distributions break; 375*a3bb9fccSApple OSS Distributions 376*a3bb9fccSApple OSS Distributions case kOSSerializeBoolean: 377*a3bb9fccSApple OSS Distributions o = (len ? kOSBooleanTrue : kOSBooleanFalse); 378*a3bb9fccSApple OSS Distributions break; 379*a3bb9fccSApple OSS Distributions 380*a3bb9fccSApple OSS Distributions default: 381*a3bb9fccSApple OSS Distributions break; 382*a3bb9fccSApple OSS Distributions } 383*a3bb9fccSApple OSS Distributions 384*a3bb9fccSApple OSS Distributions if (!(ok = (o != 0))) break; 385*a3bb9fccSApple OSS Distributions 386*a3bb9fccSApple OSS Distributions if (!isRef) 387*a3bb9fccSApple OSS Distributions { 388*a3bb9fccSApple OSS Distributions setAtIndex(objs, objsIdx, o); 389*a3bb9fccSApple OSS Distributions if (!ok) break; 390*a3bb9fccSApple OSS Distributions objsIdx++; 391*a3bb9fccSApple OSS Distributions } 392*a3bb9fccSApple OSS Distributions 393*a3bb9fccSApple OSS Distributions if (dict) 394*a3bb9fccSApple OSS Distributions { 395*a3bb9fccSApple OSS Distributions if (sym) 396*a3bb9fccSApple OSS Distributions { 397*a3bb9fccSApple OSS Distributions DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName()); 398*a3bb9fccSApple OSS Distributions if (o != dict) ok = dict->setObject(sym, o); 399*a3bb9fccSApple OSS Distributions o->release(); 400*a3bb9fccSApple OSS Distributions sym->release(); 401*a3bb9fccSApple OSS Distributions sym = 0; 402*a3bb9fccSApple OSS Distributions } 403*a3bb9fccSApple OSS Distributions else 404*a3bb9fccSApple OSS Distributions { 405*a3bb9fccSApple OSS Distributions sym = OSDynamicCast(OSSymbol, o); 406*a3bb9fccSApple OSS Distributions ok = (sym != 0); 407*a3bb9fccSApple OSS Distributions } 408*a3bb9fccSApple OSS Distributions } 409*a3bb9fccSApple OSS Distributions else if (array) 410*a3bb9fccSApple OSS Distributions { 411*a3bb9fccSApple OSS Distributions ok = array->setObject(o); 412*a3bb9fccSApple OSS Distributions o->release(); 413*a3bb9fccSApple OSS Distributions } 414*a3bb9fccSApple OSS Distributions else if (set) 415*a3bb9fccSApple OSS Distributions { 416*a3bb9fccSApple OSS Distributions ok = set->setObject(o); 417*a3bb9fccSApple OSS Distributions o->release(); 418*a3bb9fccSApple OSS Distributions } 419*a3bb9fccSApple OSS Distributions else 420*a3bb9fccSApple OSS Distributions { 421*a3bb9fccSApple OSS Distributions assert(!parent); 422*a3bb9fccSApple OSS Distributions result = o; 423*a3bb9fccSApple OSS Distributions } 424*a3bb9fccSApple OSS Distributions 425*a3bb9fccSApple OSS Distributions if (!ok) break; 426*a3bb9fccSApple OSS Distributions 427*a3bb9fccSApple OSS Distributions if (newCollect) 428*a3bb9fccSApple OSS Distributions { 429*a3bb9fccSApple OSS Distributions if (!end) 430*a3bb9fccSApple OSS Distributions { 431*a3bb9fccSApple OSS Distributions stackIdx++; 432*a3bb9fccSApple OSS Distributions setAtIndex(stack, stackIdx, parent); 433*a3bb9fccSApple OSS Distributions if (!ok) break; 434*a3bb9fccSApple OSS Distributions } 435*a3bb9fccSApple OSS Distributions DEBG("++stack[%d] %p\n", stackIdx, parent); 436*a3bb9fccSApple OSS Distributions parent = o; 437*a3bb9fccSApple OSS Distributions dict = newDict; 438*a3bb9fccSApple OSS Distributions array = newArray; 439*a3bb9fccSApple OSS Distributions set = newSet; 440*a3bb9fccSApple OSS Distributions end = false; 441*a3bb9fccSApple OSS Distributions } 442*a3bb9fccSApple OSS Distributions 443*a3bb9fccSApple OSS Distributions if (end) 444*a3bb9fccSApple OSS Distributions { 445*a3bb9fccSApple OSS Distributions if (!stackIdx) break; 446*a3bb9fccSApple OSS Distributions parent = stackArray[stackIdx]; 447*a3bb9fccSApple OSS Distributions DEBG("--stack[%d] %p\n", stackIdx, parent); 448*a3bb9fccSApple OSS Distributions stackIdx--; 449*a3bb9fccSApple OSS Distributions set = 0; 450*a3bb9fccSApple OSS Distributions dict = 0; 451*a3bb9fccSApple OSS Distributions array = 0; 452*a3bb9fccSApple OSS Distributions if (!(dict = OSDynamicCast(OSDictionary, parent))) 453*a3bb9fccSApple OSS Distributions { 454*a3bb9fccSApple OSS Distributions if (!(array = OSDynamicCast(OSArray, parent))) ok = (0 != (set = OSDynamicCast(OSSet, parent))); 455*a3bb9fccSApple OSS Distributions } 456*a3bb9fccSApple OSS Distributions } 457*a3bb9fccSApple OSS Distributions } 458*a3bb9fccSApple OSS Distributions DEBG("ret %p\n", result); 459*a3bb9fccSApple OSS Distributions 460*a3bb9fccSApple OSS Distributions if (objsCapacity) kfree(objsArray, objsCapacity * sizeof(*objsArray)); 461*a3bb9fccSApple OSS Distributions if (stackCapacity) kfree(stackArray, stackCapacity * sizeof(*stackArray)); 462*a3bb9fccSApple OSS Distributions 463*a3bb9fccSApple OSS Distributions if (!ok && result) 464*a3bb9fccSApple OSS Distributions { 465*a3bb9fccSApple OSS Distributions result->release(); 466*a3bb9fccSApple OSS Distributions result = 0; 467*a3bb9fccSApple OSS Distributions } 468*a3bb9fccSApple OSS Distributions return (result); 469*a3bb9fccSApple OSS Distributions }