Chameleon

Chameleon Svn Source Tree

Root/branches/rewrite/i386/libsaio/xml.c

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

Archive Download this file

Revision: 1146