Chameleon Applications

Chameleon Applications Svn Source Tree

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

Source at commit 169 created 13 years 6 months ago.
By ifabio, Update my branch folder with last changes: - Update all language with last _title and _description (need translation). - Comment (disabled) in the main make the option for advanced pkg - Added Options (from scrax's basics folder) - Added Chameleon Prefpanel - Correct some minus error - Comment (disabled) the copy for the resourced folder.
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: 169