Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/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 "Unknown";
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 alder32;
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; (unsigned)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//==========================================================================
257// XMLParseFile
258// Expects to see one dictionary in the XML file, the final pos will be returned
259// If the pos is not equal to the strlen, then there are multiple dicts
260// Puts the first dictionary it finds in the
261// tag pointer and returns the end of the dic, or returns -1 if not found.
262//
263long
264XMLParseFile( char * buffer, TagPtr * dict )
265{
266 long length, pos;
267 TagPtr tag;
268 pos = 0;
269char *configBuffer;
270
271
272
273 configBuffer = malloc(strlen(buffer)+1);
274 strcpy(configBuffer, buffer);
275
276buffer_start = configBuffer;
277
278 while (1)
279 {
280 length = XMLParseNextTag(configBuffer + pos, &tag);
281 if (length == -1) break;
282
283 pos += length;
284
285 if (tag == 0) continue;
286 if (tag->type == kTagTypeDict) break;
287
288 XMLFreeTag(tag);
289 }
290free(configBuffer);
291if (length < 0) {
292 return -1;
293 }
294 *dict = tag;
295 return pos;
296}
297
298//==========================================================================
299// ParseNextTag
300// TODO: cleanup
301long
302XMLParseNextTag( char * buffer, TagPtr * tag )
303{
304long length, pos;
305char * tagName;
306
307 length = GetNextTag(buffer, &tagName, 0);
308 if (length == -1) return -1;
309
310pos = length;
311 if (!strncmp(tagName, kXMLTagPList, 6))
312 {
313 length = 0;
314 }
315/***** dict ****/
316 else if (!strcmp(tagName, kXMLTagDict))
317 {
318 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
319 }
320 else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/')
321 {
322 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);
323 }
324 else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " ")))
325 {
326 length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
327 }
328/***** key ****/
329 else if (!strcmp(tagName, kXMLTagKey))
330 {
331 length = ParseTagKey(buffer + pos, tag);
332 }
333
334/***** string ****/
335 else if (!strcmp(tagName, kXMLTagString))
336 {
337 length = ParseTagString(buffer + pos, tag);
338 }
339 else 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);
359getc();
360return -1;
361
362}
363
364}
365length = ParseTagString(buffer + pos, tag);
366
367SaveRefString(buffer + pos, id);
368}
369else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
370{
371// IDREF=
372int id = 0;
373int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1;
374while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
375tagName[cnt] = 0;
376char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\"");
377while(*val)
378{
379if ((*val >= '0' && *val <= '9'))// 0 - 9
380{
381id = (id * 10) + (*val++ - '0');
382}
383else
384{
385printf("ParseStringIDREF error (0x%x)\n", *val);
386getc();
387return -1;
388
389}
390
391}
392char* str = GetRefString(id);
393
394TagPtr tmpTag = NewTag();
395tmpTag->type = kTagTypeString;
396tmpTag->string = str;
397tmpTag->tag = 0;
398tmpTag->tagNext = 0;
399tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0;
400*tag = tmpTag;
401
402length = 0;
403//printf("Located IDREF, id = %d, string = %s\n", id, str);
404}
405
406 }
407
408/***** integer ****/
409 else if (!strcmp(tagName, kXMLTagInteger))
410 {
411 length = ParseTagInteger(buffer + pos, tag);
412 }
413 else if (!strncmp(tagName, kXMLTagInteger " ", strlen(kXMLTagInteger " ")))
414 {
415if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID)))
416{
417// ID=
418int id = 0;
419int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1;
420while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
421tagName[cnt] = 0;
422char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\"");
423while(*val)
424{
425if ((*val >= '0' && *val <= '9'))// 0 - 9
426{
427id = (id * 10) + (*val++ - '0');
428}
429else
430{
431printf("ParseIntegerID error (0x%x)\n", *val);
432getc();
433return -1;
434
435}
436
437}
438length = ParseTagInteger(buffer + pos, tag);
439
440SaveRefString((*tag)->string, id);
441}
442else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
443{
444// IDREF=
445int id = 0;
446int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1;
447while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
448tagName[cnt] = 0;
449char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\"");
450while(*val)
451{
452if ((*val >= '0' && *val <= '9'))// 0 - 9
453{
454id = (id * 10) + (*val++ - '0');
455}
456else
457{
458printf("ParseStringIDREF error (0x%x)\n", *val);
459getc();
460return -1;
461
462}
463
464}
465int integer = (int)GetRefString(id);
466
467TagPtr tmpTag = NewTag();
468tmpTag->type = kTagTypeInteger;
469tmpTag->string = (char*) integer;
470tmpTag->tag = 0;
471tmpTag->tagNext = 0;
472tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0;
473
474*tag = tmpTag;
475
476length = 0;
477//printf("Located IDREF, id = %d, string = %s\n", id, str);
478}
479 else
480{
481length = ParseTagInteger(buffer + pos, tag);
482}
483}
484
485/***** data ****/
486 else if (!strcmp(tagName, kXMLTagData))
487 {
488 length = ParseTagData(buffer + pos, tag);
489 }
490else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " ")))
491 {
492 length = ParseTagData(buffer + pos, tag);
493 }
494 else if (!strcmp(tagName, kXMLTagDate))
495 {
496 length = ParseTagDate(buffer + pos, tag);
497 }
498
499/***** date ****/
500else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " ")))
501 {
502 length = ParseTagDate(buffer + pos, tag);
503 }
504
505/***** false ****/
506 else if (!strcmp(tagName, kXMLTagFalse))
507 {
508 length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);
509 }
510/***** true ****/
511 else if (!strcmp(tagName, kXMLTagTrue))
512 {
513 length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
514 }
515
516/***** array ****/
517 else if (!strcmp(tagName, kXMLTagArray))
518 {
519 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
520 }
521else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " ")))
522 {
523 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
524 }
525 else if (!strcmp(tagName, kXMLTagArray "/"))
526 {
527 length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
528 }
529
530/***** unknown ****/
531 else
532 {
533 *tag = 0;
534 length = 0;
535 }
536
537
538 if (length == -1) return -1;
539
540 return pos + length;
541}
542
543//==========================================================================
544// ParseTagList
545
546static long
547ParseTagList( char * buffer, TagPtr * tag, long type, long empty )
548{
549long length, pos;
550TagPtr tagList, tmpTag;
551
552 tagList = 0;
553 pos = 0;
554
555 if (!empty)
556 {
557 while (1)
558 {
559 length = XMLParseNextTag(buffer + pos, &tmpTag);
560 if (length == -1) break;
561
562 pos += length;
563
564 if (tmpTag == 0) break;
565 tmpTag->tagNext = tagList;
566 tagList = tmpTag;
567 }
568
569 if (length == -1)
570 {
571 XMLFreeTag(tagList);
572 return -1;
573 }
574 }
575
576 tmpTag = NewTag();
577 if (tmpTag == 0)
578 {
579 XMLFreeTag(tagList);
580 return -1;
581 }
582
583 tmpTag->type = type;
584 tmpTag->string = 0;
585tmpTag->offset = buffer_start ? buffer - buffer_start : 0;
586 tmpTag->tag = tagList;
587 tmpTag->tagNext = 0;
588
589 *tag = tmpTag;
590
591 return pos;
592}
593
594//==========================================================================
595// ParseTagKey
596
597static long
598ParseTagKey( char * buffer, TagPtr * tag )
599{
600 long length, length2;
601 char *string;
602 TagPtr tmpTag, subTag;
603
604 length = FixDataMatchingTag(buffer, kXMLTagKey);
605 if (length == -1) return -1;
606
607 length2 = XMLParseNextTag(buffer + length, &subTag);
608 if (length2 == -1) return -1;
609
610 tmpTag = NewTag();
611 if (tmpTag == 0)
612 {
613 XMLFreeTag(subTag);
614 return -1;
615 }
616
617 string = NewSymbol(buffer);
618 if (string == 0)
619 {
620 XMLFreeTag(subTag);
621 XMLFreeTag(tmpTag);
622 return -1;
623 }
624
625 tmpTag->type = kTagTypeKey;
626 tmpTag->string = string;
627 tmpTag->tag = subTag;
628tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
629 tmpTag->tagNext = 0;
630
631 *tag = tmpTag;
632
633 return length + length2;
634}
635
636//==========================================================================
637// ParseTagString
638
639static long
640ParseTagString( char * buffer, TagPtr * tag )
641{
642 long length;
643 char * string;
644 TagPtr tmpTag;
645
646 length = FixDataMatchingTag(buffer, kXMLTagString);
647 if (length == -1) return -1;
648
649 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;
662tmpTag->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;
676bool negative = false;
677 TagPtr tmpTag = 0;
678char* val = buffer;
679 int size;
680
681
682if(buffer[0] == '<')
683{
684printf("Warning integer is non existant\n");
685getc();
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;
796tmpTag->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;
825tmpTag->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;
847tmpTag->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;
969tag->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
1082
1083
1084bool XMLIsType(TagPtr dict, enum xmltype type)
1085{
1086if(!dict) return (type == kTagTypeNone);
1087return (dict->type == (long)type);
1088}
1089
1090
1091/*** Cast functions ***/
1092TagPtr XMLCastArray(TagPtr dict)
1093{
1094if(!dict) return NULL;
1095if(dict->type == kTagTypeArray) return dict;
1096else return NULL;
1097}
1098
1099
1100TagPtr XMLCastDict(TagPtr dict)
1101{
1102if(!dict) return NULL;
1103if(dict->type == kTagTypeDict) return dict;
1104else return NULL;
1105}
1106
1107char* XMLCastString(TagPtr dict)
1108{
1109if(!dict) return NULL;
1110
1111if((dict->type == kTagTypeString) ||
1112 (dict->type == kTagTypeKey)) return dict->string;
1113
1114return NULL;
1115}
1116
1117long XMLCastStringOffset(TagPtr dict)
1118{
1119if(dict &&
1120 ((dict->type == kTagTypeString) ||
1121 (dict->type == kTagTypeKey)))
1122{
1123return dict->offset;
1124}
1125else
1126{
1127return -1;
1128}
1129}
1130
1131
1132bool XMLCastBoolean(TagPtr dict)
1133{
1134if(!dict) return false;
1135if(dict->type == kTagTypeTrue) return true;
1136return false;
1137}
1138
1139int XMLCastInteger(TagPtr dict)
1140{
1141if(!dict)
1142{
1143printf("XMLCastInteger: null dict\n");
1144return 0;
1145}
1146if(dict->type == kTagTypeInteger) return (int)(dict->string);
1147return 0;
1148}
1149

Archive Download this file

Revision: 1119