Chameleon Applications

Chameleon Applications Svn Source Tree

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

Source at commit 307 created 12 years 11 months ago.
By ifabio, merge changes from trunk (929). Also merge the module changes from Azimutz branche (fix compile error) Also edited the info.plist into AHCIPortInjector.kext: http://forum.voodooprojects.org/index.php/topic,1170.0.html
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
70struct Module {
71 struct Module *nextModule;
72 long willLoad;
73 TagPtr dict;
74 char *plistAddr;
75 long plistLength;
76 char *driverPath;
77};
78typedef struct Module Module, *ModulePtr;
79
80struct DriverInfo {
81 char *plistAddr;
82 long plistLength;
83 void *moduleAddr;
84 long moduleLength;
85};
86typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
87
88#define kDriverPackageSignature1 'MKXT'
89#define kDriverPackageSignature2 'MOSX'
90
91struct DriversPackage {
92 unsigned long signature1;
93 unsigned long signature2;
94 unsigned long length;
95 unsigned long adler32;
96 unsigned long version;
97 unsigned long numDrivers;
98 unsigned long reserved1;
99 unsigned long reserved2;
100};
101typedef struct DriversPackage DriversPackage;
102
103enum {
104 kCFBundleType2,
105 kCFBundleType3
106};
107
108
109#define USEMALLOC 1
110#define DOFREE 1
111
112static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty);
113static long ParseTagKey(char *buffer, TagPtr *tag);
114static long ParseTagString(char *buffer, TagPtr *tag);
115static long ParseTagInteger(char *buffer, TagPtr *tag);
116static long ParseTagData(char *buffer, TagPtr *tag);
117static long ParseTagDate(char *buffer, TagPtr *tag);
118static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);
119static long GetNextTag(char *buffer, char **tag, long *start);
120static long FixDataMatchingTag(char *buffer, char *tag);
121static TagPtr NewTag(void);
122static char *NewSymbol(char *string);
123#if DOFREE
124static void FreeSymbol(char *string);
125#endif
126
127
128//==========================================================================
129// XMLGetProperty
130
131TagPtr
132XMLGetProperty( TagPtr dict, const char * key )
133{
134 TagPtr tagList, tag;
135
136 if (dict->type != kTagTypeDict) return 0;
137
138 tag = 0;
139 tagList = dict->tag;
140 while (tagList)
141 {
142 tag = tagList;
143 tagList = tag->tagNext;
144
145 if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;
146
147 if (!strcmp(tag->string, key)) return tag->tag;
148 }
149
150 return 0;
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
271
272 configBuffer = malloc(strlen(buffer)+1);
273 strcpy(configBuffer, buffer);
274
275buffer_start = configBuffer;
276
277 while (1)
278 {
279 length = XMLParseNextTag(configBuffer + pos, &tag);
280 if (length == -1) break;
281
282 pos += length;
283
284 if (tag == 0) continue;
285 if (tag->type == kTagTypeDict) break;
286
287 XMLFreeTag(tag);
288 }
289free(configBuffer);
290if (length < 0) {
291 return -1;
292 }
293 *dict = tag;
294 return pos;
295}
296//#endif /* UNUSED */
297
298//==========================================================================
299// ParseNextTag
300// TODO: cleanup
301long
302XMLParseNextTag( char * buffer, TagPtr * tag )
303{
304long length, pos;
305char * tagName;
306
307length = GetNextTag(buffer, &tagName, 0);
308if (length == -1) return -1;
309
310pos = length;
311if (!strncmp(tagName, kXMLTagPList, 6))
312{
313length = 0;
314}
315/***** dict ****/
316else if (!strcmp(tagName, kXMLTagDict))
317{
318length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
319}
320else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/')
321{
322length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);
323}
324else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " ")))
325{
326length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
327}
328/***** key ****/
329else if (!strcmp(tagName, kXMLTagKey))
330{
331length = ParseTagKey(buffer + pos, tag);
332}
333
334/***** string ****/
335else if (!strcmp(tagName, kXMLTagString))
336{
337length = ParseTagString(buffer + pos, tag);
338}
339else if (!strncmp(tagName, kXMLTagString " ", strlen(kXMLTagString " ")))
340{
341// TODO: save tag if if found
342if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID)))
343{
344// ID=
345int id = 0;
346int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1;
347while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
348tagName[cnt] = 0;
349char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\"");
350while(*val)
351{
352if ((*val >= '0' && *val <= '9'))// 0 - 9
353{
354id = (id * 10) + (*val++ - '0');
355}
356else
357{
358printf("ParseStringID error (0x%x)\n", *val);
359getchar();
360return -1;
361}
362}
363length = ParseTagString(buffer + pos, tag);
364
365SaveRefString(buffer + pos, id);
366}
367else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
368{
369// IDREF=
370int id = 0;
371int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1;
372while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
373tagName[cnt] = 0;
374char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\"");
375while(*val)
376{
377if ((*val >= '0' && *val <= '9'))// 0 - 9
378{
379id = (id * 10) + (*val++ - '0');
380}
381else
382{
383printf("ParseStringIDREF error (0x%x)\n", *val);
384getchar();
385return -1;
386}
387}
388char* str = GetRefString(id);
389
390TagPtr tmpTag = NewTag();
391tmpTag->type = kTagTypeString;
392tmpTag->string = str;
393tmpTag->tag = 0;
394tmpTag->tagNext = 0;
395tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0;
396*tag = tmpTag;
397
398length = 0;
399//printf("Located IDREF, id = %d, string = %s\n", id, str);
400}
401}
402
403/***** integer ****/
404else if (!strcmp(tagName, kXMLTagInteger))
405{
406length = ParseTagInteger(buffer + pos, tag);
407}
408else 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);
427getchar();
428return -1;
429}
430}
431length = ParseTagInteger(buffer + pos, tag);
432
433SaveRefString((*tag)->string, id);
434}
435else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
436{
437// IDREF=
438int id = 0;
439int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1;
440while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
441tagName[cnt] = 0;
442char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\"");
443while(*val)
444{
445if ((*val >= '0' && *val <= '9'))// 0 - 9
446{
447id = (id * 10) + (*val++ - '0');
448}
449else
450{
451printf("ParseStringIDREF error (0x%x)\n", *val);
452getchar();
453return -1;
454}
455}
456int integer = (int)GetRefString(id);
457
458TagPtr tmpTag = NewTag();
459tmpTag->type = kTagTypeInteger;
460tmpTag->string = (char*) integer;
461tmpTag->tag = 0;
462tmpTag->tagNext = 0;
463tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0;
464
465*tag = tmpTag;
466
467length = 0;
468//printf("Located IDREF, id = %d, string = %s\n", id, str);
469}
470else
471{
472length = ParseTagInteger(buffer + pos, tag);
473}
474}
475
476/***** data ****/
477else if (!strcmp(tagName, kXMLTagData))
478{
479length = ParseTagData(buffer + pos, tag);
480}
481else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " ")))
482{
483length = ParseTagData(buffer + pos, tag);
484}
485else if (!strcmp(tagName, kXMLTagDate))
486{
487length = ParseTagDate(buffer + pos, tag);
488}
489
490/***** date ****/
491else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " ")))
492{
493length = ParseTagDate(buffer + pos, tag);
494}
495
496/***** false ****/
497else if (!strcmp(tagName, kXMLTagFalse))
498{
499length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);
500}
501/***** true ****/
502else if (!strcmp(tagName, kXMLTagTrue))
503{
504length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
505}
506
507/***** array ****/
508else if (!strcmp(tagName, kXMLTagArray))
509{
510length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
511}
512else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " ")))
513{
514length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
515}
516else if (!strcmp(tagName, kXMLTagArray "/"))
517{
518length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
519}
520
521/***** unknown ****/
522else
523{
524*tag = 0;
525length = 0;
526}
527
528if (length == -1) return -1;
529
530return pos + length;
531}
532
533//==========================================================================
534// ParseTagList
535
536static long
537ParseTagList( char * buffer, TagPtr * tag, long type, long empty )
538{
539long length, pos;
540TagPtr tagList, tmpTag;
541
542 tagList = 0;
543 pos = 0;
544
545 if (!empty)
546 {
547 while (1)
548 {
549 length = XMLParseNextTag(buffer + pos, &tmpTag);
550 if (length == -1) break;
551
552 pos += length;
553
554 if (tmpTag == 0) break;
555 tmpTag->tagNext = tagList;
556 tagList = tmpTag;
557 }
558
559 if (length == -1)
560 {
561 XMLFreeTag(tagList);
562 return -1;
563 }
564 }
565
566 tmpTag = NewTag();
567 if (tmpTag == 0)
568 {
569 XMLFreeTag(tagList);
570 return -1;
571 }
572
573 tmpTag->type = type;
574 tmpTag->string = 0;
575 tmpTag->offset = buffer_start ? buffer - buffer_start : 0;
576 tmpTag->tag = tagList;
577 tmpTag->tagNext = 0;
578
579 *tag = tmpTag;
580
581 return pos;
582}
583
584//==========================================================================
585// ParseTagKey
586
587static long
588ParseTagKey( char * buffer, TagPtr * tag )
589{
590 long length, length2;
591 char *string;
592 TagPtr tmpTag, subTag;
593
594 length = FixDataMatchingTag(buffer, kXMLTagKey);
595 if (length == -1) return -1;
596
597 length2 = XMLParseNextTag(buffer + length, &subTag);
598 if (length2 == -1) return -1;
599
600 tmpTag = NewTag();
601 if (tmpTag == 0)
602 {
603 XMLFreeTag(subTag);
604 return -1;
605 }
606
607 string = NewSymbol(buffer);
608 if (string == 0)
609 {
610 XMLFreeTag(subTag);
611 XMLFreeTag(tmpTag);
612 return -1;
613 }
614
615 tmpTag->type = kTagTypeKey;
616 tmpTag->string = string;
617 tmpTag->tag = subTag;
618 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
619 tmpTag->tagNext = 0;
620
621 *tag = tmpTag;
622
623 return length + length2;
624}
625
626//==========================================================================
627// ParseTagString
628
629static long
630ParseTagString( char * buffer, TagPtr * tag )
631{
632 long length;
633 char * string;
634
635 length = FixDataMatchingTag(buffer, kXMLTagString);
636 if (length == -1) return -1;
637
638 TagPtr tmpTag = NewTag();
639 if (tmpTag == 0) return -1;
640
641 string = NewSymbol(buffer);
642 if (string == 0)
643 {
644 XMLFreeTag(tmpTag);
645 return -1;
646 }
647
648 tmpTag->type = kTagTypeString;
649 tmpTag->string = string;
650 tmpTag->tag = 0;
651 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
652 tmpTag->tagNext = 0;
653
654 *tag = tmpTag;
655 return length;
656}
657
658//==========================================================================
659// ParseTagInteger
660
661static long
662ParseTagInteger( char * buffer, TagPtr * tag )
663{
664 long length, integer;
665 bool negative = false;
666 TagPtr tmpTag;
667 char* val = buffer;
668 int size;
669
670if(buffer[0] == '<')
671{
672printf("Warning integer is non existant\n");
673getchar();
674tmpTag = NewTag();
675tmpTag->type = kTagTypeInteger;
676tmpTag->string = 0;
677tmpTag->tag = 0;
678tmpTag->offset = 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);
714getchar();
715return -1;
716}
717}
718}
719else if ( size )// Decimal value
720{
721if (*val == '-')
722{
723negative = true;
724val++;
725size--;
726}
727
728for (integer = 0; size > 0; size--)
729{
730if(*val) // UGLY HACK, fix me.
731{
732if (*val < '0' || *val > '9')
733{
734printf("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer);
735getchar();
736return -1;
737}
738
739integer = (integer * 10) + (*val++ - '0');
740}
741}
742
743if (negative)
744integer = -integer;
745}
746
747 tmpTag->type = kTagTypeInteger;
748tmpTag->string = (char *)integer;
749tmpTag->tag = 0;
750tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
751 tmpTag->tagNext = 0;
752
753 *tag = tmpTag;
754
755 return length;
756}
757
758//==========================================================================
759// ParseTagData
760
761static long
762ParseTagData( char * buffer, TagPtr * tag )
763{
764 long length;
765 TagPtr tmpTag;
766
767 length = FixDataMatchingTag(buffer, kXMLTagData);
768 if (length == -1) return -1;
769
770 tmpTag = NewTag();
771 if (tmpTag == 0) return -1;
772
773//printf("ParseTagData unimplimented\n");
774//printf("Data: %s\n", buffer);
775//getchar();
776
777// TODO: base64 decode
778
779char* string = NewSymbol(buffer);
780 tmpTag->type = kTagTypeData;
781 tmpTag->string = string;
782 tmpTag->tag = 0;
783 tmpTag->offset = buffer_start ? buffer - buffer_start: 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");
807getchar();
808
809 tmpTag->type = kTagTypeDate;
810 tmpTag->string = 0;
811 tmpTag->tag = 0;
812 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
813 tmpTag->tagNext = 0;
814
815 *tag = tmpTag;
816
817 return length;
818}
819
820//==========================================================================
821// ParseTagBoolean
822
823static long
824ParseTagBoolean( char * buffer, TagPtr * tag, long type )
825{
826 TagPtr tmpTag;
827
828 tmpTag = NewTag();
829 if (tmpTag == 0) return -1;
830
831 tmpTag->type = type;
832 tmpTag->string = 0;
833 tmpTag->tag = 0;
834 tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
835 tmpTag->tagNext = 0;
836
837 *tag = tmpTag;
838
839 return 0;
840}
841
842//==========================================================================
843// GetNextTag
844
845static long
846GetNextTag( char * buffer, char ** tag, long * start )
847{
848 long cnt, cnt2;
849
850 if (tag == 0) return -1;
851
852 // Find the start of the tag.
853 cnt = 0;
854 while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;
855 if (buffer[cnt] == '\0') return -1;
856
857 // Find the end of the tag.
858 cnt2 = cnt + 1;
859 while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;
860 if (buffer[cnt2] == '\0') return -1;
861
862 // Fix the tag data.
863 *tag = buffer + cnt + 1;
864 buffer[cnt2] = '\0';
865 if (start) *start = cnt;
866
867 return cnt2 + 1;
868}
869
870//==========================================================================
871// FixDataMatchingTag
872// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
873// Returns the length of the data found, counting the end tag,
874// or -1 if the end tag was not found.
875
876static long
877FixDataMatchingTag( char * buffer, char * tag )
878{
879 long length, start, stop;
880 char * endTag;
881
882 start = 0;
883 while (1)
884 {
885 length = GetNextTag(buffer + start, &endTag, &stop);
886 if (length == -1) return -1;
887
888 if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break;
889 start += length;
890 }
891
892 buffer[start + stop] = '\0';
893
894 return start + length;
895}
896
897//==========================================================================
898// NewTag
899
900#define kTagsPerBlock (0x1000)
901
902static TagPtr gTagsFree;
903
904static TagPtr
905NewTag( void )
906{
907long cnt;
908TagPtr tag;
909
910 if (gTagsFree == 0)
911 {
912#if USEMALLOC
913 tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag));
914#else
915 tag = (TagPtr)AllocateBootXMemory(kTagsPerBlock * sizeof(Tag));
916#endif
917 if (tag == 0) return 0;
918
919 // Initalize the new tags.
920 for (cnt = 0; cnt < kTagsPerBlock; cnt++)
921 {
922 tag[cnt].type = kTagTypeNone;
923 tag[cnt].string = 0;
924 tag[cnt].tag = 0;
925 tag[cnt].tagNext = tag + cnt + 1;
926 }
927 tag[kTagsPerBlock - 1].tagNext = 0;
928
929 gTagsFree = tag;
930 }
931
932 tag = gTagsFree;
933 gTagsFree = tag->tagNext;
934
935 return tag;
936}
937
938//==========================================================================
939// XMLFreeTag
940
941void
942XMLFreeTag( TagPtr tag )
943{
944#if DOFREE
945 if (tag == 0) return;
946
947 if (tag->string) FreeSymbol(tag->string);
948
949 XMLFreeTag(tag->tag);
950 XMLFreeTag(tag->tagNext);
951
952 // Clear and free the tag.
953 tag->type = kTagTypeNone;
954 tag->string = 0;
955 tag->tag = 0;
956 tag->offset = 0;
957 tag->tagNext = gTagsFree;
958 gTagsFree = tag;
959#else
960 return;
961#endif
962}
963
964//==========================================================================
965// Symbol object.
966
967struct Symbol
968{
969 long refCount;
970 struct Symbol *next;
971 char string[];
972};
973typedef struct Symbol Symbol, *SymbolPtr;
974
975static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol);
976
977static SymbolPtr gSymbolsHead;
978
979//==========================================================================
980// NewSymbol
981
982static char *
983NewSymbol( char * string )
984{
985static SymbolPtr lastGuy = 0;
986SymbolPtr symbol;
987
988 // Look for string in the list of symbols.
989 symbol = FindSymbol(string, 0);
990
991 // Add the new symbol.
992 if (symbol == 0)
993 {
994#if USEMALLOC
995 symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
996#else
997 symbol = (SymbolPtr)AllocateBootXMemory(sizeof(Symbol) + 1 + strlen(string));
998#endif
999 if (symbol == 0) //return 0;
1000 stop("NULL symbol!");
1001
1002 // Set the symbol's data.
1003 symbol->refCount = 0;
1004 strcpy(symbol->string, string);
1005
1006 // Add the symbol to the list.
1007 symbol->next = gSymbolsHead;
1008 gSymbolsHead = symbol;
1009 }
1010
1011 // Update the refCount and return the string.
1012 symbol->refCount++;
1013
1014 if (lastGuy && lastGuy->next != 0) stop("last guy not last!");
1015 return symbol->string;
1016}
1017
1018//==========================================================================
1019// FreeSymbol
1020
1021#if DOFREE
1022static void
1023FreeSymbol( char * string )
1024{
1025 SymbolPtr symbol, prev;
1026prev = 0;
1027
1028 // Look for string in the list of symbols.
1029 symbol = FindSymbol(string, &prev);
1030 if (symbol == 0) return;
1031
1032 // Update the refCount.
1033 symbol->refCount--;
1034
1035 if (symbol->refCount != 0) return;
1036
1037 // Remove the symbol from the list.
1038 if (prev != 0) prev->next = symbol->next;
1039 else gSymbolsHead = symbol->next;
1040
1041 // Free the symbol's memory.
1042 free(symbol);
1043}
1044#endif
1045
1046//==========================================================================
1047// FindSymbol
1048
1049static SymbolPtr
1050FindSymbol( char * string, SymbolPtr * prevSymbol )
1051{
1052 SymbolPtr symbol, prev;
1053
1054 symbol = gSymbolsHead;
1055 prev = 0;
1056
1057 while (symbol != 0) {
1058 if (!strcmp(symbol->string, string)) break;
1059
1060 prev = symbol;
1061 symbol = symbol->next;
1062 }
1063
1064 if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;
1065
1066 return symbol;
1067}
1068
1069bool XMLIsType(TagPtr dict, enum xmltype type)
1070{
1071if(!dict) return (type == kTagTypeNone);
1072return (dict->type == type);
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
1083TagPtr XMLCastDict(TagPtr dict)
1084{
1085if(!dict) return NULL;
1086if(dict->type == kTagTypeDict) return dict;
1087else return NULL;
1088}
1089
1090char* XMLCastString(TagPtr dict)
1091{
1092if(!dict) return NULL;
1093
1094if((dict->type == kTagTypeString) ||
1095 (dict->type == kTagTypeKey)) return dict->string;
1096
1097return NULL;
1098}
1099
1100long XMLCastStringOffset(TagPtr dict)
1101{
1102if(dict &&
1103 ((dict->type == kTagTypeString) ||
1104 (dict->type == kTagTypeKey)))
1105{
1106return dict->offset;
1107}
1108else
1109{
1110return -1;
1111}
1112}
1113
1114bool XMLCastBoolean(TagPtr dict)
1115{
1116if(!dict) return false;
1117if(dict->type == kTagTypeTrue) return true;
1118return false;
1119}
1120
1121int XMLCastInteger(TagPtr dict)
1122{
1123if(!dict)
1124{
1125printf("XMLCastInteger: null dict\n");
1126return 0;
1127}
1128if(dict->type == kTagTypeInteger) return (int)(dict->string);
1129return 0;
1130}
1131

Archive Download this file

Revision: 307