Chameleon Applications

Chameleon Applications Svn Source Tree

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

Source at commit 296 created 12 years 11 months ago.
By ifabio, add i386 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
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 if (length == -1) return -1;
540
541 return pos + length;
542}
543
544//==========================================================================
545// ParseTagList
546
547static long
548ParseTagList( char * buffer, TagPtr * tag, long type, long empty )
549{
550long length, pos;
551TagPtr tagList, tmpTag;
552
553 tagList = 0;
554 pos = 0;
555
556 if (!empty)
557 {
558 while (1)
559 {
560 length = XMLParseNextTag(buffer + pos, &tmpTag);
561 if (length == -1) break;
562
563 pos += length;
564
565 if (tmpTag == 0) break;
566 tmpTag->tagNext = tagList;
567 tagList = tmpTag;
568 }
569
570 if (length == -1)
571 {
572 XMLFreeTag(tagList);
573 return -1;
574 }
575 }
576
577 tmpTag = NewTag();
578 if (tmpTag == 0)
579 {
580 XMLFreeTag(tagList);
581 return -1;
582 }
583
584 tmpTag->type = type;
585 tmpTag->string = 0;
586 tmpTag->offset = buffer_start ? buffer - buffer_start : 0;
587 tmpTag->tag = tagList;
588 tmpTag->tagNext = 0;
589
590 *tag = tmpTag;
591
592 return pos;
593}
594
595//==========================================================================
596// ParseTagKey
597
598static long
599ParseTagKey( char * buffer, TagPtr * tag )
600{
601 long length, length2;
602 char *string;
603 TagPtr tmpTag, subTag;
604
605 length = FixDataMatchingTag(buffer, kXMLTagKey);
606 if (length == -1) return -1;
607
608 length2 = XMLParseNextTag(buffer + length, &subTag);
609 if (length2 == -1) return -1;
610
611 tmpTag = NewTag();
612 if (tmpTag == 0)
613 {
614 XMLFreeTag(subTag);
615 return -1;
616 }
617
618 string = NewSymbol(buffer);
619 if (string == 0)
620 {
621 XMLFreeTag(subTag);
622 XMLFreeTag(tmpTag);
623 return -1;
624 }
625
626 tmpTag->type = kTagTypeKey;
627 tmpTag->string = string;
628 tmpTag->tag = subTag;
629 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
630 tmpTag->tagNext = 0;
631
632 *tag = tmpTag;
633
634 return length + length2;
635}
636
637//==========================================================================
638// ParseTagString
639
640static long
641ParseTagString( char * buffer, TagPtr * tag )
642{
643 long length;
644 char * string;
645
646 length = FixDataMatchingTag(buffer, kXMLTagString);
647 if (length == -1) return -1;
648
649 TagPtr tmpTag = NewTag();
650 if (tmpTag == 0) return -1;
651
652 string = NewSymbol(buffer);
653 if (string == 0)
654 {
655 XMLFreeTag(tmpTag);
656 return -1;
657 }
658
659 tmpTag->type = kTagTypeString;
660 tmpTag->string = string;
661 tmpTag->tag = 0;
662 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
663 tmpTag->tagNext = 0;
664
665 *tag = tmpTag;
666 return length;
667}
668
669//==========================================================================
670// ParseTagInteger
671
672static long
673ParseTagInteger( char * buffer, TagPtr * tag )
674{
675 long length, integer;
676 bool negative = false;
677 TagPtr tmpTag;
678 char* val = buffer;
679 int size;
680
681if(buffer[0] == '<')
682{
683printf("Warning integer is non existant\n");
684getc();
685tmpTag = NewTag();
686tmpTag->type = kTagTypeInteger;
687tmpTag->string = 0;
688tmpTag->tag = 0;
689tmpTag->offset = 0;
690tmpTag->tagNext = 0;
691
692*tag = tmpTag;
693
694return 0;
695}
696
697 size = length = FixDataMatchingTag(buffer, kXMLTagInteger);
698 if (length == -1) return -1;
699
700 tmpTag = NewTag();
701 if (tmpTag == 0) return -1;
702
703 integer = 0;
704
705if(size > 1 && (val[1] == 'x' || val[1] == 'X'))// Hex value
706{
707val += 2;
708while(*val)
709{
710if ((*val >= '0' && *val <= '9'))// 0 - 9
711{
712integer = (integer * 16) + (*val++ - '0');
713}
714else if ((*val >= 'a' && *val <= 'f'))// a - f
715{
716integer = (integer * 16) + (*val++ - 'a' + 10);
717}
718else if ((*val >= 'A' && *val <= 'F'))// A - F
719{
720integer = (integer * 16) + (*val++ - 'a' + 10);
721}
722else
723{
724printf("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer);
725getc();
726return -1;
727
728}
729
730}
731}
732else if ( size )// Decimal value
733{
734if (*val == '-')
735{
736negative = true;
737val++;
738size--;
739}
740
741for (integer = 0; size > 0; size--)
742{
743if(*val) // UGLY HACK, fix me.
744{
745if (*val < '0' || *val > '9')
746{
747printf("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer);
748getc();
749return -1;
750}
751
752integer = (integer * 10) + (*val++ - '0');
753}
754}
755
756if (negative)
757integer = -integer;
758}
759
760 tmpTag->type = kTagTypeInteger;
761tmpTag->string = (char *)integer;
762tmpTag->tag = 0;
763tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
764 tmpTag->tagNext = 0;
765
766 *tag = tmpTag;
767
768 return length;
769}
770
771//==========================================================================
772// ParseTagData
773
774static long
775ParseTagData( char * buffer, TagPtr * tag )
776{
777 long length;
778 TagPtr tmpTag;
779
780 length = FixDataMatchingTag(buffer, kXMLTagData);
781 if (length == -1) return -1;
782
783 tmpTag = NewTag();
784 if (tmpTag == 0) return -1;
785
786//printf("ParseTagData unimplimented\n");
787//printf("Data: %s\n", buffer);
788//getc();
789
790// TODO: base64 decode
791
792char* string = NewSymbol(buffer);
793 tmpTag->type = kTagTypeData;
794 tmpTag->string = string;
795 tmpTag->tag = 0;
796 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
797 tmpTag->tagNext = 0;
798
799 *tag = tmpTag;
800
801 return length;
802}
803
804//==========================================================================
805// ParseTagDate
806
807static long
808ParseTagDate( char * buffer, TagPtr * tag )
809{
810 long length;
811 TagPtr tmpTag;
812
813 length = FixDataMatchingTag(buffer, kXMLTagDate);
814 if (length == -1) return -1;
815
816 tmpTag = NewTag();
817 if (tmpTag == 0) return -1;
818
819printf("ParseTagDate unimplimented\n");
820getc();
821
822 tmpTag->type = kTagTypeDate;
823 tmpTag->string = 0;
824 tmpTag->tag = 0;
825 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
826 tmpTag->tagNext = 0;
827
828 *tag = tmpTag;
829
830 return length;
831}
832
833//==========================================================================
834// ParseTagBoolean
835
836static long
837ParseTagBoolean( char * buffer, TagPtr * tag, long type )
838{
839 TagPtr tmpTag;
840
841 tmpTag = NewTag();
842 if (tmpTag == 0) return -1;
843
844 tmpTag->type = type;
845 tmpTag->string = 0;
846 tmpTag->tag = 0;
847 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
848 tmpTag->tagNext = 0;
849
850 *tag = tmpTag;
851
852 return 0;
853}
854
855//==========================================================================
856// GetNextTag
857
858static long
859GetNextTag( char * buffer, char ** tag, long * start )
860{
861 long cnt, cnt2;
862
863 if (tag == 0) return -1;
864
865 // Find the start of the tag.
866 cnt = 0;
867 while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
868 if (buffer[cnt] == '\0') return -1;
869
870 // Find the end of the tag.
871 cnt2 = cnt + 1;
872 while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
873 if (buffer[cnt2] == '\0') return -1;
874
875 // Fix the tag data.
876 *tag = buffer + cnt + 1;
877 buffer[cnt2] = '\0';
878 if (start) *start = cnt;
879
880 return cnt2 + 1;
881}
882
883//==========================================================================
884// FixDataMatchingTag
885// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
886// Returns the length of the data found, counting the end tag,
887// or -1 if the end tag was not found.
888
889static long
890FixDataMatchingTag( char * buffer, char * tag )
891{
892 long length, start, stop;
893 char * endTag;
894
895 start = 0;
896 while (1)
897 {
898 length = GetNextTag(buffer + start, &endTag, &stop);
899 if (length == -1) return -1;
900
901 if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break;
902 start += length;
903 }
904
905 buffer[start + stop] = '\0';
906
907 return start + length;
908}
909
910//==========================================================================
911// NewTag
912
913#define kTagsPerBlock (0x1000)
914
915static TagPtr gTagsFree;
916
917static TagPtr
918NewTag( void )
919{
920long cnt;
921TagPtr tag;
922
923 if (gTagsFree == 0)
924 {
925#if USEMALLOC
926 tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag));
927#else
928 tag = (TagPtr)AllocateBootXMemory(kTagsPerBlock * sizeof(Tag));
929#endif
930 if (tag == 0) return 0;
931
932 // Initalize the new tags.
933 for (cnt = 0; cnt < kTagsPerBlock; cnt++)
934 {
935 tag[cnt].type = kTagTypeNone;
936 tag[cnt].string = 0;
937 tag[cnt].tag = 0;
938 tag[cnt].tagNext = tag + cnt + 1;
939 }
940 tag[kTagsPerBlock - 1].tagNext = 0;
941
942 gTagsFree = tag;
943 }
944
945 tag = gTagsFree;
946 gTagsFree = tag->tagNext;
947
948 return tag;
949}
950
951//==========================================================================
952// XMLFreeTag
953
954void
955XMLFreeTag( TagPtr tag )
956{
957#if DOFREE
958 if (tag == 0) return;
959
960 if (tag->string) FreeSymbol(tag->string);
961
962 XMLFreeTag(tag->tag);
963 XMLFreeTag(tag->tagNext);
964
965 // Clear and free the tag.
966 tag->type = kTagTypeNone;
967 tag->string = 0;
968 tag->tag = 0;
969 tag->offset = 0;
970 tag->tagNext = gTagsFree;
971 gTagsFree = tag;
972#else
973 return;
974#endif
975}
976
977//==========================================================================
978// Symbol object.
979
980struct Symbol
981{
982 long refCount;
983 struct Symbol *next;
984 char string[];
985};
986typedef struct Symbol Symbol, *SymbolPtr;
987
988static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol);
989
990static SymbolPtr gSymbolsHead;
991
992//==========================================================================
993// NewSymbol
994
995static char *
996NewSymbol( char * string )
997{
998static SymbolPtr lastGuy = 0;
999SymbolPtr symbol;
1000
1001 // Look for string in the list of symbols.
1002 symbol = FindSymbol(string, 0);
1003
1004 // Add the new symbol.
1005 if (symbol == 0)
1006 {
1007#if USEMALLOC
1008 symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
1009#else
1010 symbol = (SymbolPtr)AllocateBootXMemory(sizeof(Symbol) + 1 + strlen(string));
1011#endif
1012 if (symbol == 0) //return 0;
1013 stop("NULL symbol!");
1014
1015 // Set the symbol's data.
1016 symbol->refCount = 0;
1017 strcpy(symbol->string, string);
1018
1019 // Add the symbol to the list.
1020 symbol->next = gSymbolsHead;
1021 gSymbolsHead = symbol;
1022 }
1023
1024 // Update the refCount and return the string.
1025 symbol->refCount++;
1026
1027 if (lastGuy && lastGuy->next != 0) stop("last guy not last!");
1028 return symbol->string;
1029}
1030
1031//==========================================================================
1032// FreeSymbol
1033
1034#if DOFREE
1035static void
1036FreeSymbol( char * string )
1037{
1038 SymbolPtr symbol, prev;
1039prev = 0;
1040
1041 // Look for string in the list of symbols.
1042 symbol = FindSymbol(string, &prev);
1043 if (symbol == 0) return;
1044
1045 // Update the refCount.
1046 symbol->refCount--;
1047
1048 if (symbol->refCount != 0) return;
1049
1050 // Remove the symbol from the list.
1051 if (prev != 0) prev->next = symbol->next;
1052 else gSymbolsHead = symbol->next;
1053
1054 // Free the symbol's memory.
1055 free(symbol);
1056}
1057#endif
1058
1059//==========================================================================
1060// FindSymbol
1061
1062static SymbolPtr
1063FindSymbol( char * string, SymbolPtr * prevSymbol )
1064{
1065 SymbolPtr symbol, prev;
1066
1067 symbol = gSymbolsHead;
1068 prev = 0;
1069
1070 while (symbol != 0) {
1071 if (!strcmp(symbol->string, string)) break;
1072
1073 prev = symbol;
1074 symbol = symbol->next;
1075 }
1076
1077 if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;
1078
1079 return symbol;
1080}
1081
1082bool XMLIsType(TagPtr dict, enum xmltype type)
1083{
1084if(!dict) return (type == kTagTypeNone);
1085return (dict->type == type);
1086}
1087
1088/*** Cast functions ***/
1089TagPtr XMLCastArray(TagPtr dict)
1090{
1091if(!dict) return NULL;
1092if(dict->type == kTagTypeArray) return dict;
1093else return NULL;
1094}
1095
1096TagPtr XMLCastDict(TagPtr dict)
1097{
1098if(!dict) return NULL;
1099if(dict->type == kTagTypeDict) return dict;
1100else return NULL;
1101}
1102
1103char* XMLCastString(TagPtr dict)
1104{
1105if(!dict) return NULL;
1106
1107if((dict->type == kTagTypeString) ||
1108 (dict->type == kTagTypeKey)) return dict->string;
1109
1110return NULL;
1111}
1112
1113long XMLCastStringOffset(TagPtr dict)
1114{
1115if(dict &&
1116 ((dict->type == kTagTypeString) ||
1117 (dict->type == kTagTypeKey)))
1118{
1119return dict->offset;
1120}
1121else
1122{
1123return -1;
1124}
1125}
1126
1127
1128bool XMLCastBoolean(TagPtr dict)
1129{
1130if(!dict) return false;
1131if(dict->type == kTagTypeTrue) return true;
1132return false;
1133}
1134
1135int XMLCastInteger(TagPtr dict)
1136{
1137if(!dict)
1138{
1139printf("XMLCastInteger: null dict\n");
1140return 0;
1141}
1142if(dict->type == kTagTypeInteger) return (int)(dict->string);
1143return 0;
1144}
1145

Archive Download this file

Revision: 296