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

Archive Download this file

Revision: 1027