Chameleon

Chameleon Svn Source Tree

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

Source at commit 599 created 13 years 6 months ago.
By meklort, xml bugfixes + hacks
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
30string_ref* ref_strings = NULL;
31
32// TODO: redo the next two functions
33void SaveRefString(char* string, int id)
34{
35//printf("Adding Ref String %d (%s)\n", id, string);
36string_ref* tmp = ref_strings;
37while(tmp)
38{
39if(tmp->id == id)
40{
41tmp->string = malloc(strlen(string+1));
42sprintf(tmp->string, "%s", string);
43return;
44}
45tmp = tmp->next;
46}
47
48string_ref* new_ref = malloc(sizeof(string_ref));
49new_ref->string = malloc(strlen(string)+1);
50sprintf(new_ref->string, "%s", string);
51new_ref->id = id;
52new_ref->next = ref_strings;
53ref_strings = new_ref;
54}
55
56char* GetRefString(int id)
57{
58string_ref* tmp = ref_strings;
59while(tmp)
60{
61if(tmp->id == id) return tmp->string;
62tmp = tmp->next;
63}
64//verbose("Unable to locate Ref String %d\n", id);
65return "Unknown";
66}
67
68
69struct Module {
70 struct Module *nextModule;
71 long willLoad;
72 TagPtr dict;
73 char *plistAddr;
74 long plistLength;
75 char *driverPath;
76};
77typedef struct Module Module, *ModulePtr;
78
79struct DriverInfo {
80 char *plistAddr;
81 long plistLength;
82 void *moduleAddr;
83 long moduleLength;
84};
85typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
86
87#define kDriverPackageSignature1 'MKXT'
88#define kDriverPackageSignature2 'MOSX'
89
90struct DriversPackage {
91 unsigned long signature1;
92 unsigned long signature2;
93 unsigned long length;
94 unsigned long alder32;
95 unsigned long version;
96 unsigned long numDrivers;
97 unsigned long reserved1;
98 unsigned long reserved2;
99};
100typedef struct DriversPackage DriversPackage;
101
102enum {
103 kCFBundleType2,
104 kCFBundleType3
105};
106
107
108#define USEMALLOC 1
109#define DOFREE 1
110
111static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty);
112static long ParseTagKey(char *buffer, TagPtr *tag);
113static long ParseTagString(char *buffer, TagPtr *tag);
114static long ParseTagInteger(char *buffer, TagPtr *tag);
115static long ParseTagData(char *buffer, TagPtr *tag);
116static long ParseTagDate(char *buffer, TagPtr *tag);
117static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);
118static long GetNextTag(char *buffer, char **tag, long *start);
119static long FixDataMatchingTag(char *buffer, char *tag);
120static TagPtr NewTag(void);
121static char *NewSymbol(char *string);
122#if DOFREE
123static void FreeSymbol(char *string);
124#endif
125
126
127//==========================================================================
128// XMLGetProperty
129
130TagPtr
131XMLGetProperty( TagPtr dict, const char * key )
132{
133 TagPtr tagList, tag;
134
135 if (dict->type != kTagTypeDict) return 0;
136
137 tag = 0;
138 tagList = dict->tag;
139 while (tagList)
140 {
141 tag = tagList;
142 tagList = tag->tagNext;
143
144 if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;
145
146 if (!strcmp(tag->string, key)) return tag->tag;
147 }
148
149 return 0;
150}
151
152
153// XMLGetTag(int index)
154
155// XMLTagCount( TagPtr dict )
156int XMLTagCount( TagPtr dict )
157{
158int count = 0;
159TagPtr tagList, tag;
160
161 if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) return 0;
162tag = 0;
163 tagList = dict->tag;
164 while (tagList)
165 {
166tag = tagList;
167 tagList = tag->tagNext;
168
169if (((tag->type != kTagTypeKey) && ((tag->string == 0) || (tag->string[0] == 0)))
170&& (dict->type != kTagTypeArray)// If we are an array, any element is valid
171) continue;
172
173if(tag->type == kTagTypeKey) printf("Located key %s\n", tag->string);
174
175count++;
176 }
177
178return count;
179}
180
181TagPtr XMLGetElement( TagPtr dict, int id )
182{
183if(dict->type != kTagTypeArray) return 0;
184
185int element = 0;
186TagPtr tmp = dict->tag;
187
188while(element < id)
189{
190element++;
191tmp = tmp->tagNext;
192}
193
194return tmp;
195}
196/* Function for basic XML character entities parsing */
197
198char*
199XMLDecode(const char* src)
200{
201 typedef const struct XMLEntity {
202 const char* name;
203 size_t nameLen;
204 char value;
205 } XMLEntity;
206
207 /* This is ugly, but better than specifying the lengths by hand */
208 #define _e(str,c) {str,sizeof(str)-1,c}
209 const XMLEntity ents[] = {
210 _e("quot;",'"'), _e("apos;",'\''),
211 _e("lt;", '<'), _e("gt;", '>'),
212 _e("amp;", '&')
213 };
214
215 size_t len;
216 const char *s;
217 char *out, *o;
218
219 if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) )
220 return 0;
221
222 o = out;
223 s = src;
224 while (s <= src+len) /* Make sure the terminator is also copied */
225 {
226 if ( *s == '&' )
227 {
228 bool entFound = false;
229 int i;
230
231 s++;
232 for ( i = 0; i < sizeof(ents); i++)
233 {
234 if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 )
235 {
236 entFound = true;
237 break;
238 }
239 }
240 if ( entFound )
241 {
242 *o++ = ents[i].value;
243 s += ents[i].nameLen;
244 continue;
245 }
246 }
247
248 *o++ = *s++;
249 }
250
251 return out;
252}
253
254//#if UNUSED
255//==========================================================================
256// XMLParseFile
257// Expects to see one dictionary in the XML file, the final pos will be returned
258// If the pos is not equal to the strlen, then there are multiple dicts
259// Puts the first dictionary it finds in the
260// tag pointer and returns the end of the dic, or returns -1 if not found.
261//
262long
263XMLParseFile( char * buffer, TagPtr * dict )
264{
265 long length, pos;
266 TagPtr tag;
267 pos = 0;
268char *configBuffer;
269
270 configBuffer = malloc(strlen(buffer)+1);
271 strcpy(configBuffer, buffer);
272
273 while (1)
274 {
275 length = XMLParseNextTag(configBuffer + pos, &tag);
276 if (length == -1) break;
277
278 pos += length;
279
280 if (tag == 0) continue;
281 if (tag->type == kTagTypeDict) break;
282
283 XMLFreeTag(tag);
284 }
285free(configBuffer);
286if (length < 0) {
287 return -1;
288 }
289 *dict = tag;
290 return pos;
291}
292//#endif /* UNUSED */
293
294//==========================================================================
295// ParseNextTag
296// TODO: cleanup
297long
298XMLParseNextTag( char * buffer, TagPtr * tag )
299{
300long length, pos;
301char * tagName;
302
303 length = GetNextTag(buffer, &tagName, 0);
304 if (length == -1) return -1;
305
306pos = length;
307 if (!strncmp(tagName, kXMLTagPList, 6))
308 {
309 length = 0;
310 }
311/***** dict ****/
312 else if (!strcmp(tagName, kXMLTagDict))
313 {
314 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
315 }
316 else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/')
317 {
318 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);
319 }
320 else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " ")))
321 {
322 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
323 }
324/***** key ****/
325 else if (!strcmp(tagName, kXMLTagKey))
326 {
327 length = ParseTagKey(buffer + pos, tag);
328 }
329
330/***** string ****/
331 else if (!strcmp(tagName, kXMLTagString))
332 {
333 length = ParseTagString(buffer + pos, tag);
334 }
335 else if (!strncmp(tagName, kXMLTagString " ", strlen(kXMLTagString " ")))
336 {
337// TODO: save tag if if found
338if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID)))
339{
340// ID=
341int id = 0;
342int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1;
343while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
344tagName[cnt] = 0;
345char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\"");
346while(*val)
347{
348if ((*val >= '0' && *val <= '9'))// 0 - 9
349{
350id = (id * 10) + (*val++ - '0');
351}
352else
353{
354printf("ParseStringID error (0x%x)\n", *val);
355getc();
356return -1;
357
358}
359
360}
361length = ParseTagString(buffer + pos, tag);
362
363SaveRefString(buffer + pos, id);
364}
365else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
366{
367// IDREF=
368int id = 0;
369int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1;
370while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
371tagName[cnt] = 0;
372char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\"");
373while(*val)
374{
375if ((*val >= '0' && *val <= '9'))// 0 - 9
376{
377id = (id * 10) + (*val++ - '0');
378}
379else
380{
381printf("ParseStringIDREF error (0x%x)\n", *val);
382getc();
383return -1;
384
385}
386
387}
388char* str = GetRefString(id);
389
390TagPtr tmpTag = NewTag();
391tmpTag->type = kTagTypeString;
392tmpTag->string = str;
393tmpTag->tag = 0;
394tmpTag->tagNext = 0;
395*tag = tmpTag;
396
397length = 0;
398//printf("Located IDREF, id = %d, string = %s\n", id, str);
399}
400
401 }
402
403/***** integer ****/
404 else if (!strcmp(tagName, kXMLTagInteger))
405 {
406 length = ParseTagInteger(buffer + pos, tag);
407 }
408 else if (!strncmp(tagName, kXMLTagInteger " ", strlen(kXMLTagInteger " ")))
409 {
410if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID)))
411{
412// ID=
413int id = 0;
414int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1;
415while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
416tagName[cnt] = 0;
417char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\"");
418while(*val)
419{
420if ((*val >= '0' && *val <= '9'))// 0 - 9
421{
422id = (id * 10) + (*val++ - '0');
423}
424else
425{
426printf("ParseIntegerID error (0x%x)\n", *val);
427getc();
428return -1;
429
430}
431
432}
433length = ParseTagInteger(buffer + pos, tag);
434
435SaveRefString((*tag)->string, id);
436}
437else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
438{
439// IDREF=
440int id = 0;
441int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1;
442while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
443tagName[cnt] = 0;
444char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\"");
445while(*val)
446{
447if ((*val >= '0' && *val <= '9'))// 0 - 9
448{
449id = (id * 10) + (*val++ - '0');
450}
451else
452{
453printf("ParseStringIDREF error (0x%x)\n", *val);
454getc();
455return -1;
456
457}
458
459}
460int integer = (int)GetRefString(id);
461
462TagPtr tmpTag = NewTag();
463tmpTag->type = kTagTypeInteger;
464tmpTag->string = (char*) integer;
465tmpTag->tag = 0;
466tmpTag->tagNext = 0;
467*tag = tmpTag;
468
469length = 0;
470//printf("Located IDREF, id = %d, string = %s\n", id, str);
471}
472 else
473{
474length = ParseTagInteger(buffer + pos, tag);
475}
476}
477
478/***** data ****/
479 else if (!strcmp(tagName, kXMLTagData))
480 {
481 length = ParseTagData(buffer + pos, tag);
482 }
483else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " ")))
484 {
485 length = ParseTagData(buffer + pos, tag);
486 }
487 else if (!strcmp(tagName, kXMLTagDate))
488 {
489 length = ParseTagDate(buffer + pos, tag);
490 }
491
492/***** date ****/
493else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " ")))
494 {
495 length = ParseTagDate(buffer + pos, tag);
496 }
497
498/***** false ****/
499 else if (!strcmp(tagName, kXMLTagFalse))
500 {
501 length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);
502 }
503/***** true ****/
504 else if (!strcmp(tagName, kXMLTagTrue))
505 {
506 length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
507 }
508
509/***** array ****/
510 else if (!strcmp(tagName, kXMLTagArray))
511 {
512 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
513 }
514else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " ")))
515 {
516 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
517 }
518 else if (!strcmp(tagName, kXMLTagArray "/"))
519 {
520 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
521 }
522
523/***** unknown ****/
524 else
525 {
526 *tag = 0;
527 length = 0;
528 }
529
530
531 if (length == -1) return -1;
532
533 return pos + length;
534}
535
536//==========================================================================
537// ParseTagList
538
539static long
540ParseTagList( char * buffer, TagPtr * tag, long type, long empty )
541{
542long length, pos;
543TagPtr tagList, tmpTag;
544
545 tagList = 0;
546 pos = 0;
547
548 if (!empty)
549 {
550 while (1)
551 {
552 length = XMLParseNextTag(buffer + pos, &tmpTag);
553 if (length == -1) break;
554
555 pos += length;
556
557 if (tmpTag == 0) break;
558 tmpTag->tagNext = tagList;
559 tagList = tmpTag;
560 }
561
562 if (length == -1)
563 {
564 XMLFreeTag(tagList);
565 return -1;
566 }
567 }
568
569 tmpTag = NewTag();
570 if (tmpTag == 0)
571 {
572 XMLFreeTag(tagList);
573 return -1;
574 }
575
576 tmpTag->type = type;
577 tmpTag->string = 0;
578 tmpTag->tag = tagList;
579 tmpTag->tagNext = 0;
580
581 *tag = tmpTag;
582
583 return pos;
584}
585
586//==========================================================================
587// ParseTagKey
588
589static long
590ParseTagKey( char * buffer, TagPtr * tag )
591{
592 long length, length2;
593 char *string;
594 TagPtr tmpTag, subTag;
595
596 length = FixDataMatchingTag(buffer, kXMLTagKey);
597 if (length == -1) return -1;
598
599 length2 = XMLParseNextTag(buffer + length, &subTag);
600 if (length2 == -1) return -1;
601
602 tmpTag = NewTag();
603 if (tmpTag == 0)
604 {
605 XMLFreeTag(subTag);
606 return -1;
607 }
608
609 string = NewSymbol(buffer);
610 if (string == 0)
611 {
612 XMLFreeTag(subTag);
613 XMLFreeTag(tmpTag);
614 return -1;
615 }
616
617 tmpTag->type = kTagTypeKey;
618 tmpTag->string = string;
619 tmpTag->tag = subTag;
620 tmpTag->tagNext = 0;
621
622 *tag = tmpTag;
623
624 return length + length2;
625}
626
627//==========================================================================
628// ParseTagString
629
630static long
631ParseTagString( char * buffer, TagPtr * tag )
632{
633 long length;
634 char * string;
635 TagPtr tmpTag;
636
637 length = FixDataMatchingTag(buffer, kXMLTagString);
638 if (length == -1) return -1;
639
640 tmpTag = NewTag();
641 if (tmpTag == 0) return -1;
642
643 string = NewSymbol(buffer);
644 if (string == 0)
645 {
646 XMLFreeTag(tmpTag);
647 return -1;
648 }
649
650 tmpTag->type = kTagTypeString;
651 tmpTag->string = string;
652 tmpTag->tag = 0;
653 tmpTag->tagNext = 0;
654
655 *tag = tmpTag;
656 return length;
657}
658
659//==========================================================================
660// ParseTagInteger
661
662static long
663ParseTagInteger( char * buffer, TagPtr * tag )
664{
665 long length, integer;
666bool negative = false;
667 TagPtr tmpTag;
668char* val = buffer;
669 int size;
670
671
672if(buffer[0] == '<')
673{
674printf("Warning integer is non existant\n");
675getc();
676tmpTag->type = kTagTypeInteger;
677tmpTag->string = 0;
678tmpTag->tag = 0;
679tmpTag->tagNext = 0;
680
681*tag = tmpTag;
682
683return 0;
684}
685
686 size = length = FixDataMatchingTag(buffer, kXMLTagInteger);
687 if (length == -1) return -1;
688
689 tmpTag = NewTag();
690 if (tmpTag == 0) return -1;
691
692 integer = 0;
693
694if(size > 1 && (val[1] == 'x' || val[1] == 'X'))// Hex value
695{
696val += 2;
697while(*val)
698{
699if ((*val >= '0' && *val <= '9'))// 0 - 9
700{
701integer = (integer * 16) + (*val++ - '0');
702}
703else if ((*val >= 'a' && *val <= 'f'))// a - f
704{
705integer = (integer * 16) + (*val++ - 'a' + 10);
706}
707else if ((*val >= 'A' && *val <= 'F'))// A - F
708{
709integer = (integer * 16) + (*val++ - 'a' + 10);
710}
711else
712{
713printf("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer);
714getc();
715return -1;
716
717}
718
719}
720}
721else if ( size )// Decimal value
722{
723if (*val == '-')
724{
725negative = true;
726val++;
727size--;
728}
729
730for (integer = 0; size > 0; size--)
731{
732if(*val) // UGLY HACK, fix me.
733{
734if (*val < '0' || *val > '9')
735{
736printf("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer);
737getc();
738return -1;
739}
740
741integer = (integer * 10) + (*val++ - '0');
742}
743}
744
745if (negative)
746integer = -integer;
747}
748
749 tmpTag->type = kTagTypeInteger;
750tmpTag->string = (char *)integer;
751tmpTag->tag = 0;
752 tmpTag->tagNext = 0;
753
754 *tag = tmpTag;
755
756 return length;
757}
758
759//==========================================================================
760// ParseTagData
761
762static long
763ParseTagData( char * buffer, TagPtr * tag )
764{
765 long length;
766 TagPtr tmpTag;
767
768 length = FixDataMatchingTag(buffer, kXMLTagData);
769 if (length == -1) return -1;
770
771 tmpTag = NewTag();
772 if (tmpTag == 0) return -1;
773
774//printf("ParseTagData unimplimented\n");
775//printf("Data: %s\n", buffer);
776//getc();
777
778// TODO: base64 decode
779
780char* string = NewSymbol(buffer);
781 tmpTag->type = kTagTypeData;
782 tmpTag->string = string;
783 tmpTag->tag = 0;
784 tmpTag->tagNext = 0;
785
786 *tag = tmpTag;
787
788 return length;
789}
790
791//==========================================================================
792// ParseTagDate
793
794static long
795ParseTagDate( char * buffer, TagPtr * tag )
796{
797 long length;
798 TagPtr tmpTag;
799
800 length = FixDataMatchingTag(buffer, kXMLTagDate);
801 if (length == -1) return -1;
802
803 tmpTag = NewTag();
804 if (tmpTag == 0) return -1;
805
806printf("ParseTagDate unimplimented\n");
807getc();
808
809 tmpTag->type = kTagTypeDate;
810 tmpTag->string = 0;
811 tmpTag->tag = 0;
812 tmpTag->tagNext = 0;
813
814 *tag = tmpTag;
815
816 return length;
817}
818
819//==========================================================================
820// ParseTagBoolean
821
822static long
823ParseTagBoolean( char * buffer, TagPtr * tag, long type )
824{
825 TagPtr tmpTag;
826
827 tmpTag = NewTag();
828 if (tmpTag == 0) return -1;
829
830 tmpTag->type = type;
831 tmpTag->string = 0;
832 tmpTag->tag = 0;
833 tmpTag->tagNext = 0;
834
835 *tag = tmpTag;
836
837 return 0;
838}
839
840//==========================================================================
841// GetNextTag
842
843static long
844GetNextTag( char * buffer, char ** tag, long * start )
845{
846 long cnt, cnt2;
847
848 if (tag == 0) return -1;
849
850 // Find the start of the tag.
851 cnt = 0;
852 while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
853 if (buffer[cnt] == '\0') return -1;
854
855 // Find the end of the tag.
856 cnt2 = cnt + 1;
857 while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
858 if (buffer[cnt2] == '\0') return -1;
859
860 // Fix the tag data.
861 *tag = buffer + cnt + 1;
862 buffer[cnt2] = '\0';
863 if (start) *start = cnt;
864
865 return cnt2 + 1;
866}
867
868//==========================================================================
869// FixDataMatchingTag
870// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
871// Returns the length of the data found, counting the end tag,
872// or -1 if the end tag was not found.
873
874static long
875FixDataMatchingTag( char * buffer, char * tag )
876{
877 long length, start, stop;
878 char * endTag;
879
880 start = 0;
881 while (1)
882 {
883 length = GetNextTag(buffer + start, &endTag, &stop);
884 if (length == -1) return -1;
885
886 if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break;
887 start += length;
888 }
889
890 buffer[start + stop] = '\0';
891
892 return start + length;
893}
894
895//==========================================================================
896// NewTag
897
898#define kTagsPerBlock (0x1000)
899
900static TagPtr gTagsFree;
901
902static TagPtr
903NewTag( void )
904{
905long cnt;
906TagPtr tag;
907
908 if (gTagsFree == 0)
909 {
910#if USEMALLOC
911 tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag));
912#else
913 tag = (TagPtr)AllocateBootXMemory(kTagsPerBlock * sizeof(Tag));
914#endif
915 if (tag == 0) return 0;
916
917 // Initalize the new tags.
918 for (cnt = 0; cnt < kTagsPerBlock; cnt++)
919 {
920 tag[cnt].type = kTagTypeNone;
921 tag[cnt].string = 0;
922 tag[cnt].tag = 0;
923 tag[cnt].tagNext = tag + cnt + 1;
924 }
925 tag[kTagsPerBlock - 1].tagNext = 0;
926
927 gTagsFree = tag;
928 }
929
930 tag = gTagsFree;
931 gTagsFree = tag->tagNext;
932
933 return tag;
934}
935
936//==========================================================================
937// XMLFreeTag
938
939void
940XMLFreeTag( TagPtr tag )
941{
942#if DOFREE
943 if (tag == 0) return;
944
945 if (tag->string) FreeSymbol(tag->string);
946
947 XMLFreeTag(tag->tag);
948 XMLFreeTag(tag->tagNext);
949
950 // Clear and free the tag.
951 tag->type = kTagTypeNone;
952 tag->string = 0;
953 tag->tag = 0;
954 tag->tagNext = gTagsFree;
955 gTagsFree = tag;
956#else
957 return;
958#endif
959}
960
961//==========================================================================
962// Symbol object.
963
964struct Symbol
965{
966 long refCount;
967 struct Symbol *next;
968 char string[];
969};
970typedef struct Symbol Symbol, *SymbolPtr;
971
972static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol);
973
974static SymbolPtr gSymbolsHead;
975
976//==========================================================================
977// NewSymbol
978
979static char *
980NewSymbol( char * string )
981{
982static SymbolPtr lastGuy = 0;
983SymbolPtr symbol;
984
985 // Look for string in the list of symbols.
986 symbol = FindSymbol(string, 0);
987
988 // Add the new symbol.
989 if (symbol == 0)
990 {
991#if USEMALLOC
992 symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
993#else
994 symbol = (SymbolPtr)AllocateBootXMemory(sizeof(Symbol) + 1 + strlen(string));
995#endif
996 if (symbol == 0) //return 0;
997 stop("NULL symbol!");
998
999 // Set the symbol's data.
1000 symbol->refCount = 0;
1001 strcpy(symbol->string, string);
1002
1003 // Add the symbol to the list.
1004 symbol->next = gSymbolsHead;
1005 gSymbolsHead = symbol;
1006 }
1007
1008 // Update the refCount and return the string.
1009 symbol->refCount++;
1010
1011 if (lastGuy && lastGuy->next != 0) stop("last guy not last!");
1012 return symbol->string;
1013}
1014
1015//==========================================================================
1016// FreeSymbol
1017
1018#if DOFREE
1019static void
1020FreeSymbol( char * string )
1021{
1022 SymbolPtr symbol, prev;
1023prev = 0;
1024
1025 // Look for string in the list of symbols.
1026 symbol = FindSymbol(string, &prev);
1027 if (symbol == 0) return;
1028
1029 // Update the refCount.
1030 symbol->refCount--;
1031
1032 if (symbol->refCount != 0) return;
1033
1034 // Remove the symbol from the list.
1035 if (prev != 0) prev->next = symbol->next;
1036 else gSymbolsHead = symbol->next;
1037
1038 // Free the symbol's memory.
1039 free(symbol);
1040}
1041#endif
1042
1043//==========================================================================
1044// FindSymbol
1045
1046static SymbolPtr
1047FindSymbol( char * string, SymbolPtr * prevSymbol )
1048{
1049 SymbolPtr symbol, prev;
1050
1051 symbol = gSymbolsHead;
1052 prev = 0;
1053
1054 while (symbol != 0) {
1055 if (!strcmp(symbol->string, string)) break;
1056
1057 prev = symbol;
1058 symbol = symbol->next;
1059 }
1060
1061 if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;
1062
1063 return symbol;
1064}
1065
1066
1067
1068bool XMLIsType(TagPtr dict, enum xmltype type)
1069{
1070if(!dict) return (type == kTagTypeNone);
1071return (dict->type == type);
1072}
1073
1074
1075/*** Cast functions ***/
1076TagPtr XMLCastArray(TagPtr dict)
1077{
1078if(!dict) return NULL;
1079if(dict->type == kTagTypeArray) return dict;
1080else return NULL;
1081}
1082
1083
1084TagPtr XMLCastDict(TagPtr dict)
1085{
1086if(!dict) return NULL;
1087if(dict->type == kTagTypeDict) return dict;
1088else return NULL;
1089}
1090
1091char* XMLCastString(TagPtr dict)
1092{
1093if(!dict) return NULL;
1094
1095if((dict->type == kTagTypeString) ||
1096 (dict->type == kTagTypeKey)) return dict->string;
1097
1098return NULL;
1099}
1100
1101bool XMLCastBoolean(TagPtr dict)
1102{
1103if(!dict) return false;
1104if(dict->type == kTagTypeTrue) return true;
1105return false;
1106}
1107
1108int XMLCastInteger(TagPtr dict)
1109{
1110if(!dict)
1111{
1112printf("XMLCastInteger: null dict\n");
1113return 0;
1114}
1115if(dict->type == kTagTypeInteger) return (int)(dict->string);
1116return 0;
1117}
1118

Archive Download this file

Revision: 599