2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 #include "bootstruct.h"
32 struct Module
*nextModule
;
39 typedef struct Module Module
, *ModulePtr
;
47 typedef struct DriverInfo DriverInfo
, *DriverInfoPtr
;
49 #define kDriverPackageSignature1 'MKXT'
50 #define kDriverPackageSignature2 'MOSX'
52 struct DriversPackage
{
53 unsigned long signature1
;
54 unsigned long signature2
;
56 unsigned long alder32
;
57 unsigned long version
;
58 unsigned long numDrivers
;
59 unsigned long reserved1
;
60 unsigned long reserved2
;
62 typedef struct DriversPackage DriversPackage
;
73 static long ParseTagList(char *buffer
, TagPtr
*tag
, long type
, long empty
);
74 static long ParseTagKey(char *buffer
, TagPtr
*tag
);
75 static long ParseTagString(char *buffer
, TagPtr
*tag
);
76 static long ParseTagInteger(char *buffer
, TagPtr
*tag
);
77 static long ParseTagData(char *buffer
, TagPtr
*tag
);
78 static long ParseTagDate(char *buffer
, TagPtr
*tag
);
79 static long ParseTagBoolean(char *buffer
, TagPtr
*tag
, long type
);
80 static long GetNextTag(char *buffer
, char **tag
, long *start
);
81 static long FixDataMatchingTag(char *buffer
, char *tag
);
82 static TagPtr
NewTag(void);
83 static char *NewSymbol(char *string
);
85 static void FreeSymbol(char *string
);
89 //==========================================================================
93 XMLGetProperty( TagPtr dict
, const char * key
)
97 if (dict
->type
!= kTagTypeDict
) return 0;
104 tagList
= tag
->tagNext
;
106 if ((tag
->type
!= kTagTypeKey
) || (tag
->string
== 0)) continue;
108 if (!strcmp(tag
->string
, key
)) return tag
->tag
;
115 //==========================================================================
117 // Expects to see one dictionary in the XML file.
118 // Puts the first dictionary it finds in the
119 // tag pointer and returns 0, or returns -1 if not found.
122 XMLParseFile( char * buffer
, TagPtr
* dict
)
130 length
= XMLParseNextTag(buffer
+ pos
, &tag
);
131 if (length
== -1) break;
135 if (tag
== 0) continue;
136 if (tag
->type
== kTagTypeDict
) break;
147 //==========================================================================
151 XMLParseNextTag( char * buffer
, TagPtr
* tag
)
156 length
= GetNextTag(buffer
, &tagName
, 0);
157 if (length
== -1) return -1;
160 if (!strncmp(tagName
, kXMLTagPList
, 6))
164 else if (!strcmp(tagName
, kXMLTagDict
))
166 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeDict
, 0);
168 else if (!strcmp(tagName
, kXMLTagDict
"/"))
170 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeDict
, 1);
172 else if (!strcmp(tagName
, kXMLTagKey
))
174 length
= ParseTagKey(buffer
+ pos
, tag
);
176 else if (!strcmp(tagName
, kXMLTagString
))
178 length
= ParseTagString(buffer
+ pos
, tag
);
180 else if (!strcmp(tagName
, kXMLTagInteger
))
182 length
= ParseTagInteger(buffer
+ pos
, tag
);
184 else if (!strcmp(tagName
, kXMLTagData
))
186 length
= ParseTagData(buffer
+ pos
, tag
);
188 else if (!strcmp(tagName
, kXMLTagDate
))
190 length
= ParseTagDate(buffer
+ pos
, tag
);
192 else if (!strcmp(tagName
, kXMLTagFalse
))
194 length
= ParseTagBoolean(buffer
+ pos
, tag
, kTagTypeFalse
);
196 else if (!strcmp(tagName
, kXMLTagTrue
))
198 length
= ParseTagBoolean(buffer
+ pos
, tag
, kTagTypeTrue
);
200 else if (!strcmp(tagName
, kXMLTagArray
))
202 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeArray
, 0);
204 else if (!strcmp(tagName
, kXMLTagArray
"/"))
206 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeArray
, 1);
214 if (length
== -1) return -1;
219 //==========================================================================
223 ParseTagList( char * buffer
, TagPtr
* tag
, long type
, long empty
)
226 TagPtr tagList
, tmpTag
;
235 length
= XMLParseNextTag(buffer
+ pos
, &tmpTag
);
236 if (length
== -1) break;
240 if (tmpTag
== 0) break;
241 tmpTag
->tagNext
= tagList
;
261 tmpTag
->tag
= tagList
;
269 //==========================================================================
273 ParseTagKey( char * buffer
, TagPtr
* tag
)
275 long length
, length2
;
277 TagPtr tmpTag
, subTag
;
279 length
= FixDataMatchingTag(buffer
, kXMLTagKey
);
280 if (length
== -1) return -1;
282 length2
= XMLParseNextTag(buffer
+ length
, &subTag
);
283 if (length2
== -1) return -1;
292 string
= NewSymbol(buffer
);
300 tmpTag
->type
= kTagTypeKey
;
301 tmpTag
->string
= string
;
302 tmpTag
->tag
= subTag
;
307 return length
+ length2
;
310 //==========================================================================
314 ParseTagString( char * buffer
, TagPtr
* tag
)
320 length
= FixDataMatchingTag(buffer
, kXMLTagString
);
321 if (length
== -1) return -1;
324 if (tmpTag
== 0) return -1;
326 string
= NewSymbol(buffer
);
333 tmpTag
->type
= kTagTypeString
;
334 tmpTag
->string
= string
;
342 //==========================================================================
346 ParseTagInteger( char * buffer
, TagPtr
* tag
)
348 long length
, integer
;
351 length
= FixDataMatchingTag(buffer
, kXMLTagInteger
);
352 if (length
== -1) return -1;
355 if (tmpTag
== 0) return -1;
359 tmpTag
->type
= kTagTypeInteger
;
360 tmpTag
->string
= (char *)integer
;
369 //==========================================================================
373 ParseTagData( char * buffer
, TagPtr
* tag
)
378 length
= FixDataMatchingTag(buffer
, kXMLTagData
);
379 if (length
== -1) return -1;
382 if (tmpTag
== 0) return -1;
384 tmpTag
->type
= kTagTypeData
;
394 //==========================================================================
398 ParseTagDate( char * buffer
, TagPtr
* tag
)
403 length
= FixDataMatchingTag(buffer
, kXMLTagDate
);
404 if (length
== -1) return -1;
407 if (tmpTag
== 0) return -1;
409 tmpTag
->type
= kTagTypeDate
;
419 //==========================================================================
423 ParseTagBoolean( char * buffer
, TagPtr
* tag
, long type
)
428 if (tmpTag
== 0) return -1;
440 //==========================================================================
444 GetNextTag( char * buffer
, char ** tag
, long * start
)
448 if (tag
== 0) return -1;
450 // Find the start of the tag.
452 while ((buffer
[cnt
] != '\0') && (buffer
[cnt
] != '<')) cnt
++;
453 if (buffer
[cnt
] == '\0') return -1;
455 // Find the end of the tag.
457 while ((buffer
[cnt2
] != '\0') && (buffer
[cnt2
] != '>')) cnt2
++;
458 if (buffer
[cnt2
] == '\0') return -1;
461 *tag
= buffer
+ cnt
+ 1;
463 if (start
) *start
= cnt
;
468 //==========================================================================
469 // FixDataMatchingTag
470 // Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
471 // Returns the length of the data found, counting the end tag,
472 // or -1 if the end tag was not found.
475 FixDataMatchingTag( char * buffer
, char * tag
)
477 long length
, start
, stop
;
483 length
= GetNextTag(buffer
+ start
, &endTag
, &stop
);
484 if (length
== -1) return -1;
486 if ((*endTag
== '/') && !strcmp(endTag
+ 1, tag
)) break;
490 buffer
[start
+ stop
] = '\0';
492 return start
+ length
;
495 //==========================================================================
498 #define kTagsPerBlock (0x1000)
500 static TagPtr gTagsFree
;
511 tag
= (TagPtr
)malloc(kTagsPerBlock
* sizeof(Tag
));
513 tag
= (TagPtr
)AllocateBootXMemory(kTagsPerBlock
* sizeof(Tag
));
515 if (tag
== 0) return 0;
517 // Initalize the new tags.
518 for (cnt
= 0; cnt
< kTagsPerBlock
; cnt
++)
520 tag
[cnt
].type
= kTagTypeNone
;
523 tag
[cnt
].tagNext
= tag
+ cnt
+ 1;
525 tag
[kTagsPerBlock
- 1].tagNext
= 0;
531 gTagsFree
= tag
->tagNext
;
536 //==========================================================================
540 XMLFreeTag( TagPtr tag
)
543 if (tag
== 0) return;
545 if (tag
->string
) FreeSymbol(tag
->string
);
547 XMLFreeTag(tag
->tag
);
548 XMLFreeTag(tag
->tagNext
);
550 // Clear and free the tag.
551 tag
->type
= kTagTypeNone
;
554 tag
->tagNext
= gTagsFree
;
561 //==========================================================================
570 typedef struct Symbol Symbol
, *SymbolPtr
;
572 static SymbolPtr
FindSymbol(char * string
, SymbolPtr
* prevSymbol
);
574 static SymbolPtr gSymbolsHead
;
576 //==========================================================================
580 NewSymbol( char * string
)
582 static SymbolPtr lastGuy
= 0;
585 // Look for string in the list of symbols.
586 symbol
= FindSymbol(string
, 0);
588 // Add the new symbol.
592 symbol
= (SymbolPtr
)malloc(sizeof(Symbol
) + 1 + strlen(string
));
594 symbol
= (SymbolPtr
)AllocateBootXMemory(sizeof(Symbol
) + 1 + strlen(string
));
596 if (symbol
== 0) //return 0;
597 stop("NULL symbol!");
599 // Set the symbol's data.
600 symbol
->refCount
= 0;
601 strcpy(symbol
->string
, string
);
603 // Add the symbol to the list.
604 symbol
->next
= gSymbolsHead
;
605 gSymbolsHead
= symbol
;
608 // Update the refCount and return the string.
611 if (lastGuy
&& lastGuy
->next
!= 0) stop("last guy not last!");
612 return symbol
->string
;
615 //==========================================================================
620 FreeSymbol( char * string
)
622 SymbolPtr symbol
, prev
;
624 // Look for string in the list of symbols.
625 symbol
= FindSymbol(string
, &prev
);
626 if (symbol
== 0) return;
628 // Update the refCount.
631 if (symbol
->refCount
!= 0) return;
633 // Remove the symbol from the list.
634 if (prev
!= 0) prev
->next
= symbol
->next
;
635 else gSymbolsHead
= symbol
->next
;
637 // Free the symbol's memory.
642 //==========================================================================
646 FindSymbol( char * string
, SymbolPtr
* prevSymbol
)
648 SymbolPtr symbol
, prev
;
650 symbol
= gSymbolsHead
;
653 while (symbol
!= 0) {
654 if (!strcmp(symbol
->string
, string
)) break;
657 symbol
= symbol
->next
;
660 if ((symbol
!= 0) && (prevSymbol
!= 0)) *prevSymbol
= prev
;