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

Archive Download this file

Revision: 840