Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 877