|
|
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:
23: /* OSUnserializeXML.y created by rsulack on Tue Oct 12 1999 */
24:
25: // XML parser for unserializing OSContainer objects
26: //
27: // to build :
28: // bison -p OSUnserializeXML OSUnserializeXML.y
29: // sed -e "s/stdio.h/stddef.h/" < OSUnserializeXML.tab.c > OSUnserializeXML.cpp
30: //
31: // when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
32: //
33: //
34: //
35: //
36: //
37: //
38: //
39: // DO NOT EDIT OSUnserializeXML.cpp!
40: //
41: // this means you!
42: //
43: //
44: //
45: //
46: //
47:
48:
49: %{
50: #include <string.h>
51: #include <libkern/c++/OSMetaClass.h>
52: #include <libkern/c++/OSContainers.h>
53: #include <libkern/c++/OSLib.h>
54:
55: typedef struct object {
56: struct object *next;
57: struct object *free;
58: struct object *elements;
59: OSObject *object;
60: const OSSymbol *key; // for dictionary
61: int size;
62: void *data; // for data
63: char *string; // for string & symbol
64: long long number; // for number
65: int idref;
66: } object_t;
67:
68: static int yyparse();
69: static int yyerror(char *s);
70: static int yylex();
71:
72: static object_t * newObject();
73: static void freeObject(object_t *o);
74:
75: static object_t *buildOSDictionary(object_t *);
76: static object_t *buildOSArray(object_t *);
77: static object_t *buildOSSet(object_t *);
78: static object_t *buildOSString(object_t *);
79: static object_t *buildKey(object_t *);
80: static object_t *buildOSData(object_t *);
81: static object_t *buildOSNumber(object_t *);
82: static object_t *buildOSBoolean(object_t *o);
83:
84: static void rememberObject(int, OSObject *);
85: static object_t *retrieveObject(int);
86:
87: // resultant object of parsed text
88: static OSObject *parsedObject;
89:
90: #define YYSTYPE object_t *
91:
92: extern "C" {
93: extern void *kern_os_malloc(size_t size);
94: extern void *kern_os_realloc(void * addr, size_t size);
95: extern void kern_os_free(void * addr);
96:
97: //XXX shouldn't have to define these
98: extern long strtol(const char *, char **, int);
99: extern unsigned long strtoul(const char *, char **, int);
100:
101: } /* extern "C" */
102:
103: #define malloc(s) kern_os_malloc(s)
104: #define realloc(a, s) kern_os_realloc(a, s)
105: #define free(a) kern_os_free(a)
106:
107: %}
108: %token KEY
109: %token NUMBER
110: %token STRING
111: %token DATA
112: %token IDREF
113: %token BOOLEAN
114: %token SYNTAX_ERROR
115: %% /* Grammar rules and actions follow */
116:
117: input: /* empty */ { parsedObject = (OSObject *)NULL; YYACCEPT; }
118: | object { parsedObject = $1->object;
119: $1->object = 0;
120: freeObject($1);
121: YYACCEPT;
122: }
123: | SYNTAX_ERROR {
124: yyerror("syntax error");
125: YYERROR;
126: }
127: ;
128:
129: object: dict { $$ = buildOSDictionary($1); }
130: | array { $$ = buildOSArray($1); }
131: | set { $$ = buildOSSet($1); }
132: | string { $$ = buildOSString($1); }
133: | data { $$ = buildOSData($1); }
134: | number { $$ = buildOSNumber($1); }
135: | boolean { $$ = buildOSBoolean($1); }
136: | idref { $$ = retrieveObject($1->idref);
137: if ($$) {
138: $$->object->retain();
139: } else {
140: yyerror("forward reference detected");
141: YYERROR;
142: }
143: freeObject($1);
144: }
145: ;
146:
147: //------------------------------------------------------------------------------
148:
149: dict: '{' '}' { $$ = $1;
150: $$->elements = NULL;
151: }
152: | '{' pairs '}' { $$ = $1;
153: $$->elements = $2;
154: }
155: ;
156:
157: pairs: pair
158: | pairs pair { $$ = $2;
159: $$->next = $1;
160: }
161: ;
162:
163: pair: key object { $$ = $1;
164: $$->next = NULL;
165: $$->object = $2->object;
166: $2->object = 0;
167: freeObject($2);
168: }
169: ;
170:
171: key: KEY { $$ = buildKey($1); }
172: ;
173:
174: //------------------------------------------------------------------------------
175:
176: array: '(' ')' { $$ = $1;
177: $$->elements = NULL;
178: }
179: | '(' elements ')' { $$ = $1;
180: $$->elements = $2;
181: }
182: ;
183:
184: set: '[' ']' { $$ = $1;
185: $$->elements = NULL;
186: }
187: | '[' elements ']' { $$ = $1;
188: $$->elements = $2;
189: }
190: ;
191:
192: elements: object { $$ = $1;
193: $$->next = NULL;
194: }
195: | elements object { $$ = $2;
196: $$->next = $1;
197: }
198: ;
199:
200: //------------------------------------------------------------------------------
201:
202: number: NUMBER
203: ;
204:
205: data: DATA
206: ;
207:
208: string: STRING
209: ;
210:
211: idref: IDREF
212: ;
213:
214: boolean: BOOLEAN
215: ;
216:
217: %%
218:
219: static int lineNumber = 0;
220: static const char *parseBuffer;
221: static int parseBufferIndex;
222:
223: #define currentChar() (parseBuffer[parseBufferIndex])
224: #define nextChar() (parseBuffer[++parseBufferIndex])
225: #define prevChar() (parseBuffer[parseBufferIndex - 1])
226:
227: #define isSpace(c) ((c) == ' ' || (c) == '\t')
228: #define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
229: #define isDigit(c) ((c) >= '0' && (c) <= '9')
230: #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
231: #define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
232: #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
233:
234: static char yyerror_message[128];
235:
236: int
237: yyerror(char *s) /* Called by yyparse on error */
238: {
239: sprintf(yyerror_message, "OSUnserializeXML: %s near line %d\n", s, lineNumber);
240: return 0;
241: }
242:
243: #define TAG_MAX_LENGTH 32
244: #define TAG_MAX_ATTRIBUTES 32
245: #define TAG_BAD 0
246: #define TAG_START 1
247: #define TAG_END 2
248: #define TAG_EMPTY 3
249: #define TAG_COMMENT 4
250:
251: static int
252: getTag(char tag[TAG_MAX_LENGTH],
253: int *attributeCount,
254: char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH],
255: char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH] )
256: {
257: int length = 0;;
258: int c = currentChar();
259: int tagType = TAG_START;
260:
261: *attributeCount = 0;
262:
263: if (c != '<') return TAG_BAD;
264: c = nextChar(); // skip '<'
265:
266: if (c == '?' || c == '!') {
267: while ((c = nextChar()) != 0) {
268: if (c == '\n') lineNumber++;
269: if (c == '>') {
270: (void)nextChar();
271: return TAG_COMMENT;
272: }
273: }
274: }
275:
276: if (c == '/') {
277: c = nextChar(); // skip '/'
278: tagType = TAG_END;
279: }
280: if (!isAlpha(c)) return TAG_BAD;
281:
282: /* find end of tag while copying it */
283: while (isAlphaNumeric(c)) {
284: tag[length++] = c;
285: c = nextChar();
286: if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
287: }
288:
289: tag[length] = 0;
290:
291: //printf("tag %s, type %d\n", tag, tagType);
292:
293: // look for attributes of the form attribute = "value" ...
294: while ((c != '>') && (c != '/')) {
295: while (isSpace(c)) c = nextChar();
296:
297: length = 0;
298: while (isAlphaNumeric(c)) {
299: attributes[*attributeCount][length++] = c;
300: if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
301: c = nextChar();
302: }
303: attributes[*attributeCount][length] = 0;
304:
305: while (isSpace(c)) c = nextChar();
306:
307: if (c != '=') return TAG_BAD;
308: c = nextChar();
309:
310: while (isSpace(c)) c = nextChar();
311:
312: if (c != '"') return TAG_BAD;
313: c = nextChar();
314: length = 0;
315: while (c != '"') {
316: values[*attributeCount][length++] = c;
317: if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
318: c = nextChar();
319: }
320: values[*attributeCount][length] = 0;
321:
322: c = nextChar(); // skip closing quote
323:
324: //printf(" attribute '%s' = '%s', nextchar = '%c'\n", attributes[*attributeCount], values[*attributeCount], c);
325:
326: (*attributeCount)++;
327: if (*attributeCount >= TAG_MAX_ATTRIBUTES) return TAG_BAD;
328: }
329:
330: if (c == '/') {
331: c = nextChar(); // skip '/'
332: tagType = TAG_EMPTY;
333: }
334: if (c != '>') return TAG_BAD;
335: c = nextChar(); // skip '>'
336:
337: return tagType;
338: }
339:
340: static char *
341: getString()
342: {
343: int c = currentChar();
344:
345: int start, length, i, j;;
346: char * tempString;
347:
348: start = parseBufferIndex;
349: /* find end of string */
350:
351: while (c != 0) {
352: if (c == '\n') lineNumber++;
353: if (c == '<') {
354: break;
355: }
356: c = nextChar();
357: }
358:
359: if (c != '<') return 0;
360:
361: length = parseBufferIndex - start;
362:
363: /* copy to null terminated buffer */
364: tempString = (char *)malloc(length + 1);
365: if (tempString == 0) {
366: printf("OSUnserializeXML: can't alloc temp memory\n");
367: return 0;
368: }
369:
370: // copy out string in tempString
371: // "&" -> '&', "<" -> '<', ">" -> '>'
372:
373: i = j = 0;
374: while (i < length) {
375: c = parseBuffer[start + i++];
376: if (c != '&') {
377: tempString[j++] = c;
378: } else {
379: if ((i+3) > length) goto error;
380: c = parseBuffer[start + i++];
381: if (c == 'l') {
382: if (parseBuffer[start + i++] != 't') goto error;
383: if (parseBuffer[start + i++] != ';') goto error;
384: tempString[j++] = '<';
385: continue;
386: }
387: if (c == 'g') {
388: if (parseBuffer[start + i++] != 't') goto error;
389: if (parseBuffer[start + i++] != ';') goto error;
390: tempString[j++] = '>';
391: continue;
392: }
393: if ((i+3) > length) goto error;
394: if (c == 'a') {
395: if (parseBuffer[start + i++] != 'm') goto error;
396: if (parseBuffer[start + i++] != 'p') goto error;
397: if (parseBuffer[start + i++] != ';') goto error;
398: tempString[j++] = '&';
399: continue;
400: }
401: goto error;
402: }
403: }
404: tempString[j] = 0;
405:
406: //printf("string %s\n", tempString);
407:
408: return tempString;
409:
410: error:
411: if (tempString) free(tempString);
412: return 0;
413: }
414:
415: static long long
416: getNumber()
417: {
418: unsigned long long n = 0;
419: int base = 10;
420: int c = currentChar();
421:
422: if (!isDigit (c)) return 0;
423:
424: if (c == '0') {
425: c = nextChar();
426: if (c == 'x') {
427: base = 16;
428: c = nextChar();
429: }
430: }
431: if (base == 10) {
432: while(isDigit(c)) {
433: n = (n * base + c - '0');
434: c = nextChar();
435: }
436: } else {
437: while(isHexDigit(c)) {
438: if (isDigit(c)) {
439: n = (n * base + c - '0');
440: } else {
441: n = (n * base + 0xa + c - 'a');
442: }
443: c = nextChar();
444: }
445: }
446: //printf("number 0x%x\n", (unsigned long)n);
447: return n;
448: }
449:
450: // taken from CFXMLParsing/CFPropertyList.c
451:
452: static const signed char __CFPLDataDecodeTable[128] = {
453: /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
454: /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
455: /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
456: /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
457: /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
458: /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
459: /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
460: /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
461: /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
462: /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
463: /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
464: /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
465: /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
466: /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
467: /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
468: /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
469: };
470:
471: #define OSDATA_ALLOC_SIZE 4096
472:
473: static void *
474: getData(unsigned int *size)
475: {
476: int numeq = 0, acc = 0, cntr = 0;
477: int tmpbufpos = 0, tmpbuflen = 0;
478: unsigned char *tmpbuf = (unsigned char *)malloc(OSDATA_ALLOC_SIZE);
479:
480: int c = currentChar();
481: *size = 0;
482:
483: while (c != '<') {
484: c &= 0x7f;
485: if (c == 0) {
486: free(tmpbuf);
487: return 0;
488: }
489: if (c == '=') numeq++; else numeq = 0;
490: if (c == '\n') lineNumber++;
491: if (__CFPLDataDecodeTable[c] < 0) {
492: c = nextChar();
493: continue;
494: }
495: cntr++;
496: acc <<= 6;
497: acc += __CFPLDataDecodeTable[c];
498: if (0 == (cntr & 0x3)) {
499: if (tmpbuflen <= tmpbufpos + 2) {
500: tmpbuflen += OSDATA_ALLOC_SIZE;
501: tmpbuf = (unsigned char *)realloc(tmpbuf, tmpbuflen);
502: }
503: tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
504: if (numeq < 2)
505: tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
506: if (numeq < 1)
507: tmpbuf[tmpbufpos++] = acc & 0xff;
508: }
509: c = nextChar();
510: }
511: *size = tmpbufpos;
512: return tmpbuf;
513: }
514:
515: static int
516: yylex()
517: {
518: int c;
519: int tagType;
520: char tag[TAG_MAX_LENGTH];
521: int attributeCount;
522: char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
523: char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
524:
525: if (parseBufferIndex == 0) lineNumber = 1;
526:
527: top:
528: c = currentChar();
529:
530: /* skip white space */
531: if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
532:
533: /* keep track of line number, don't return \n's */
534: if (c == '\n') {
535: lineNumber++;
536: (void)nextChar();
537: goto top;
538: }
539:
540: if (!c || c == ',') {
541: (void)nextChar();
542: return c;
543: }
544:
545: tagType = getTag(tag, &attributeCount, attributes, values);
546: if (tagType == TAG_BAD) return SYNTAX_ERROR;
547: if (tagType == TAG_COMMENT) goto top;
548:
549: // this code handles empty tags, for idrefs we ignore the tag
550: // for this to work all idrefs must be unique across the whole serialization
551: if (tagType == TAG_EMPTY) {
552: if (!strcmp(tag, "true") || !strcmp(tag, "false")) {
553: yylval = newObject();
554: yylval->number = *tag == 't';
555: return BOOLEAN;
556: }
557: for (int i=0; i < attributeCount; i++) {
558: if (!strcmp(attributes[i], "IDREF")) {
559: yylval = newObject();
560: yylval->idref = strtol(values[i], NULL, 0);
561: return IDREF;
562: }
563: }
564: return SYNTAX_ERROR;
565: }
566:
567: // handle allocation and check of "ID" tag up front
568: yylval = newObject();
569: yylval->idref = -1;
570: for (int i=0; i < attributeCount; i++) {
571: if (attributes[i][0] == 'I' && attributes[i][1] == 'D' && !attributes[i][2]) {
572: yylval->idref = strtol(values[i], NULL, 0);
573: }
574: }
575:
576: switch (*tag) {
577: case 'a':
578: if (!strcmp(tag, "array")) {
579: return (tagType == TAG_START) ? '(' : ')';
580: }
581: break;
582: case 'd':
583: if (!strcmp(tag, "dict")) {
584: return (tagType == TAG_START) ? '{' : '}';
585: }
586: if (!strcmp(tag, "data")) {
587: unsigned int size;
588: yylval->data = getData(&size);
589: yylval->size = size;
590: if ((getTag(tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
591: return SYNTAX_ERROR;
592: }
593: return DATA;
594: }
595: break;
596: case 'i':
597: if (!strcmp(tag, "integer")) {
598: yylval->number = getNumber();
599: yylval->size = 64; // default
600: for (int i=0; i < attributeCount; i++) {
601: if (!strcmp(attributes[i], "size")) {
602: yylval->size = strtoul(values[i], NULL, 0);
603: }
604: }
605: if ((getTag(tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
606: return SYNTAX_ERROR;
607: }
608: return NUMBER;
609: }
610: break;
611: case 'k':
612: if (!strcmp(tag, "key")) {
613: yylval->string = getString();
614: if (!yylval->string) {
615: return SYNTAX_ERROR;
616: }
617: if ((getTag(tag, &attributeCount, attributes, values) != TAG_END)
618: || strcmp(tag, "key")) {
619: return SYNTAX_ERROR;
620: }
621: return KEY;
622: }
623: break;
624: case 'p':
625: if (!strcmp(tag, "plist")) {
626: freeObject(yylval);
627: goto top;
628: }
629: break;
630: case 's':
631: if (!strcmp(tag, "string")) {
632: yylval->string = getString();
633: if (!yylval->string) {
634: return SYNTAX_ERROR;
635: }
636: if ((getTag(tag, &attributeCount, attributes, values) != TAG_END)
637: || strcmp(tag, "string")) {
638: return SYNTAX_ERROR;
639: }
640: return STRING;
641: }
642: if (!strcmp(tag, "set")) {
643: if (tagType == TAG_START) {
644: return '[';
645: } else {
646: return ']';
647: }
648: }
649: break;
650:
651: default:
652: // XXX should we ignore invalid tags?
653: return SYNTAX_ERROR;
654: break;
655: }
656:
657: return 0;
658: }
659:
660: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
661: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
662: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
663:
664: // "java" like allocation, if this code hits a syntax error in the
665: // the middle of the parsed string we just bail with pointers hanging
666: // all over place, so this code helps keeps all together
667:
668: static object_t *objects = 0;
669: static object_t *freeObjects = 0;
670:
671: object_t *
672: newObject()
673: {
674: object_t *o;
675:
676: if (freeObjects) {
677: o = freeObjects;
678: freeObjects = freeObjects->next;
679: } else {
680: o = (object_t *)malloc(sizeof(object_t));
681: bzero(o, sizeof(object_t));
682: o->free = objects;
683: objects = o;
684: }
685:
686: return o;
687: }
688:
689: void
690: freeObject(object_t *o)
691: {
692: o->next = freeObjects;
693: freeObjects = o;
694: }
695:
696: void
697: cleanupObjects()
698: {
699: object_t *t, *o = objects;
700:
701: while (o) {
702: if (o->object) {
703: printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
704: o->object->release();
705: }
706: if (o->data) {
707: printf("OSUnserializeXML: freeing object o=%x data=%x\n", (int)o, (int)o->data);
708: free(o->data);
709: }
710: if (o->key) {
711: printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
712: o->key->release();
713: }
714: if (o->string) {
715: printf("OSUnserializeXML: freeing object o=%x string=%x\n", (int)o, (int)o->string);
716: free(o->string);
717: }
718:
719: t = o;
720: o = o->free;
721: free(t);
722: }
723: }
724:
725: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
726: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
727: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
728:
729: static OSDictionary *tags;
730:
731: static void
732: rememberObject(int tag, OSObject *o)
733: {
734: char key[16];
735: sprintf(key, "%u", tag);
736:
737: //printf("remember key %s\n", key);
738:
739: tags->setObject(key, o);
740: }
741:
742: static object_t *
743: retrieveObject(int tag)
744: {
745: char key[16];
746: sprintf(key, "%u", tag);
747:
748: //printf("retrieve key '%s'\n", key);
749:
750: OSObject *ref = tags->getObject(key);
751: if (!ref) return 0;
752:
753: object_t *o = newObject();
754: o->object = ref;
755: return o;
756: }
757:
758: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
759: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
760: // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
761:
762: object_t *
763: buildOSDictionary(object_t * header)
764: {
765: object_t *o, *t;
766: int count = 0;
767:
768: // get count and reverse order
769: o = header->elements;
770: header->elements = 0;
771: while (o) {
772: count++;
773: t = o;
774: o = o->next;
775:
776: t->next = header->elements;
777: header->elements = t;
778: }
779:
780: OSDictionary *d = OSDictionary::withCapacity(count);
781:
782: if (header->idref >= 0) rememberObject(header->idref, d);
783:
784: o = header->elements;
785: while (o) {
786: d->setObject(o->key, o->object);
787: o->object->release();
788: o->object = 0;
789: o->key->release();
790: o->key = 0;
791: t = o;
792: o = o->next;
793: freeObject(t);
794: }
795: o = header;
796: o->object = d;
797: return o;
798: };
799:
800: object_t *
801: buildOSArray(object_t * header)
802: {
803: object_t *o, *t;
804: int count = 0;
805:
806: // get count and reverse order
807: o = header->elements;
808: header->elements = 0;
809: while (o) {
810: count++;
811: t = o;
812: o = o->next;
813:
814: t->next = header->elements;
815: header->elements = t;
816: }
817:
818: OSArray *a = OSArray::withCapacity(count);
819:
820: if (header->idref >= 0) rememberObject(header->idref, a);
821:
822: o = header->elements;
823: while (o) {
824: a->setObject(o->object);
825: o->object->release();
826: o->object = 0;
827: t = o;
828: o = o->next;
829: freeObject(t);
830: }
831: o = header;
832: o->object = a;
833: return o;
834: };
835:
836: object_t *
837: buildOSSet(object_t *o)
838: {
839: o = buildOSArray(o);
840: OSArray *a = (OSArray *)o->object;
841:
842: OSSet *s = OSSet::withArray(a, a->getCapacity());
843:
844: //write over reference created in array
845: if (o->idref >= 0) rememberObject(o->idref, s);
846:
847: a->release();
848: o->object = s;
849: return o;
850: };
851:
852: object_t *
853: buildOSString(object_t *o)
854: {
855: OSString *s = OSString::withCString(o->string);
856:
857: if (o->idref >= 0) rememberObject(o->idref, s);
858:
859: free(o->string);
860: o->string = 0;
861: o->object = s;
862:
863: return o;
864: };
865:
866: object_t *
867: buildKey(object_t *o)
868: {
869: const OSSymbol *s = OSSymbol::withCString(o->string);
870:
871: free(o->string);
872: o->string = 0;
873: o->key = s;
874:
875: return o;
876: };
877:
878: object_t *
879: buildOSData(object_t *o)
880: {
881: OSData *d;
882:
883: if (o->size) {
884: d = OSData::withBytes(o->data, o->size);
885: free(o->data);
886: } else {
887: d = OSData::withCapacity(0);
888: }
889: if (o->idref >= 0) rememberObject(o->idref, d);
890:
891: o->data = 0;
892: o->object = d;
893: return o;
894: };
895:
896: object_t *
897: buildOSNumber(object_t *o)
898: {
899: OSNumber *n = OSNumber::withNumber(o->number, o->size);
900:
901: if (o->idref >= 0) rememberObject(o->idref, n);
902:
903: o->object = n;
904: return o;
905: };
906:
907: object_t *
908: buildOSBoolean(object_t *o)
909: {
910: OSBoolean *b = OSBoolean::withBoolean(o->number != 0);
911: o->object = b;
912: return o;
913: };
914:
915: __BEGIN_DECLS
916: #include <kern/lock.h>
917: __END_DECLS
918:
919: static mutex_t *lock = 0;
920:
921: OSObject*
922: OSUnserializeXML(const char *buffer, OSString **errorString)
923: {
924: OSObject *object;
925:
926: if (!lock) {
927: lock = mutex_alloc(ETAP_IO_AHA);
928: _mutex_lock(lock);
929: } else {
930: _mutex_lock(lock);
931:
932: }
933:
934: objects = 0;
935: freeObjects = 0;
936: yyerror_message[0] = 0; //just in case
937: parseBuffer = buffer;
938: parseBufferIndex = 0;
939: tags = OSDictionary::withCapacity(128);
940: if (yyparse() == 0) {
941: object = parsedObject;
942: if (errorString) *errorString = 0;
943: } else {
944: object = 0;
945: if (errorString)
946: *errorString = OSString::withCString(yyerror_message);
947: }
948:
949: cleanupObjects();
950: tags->release();
951: mutex_unlock(lock);
952:
953: return object;
954: }
955:
956:
957: //
958: //
959: //
960: //
961: //
962: // DO NOT EDIT OSUnserializeXML.cpp!
963: //
964: // this means you!
965: //
966: //
967: //
968: //
969: //
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.