Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazileon/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 "bootstruct.h"
26#include "libsaio.h"
27#include "sl.h"
28#include "xml.h"
29
30struct Module {
31 struct Module *nextModule;
32 long willLoad;
33 TagPtr dict;
34 char *plistAddr;
35 long plistLength;
36 char *driverPath;
37};
38typedef struct Module Module, *ModulePtr;
39
40struct DriverInfo {
41 char *plistAddr;
42 long plistLength;
43 void *moduleAddr;
44 long moduleLength;
45};
46typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
47
48#define kDriverPackageSignature1 'MKXT'
49#define kDriverPackageSignature2 'MOSX'
50
51struct DriversPackage {
52 unsigned long signature1;
53 unsigned long signature2;
54 unsigned long length;
55 unsigned long alder32;
56 unsigned long version;
57 unsigned long numDrivers;
58 unsigned long reserved1;
59 unsigned long reserved2;
60};
61typedef struct DriversPackage DriversPackage;
62
63enum {
64 kCFBundleType2,
65 kCFBundleType3
66};
67
68
69#define USEMALLOC 1
70#define DOFREE 1
71
72static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty);
73static long ParseTagKey(char *buffer, TagPtr *tag);
74static long ParseTagString(char *buffer, TagPtr *tag);
75static long ParseTagInteger(char *buffer, TagPtr *tag);
76static long ParseTagData(char *buffer, TagPtr *tag);
77static long ParseTagDate(char *buffer, TagPtr *tag);
78static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);
79static long GetNextTag(char *buffer, char **tag, long *start);
80static long FixDataMatchingTag(char *buffer, char *tag);
81static TagPtr NewTag(void);
82static char *NewSymbol(char *string);
83#if DOFREE
84static void FreeSymbol(char *string);
85#endif
86
87
88//==========================================================================
89// XMLGetProperty
90
91TagPtr
92XMLGetProperty( TagPtr dict, const char * key )
93{
94 TagPtr tagList, tag;
95
96 if (dict->type != kTagTypeDict) return 0;
97
98 tag = 0;
99 tagList = dict->tag;
100 while (tagList)
101 {
102 tag = tagList;
103 tagList = tag->tagNext;
104
105 if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;
106
107 if (!strcmp(tag->string, key)) return tag->tag;
108 }
109
110 return 0;
111}
112
113
114#if UNUSED
115//==========================================================================
116// XMLParseFile
117// Expects to see one dictionary in the XML file.
118// Puts the first dictionary it finds in the
119// tag pointer and returns 0, or returns -1 if not found.
120//
121long
122XMLParseFile( char * buffer, TagPtr * dict )
123{
124 long length, pos;
125 TagPtr tag;
126 pos = 0;
127
128 while (1)
129 {
130 length = XMLParseNextTag(buffer + pos, &tag);
131 if (length == -1) break;
132
133 pos += length;
134
135 if (tag == 0) continue;
136 if (tag->type == kTagTypeDict) break;
137
138 XMLFreeTag(tag);
139 }
140 if (length < 0) {
141 return -1;
142 }
143 *dict = tag;
144 return 0;
145}
146#endif /* UNUSED */
147
148//==========================================================================
149// ParseNextTag
150
151long
152XMLParseNextTag( char * buffer, TagPtr * tag )
153{
154long length, pos;
155char * tagName;
156
157 length = GetNextTag(buffer, &tagName, 0);
158 if (length == -1) return -1;
159
160pos = length;
161 if (!strncmp(tagName, kXMLTagPList, 6))
162 {
163 length = 0;
164 }
165 else if (!strcmp(tagName, kXMLTagDict))
166 {
167 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
168 }
169 else if (!strcmp(tagName, kXMLTagDict "/"))
170 {
171 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);
172 }
173 else if (!strcmp(tagName, kXMLTagKey))
174 {
175 length = ParseTagKey(buffer + pos, tag);
176 }
177 else if (!strcmp(tagName, kXMLTagString))
178 {
179 length = ParseTagString(buffer + pos, tag);
180 }
181 else if (!strcmp(tagName, kXMLTagInteger))
182 {
183 length = ParseTagInteger(buffer + pos, tag);
184 }
185 else if (!strcmp(tagName, kXMLTagData))
186 {
187 length = ParseTagData(buffer + pos, tag);
188 }
189 else if (!strcmp(tagName, kXMLTagDate))
190 {
191 length = ParseTagDate(buffer + pos, tag);
192 }
193 else if (!strcmp(tagName, kXMLTagFalse))
194 {
195 length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);
196 }
197 else if (!strcmp(tagName, kXMLTagTrue))
198 {
199 length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
200 }
201 else if (!strcmp(tagName, kXMLTagArray))
202 {
203 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
204 }
205 else if (!strcmp(tagName, kXMLTagArray "/"))
206 {
207 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
208 }
209 else
210 {
211 *tag = 0;
212 length = 0;
213 }
214
215 if (length == -1) return -1;
216
217 return pos + length;
218}
219
220//==========================================================================
221// ParseTagList
222
223static long
224ParseTagList( char * buffer, TagPtr * tag, long type, long empty )
225{
226long length, pos;
227TagPtr tagList, tmpTag;
228
229 tagList = 0;
230 pos = 0;
231
232 if (!empty)
233 {
234 while (1)
235 {
236 length = XMLParseNextTag(buffer + pos, &tmpTag);
237 if (length == -1) break;
238
239 pos += length;
240
241 if (tmpTag == 0) break;
242 tmpTag->tagNext = tagList;
243 tagList = tmpTag;
244 }
245
246 if (length == -1)
247 {
248 XMLFreeTag(tagList);
249 return -1;
250 }
251 }
252
253 tmpTag = NewTag();
254 if (tmpTag == 0)
255 {
256 XMLFreeTag(tagList);
257 return -1;
258 }
259
260 tmpTag->type = type;
261 tmpTag->string = 0;
262 tmpTag->tag = tagList;
263 tmpTag->tagNext = 0;
264
265 *tag = tmpTag;
266
267 return pos;
268}
269
270//==========================================================================
271// ParseTagKey
272
273static long
274ParseTagKey( char * buffer, TagPtr * tag )
275{
276 long length, length2;
277 char *string;
278 TagPtr tmpTag, subTag;
279
280 length = FixDataMatchingTag(buffer, kXMLTagKey);
281 if (length == -1) return -1;
282
283 length2 = XMLParseNextTag(buffer + length, &subTag);
284 if (length2 == -1) return -1;
285
286 tmpTag = NewTag();
287 if (tmpTag == 0)
288 {
289 XMLFreeTag(subTag);
290 return -1;
291 }
292
293 string = NewSymbol(buffer);
294 if (string == 0)
295 {
296 XMLFreeTag(subTag);
297 XMLFreeTag(tmpTag);
298 return -1;
299 }
300
301 tmpTag->type = kTagTypeKey;
302 tmpTag->string = string;
303 tmpTag->tag = subTag;
304 tmpTag->tagNext = 0;
305
306 *tag = tmpTag;
307
308 return length + length2;
309}
310
311//==========================================================================
312// ParseTagString
313
314static long
315ParseTagString( char * buffer, TagPtr * tag )
316{
317 long length;
318 char * string;
319 TagPtr tmpTag;
320
321 length = FixDataMatchingTag(buffer, kXMLTagString);
322 if (length == -1) return -1;
323
324 tmpTag = NewTag();
325 if (tmpTag == 0) return -1;
326
327 string = NewSymbol(buffer);
328 if (string == 0)
329 {
330 XMLFreeTag(tmpTag);
331 return -1;
332 }
333
334 tmpTag->type = kTagTypeString;
335 tmpTag->string = string;
336 tmpTag->tag = 0;
337 tmpTag->tagNext = 0;
338
339 *tag = tmpTag;
340 return length;
341}
342
343//==========================================================================
344// ParseTagInteger
345
346static long
347ParseTagInteger( char * buffer, TagPtr * tag )
348{
349 long length, integer;
350 TagPtr tmpTag;
351
352 length = FixDataMatchingTag(buffer, kXMLTagInteger);
353 if (length == -1) return -1;
354
355 tmpTag = NewTag();
356 if (tmpTag == 0) return -1;
357
358 integer = 0;
359
360 tmpTag->type = kTagTypeInteger;
361 tmpTag->string = (char *)integer;
362 tmpTag->tag = 0;
363 tmpTag->tagNext = 0;
364
365 *tag = tmpTag;
366
367 return length;
368}
369
370//==========================================================================
371// ParseTagData
372
373static long
374ParseTagData( char * buffer, TagPtr * tag )
375{
376 long length;
377 TagPtr tmpTag;
378
379 length = FixDataMatchingTag(buffer, kXMLTagData);
380 if (length == -1) return -1;
381
382 tmpTag = NewTag();
383 if (tmpTag == 0) return -1;
384
385 tmpTag->type = kTagTypeData;
386 tmpTag->string = 0;
387 tmpTag->tag = 0;
388 tmpTag->tagNext = 0;
389
390 *tag = tmpTag;
391
392 return length;
393}
394
395//==========================================================================
396// ParseTagDate
397
398static long
399ParseTagDate( char * buffer, TagPtr * tag )
400{
401 long length;
402 TagPtr tmpTag;
403
404 length = FixDataMatchingTag(buffer, kXMLTagDate);
405 if (length == -1) return -1;
406
407 tmpTag = NewTag();
408 if (tmpTag == 0) return -1;
409
410 tmpTag->type = kTagTypeDate;
411 tmpTag->string = 0;
412 tmpTag->tag = 0;
413 tmpTag->tagNext = 0;
414
415 *tag = tmpTag;
416
417 return length;
418}
419
420//==========================================================================
421// ParseTagBoolean
422
423static long
424ParseTagBoolean( char * buffer, TagPtr * tag, long type )
425{
426 TagPtr tmpTag;
427
428 tmpTag = NewTag();
429 if (tmpTag == 0) return -1;
430
431 tmpTag->type = type;
432 tmpTag->string = 0;
433 tmpTag->tag = 0;
434 tmpTag->tagNext = 0;
435
436 *tag = tmpTag;
437
438 return 0;
439}
440
441//==========================================================================
442// GetNextTag
443
444static long
445GetNextTag( char * buffer, char ** tag, long * start )
446{
447 long cnt, cnt2;
448
449 if (tag == 0) return -1;
450
451 // Find the start of the tag.
452 cnt = 0;
453 while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
454 if (buffer[cnt] == '\0') return -1;
455
456 // Find the end of the tag.
457 cnt2 = cnt + 1;
458 while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
459 if (buffer[cnt2] == '\0') return -1;
460
461 // Fix the tag data.
462 *tag = buffer + cnt + 1;
463 buffer[cnt2] = '\0';
464 if (start) *start = cnt;
465
466 return cnt2 + 1;
467}
468
469//==========================================================================
470// FixDataMatchingTag
471// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
472// Returns the length of the data found, counting the end tag,
473// or -1 if the end tag was not found.
474
475static long
476FixDataMatchingTag( char * buffer, char * tag )
477{
478 long length, start, stop;
479 char * endTag;
480
481 start = 0;
482 while (1)
483 {
484 length = GetNextTag(buffer + start, &endTag, &stop);
485 if (length == -1) return -1;
486
487 if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break;
488 start += length;
489 }
490
491 buffer[start + stop] = '\0';
492
493 return start + length;
494}
495
496//==========================================================================
497// NewTag
498
499#define kTagsPerBlock (0x1000)
500
501static TagPtr gTagsFree;
502
503static TagPtr
504NewTag( void )
505{
506long cnt;
507TagPtr tag;
508
509 if (gTagsFree == 0)
510 {
511#if USEMALLOC
512 tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag));
513#else
514 tag = (TagPtr)AllocateBootXMemory(kTagsPerBlock * sizeof(Tag));
515#endif
516 if (tag == 0) return 0;
517
518 // Initalize the new tags.
519 for (cnt = 0; cnt < kTagsPerBlock; cnt++)
520 {
521 tag[cnt].type = kTagTypeNone;
522 tag[cnt].string = 0;
523 tag[cnt].tag = 0;
524 tag[cnt].tagNext = tag + cnt + 1;
525 }
526 tag[kTagsPerBlock - 1].tagNext = 0;
527
528 gTagsFree = tag;
529 }
530
531 tag = gTagsFree;
532 gTagsFree = tag->tagNext;
533
534 return tag;
535}
536
537//==========================================================================
538// XMLFreeTag
539
540void
541XMLFreeTag( TagPtr tag )
542{
543#if DOFREE
544 if (tag == 0) return;
545
546 if (tag->string) FreeSymbol(tag->string);
547
548 XMLFreeTag(tag->tag);
549 XMLFreeTag(tag->tagNext);
550
551 // Clear and free the tag.
552 tag->type = kTagTypeNone;
553 tag->string = 0;
554 tag->tag = 0;
555 tag->tagNext = gTagsFree;
556 gTagsFree = tag;
557#else
558 return;
559#endif
560}
561
562//==========================================================================
563// Symbol object.
564
565struct Symbol
566{
567 long refCount;
568 struct Symbol *next;
569 char string[];
570};
571typedef struct Symbol Symbol, *SymbolPtr;
572
573static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol);
574
575static SymbolPtr gSymbolsHead;
576
577//==========================================================================
578// NewSymbol
579
580static char *
581NewSymbol( char * string )
582{
583static SymbolPtr lastGuy = 0;
584SymbolPtr symbol;
585
586 // Look for string in the list of symbols.
587 symbol = FindSymbol(string, 0);
588
589 // Add the new symbol.
590 if (symbol == 0)
591 {
592#if USEMALLOC
593 symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
594#else
595 symbol = (SymbolPtr)AllocateBootXMemory(sizeof(Symbol) + 1 + strlen(string));
596#endif
597 if (symbol == 0) //return 0;
598 stop("NULL symbol!");
599
600 // Set the symbol's data.
601 symbol->refCount = 0;
602 strcpy(symbol->string, string);
603
604 // Add the symbol to the list.
605 symbol->next = gSymbolsHead;
606 gSymbolsHead = symbol;
607 }
608
609 // Update the refCount and return the string.
610 symbol->refCount++;
611
612 if (lastGuy && lastGuy->next != 0) stop("last guy not last!");
613 return symbol->string;
614}
615
616//==========================================================================
617// FreeSymbol
618
619#if DOFREE
620static void
621FreeSymbol( char * string )
622{
623 SymbolPtr symbol, prev;
624prev = 0;
625
626 // Look for string in the list of symbols.
627 symbol = FindSymbol(string, &prev);
628 if (symbol == 0) return;
629
630 // Update the refCount.
631 symbol->refCount--;
632
633 if (symbol->refCount != 0) return;
634
635 // Remove the symbol from the list.
636 if (prev != 0) prev->next = symbol->next;
637 else gSymbolsHead = symbol->next;
638
639 // Free the symbol's memory.
640 free(symbol);
641}
642#endif
643
644//==========================================================================
645// FindSymbol
646
647static SymbolPtr
648FindSymbol( char * string, SymbolPtr * prevSymbol )
649{
650 SymbolPtr symbol, prev;
651
652 symbol = gSymbolsHead;
653 prev = 0;
654
655 while (symbol != 0) {
656 if (!strcmp(symbol->string, string)) break;
657
658 prev = symbol;
659 symbol = symbol->next;
660 }
661
662 if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;
663
664 return symbol;
665}
666

Archive Download this file

Revision: 399