Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/libsaio/xml.c

Source at commit 429 created 13 years 9 months ago.
By meklort, Updated module system. Hooks can now be used within modules when cetaion functions are called in chameleon. Note that onle two hooks currently exist, more need to be added. I also updated the HelloWorld module to use a hook instead of print out right away.
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: 429