]> git.saurik.com Git - apple/xnu.git/blame - libkern/c++/OSSerializeBinary.cpp
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / libkern / c++ / OSSerializeBinary.cpp
CommitLineData
fe8ab488
A
1/*
2 * Copyright (c) 2014 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
fe8ab488
A
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.
0a7de745 14 *
fe8ab488
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
fe8ab488
A
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.
0a7de745 25 *
fe8ab488
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29
f427ee49
A
30#include <libkern/c++/OSSharedPtr.h>
31#include <libkern/OSSerializeBinary.h>
fe8ab488
A
32#include <libkern/c++/OSContainers.h>
33#include <libkern/c++/OSLib.h>
34#include <libkern/c++/OSDictionary.h>
35#include <libkern/OSSerializeBinary.h>
f427ee49 36#include <libkern/c++/OSSharedPtr.h>
fe8ab488
A
37
38#include <IOKit/IOLib.h>
39
40/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
41
42#if 0
0a7de745 43#define DEBG(fmt, args ...) { kprintf(fmt, args); }
fe8ab488 44#else
0a7de745 45#define DEBG(fmt, args ...) {}
fe8ab488
A
46#endif
47
48/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49
0a7de745
A
50OSSerialize *
51OSSerialize::binaryWithCapacity(unsigned int inCapacity,
52 Editor editor, void * reference)
fe8ab488
A
53{
54 OSSerialize *me;
55
0a7de745 56 if (inCapacity < sizeof(uint32_t)) {
cb323159 57 return NULL;
0a7de745 58 }
fe8ab488 59 me = OSSerialize::withCapacity(inCapacity);
0a7de745 60 if (!me) {
cb323159 61 return NULL;
0a7de745 62 }
fe8ab488 63
0a7de745
A
64 me->binary = true;
65 me->endCollection = true;
66 me->editor = editor;
67 me->editRef = reference;
fe8ab488
A
68
69 bcopy(kOSSerializeBinarySignature, &me->data[0], sizeof(kOSSerializeBinarySignature));
70 me->length = sizeof(kOSSerializeBinarySignature);
71
0a7de745 72 return me;
fe8ab488
A
73}
74
0a7de745
A
75bool
76OSSerialize::addBinary(const void * bits, size_t size)
fe8ab488 77{
0a7de745
A
78 unsigned int newCapacity;
79 size_t alignSize;
fe8ab488 80
0a7de745
A
81 if (os_add_overflow(size, 3, &alignSize)) {
82 return false;
83 }
d190cdc3 84 alignSize &= ~3L;
0a7de745
A
85 if (os_add_overflow(length, alignSize, &newCapacity)) {
86 return false;
87 }
88 if (newCapacity >= capacity) {
89 newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement;
90 if (newCapacity < capacity) {
91 return false;
92 }
93 if (newCapacity > ensureCapacity(newCapacity)) {
94 return false;
95 }
96 }
fe8ab488
A
97
98 bcopy(bits, &data[length], size);
99 length += alignSize;
0a7de745
A
100
101 return true;
fe8ab488
A
102}
103
cb323159
A
104void
105OSSerialize::setIndexed(bool index __unused)
106{
107 assert(index && !indexData);
108 indexData = OSData::withCapacity(256);
109 assert(indexData);
110}
111
0a7de745
A
112bool
113OSSerialize::addBinaryObject(const OSMetaClassBase * o, uint32_t key,
f427ee49 114 const void * bits, uint32_t size,
cb323159 115 uint32_t * startCollection)
fe8ab488 116{
0a7de745
A
117 unsigned int newCapacity;
118 size_t alignSize;
cb323159 119 size_t headerSize;
fe8ab488 120
0a7de745 121 // add to tag array
39037602 122 tags->setObject(o);
fe8ab488 123
cb323159
A
124 headerSize = sizeof(key);
125 if (indexData) {
126 uint32_t offset = length;
127 if (startCollection) {
128 *startCollection = offset;
129 headerSize += sizeof(uint32_t);
130 }
131 offset /= sizeof(uint32_t);
132 indexData->appendBytes(&offset, sizeof(offset));
133 }
134
135 if (os_add3_overflow(size, headerSize, 3, &alignSize)) {
0a7de745
A
136 return false;
137 }
d190cdc3 138 alignSize &= ~3L;
0a7de745
A
139 if (os_add_overflow(length, alignSize, &newCapacity)) {
140 return false;
141 }
142 if (newCapacity >= capacity) {
143 newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement;
144 if (newCapacity < capacity) {
145 return false;
146 }
147 if (newCapacity > ensureCapacity(newCapacity)) {
148 return false;
149 }
150 }
151
152 if (endCollection) {
153 endCollection = false;
154 key |= kOSSerializeEndCollecton;
155 }
fe8ab488
A
156
157 bcopy(&key, &data[length], sizeof(key));
cb323159 158 bcopy(bits, &data[length + headerSize], size);
fe8ab488 159 length += alignSize;
0a7de745
A
160
161 return true;
fe8ab488
A
162}
163
cb323159
A
164void
165OSSerialize::endBinaryCollection(uint32_t startCollection)
166{
167 uint32_t clength;
168
169 if (!indexData) {
170 return;
171 }
172
173 assert(length > startCollection);
174 if (length <= startCollection) {
175 return;
176 }
177
178 clength = length - startCollection;
179 assert(!(clength & 3));
180 clength /= sizeof(uint32_t);
181
182 memcpy(&data[startCollection + sizeof(uint32_t)], &clength, sizeof(clength));
183}
184
0a7de745
A
185bool
186OSSerialize::binarySerialize(const OSMetaClassBase *o)
cb323159
A
187{
188 bool ok;
189 uint32_t header;
190
191 ok = binarySerializeInternal(o);
192 if (!ok) {
193 return ok;
194 }
195
196 if (indexData) {
197 header = indexData->getLength() / sizeof(uint32_t);
198 assert(header <= kOSSerializeDataMask);
199 header <<= 8;
200 header |= kOSSerializeIndexedBinarySignature;
201
202 memcpy(&data[0], &header, sizeof(header));
203 }
204
205 return ok;
206}
207
208bool
209OSSerialize::binarySerializeInternal(const OSMetaClassBase *o)
fe8ab488 210{
0a7de745
A
211 OSDictionary * dict;
212 OSArray * array;
213 OSSet * set;
214 OSNumber * num;
215 OSSymbol * sym;
216 OSString * str;
217 OSData * ldata;
218 OSBoolean * boo;
fe8ab488 219
39037602 220 unsigned int tagIdx;
cb323159 221 uint32_t i, key, startCollection;
f427ee49 222 uint32_t len;
0a7de745 223 bool ok;
fe8ab488 224
39037602 225 tagIdx = tags->getNextIndexOfObject(o, 0);
fe8ab488 226 // does it exist?
0a7de745 227 if (-1U != tagIdx) {
cb323159
A
228 if (indexData) {
229 assert(indexData->getLength() > (tagIdx * sizeof(uint32_t)));
230 tagIdx = ((const uint32_t *)indexData->getBytesNoCopy())[tagIdx];
231 assert(tagIdx <= kOSSerializeDataMask);
232 }
39037602 233 key = (kOSSerializeObject | tagIdx);
0a7de745
A
234 if (endCollection) {
235 endCollection = false;
236 key |= kOSSerializeEndCollecton;
fe8ab488
A
237 }
238 ok = addBinary(&key, sizeof(key));
0a7de745 239 return ok;
fe8ab488
A
240 }
241
0a7de745 242 if ((dict = OSDynamicCast(OSDictionary, o))) {
fe8ab488 243 key = (kOSSerializeDictionary | dict->count);
cb323159 244 ok = addBinaryObject(o, key, NULL, 0, &startCollection);
0a7de745 245 for (i = 0; ok && (i < dict->count);) {
fe8ab488
A
246 const OSSymbol * dictKey;
247 const OSMetaClassBase * dictValue;
cb323159 248 const OSMetaClassBase * nvalue = NULL;
fe8ab488 249
39037602
A
250 dictKey = dict->dictionary[i].key;
251 dictValue = dict->dictionary[i].value;
fe8ab488 252 i++;
0a7de745 253 if (editor) {
fe8ab488 254 dictValue = nvalue = (*editor)(editRef, this, dict, dictKey, dictValue);
0a7de745
A
255 if (!dictValue) {
256 dictValue = dict;
257 }
fe8ab488
A
258 }
259 ok = binarySerialize(dictKey);
0a7de745
A
260 if (!ok) {
261 break;
262 }
fe8ab488
A
263 endCollection = (i == dict->count);
264 ok = binarySerialize(dictValue);
0a7de745
A
265 if (!ok) {
266 ok = dictValue->serialize(this);
267 }
268 if (nvalue) {
269 nvalue->release();
270 }
fe8ab488 271// if (!ok) ok = binarySerialize(kOSBooleanFalse);
0a7de745 272 }
cb323159 273 endBinaryCollection(startCollection);
0a7de745 274 } else if ((array = OSDynamicCast(OSArray, o))) {
fe8ab488 275 key = (kOSSerializeArray | array->count);
cb323159 276 ok = addBinaryObject(o, key, NULL, 0, &startCollection);
0a7de745 277 for (i = 0; ok && (i < array->count);) {
fe8ab488
A
278 i++;
279 endCollection = (i == array->count);
0a7de745
A
280 ok = binarySerialize(array->array[i - 1]);
281 if (!ok) {
282 ok = array->array[i - 1]->serialize(this);
283 }
fe8ab488 284// if (!ok) ok = binarySerialize(kOSBooleanFalse);
0a7de745 285 }
cb323159 286 endBinaryCollection(startCollection);
0a7de745 287 } else if ((set = OSDynamicCast(OSSet, o))) {
fe8ab488 288 key = (kOSSerializeSet | set->members->count);
cb323159 289 ok = addBinaryObject(o, key, NULL, 0, &startCollection);
0a7de745 290 for (i = 0; ok && (i < set->members->count);) {
fe8ab488
A
291 i++;
292 endCollection = (i == set->members->count);
0a7de745
A
293 ok = binarySerialize(set->members->array[i - 1]);
294 if (!ok) {
295 ok = set->members->array[i - 1]->serialize(this);
296 }
fe8ab488 297// if (!ok) ok = binarySerialize(kOSBooleanFalse);
0a7de745 298 }
cb323159 299 endBinaryCollection(startCollection);
0a7de745 300 } else if ((num = OSDynamicCast(OSNumber, o))) {
fe8ab488 301 key = (kOSSerializeNumber | num->size);
cb323159 302 ok = addBinaryObject(o, key, &num->value, sizeof(num->value), NULL);
0a7de745 303 } else if ((boo = OSDynamicCast(OSBoolean, o))) {
fe8ab488 304 key = (kOSSerializeBoolean | (kOSBooleanTrue == boo));
cb323159 305 ok = addBinaryObject(o, key, NULL, 0, NULL);
0a7de745 306 } else if ((sym = OSDynamicCast(OSSymbol, o))) {
fe8ab488
A
307 len = (sym->getLength() + 1);
308 key = (kOSSerializeSymbol | len);
cb323159 309 ok = addBinaryObject(o, key, sym->getCStringNoCopy(), len, NULL);
0a7de745 310 } else if ((str = OSDynamicCast(OSString, o))) {
cb323159 311 len = (str->getLength() + ((indexData != NULL) ? 1 : 0));
fe8ab488 312 key = (kOSSerializeString | len);
cb323159 313 ok = addBinaryObject(o, key, str->getCStringNoCopy(), len, NULL);
0a7de745 314 } else if ((ldata = OSDynamicCast(OSData, o))) {
39037602 315 len = ldata->getLength();
0a7de745
A
316 if (ldata->reserved && ldata->reserved->disableSerialization) {
317 len = 0;
318 }
fe8ab488 319 key = (kOSSerializeData | len);
cb323159 320 ok = addBinaryObject(o, key, ldata->getBytesNoCopy(), len, NULL);
0a7de745
A
321 } else {
322 return false;
fe8ab488 323 }
fe8ab488 324
0a7de745 325 return ok;
fe8ab488
A
326}
327
328/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
329
0a7de745
A
330#define setAtIndex(v, idx, o) \
331 if (idx >= v##Capacity) \
332 { \
333 if (v##Capacity >= v##CapacityMax) ok = false; \
334 else \
335 { \
336 uint32_t ncap = v##Capacity + 64; \
337 typeof(v##Array) nbuf = (typeof(v##Array)) kalloc_container(ncap * sizeof(o)); \
338 if (!nbuf) ok = false; \
339 else \
340 { \
341 if (v##Array) \
342 { \
343 bcopy(v##Array, nbuf, v##Capacity * sizeof(o)); \
344 kfree(v##Array, v##Capacity * sizeof(o)); \
345 } \
346 v##Array = nbuf; \
347 v##Capacity = ncap; \
348 } \
349 } \
350 } \
fe8ab488
A
351 if (ok) v##Array[idx] = o;
352
353/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
354
355OSObject *
356OSUnserializeBinary(const char *buffer, size_t bufferSize, OSString **errorString)
357{
358 OSObject ** objsArray;
359 uint32_t objsCapacity;
0a7de745 360 enum { objsCapacityMax = 16 * 1024 * 1024 };
fe8ab488
A
361 uint32_t objsIdx;
362
363 OSObject ** stackArray;
364 uint32_t stackCapacity;
d190cdc3 365 enum { stackCapacityMax = 64 };
fe8ab488
A
366 uint32_t stackIdx;
367
0a7de745
A
368 OSObject * result;
369 OSObject * parent;
370 OSDictionary * dict;
371 OSArray * array;
372 OSSet * set;
373 OSDictionary * newDict;
374 OSArray * newArray;
375 OSSet * newSet;
376 OSObject * o;
377 OSSymbol * sym;
378 OSString * str;
379
380 size_t bufferPos;
381 const uint32_t * next;
cb323159 382 uint32_t key, len, wordLen, length;
0a7de745
A
383 bool end, newCollect, isRef;
384 unsigned long long value;
cb323159 385 bool ok, indexed, hasLength;
0a7de745 386
cb323159 387 indexed = false;
0a7de745 388 if (errorString) {
cb323159 389 *errorString = NULL;
0a7de745 390 }
cb323159 391
0a7de745
A
392 if (bufferSize < sizeof(kOSSerializeBinarySignature)) {
393 return NULL;
394 }
cb323159
A
395 if (kOSSerializeIndexedBinarySignature == (((const uint8_t *) buffer)[0])) {
396 indexed = true;
397 } else if (0 != strcmp(kOSSerializeBinarySignature, buffer)) {
0a7de745
A
398 return NULL;
399 }
400 if (3 & ((uintptr_t) buffer)) {
401 return NULL;
402 }
cb323159 403
fe8ab488 404 bufferPos = sizeof(kOSSerializeBinarySignature);
0a7de745 405 next = (typeof(next))(((uintptr_t) buffer) + bufferPos);
fe8ab488
A
406
407 DEBG("---------OSUnserializeBinary(%p)\n", buffer);
408
409 objsArray = stackArray = NULL;
410 objsIdx = objsCapacity = 0;
411 stackIdx = stackCapacity = 0;
412
cb323159
A
413 result = NULL;
414 parent = NULL;
415 dict = NULL;
416 array = NULL;
417 set = NULL;
418 sym = NULL;
fe8ab488
A
419
420 ok = true;
0a7de745 421 while (ok) {
fe8ab488 422 bufferPos += sizeof(*next);
0a7de745
A
423 if (!(ok = (bufferPos <= bufferSize))) {
424 break;
425 }
fe8ab488 426 key = *next++;
cb323159 427 length = 0;
fe8ab488 428
0a7de745
A
429 len = (key & kOSSerializeDataMask);
430 wordLen = (len + 3) >> 2;
fe8ab488 431 end = (0 != (kOSSerializeEndCollecton & key));
0a7de745 432 DEBG("key 0x%08x: 0x%04x, %d\n", key, len, end);
fe8ab488 433
cb323159
A
434 newCollect = isRef = hasLength = false;
435 o = NULL; newDict = NULL; newArray = NULL; newSet = NULL;
0a7de745
A
436
437 switch (kOSSerializeTypeMask & key) {
438 case kOSSerializeDictionary:
439 o = newDict = OSDictionary::withCapacity(len);
440 newCollect = (len != 0);
cb323159 441 hasLength = indexed;
0a7de745
A
442 break;
443 case kOSSerializeArray:
444 o = newArray = OSArray::withCapacity(len);
445 newCollect = (len != 0);
cb323159 446 hasLength = indexed;
0a7de745
A
447 break;
448 case kOSSerializeSet:
449 o = newSet = OSSet::withCapacity(len);
450 newCollect = (len != 0);
cb323159 451 hasLength = indexed;
0a7de745
A
452 break;
453
454 case kOSSerializeObject:
455 if (len >= objsIdx) {
456 break;
457 }
458 o = objsArray[len];
459 isRef = true;
460 break;
461
462 case kOSSerializeNumber:
463 bufferPos += sizeof(long long);
464 if (bufferPos > bufferSize) {
fe8ab488 465 break;
0a7de745
A
466 }
467 if ((len != 32) && (len != 64) && (len != 16) && (len != 8)) {
468 break;
469 }
470 value = next[1];
471 value <<= 32;
472 value |= next[0];
473 o = OSNumber::withNumber(value, len);
474 next += 2;
475 break;
476
477 case kOSSerializeSymbol:
478 bufferPos += (wordLen * sizeof(uint32_t));
479 if (bufferPos > bufferSize) {
480 break;
481 }
482 if (len < 2) {
483 break;
484 }
485 if (0 != ((const char *)next)[len - 1]) {
486 break;
487 }
488 o = (OSObject *) OSSymbol::withCString((const char *) next);
489 next += wordLen;
490 break;
491
492 case kOSSerializeString:
493 bufferPos += (wordLen * sizeof(uint32_t));
494 if (bufferPos > bufferSize) {
495 break;
496 }
497 o = OSString::withStringOfLength((const char *) next, len);
498 next += wordLen;
499 break;
500
501 case kOSSerializeData:
502 bufferPos += (wordLen * sizeof(uint32_t));
503 if (bufferPos > bufferSize) {
504 break;
505 }
506 o = OSData::withBytes(next, len);
507 next += wordLen;
508 break;
fe8ab488 509
0a7de745
A
510 case kOSSerializeBoolean:
511 o = (len ? kOSBooleanTrue : kOSBooleanFalse);
512 break;
513
514 default:
515 break;
fe8ab488
A
516 }
517
cb323159 518 if (!(ok = (o != NULL))) {
0a7de745
A
519 break;
520 }
fe8ab488 521
cb323159
A
522 if (hasLength) {
523 bufferPos += sizeof(*next);
524 if (!(ok = (bufferPos <= bufferSize))) {
f427ee49 525 o->release();
cb323159
A
526 break;
527 }
528 length = *next++;
529 }
530
0a7de745 531 if (!isRef) {
fe8ab488 532 setAtIndex(objs, objsIdx, o);
0a7de745
A
533 if (!ok) {
534 o->release();
535 break;
536 }
fe8ab488
A
537 objsIdx++;
538 }
539
0a7de745
A
540 if (dict) {
541 if (!sym) {
542 sym = (OSSymbol *) o;
543 } else {
544 str = sym;
39037602 545 sym = OSDynamicCast(OSSymbol, sym);
0a7de745
A
546 if (!sym && (str = OSDynamicCast(OSString, str))) {
547 sym = const_cast<OSSymbol *>(OSSymbol::withString(str));
cb323159 548 ok = (sym != NULL);
0a7de745
A
549 if (!ok) {
550 break;
551 }
3e170ce0 552 }
39037602 553 DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName());
0a7de745
A
554 if (o != dict) {
555 ok = dict->setObject(sym, o);
556 }
557 if (sym && (sym != str)) {
558 sym->release();
559 }
cb323159 560 sym = NULL;
fe8ab488 561 }
0a7de745
A
562 } else if (array) {
563 ok = array->setObject(o);
564 } else if (set) {
565 ok = set->setObject(o);
566 } else if (result) {
567 ok = false;
568 } else {
569 assert(!parent);
570 result = o;
fe8ab488
A
571 }
572
0a7de745
A
573 if (!ok) {
574 break;
575 }
fe8ab488 576
0a7de745 577 if (end) {
cb323159 578 parent = NULL;
0a7de745
A
579 }
580 if (newCollect) {
581 stackIdx++;
582 setAtIndex(stack, stackIdx, parent);
583 if (!ok) {
584 break;
585 }
fe8ab488
A
586 DEBG("++stack[%d] %p\n", stackIdx, parent);
587 parent = o;
588 dict = newDict;
589 array = newArray;
590 set = newSet;
591 end = false;
592 }
593
0a7de745
A
594 if (end) {
595 while (stackIdx) {
596 parent = stackArray[stackIdx];
597 DEBG("--stack[%d] %p\n", stackIdx, parent);
598 stackIdx--;
599 if (parent) {
600 break;
601 }
602 }
603 if (!parent) {
604 break;
605 }
cb323159
A
606 set = NULL;
607 dict = NULL;
608 array = NULL;
0a7de745
A
609 if (!(dict = OSDynamicCast(OSDictionary, parent))) {
610 if (!(array = OSDynamicCast(OSArray, parent))) {
cb323159 611 ok = (NULL != (set = OSDynamicCast(OSSet, parent)));
0a7de745 612 }
fe8ab488
A
613 }
614 }
615 }
616 DEBG("ret %p\n", result);
617
0a7de745 618 if (!ok) {
cb323159 619 result = NULL;
0a7de745 620 }
fe8ab488 621
0a7de745 622 if (objsCapacity) {
cb323159 623 for (len = (result != NULL); len < objsIdx; len++) {
0a7de745
A
624 objsArray[len]->release();
625 }
626 kfree(objsArray, objsCapacity * sizeof(*objsArray));
627 }
628 if (stackCapacity) {
629 kfree(stackArray, stackCapacity * sizeof(*stackArray));
630 }
39037602 631
0a7de745 632 return result;
39037602 633}
f427ee49
A
634
635OSObject*
636OSUnserializeXML(
637 const char * buffer,
638 OSSharedPtr<OSString>& errorString)
639{
640 OSString* errorStringRaw = NULL;
641 OSObject* result = OSUnserializeXML(buffer, &errorStringRaw);
642 errorString.reset(errorStringRaw, OSNoRetain);
643 return result;
644}
645
646OSObject*
647OSUnserializeXML(
648 const char * buffer,
649 size_t bufferSize,
650 OSSharedPtr<OSString> &errorString)
651{
652 OSString* errorStringRaw = NULL;
653 OSObject* result = OSUnserializeXML(buffer, bufferSize, &errorStringRaw);
654 errorString.reset(errorStringRaw, OSNoRetain);
655 return result;
656}
657
658OSObject*
659OSUnserializeBinary(const char *buffer, size_t bufferSize, OSSharedPtr<OSString>& errorString)
660{
661 OSString* errorStringRaw = NULL;
662 OSObject* result = OSUnserializeBinary(buffer, bufferSize, &errorStringRaw);
663 errorString.reset(errorStringRaw, OSNoRetain);
664 return result;
665}
666
667OSObject*
668OSUnserialize(const char *buffer, OSSharedPtr<OSString>& errorString)
669{
670 OSString* errorStringRaw = NULL;
671 OSObject* result = OSUnserialize(buffer, &errorStringRaw);
672 errorString.reset(errorStringRaw, OSNoRetain);
673 return result;
674}