Chameleon

Chameleon Svn Source Tree

Root/branches/zenith432/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
70struct Module {
71struct Module *nextModule;
72longwillLoad;
73TagPtrdict;
74char*plistAddr;
75longplistLength;
76char*driverPath;
77};
78typedef struct Module Module, *ModulePtr;
79
80struct DriverInfo {
81char*plistAddr;
82longplistLength;
83void*moduleAddr;
84longmoduleLength;
85};
86typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
87
88#define kDriverPackageSignature1 'MKXT'
89#define kDriverPackageSignature2 'MOSX'
90
91struct DriversPackage {
92unsigned long signature1;
93unsigned long signature2;
94unsigned long length;
95unsigned long adler32;
96unsigned long version;
97unsigned long numDrivers;
98unsigned long reserved1;
99unsigned long reserved2;
100};
101typedef struct DriversPackage DriversPackage;
102
103enum {
104kCFBundleType2,
105kCFBundleType3
106};
107
108
109#define DOFREE 1
110
111static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty);
112static long ParseTagKey(char *buffer, TagPtr *tag);
113static long ParseTagString(char *buffer, TagPtr *tag);
114static long ParseTagInteger(char *buffer, TagPtr *tag);
115static long ParseTagData(char *buffer, TagPtr *tag);
116static long ParseTagDate(char *buffer, TagPtr *tag);
117//static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);
118static long GetNextTag(char *buffer, char **tag, long *start);
119static long FixDataMatchingTag(char *buffer, char *tag);
120static TagPtr NewTag(void);
121static char *NewSymbol(char *string);
122#if DOFREE
123static void FreeSymbol(char *string);
124#endif
125
126
127//==========================================================================
128// XMLGetProperty
129
130TagPtr XMLGetProperty(TagPtr dict, const char *key)
131{
132TagPtr tagList, tag;
133
134if (dict->type != kTagTypeDict)
135{
136return 0;
137}
138
139tag = 0;
140tagList = dict->tag;
141while (tagList) {
142tag = tagList;
143tagList = tag->tagNext;
144
145if ((tag->type != kTagTypeKey) || (tag->string == 0))
146{
147continue;
148}
149
150if (!strcmp(tag->string, key))
151{
152return tag->tag;
153}
154}
155return 0;
156}
157
158//==========================================================================
159// XMLGetProperty
160
161TagPtr XMLGetKey( TagPtr dict, int id )
162{
163TagPtr tagList, tag;
164
165if (dict->type != kTagTypeDict)
166{
167return 0;
168}
169
170tag = 0;
171int element = 0;
172tagList = dict->tag;
173while (tagList && element != id)
174{
175tag = tagList;
176tagList = tag->tagNext;
177
178if ((tag->type != kTagTypeKey) || (tag->string == 0))
179{
180continue;
181}
182
183 element++;
184if(id == element)
185{
186return tag;
187}
188
189}
190return 0;
191}
192
193TagPtr XMLGetValueForKey(TagPtr key)
194{
195if (!key || key->type != kTagTypeKey)
196{
197return 0;
198}
199
200return key->tag;
201}
202
203
204// XMLGetTag(int index)
205
206// XMLTagCount( TagPtr dict )
207int XMLTagCount( TagPtr dict )
208{
209int count = 0;
210TagPtr tagList, tag;
211
212if (dict->type != kTagTypeDict && dict->type != kTagTypeArray)
213{
214return 0;
215}
216
217tag = 0;
218tagList = dict->tag;
219while (tagList)
220{
221tag = tagList;
222tagList = tag->tagNext;
223
224if (((tag->type != kTagTypeKey) && ((tag->string == 0) || (tag->string[0] == 0)))
225&& (dict->type != kTagTypeArray)// If we are an array, any element is valid
226)
227{
228continue;
229}
230
231//if(tag->type == kTagTypeKey) printf("Located key %s\n", tag->string);
232
233count++;
234}
235
236return count;
237}
238
239TagPtr XMLGetElement( TagPtr dict, int id )
240{
241if(dict->type != kTagTypeArray)
242{
243return 0;
244}
245
246int element = 0;
247TagPtr tmp = dict->tag;
248
249while(element < id)
250{
251element++;
252tmp = tmp->tagNext;
253}
254
255return tmp;
256}
257
258/* Function for basic XML character entities parsing */
259
260char *XMLDecode(const char* src)
261{
262typedef const struct XMLEntity {
263const char *name;
264size_t nameLen;
265char value;
266} XMLEntity;
267
268/* This is ugly, but better than specifying the lengths by hand */
269#define _e(str,c) {str,sizeof(str)-1,c}
270const XMLEntity ents[] = {
271_e("quot;",'"'), _e("apos;",'\''),
272_e("lt;", '<'), _e("gt;", '>'),
273_e("amp;", '&')
274};
275
276size_t len;
277const char *s;
278char *out, *o;
279
280if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) )
281{
282return 0;
283}
284
285o = out;
286s = src;
287while (s <= src+len) /* Make sure the terminator is also copied */
288{
289if ( *s == '&' )
290{
291bool entFound = false;
292int i;
293
294s++;
295for ( i = 0; i < sizeof(ents)/sizeof(ents[0]); i++)
296{
297if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 )
298{
299entFound = true;
300break;
301}
302}
303if ( entFound )
304{
305*o++ = ents[i].value;
306s += ents[i].nameLen;
307
308continue;
309}
310}
311
312*o++ = *s++;
313}
314
315return out;
316}
317
318//==========================================================================
319// XMLParseFile
320// Expects to see one dictionary in the XML file, the final pos will be returned
321// If the pos is not equal to the strlen, then there are multiple dicts
322// Puts the first dictionary it finds in the
323// tag pointer and returns the end of the dic, or returns -1 if not found.
324//
325long XMLParseFile( char * buffer, TagPtr *dict )
326{
327longlength;
328longpos = 0;
329TagPtrtag;
330char*configBuffer;
331
332int strlength = strlen(buffer);
333configBuffer = malloc(strlength+1);
334bcopy(buffer, configBuffer, strlength);
335
336configBuffer[strlength] = 0;
337
338buffer_start = configBuffer;
339
340while (1)
341{
342length = XMLParseNextTag(configBuffer + pos, &tag);
343if (length == -1) break;
344
345pos += length;
346
347if (tag == 0)
348{
349continue;
350}
351
352if (tag->type == kTagTypeDict)
353{
354break;
355}
356
357XMLFreeTag(tag);
358}
359free(configBuffer);
360if (length < 0)
361{
362return -1;
363}
364*dict = tag;
365return pos;
366}
367
368//==========================================================================
369// ParseNextTag
370// TODO: cleanup
371long XMLParseNextTag( char *buffer, TagPtr *tag )
372{
373longlength = 0;
374longpos = 0;
375
376
377char*tagName;
378
379length = GetNextTag(buffer, &tagName, 0);
380if (length == -1)
381{
382return -1;
383}
384
385pos = length;
386if (!strncmp(tagName, kXMLTagPList, 6))
387{
388length = 0;
389 // just a header; nothing to parse
390 // return-via-reference tag should be left alone
391}
392/***** dict ****/
393else if (!strcmp(tagName, kXMLTagDict))
394{
395length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
396}
397else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/')
398{
399length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);
400}
401else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " ")))
402{
403length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);
404}
405/***** key ****/
406else if (!strcmp(tagName, kXMLTagKey))
407{
408length = ParseTagKey(buffer + pos, tag);
409}
410
411/***** string ****/
412else if (!strcmp(tagName, kXMLTagString))
413{
414length = ParseTagString(buffer + pos, tag);
415}
416else if (!strncmp(tagName, kXMLTagString " ", strlen(kXMLTagString " ")))
417{
418// TODO: save tag if if found
419if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID)))
420{
421// ID=
422int id = 0;
423int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1;
424while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
425tagName[cnt] = 0;
426char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\"");
427while(*val)
428{
429if ((*val >= '0' && *val <= '9'))// 0 - 9
430{
431id = (id * 10) + (*val++ - '0');
432}
433else
434{
435printf("ParseStringID error (0x%x)\n", *val);
436getchar();
437return -1;
438}
439}
440length = ParseTagString(buffer + pos, tag);
441
442SaveRefString(buffer + pos, id);
443}
444else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
445{
446// IDREF=
447int id = 0;
448int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1;
449while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
450tagName[cnt] = 0;
451char* val = tagName + strlen(kXMLTagString " " 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);
461getchar();
462return -1;
463}
464}
465char* str = GetRefString(id);
466
467TagPtr tmpTag = NewTag();
468tmpTag->type = kTagTypeString;
469tmpTag->string = str;
470tmpTag->tag = 0;
471tmpTag->tagNext = 0;
472tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0;
473*tag = tmpTag;
474
475length = 0;
476//printf("Located IDREF, id = %d, string = %s\n", id, str);
477}
478}
479
480/***** integer ****/
481else if (!strcmp(tagName, kXMLTagInteger))
482{
483length = ParseTagInteger(buffer + pos, tag);
484}
485else if (!strncmp(tagName, kXMLTagInteger " ", strlen(kXMLTagInteger " ")))
486{
487if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID)))
488{
489// ID=
490int id = 0;
491int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1;
492while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
493tagName[cnt] = 0;
494char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\"");
495while(*val)
496{
497if ((*val >= '0' && *val <= '9'))// 0 - 9
498{
499id = (id * 10) + (*val++ - '0');
500}
501else
502{
503printf("ParseIntegerID error (0x%x)\n", *val);
504getchar();
505return -1;
506}
507}
508length = ParseTagInteger(buffer + pos, tag);
509
510SaveRefString((*tag)->string, id);
511}
512else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef)))
513{
514// IDREF=
515int id = 0;
516int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1;
517while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++;
518tagName[cnt] = 0;
519char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\"");
520while(*val)
521{
522if ((*val >= '0' && *val <= '9'))// 0 - 9
523{
524id = (id * 10) + (*val++ - '0');
525}
526else
527{
528printf("ParseStringIDREF error (0x%x)\n", *val);
529getchar();
530return -1;
531}
532}
533int integer = (int)GetRefString(id);
534
535TagPtr tmpTag = NewTag();
536tmpTag->type = kTagTypeInteger;
537tmpTag->string = (char*) integer;
538tmpTag->tag = 0;
539tmpTag->tagNext = 0;
540tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0;
541
542*tag = tmpTag;
543
544length = 0;
545//printf("Located IDREF, id = %d, string = %s\n", id, str);
546}
547else
548{
549length = ParseTagInteger(buffer + pos, tag);
550}
551}
552
553
554/***** false ****/
555else if (!strcmp(tagName, kXMLTagFalse))
556{
557length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);
558}
559
560/***** true ****/
561else if (!strcmp(tagName, kXMLTagTrue))
562{
563length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);
564}
565
566/***** plist ****/
567
568
569/***** dict ****/
570
571
572/***** data ****/
573else if (!strcmp(tagName, kXMLTagData))
574{
575length = ParseTagData(buffer + pos, tag);
576}
577else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " ")))
578{
579length = ParseTagData(buffer + pos, tag);
580}
581else if (!strcmp(tagName, kXMLTagDate))
582{
583length = ParseTagDate(buffer + pos, tag);
584}
585
586/***** date ****/
587else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " ")))
588{
589length = ParseTagDate(buffer + pos, tag);
590}/***** array ****/
591else if (!strcmp(tagName, kXMLTagArray))
592{
593length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
594}
595else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " ")))
596{
597length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);
598}
599else if (!strcmp(tagName, kXMLTagArray "/"))
600{
601length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);
602}
603
604/***** unknown ****/
605else
606{
607// it wasn't parsed so we consumed no additional characters
608*tag = 0;
609length = 0;
610}
611
612if (length == -1)
613{
614return -1;
615}
616
617return pos + length;
618}
619
620//==========================================================================
621// ParseTagList
622
623static long ParseTagList( char *buffer, TagPtr *tag, long type, long empty )
624{
625longpos = 0;
626longlength = 0;
627TagPtrtagList = 0;
628TagPtrtmpTag;
629
630
631if (!empty)
632{
633while (1)
634{
635length = XMLParseNextTag(buffer + pos, &tmpTag);
636if (length == -1)
637{
638break;
639}
640
641pos += length;
642
643// detect end of list
644if (tmpTag == 0)
645{
646break;
647}
648tmpTag->tagNext = tagList;
649tagList = tmpTag;
650}
651
652if (length == -1)
653{
654XMLFreeTag(tagList);
655return -1;
656}
657}
658
659tmpTag = NewTag();
660if (tmpTag == 0)
661{
662XMLFreeTag(tagList);
663return -1;
664}
665
666tmpTag->type = type;
667tmpTag->string = 0;
668tmpTag->offset = buffer_start ? buffer - buffer_start : 0;
669tmpTag->tag = tagList;
670tmpTag->tagNext = 0;
671
672*tag = tmpTag;
673
674return pos;
675}
676
677//==========================================================================
678// ParseTagKey
679
680static long ParseTagKey( char *buffer, TagPtr *tag )
681{
682longlength = 0;
683longlength2 = 0;
684char*string;
685TagPtrtmpTag;
686TagPtrsubTag;
687
688length = FixDataMatchingTag(buffer, kXMLTagKey);
689if (length == -1)
690{
691return -1;
692}
693
694length2 = XMLParseNextTag(buffer + length, &subTag);
695if (length2 == -1)
696{
697return -1;
698}
699
700tmpTag = NewTag();
701if (tmpTag == 0)
702{
703XMLFreeTag(subTag);
704return -1;
705}
706
707string = NewSymbol(buffer);
708if (string == 0)
709{
710XMLFreeTag(subTag);
711XMLFreeTag(tmpTag);
712return -1;
713}
714
715tmpTag->type = kTagTypeKey;
716tmpTag->string = string;
717tmpTag->tag = subTag;
718tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
719tmpTag->tagNext = 0;
720
721*tag = tmpTag;
722
723return length + length2;
724}
725
726//==========================================================================
727// ParseTagString
728
729static long ParseTagString( char *buffer, TagPtr *tag )
730{
731longlength = 0;
732char*string;
733
734length = FixDataMatchingTag(buffer, kXMLTagString);
735if (length == -1)
736{
737return -1;
738}
739
740TagPtr tmpTag = NewTag();
741if (tmpTag == 0)
742{
743return -1;
744}
745
746string = NewSymbol(buffer);
747if (string == 0)
748{
749XMLFreeTag(tmpTag);
750return -1;
751}
752
753tmpTag->type = kTagTypeString;
754tmpTag->string = string;
755tmpTag->tag = 0;
756tmpTag->tagNext = 0;
757tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
758
759*tag = tmpTag;
760return length;
761}
762
763//==========================================================================
764// ParseTagInteger
765
766static long ParseTagInteger( char *buffer, TagPtr *tag )
767{
768long length, integer;
769bool negative = false;
770TagPtr tmpTag;
771char* val = buffer;
772int size;
773
774if(buffer[0] == '<')
775{
776printf("Warning integer is non existant\n");
777getchar();
778tmpTag = NewTag();
779tmpTag->type = kTagTypeInteger;
780tmpTag->string = 0;
781tmpTag->tag = 0;
782tmpTag->offset = 0;
783tmpTag->tagNext = 0;
784
785*tag = tmpTag;
786
787return 0;
788}
789
790size = length = FixDataMatchingTag(buffer, kXMLTagInteger);
791if (length == -1)
792{
793return -1;
794}
795
796tmpTag = NewTag();
797
798if (tmpTag == 0)
799{
800return -1;
801}
802integer = 0;
803
804if(size > 1 && (val[1] == 'x' || val[1] == 'X'))// Hex value
805{
806val += 2;
807while(*val)
808{
809if ((*val >= '0' && *val <= '9'))// 0 - 9
810{
811integer = (integer * 16) + (*val++ - '0');
812}
813else if ((*val >= 'a' && *val <= 'f'))// a - f
814{
815integer = (integer * 16) + (*val++ - 'a' + 10);
816}
817else if ((*val >= 'A' && *val <= 'F'))// A - F
818{
819integer = (integer * 16) + (*val++ - 'A' + 10);
820}
821else
822{
823printf("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer);
824getchar();
825XMLFreeTag(tmpTag);
826return -1;
827}
828}
829}
830else if ( size )// Decimal value
831{
832if (*val == '-')
833{
834negative = true;
835val++;
836size--;
837}
838
839for (integer = 0; size > 0; size--)
840{
841if(*val) // UGLY HACK, fix me.
842{
843if (*val < '0' || *val > '9')
844{
845printf("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer);
846getchar();
847return -1;
848}
849
850integer = (integer * 10) + (*val++ - '0');
851}
852}
853
854if (negative) {
855integer = -integer;
856}
857}
858
859tmpTag->type = kTagTypeInteger;
860tmpTag->string = (char *)integer;
861tmpTag->tag = 0;
862tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
863tmpTag->tagNext = 0;
864
865*tag = tmpTag;
866
867return length;
868}
869
870//==========================================================================
871// ParseTagData
872
873static long ParseTagData( char *buffer, TagPtr *tag )
874{
875intactuallen = 0;
876longlength = 0;
877TagPtrtmpTag;
878char*string;
879
880length = FixDataMatchingTag(buffer, kXMLTagData);
881if (length == -1)
882{
883return -1;
884}
885
886tmpTag = NewTag();
887if (tmpTag == 0)
888{
889return -1;
890}
891
892//printf("ParseTagData unimplimented\n");
893//printf("Data: %s\n", buffer);
894//getchar();
895
896string = BASE64Decode(buffer, strlen(buffer), &actuallen);
897tmpTag->type = kTagTypeData;
898tmpTag->string = string;
899
900tmpTag->tag = 0;
901tmpTag->offset = actuallen; // buffer_start ? buffer - buffer_start: 0;
902
903tmpTag->tagNext = 0;
904
905*tag = tmpTag;
906
907return length;
908}
909
910//==========================================================================
911// ParseTagDate
912
913static long ParseTagDate( char *buffer, TagPtr *tag )
914{
915longlength = 0;
916TagPtrtmpTag;
917
918length = FixDataMatchingTag(buffer, kXMLTagDate);
919if (length == -1)
920{
921return -1;
922}
923
924tmpTag = NewTag();
925if (tmpTag == 0)
926{
927return -1;
928}
929
930printf("ParseTagDate unimplimented\n");
931getchar();
932
933tmpTag->type = kTagTypeDate;
934tmpTag->string = 0;
935tmpTag->tag = 0;
936tmpTag->tagNext = 0;
937tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
938
939*tag = tmpTag;
940
941return length;
942}
943
944//==========================================================================
945// ParseTagBoolean
946
947long ParseTagBoolean( char *buffer, TagPtr *tag, long type )
948{
949TagPtr tmpTag;
950
951tmpTag = NewTag();
952if (tmpTag == 0)
953{
954return -1;
955}
956
957tmpTag->type = type;
958tmpTag->string = 0;
959tmpTag->tag = 0;
960tmpTag->tagNext = 0;
961tmpTag->offset = buffer_start ? buffer - buffer_start: 0;
962
963*tag = tmpTag;
964
965return 0;
966}
967
968//==========================================================================
969// GetNextTag
970
971static long GetNextTag( char *buffer, char **tag, long *start )
972{
973longcnt;
974longcnt2;
975
976if (tag == 0)
977{
978return -1;
979}
980
981// Find the start of the tag.
982cnt = 0;
983while ((buffer[cnt] != '\0') && (buffer[cnt] != '<'))
984{
985cnt++;
986}
987
988if (buffer[cnt] == '\0')
989{
990return -1;
991}
992// Find the end of the tag.
993cnt2 = cnt + 1;
994while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>'))
995{
996cnt2++;
997}
998
999if (buffer[cnt2] == '\0')
1000{
1001return -1;
1002}
1003
1004// Fix the tag data.
1005*tag = buffer + cnt + 1;
1006buffer[cnt2] = '\0';
1007if (start)
1008{
1009*start = cnt;
1010}
1011
1012return cnt2 + 1;
1013}
1014
1015//==========================================================================
1016// FixDataMatchingTag
1017// Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
1018// Returns the length of the data found, counting the end tag,
1019// or -1 if the end tag was not found.
1020
1021static long FixDataMatchingTag( char *buffer, char *tag )
1022{
1023longlength;
1024longstart;
1025longstop;
1026char*endTag;
1027
1028start = 0;
1029while (1)
1030{
1031length = GetNextTag(buffer + start, &endTag, &stop);
1032if (length == -1)
1033{
1034return -1;
1035}
1036
1037if ((*endTag == '/') && !strcmp(endTag + 1, tag))
1038{
1039break;
1040}
1041
1042start += length;
1043}
1044
1045buffer[start + stop] = '\0';
1046
1047return start + length;
1048}
1049
1050//==========================================================================
1051// NewTag
1052
1053#define kTagsPerBlock (0x1000)
1054
1055static TagPtr gTagsFree;
1056
1057static TagPtr NewTag( void )
1058{
1059longcnt;
1060TagPtrtag;
1061
1062if (gTagsFree == 0)
1063{
1064tag = (TagPtr)malloc(kTagsPerBlock *sizeof(Tag));
1065if (tag == 0)
1066{
1067return 0;
1068}
1069
1070// Initalize the new tags.
1071for (cnt = 0; cnt < kTagsPerBlock; cnt++)
1072{
1073tag[cnt].type = kTagTypeNone;
1074tag[cnt].string = 0;
1075tag[cnt].tag = 0;
1076tag[cnt].tagNext = tag + cnt + 1;
1077}
1078tag[kTagsPerBlock - 1].tagNext = 0;
1079
1080gTagsFree = tag;
1081}
1082
1083tag = gTagsFree;
1084gTagsFree = tag->tagNext;
1085
1086return tag;
1087}
1088
1089//==========================================================================
1090// XMLFreeTag
1091
1092void XMLFreeTag( TagPtr tag )
1093{
1094#if DOFREE
1095if (tag == 0)
1096{
1097return;
1098}
1099
1100if (!XMLIsInteger(tag) && tag->string)
1101{
1102FreeSymbol(tag->string);
1103}
1104
1105XMLFreeTag(tag->tag);
1106XMLFreeTag(tag->tagNext);
1107
1108// Clear and free the tag.
1109tag->type = kTagTypeNone;
1110tag->string = 0;
1111tag->tag = 0;
1112tag->offset = 0;
1113tag->tagNext = gTagsFree;
1114gTagsFree = tag;
1115#else
1116return;
1117#endif
1118}
1119
1120//==========================================================================
1121// Symbol object.
1122
1123struct Symbol
1124{
1125long refCount;
1126struct Symbol *next;
1127char string[];
1128};
1129typedef struct Symbol Symbol, *SymbolPtr;
1130
1131static SymbolPtr FindSymbol(char *string, SymbolPtr *prevSymbol);
1132
1133static SymbolPtr gSymbolsHead;
1134
1135//==========================================================================
1136// NewSymbol
1137
1138static char *NewSymbol( char *string )
1139{
1140static SymbolPtr lastGuy = 0;
1141
1142SymbolPtrsymbol;
1143
1144// Look for string in the list of symbols.
1145symbol = FindSymbol(string, 0);
1146
1147// Add the new symbol.
1148if (symbol == 0)
1149{
1150symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));
1151if (symbol == 0)
1152{//return 0;
1153stop("NULL symbol!");
1154}
1155
1156// Set the symbol's data.
1157symbol->refCount = 0;
1158strcpy(symbol->string, string);
1159
1160// Add the symbol to the list.
1161symbol->next = gSymbolsHead;
1162gSymbolsHead = symbol;
1163}
1164
1165// Update the refCount and return the string.
1166symbol->refCount++;
1167
1168if (lastGuy && lastGuy->next != 0)
1169{
1170stop("last guy not last!");
1171}
1172
1173return symbol->string;
1174}
1175
1176//==========================================================================
1177// FreeSymbol
1178
1179#if DOFREE
1180static void FreeSymbol( char *string )
1181{
1182SymbolPtr symbol, prev;
1183prev = 0;
1184
1185// Look for string in the list of symbols.
1186symbol = FindSymbol(string, &prev);
1187if (symbol == 0)
1188{
1189return;
1190}
1191
1192// Update the refCount.
1193symbol->refCount--;
1194
1195if (symbol->refCount != 0)
1196{
1197return;
1198}
1199
1200// Remove the symbol from the list.
1201if (prev != 0)
1202{
1203prev->next = symbol->next;
1204}
1205else
1206{
1207gSymbolsHead = symbol->next;
1208}
1209
1210// Free the symbol's memory.
1211free(symbol);
1212}
1213#endif
1214
1215//==========================================================================
1216// FindSymbol
1217
1218static SymbolPtr FindSymbol( char *string, SymbolPtr *prevSymbol )
1219{
1220SymbolPtr symbol, prev;
1221
1222symbol = gSymbolsHead;
1223prev = 0;
1224
1225while (symbol != NULL)
1226{
1227if (!strcmp(symbol->string, string))
1228{
1229break;
1230}
1231
1232prev = symbol;
1233symbol = symbol->next;
1234}
1235
1236if ((symbol != 0) && (prevSymbol != 0))
1237{
1238*prevSymbol = prev;
1239}
1240
1241return symbol;
1242}
1243
1244bool XMLIsType(TagPtr dict, enum xmltype type)
1245{
1246if(!dict)
1247{
1248return (type == kTagTypeNone);
1249}
1250return (dict->type == type);
1251}
1252
1253/*** Cast functions ***/
1254bool XMLIsArray(TagPtr entry)
1255{
1256return entry && (entry->type == kTagTypeArray);
1257}
1258
1259TagPtr XMLCastArray(TagPtr dict)
1260{
1261if(!dict)
1262{
1263return NULL;
1264}
1265
1266if(dict->type == kTagTypeArray)
1267{
1268return dict;
1269} else {
1270return NULL;
1271}
1272}
1273
1274bool XMLIsDict(TagPtr entry)
1275{
1276 return entry && (entry->type == kTagTypeDict);
1277}
1278
1279bool XMLIsData(TagPtr entry)
1280{
1281return entry && (entry->type == kTagTypeData);
1282}
1283
1284TagPtr XMLCastDict(TagPtr dict)
1285{
1286if(!dict)
1287{
1288return NULL;
1289}
1290
1291if(dict->type == kTagTypeDict)
1292{
1293return dict;
1294}
1295else
1296{
1297return NULL;
1298}
1299}
1300
1301bool XMLIsString(TagPtr entry)
1302{
1303 return entry && ((entry->type == kTagTypeString) || (entry->type == kTagTypeKey));
1304}
1305
1306char *XMLCastString(TagPtr dict)
1307{
1308if(!dict)
1309{
1310return NULL;
1311}
1312
1313if((dict->type == kTagTypeString) || (dict->type == kTagTypeKey))
1314{
1315return dict->string;
1316}
1317
1318return NULL;
1319}
1320
1321char *XMLCastData(TagPtr dict, int* length)
1322{
1323if(!dict)
1324{
1325return NULL;
1326}
1327
1328if((dict->type == kTagTypeData) || (dict->type == kTagTypeKey))
1329{
1330*length = dict->offset;
1331return dict->string;
1332}
1333*length = 0;
1334return NULL;
1335}
1336
1337
1338long XMLCastStringOffset(TagPtr dict)
1339{
1340if(dict && ((dict->type == kTagTypeString) || (dict->type == kTagTypeKey)))
1341{
1342return dict->offset;
1343}
1344else
1345{
1346return -1;
1347}
1348}
1349
1350bool XMLIsBoolean(TagPtr entry)
1351{
1352return entry && ((entry->type == kTagTypeTrue) || (entry->type == kTagTypeFalse));
1353}
1354
1355bool XMLCastBoolean(TagPtr dict)
1356{
1357if(!dict)
1358{
1359return false;
1360}
1361
1362if(dict->type == kTagTypeTrue)
1363{
1364return true;
1365}
1366return false;
1367}
1368
1369bool XMLIsInteger(TagPtr entry)
1370{
1371 return entry && (entry->type == kTagTypeInteger);
1372}
1373
1374int XMLCastInteger(TagPtr dict)
1375{
1376if(!dict)
1377{
1378//printf("XMLCastInteger: null dict\n");
1379return 0;
1380}
1381
1382if(dict->type == kTagTypeInteger)
1383{
1384return (int)(dict->string);
1385}
1386return 0;
1387}
1388
1389bool XMLAddTagToDictionary(TagPtr dict, char *key, TagPtr value)
1390{
1391if (!dict || dict->type != kTagTypeDict)
1392{
1393return false;
1394}
1395
1396TagPtr tmpTag;
1397char* string;
1398
1399tmpTag = NewTag();
1400if (tmpTag == 0)
1401{
1402return false;
1403}
1404
1405string = NewSymbol(key);
1406if (string == 0)
1407{
1408XMLFreeTag(tmpTag);
1409return false;
1410}
1411
1412tmpTag->type = kTagTypeKey;
1413tmpTag->string = string;
1414tmpTag->tag = value;
1415tmpTag->offset = 0;
1416tmpTag->tagNext = 0;
1417
1418TagPtr tagList = dict->tag;
1419if(!tagList)
1420{
1421// First tag
1422dict->tag = tmpTag;
1423return true;
1424}
1425while(tagList && tagList->tagNext) tagList = tagList->tagNext;
1426if(tagList)
1427{
1428tagList->tagNext = tmpTag;
1429return true;
1430}
1431
1432XMLFreeTag(tmpTag);
1433return false;
1434}
1435

Archive Download this file

Revision: 2594