Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazi/i386/libsaio/xml.c

1/*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
7 * Reserved.
8 * The contents of this file constitute Original Code as defined in and
9 * are subject to the Apple Public Source License Version 2.0 (the
10 * "License"). You may not use this file except in compliance with the
11 * License. Please obtain a copy of the License at
12 * http://www.apple.com/publicsource and read it before using this file.
13 *
14 * This Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25//#include "libsaio.h"
26#include "bootstruct.h"
27#include "sl.h"
28#include "xml.h"
29
30//getchar(); //getc(); Azi: getc stuff
31
32//Azi: start - this code is unchanged since boot132, were it was exactly the same
33// as the one in drivers.c. Atm, the one in drivers.c has some more stuff; it could be
34// added on xml.h which is included on drivers.c and here??
35struct Module {
36 struct Module *nextModule;
37 long willLoad;
38 TagPtr dict;
39 char *plistAddr;
40 long plistLength;
41 char *driverPath;
42};
43typedef struct Module Module, *ModulePtr;
44
45struct DriverInfo {
46 char *plistAddr;
47 long plistLength;
48 void *moduleAddr;
49 long moduleLength;
50};
51typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
52
53#define kDriverPackageSignature1 'MKXT'
54#define kDriverPackageSignature2 'MOSX'
55
56struct DriversPackage {
57 unsigned long signature1;
58 unsigned long signature2;
59 unsigned long length;
60 unsigned long alder32;
61 unsigned long version;
62 unsigned long numDrivers;
63 unsigned long reserved1;
64 unsigned long reserved2;
65};
66typedef struct DriversPackage DriversPackage;
67
68enum {
69 kCFBundleType2,
70 kCFBundleType3
71};
72//Azi: end ---//---
73
74#define USEMALLOC 1
75#define DOFREE 1
76
77static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty);
78static long ParseTagKey(char *buffer, TagPtr *tag);
79static long ParseTagString(char *buffer, TagPtr *tag);
80static long ParseTagInteger(char *buffer, TagPtr *tag);
81static long ParseTagData(char *buffer, TagPtr *tag);
82static long ParseTagDate(char *buffer, TagPtr *tag);
83static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);
84static long GetNextTag(char *buffer, char **tag, long *start);
85static long FixDataMatchingTag(char *buffer, char *tag);
86static TagPtr NewTag(void);
87static char *NewSymbol(char *string);
88#if DOFREE
89static void FreeSymbol(char *string);
90#endif
91
92
93//==========================================================================
94// XMLGetProperty
95
96TagPtr
97XMLGetProperty( TagPtr dict, const char * key )
98{
99 TagPtr tagList, tag;
100
101 if (dict->type != kTagTypeDict) return 0;
102
103 tag = 0;
104 tagList = dict->tag;
105 while (tagList)
106 {
107 tag = tagList;
108 tagList = tag->tagNext;
109
110 if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;
111
112 if (!strcmp(tag->string, key)) return tag->tag;
113 }
114
115 return 0;
116}
117
118/* Function for basic XML character entities parsing */
119
120char*
121XMLDecode(const char* src)
122{
123 typedef const struct XMLEntity {
124 const char* name;
125 size_t nameLen;
126 char value;
127 } XMLEntity;
128
129 /* This is ugly, but better than specifying the lengths by hand */
130 #define _e(str,c) {str,sizeof(str)-1,c}
131 const XMLEntity ents[] = {
132 _e("quot;",'"'), _e("apos;",'\''),
133 _e("lt;", '<'), _e("gt;", '>'),
134 _e("amp;", '&')
135 };
136
137 size_t len;
138 const char *s;
139 char *out, *o;
140
141 if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) )
142 return 0;
143
144 o = out;
145 s = src;
146 while (s <= src+len) /* Make sure the terminator is also copied */
147 {
148 if ( *s == '&' )
149 {
150 bool entFound = false;
151 int i;
152
153 s++;
154 for ( i = 0; i < sizeof(ents); i++)
155 {
156 if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 )
157 {
158 entFound = true;
159 break;
160 }
161 }
162 if ( entFound )
163 {
164 *o++ = ents[i].value;
165 s += ents[i].nameLen;
166 continue;
167 }
168 }
169
170 *o++ = *s++;
171 }
172
173 return out;
174}
175
176#if UNUSED
177//==========================================================================
178// XMLParseFile
179// Expects to see one dictionary in the XML file.
180// Puts the first dictionary it finds in the
181// tag pointer and returns 0, or returns -1 if not found.
182//
183long
184XMLParseFile( char * buffer, TagPtr * dict )
185{
186 long length, pos;
187 TagPtr tag;
188 pos = 0;
189
190 while (1)
191 {
192 length = XMLParseNextTag(buffer + pos, &tag);
193 if (length == -1) break;
194
195 pos += length;
196
197 if (tag == 0) continue;
198 if (tag->type == kTagTypeDict) break;
199
200 XMLFreeTag(tag);
201 }
202 if (length < 0) {
203 return -1;
204 }
205 *dict = tag;
206 return 0;
207}
208#endif /* UNUSED */
209
210//==========================================================================
211// ParseNextTag
212
213long
214XMLParseNextTag( char * buffer, TagPtr * tag )
215{
216long length, pos;
217char * tagName;
218
219 length = GetNextTag(buffer, &tagName, 0);
220 if (length == -1) return -1;
221
222pos = length;
223 if (!strncmp(tagName, kXMLTagPList, 6))
224 {
225 length = 0;
226 }
227 else if (!strcmp(tagName, kXMLTagDict))
228 {
229 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
230 }
231 else if (!strcmp(tagName, kXMLTagDict "/"))
232 {
233 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);
234 }
235 else if (!strcmp(tagName, kXMLTagKey))
236 {
237 length = ParseTagKey(buffer + pos, tag);
238 }
239 else if (!strcmp(tagName, kXMLTagString))
240 {
241 length = ParseTagString(buffer + pos, tag);
242 }
243 else if (!strcmp(tagName, kXMLTagInteger))
244 {
245 length = ParseTagInteger(buffer + pos, tag);
246 }
247 else if (!strcmp(tagName, kXMLTagData))
248 {
249 length = ParseTagData(buffer + pos, tag);
250 }
251 else if (!strcmp(tagName, kXMLTagDate))
252 {
253 length = ParseTagDate(buffer + pos, tag);
254 }
255 else if (!strcmp(tagName, kXMLTagFalse))
256 {
257 length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);
258 }
259 else if (!strcmp(tagName, kXMLTagTrue))
260 {
261 length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
262 }
263 else if (!strcmp(tagName, kXMLTagArray))
264 {
265 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
266 }
267 else if (!strcmp(tagName, kXMLTagArray "/"))
268 {
269 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
270 }
271 else
272 {
273 *tag = 0;
274 length = 0;
275 }
276
277 if (length == -1) return -1;
278
279 return pos + length;
280}
281
282//==========================================================================
283// ParseTagList
284
285static long
286ParseTagList( char * buffer, TagPtr * tag, long type, long empty )
287{
288long length, pos;
289TagPtr tagList, tmpTag;
290
291 tagList = 0;
292 pos = 0;
293
294 if (!empty)
295 {
296 while (1)
297 {
298 length = XMLParseNextTag(buffer + pos, &tmpTag);
299 if (length == -1) break;
300
301 pos += length;
302
303 if (tmpTag == 0) break;
304 tmpTag->tagNext = tagList;
305 tagList = tmpTag;
306 }
307
308 if (length == -1)
309 {
310 XMLFreeTag(tagList);
311 return -1;
312 }
313 }
314
315 tmpTag = NewTag();
316 if (tmpTag == 0)
317 {
318 XMLFreeTag(tagList);
319 return -1;
320 }
321
322 tmpTag->type = type;
323 tmpTag->string = 0;
324 tmpTag->tag = tagList;
325 tmpTag->tagNext = 0;
326
327 *tag = tmpTag;
328
329 return pos;
330}
331
332//==========================================================================
333// ParseTagKey
334
335static long
336ParseTagKey( char * buffer, TagPtr * tag )
337{
338 long length, length2;
339 char *string;
340 TagPtr tmpTag, subTag;
341
342 length = FixDataMatchingTag(buffer, kXMLTagKey);
343 if (length == -1) return -1;
344
345 length2 = XMLParseNextTag(buffer + length, &subTag);
346 if (length2 == -1) return -1;
347
348 tmpTag = NewTag();
349 if (tmpTag == 0)
350 {
351 XMLFreeTag(subTag);
352 return -1;
353 }
354
355 string = NewSymbol(buffer);
356 if (string == 0)
357 {
358 XMLFreeTag(subTag);
359 XMLFreeTag(tmpTag);
360 return -1;
361 }
362
363 tmpTag->type = kTagTypeKey;
364 tmpTag->string = string;
365 tmpTag->tag = subTag;
366 tmpTag->tagNext = 0;
367
368 *tag = tmpTag;
369
370 return length + length2;
371}
372
373//==========================================================================
374// ParseTagString
375
376static long
377ParseTagString( char * buffer, TagPtr * tag )
378{
379 long length;
380 char * string;
381 TagPtr tmpTag;
382
383 length = FixDataMatchingTag(buffer, kXMLTagString);
384 if (length == -1) return -1;
385
386 tmpTag = NewTag();
387 if (tmpTag == 0) return -1;
388
389 string = NewSymbol(buffer);
390 if (string == 0)
391 {
392 XMLFreeTag(tmpTag);
393 return -1;
394 }
395
396 tmpTag->type = kTagTypeString;
397 tmpTag->string = string;
398 tmpTag->tag = 0;
399 tmpTag->tagNext = 0;
400
401 *tag = tmpTag;
402 return length;
403}
404
405//==========================================================================
406// ParseTagInteger
407
408static long
409ParseTagInteger( char * buffer, TagPtr * tag )
410{
411 long length, integer;
412 TagPtr tmpTag;
413
414 length = FixDataMatchingTag(buffer, kXMLTagInteger);
415 if (length == -1) return -1;
416
417 tmpTag = NewTag();
418 if (tmpTag == 0) return -1;
419
420 integer = 0;
421
422 tmpTag->type = kTagTypeInteger;
423 tmpTag->string = (char *)integer;
424 tmpTag->tag = 0;
425 tmpTag->tagNext = 0;
426
427 *tag = tmpTag;
428
429 return length;
430}
431
432//==========================================================================
433// ParseTagData
434
435static long
436ParseTagData( char * buffer, TagPtr * tag )
437{
438 long length;
439 TagPtr tmpTag;
440
441 length = FixDataMatchingTag(buffer, kXMLTagData);
442 if (length == -1) return -1;
443
444 tmpTag = NewTag();
445 if (tmpTag == 0) return -1;
446
447 tmpTag->type = kTagTypeData;
448 tmpTag->string = 0;
449 tmpTag->tag = 0;
450 tmpTag->tagNext = 0;
451
452 *tag = tmpTag;
453
454 return length;
455}
456
457//==========================================================================
458// ParseTagDate
459
460static long
461ParseTagDate( char * buffer, TagPtr * tag )
462{
463 long length;
464 TagPtr tmpTag;
465
466 length = FixDataMatchingTag(buffer, kXMLTagDate);
467 if (length == -1) return -1;
468
469 tmpTag = NewTag();
470 if (tmpTag == 0) return -1;
471
472 tmpTag->type = kTagTypeDate;
473 tmpTag->string = 0;
474 tmpTag->tag = 0;
475 tmpTag->tagNext = 0;
476
477 *tag = tmpTag;
478
479 return length;
480}
481
482//==========================================================================
483// ParseTagBoolean
484
485static long
486ParseTagBoolean( char * buffer, TagPtr * tag, long type )
487{
488 TagPtr tmpTag;
489
490 tmpTag = NewTag();
491 if (tmpTag == 0) return -1;
492
493 tmpTag->type = type;
494 tmpTag->string = 0;
495 tmpTag->tag = 0;
496 tmpTag->tagNext = 0;
497
498 *tag = tmpTag;
499
500 return 0;
501}
502
503//==========================================================================
504// GetNextTag
505
506static long
507GetNextTag( char * buffer, char ** tag, long * start )
508{
509 long cnt, cnt2;
510
511 if (tag == 0) return -1;
512
513 // Find the start of the tag.
514 cnt = 0;
515 while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
516 if (buffer[cnt] == '\0') return -1;
517
518 // Find the end of the tag.
519 cnt2 = cnt + 1;
520 while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
521 if (buffer[cnt2] == '\0') return -1;
522
523 // Fix the tag data.
524 *tag = buffer + cnt + 1;
525 buffer[cnt2] = '\0';
526 if (start) *start = cnt;
527
528 return cnt2 + 1;
529}
530
531//==========================================================================
532// FixDataMatchingTag
533// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
534// Returns the length of the data found, counting the end tag,
535// or -1 if the end tag was not found.
536
537static long
538FixDataMatchingTag( char * buffer, char * tag )
539{
540 long length, start, stop;
541 char * endTag;
542
543 start = 0;
544 while (1)
545 {
546 length = GetNextTag(buffer + start, &endTag, &stop);
547 if (length == -1) return -1;
548
549 if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break;
550 start += length;
551 }
552
553 buffer[start + stop] = '\0';
554
555 return start + length;
556}
557
558//==========================================================================
559// NewTag
560
561#define kTagsPerBlock (0x1000)
562
563static TagPtr gTagsFree;
564
565static TagPtr
566NewTag( void )
567{
568long cnt;
569TagPtr tag;
570
571 if (gTagsFree == 0)
572 {
573 tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag));
574 if (tag == 0) return 0;
575
576 // Initalize the new tags.
577 for (cnt = 0; cnt < kTagsPerBlock; cnt++)
578 {
579 tag[cnt].type = kTagTypeNone;
580 tag[cnt].string = 0;
581 tag[cnt].tag = 0;
582 tag[cnt].tagNext = tag + cnt + 1;
583 }
584 tag[kTagsPerBlock - 1].tagNext = 0;
585
586 gTagsFree = tag;
587 }
588
589 tag = gTagsFree;
590 gTagsFree = tag->tagNext;
591
592 return tag;
593}
594
595//==========================================================================
596// XMLFreeTag
597
598void
599XMLFreeTag( TagPtr tag )
600{
601#if DOFREE
602 if (tag == 0) return;
603
604 if (tag->string) FreeSymbol(tag->string);
605
606 XMLFreeTag(tag->tag);
607 XMLFreeTag(tag->tagNext);
608
609 // Clear and free the tag.
610 tag->type = kTagTypeNone;
611 tag->string = 0;
612 tag->tag = 0;
613 tag->tagNext = gTagsFree;
614 gTagsFree = tag;
615#else
616 return;
617#endif
618}
619
620//==========================================================================
621// Symbol object.
622
623struct Symbol
624{
625 long refCount;
626 struct Symbol *next;
627 char string[];
628};
629typedef struct Symbol Symbol, *SymbolPtr;
630
631static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol);
632
633static SymbolPtr gSymbolsHead;
634
635//==========================================================================
636// NewSymbol
637
638static char *
639NewSymbol( char * string )
640{
641static SymbolPtr lastGuy = 0;
642SymbolPtr symbol;
643
644 // Look for string in the list of symbols.
645 symbol = FindSymbol(string, 0);
646
647 // Add the new symbol.
648 if (symbol == 0)
649 {
650 symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
651 if (symbol == 0) //return 0;
652 stop("NULL symbol!");
653
654 // Set the symbol's data.
655 symbol->refCount = 0;
656 strcpy(symbol->string, string);
657
658 // Add the symbol to the list.
659 symbol->next = gSymbolsHead;
660 gSymbolsHead = symbol;
661 }
662
663 // Update the refCount and return the string.
664 symbol->refCount++;
665
666 if (lastGuy && lastGuy->next != 0) stop("last guy not last!");
667 return symbol->string;
668}
669
670//==========================================================================
671// FreeSymbol
672
673#if DOFREE
674static void
675FreeSymbol( char * string )
676{
677 SymbolPtr symbol, prev;
678prev = 0;
679
680 // Look for string in the list of symbols.
681 symbol = FindSymbol(string, &prev);
682 if (symbol == 0) return;
683
684 // Update the refCount.
685 symbol->refCount--;
686
687 if (symbol->refCount != 0) return;
688
689 // Remove the symbol from the list.
690 if (prev != 0) prev->next = symbol->next;
691 else gSymbolsHead = symbol->next;
692
693 // Free the symbol's memory.
694 free(symbol);
695}
696#endif
697
698//==========================================================================
699// FindSymbol
700
701static SymbolPtr
702FindSymbol( char * string, SymbolPtr * prevSymbol )
703{
704 SymbolPtr symbol, prev;
705
706 symbol = gSymbolsHead;
707 prev = 0;
708
709 while (symbol != 0) {
710 if (!strcmp(symbol->string, string)) break;
711
712 prev = symbol;
713 symbol = symbol->next;
714 }
715
716 if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;
717
718 return symbol;
719}
720

Archive Download this file

Revision: 1026