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