Chameleon Applications

Chameleon Applications Svn Source Tree

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

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

Archive Download this file

Revision: 214