Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 1146