|
|
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.