2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
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.
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
22 * @APPLE_LICENSE_HEADER_END@
25 #include "bootstruct.h"
31 struct Module
*nextModule
;
38 typedef struct Module Module
, *ModulePtr
;
46 typedef struct DriverInfo DriverInfo
, *DriverInfoPtr
;
48 #define kDriverPackageSignature1 'MKXT'
49 #define kDriverPackageSignature2 'MOSX'
51 struct DriversPackage
{
52 unsigned long signature1
;
53 unsigned long signature2
;
55 unsigned long alder32
;
56 unsigned long version
;
57 unsigned long numDrivers
;
58 unsigned long reserved1
;
59 unsigned long reserved2
;
61 typedef struct DriversPackage DriversPackage
;
72 static long ParseTagList(char *buffer
, TagPtr
*tag
, long type
, long empty
);
73 static long ParseTagKey(char *buffer
, TagPtr
*tag
);
74 static long ParseTagString(char *buffer
, TagPtr
*tag
);
75 static long ParseTagInteger(char *buffer
, TagPtr
*tag
);
76 static long ParseTagData(char *buffer
, TagPtr
*tag
);
77 static long ParseTagDate(char *buffer
, TagPtr
*tag
);
78 static long ParseTagBoolean(char *buffer
, TagPtr
*tag
, long type
);
79 static long GetNextTag(char *buffer
, char **tag
, long *start
);
80 static long FixDataMatchingTag(char *buffer
, char *tag
);
81 static TagPtr
NewTag(void);
82 static char *NewSymbol(char *string
);
84 static void FreeSymbol(char *string
);
88 //==========================================================================
92 XMLGetProperty( TagPtr dict
, const char * key
)
96 if (dict
->type
!= kTagTypeDict
) return 0;
103 tagList
= tag
->tagNext
;
105 if ((tag
->type
!= kTagTypeKey
) || (tag
->string
== 0)) continue;
107 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;
148 //==========================================================================
152 XMLParseNextTag( char * buffer
, TagPtr
* tag
)
157 length
= GetNextTag(buffer
, &tagName
, 0);
158 if (length
== -1) return -1;
161 if (!strncmp(tagName
, kXMLTagPList
, 6))
165 else if (!strcmp(tagName
, kXMLTagDict
))
167 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeDict
, 0);
169 else if (!strcmp(tagName
, kXMLTagDict
"/"))
171 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeDict
, 1);
173 else if (!strcmp(tagName
, kXMLTagKey
))
175 length
= ParseTagKey(buffer
+ pos
, tag
);
177 else if (!strcmp(tagName
, kXMLTagString
))
179 length
= ParseTagString(buffer
+ pos
, tag
);
181 else if (!strcmp(tagName
, kXMLTagInteger
))
183 length
= ParseTagInteger(buffer
+ pos
, tag
);
185 else if (!strcmp(tagName
, kXMLTagData
))
187 length
= ParseTagData(buffer
+ pos
, tag
);
189 else if (!strcmp(tagName
, kXMLTagDate
))
191 length
= ParseTagDate(buffer
+ pos
, tag
);
193 else if (!strcmp(tagName
, kXMLTagFalse
))
195 length
= ParseTagBoolean(buffer
+ pos
, tag
, kTagTypeFalse
);
197 else if (!strcmp(tagName
, kXMLTagTrue
))
199 length
= ParseTagBoolean(buffer
+ pos
, tag
, kTagTypeTrue
);
201 else if (!strcmp(tagName
, kXMLTagArray
))
203 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeArray
, 0);
205 else if (!strcmp(tagName
, kXMLTagArray
"/"))
207 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeArray
, 1);
215 if (length
== -1) return -1;
220 //==========================================================================
224 ParseTagList( char * buffer
, TagPtr
* tag
, long type
, long empty
)
227 TagPtr tagList
, tmpTag
;
236 length
= XMLParseNextTag(buffer
+ pos
, &tmpTag
);
237 if (length
== -1) break;
241 if (tmpTag
== 0) break;
242 tmpTag
->tagNext
= tagList
;
262 tmpTag
->tag
= tagList
;
270 //==========================================================================
274 ParseTagKey( char * buffer
, TagPtr
* tag
)
276 long length
, length2
;
278 TagPtr tmpTag
, subTag
;
280 length
= FixDataMatchingTag(buffer
, kXMLTagKey
);
281 if (length
== -1) return -1;
283 length2
= XMLParseNextTag(buffer
+ length
, &subTag
);
284 if (length2
== -1) return -1;
293 string
= NewSymbol(buffer
);
301 tmpTag
->type
= kTagTypeKey
;
302 tmpTag
->string
= string
;
303 tmpTag
->tag
= subTag
;
308 return length
+ length2
;
311 //==========================================================================
315 ParseTagString( char * buffer
, TagPtr
* tag
)
321 length
= FixDataMatchingTag(buffer
, kXMLTagString
);
322 if (length
== -1) return -1;
325 if (tmpTag
== 0) return -1;
327 string
= NewSymbol(buffer
);
334 tmpTag
->type
= kTagTypeString
;
335 tmpTag
->string
= string
;
343 //==========================================================================
347 ParseTagInteger( char * buffer
, TagPtr
* tag
)
349 long length
, integer
;
352 length
= FixDataMatchingTag(buffer
, kXMLTagInteger
);
353 if (length
== -1) return -1;
356 if (tmpTag
== 0) return -1;
360 tmpTag
->type
= kTagTypeInteger
;
361 tmpTag
->string
= (char *)integer
;
370 //==========================================================================
374 ParseTagData( char * buffer
, TagPtr
* tag
)
379 length
= FixDataMatchingTag(buffer
, kXMLTagData
);
380 if (length
== -1) return -1;
383 if (tmpTag
== 0) return -1;
385 tmpTag
->type
= kTagTypeData
;
395 //==========================================================================
399 ParseTagDate( char * buffer
, TagPtr
* tag
)
404 length
= FixDataMatchingTag(buffer
, kXMLTagDate
);
405 if (length
== -1) return -1;
408 if (tmpTag
== 0) return -1;
410 tmpTag
->type
= kTagTypeDate
;
420 //==========================================================================
424 ParseTagBoolean( char * buffer
, TagPtr
* tag
, long type
)
429 if (tmpTag
== 0) return -1;
441 //==========================================================================
445 GetNextTag( char * buffer
, char ** tag
, long * start
)
449 if (tag
== 0) return -1;
451 // Find the start of the tag.
453 while ((buffer
[cnt
] != '\0') && (buffer
[cnt
] != '<')) cnt
++;
454 if (buffer
[cnt
] == '\0') return -1;
456 // Find the end of the tag.
458 while ((buffer
[cnt2
] != '\0') && (buffer
[cnt2
] != '>')) cnt2
++;
459 if (buffer
[cnt2
] == '\0') return -1;
462 *tag
= buffer
+ cnt
+ 1;
464 if (start
) *start
= cnt
;
469 //==========================================================================
470 // FixDataMatchingTag
471 // Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
472 // Returns the length of the data found, counting the end tag,
473 // or -1 if the end tag was not found.
476 FixDataMatchingTag( char * buffer
, char * tag
)
478 long length
, start
, stop
;
484 length
= GetNextTag(buffer
+ start
, &endTag
, &stop
);
485 if (length
== -1) return -1;
487 if ((*endTag
== '/') && !strcmp(endTag
+ 1, tag
)) break;
491 buffer
[start
+ stop
] = '\0';
493 return start
+ length
;
496 //==========================================================================
499 #define kTagsPerBlock (0x1000)
501 static TagPtr gTagsFree
;
512 tag
= (TagPtr
)malloc(kTagsPerBlock
* sizeof(Tag
));
514 tag
= (TagPtr
)AllocateBootXMemory(kTagsPerBlock
* sizeof(Tag
));
516 if (tag
== 0) return 0;
518 // Initalize the new tags.
519 for (cnt
= 0; cnt
< kTagsPerBlock
; cnt
++)
521 tag
[cnt
].type
= kTagTypeNone
;
524 tag
[cnt
].tagNext
= tag
+ cnt
+ 1;
526 tag
[kTagsPerBlock
- 1].tagNext
= 0;
532 gTagsFree
= tag
->tagNext
;
537 //==========================================================================
541 XMLFreeTag( TagPtr tag
)
544 if (tag
== 0) return;
546 if (tag
->string
) FreeSymbol(tag
->string
);
548 XMLFreeTag(tag
->tag
);
549 XMLFreeTag(tag
->tagNext
);
551 // Clear and free the tag.
552 tag
->type
= kTagTypeNone
;
555 tag
->tagNext
= gTagsFree
;
562 //==========================================================================
571 typedef struct Symbol Symbol
, *SymbolPtr
;
573 static SymbolPtr
FindSymbol(char * string
, SymbolPtr
* prevSymbol
);
575 static SymbolPtr gSymbolsHead
;
577 //==========================================================================
581 NewSymbol( char * string
)
583 static SymbolPtr lastGuy
= 0;
586 // Look for string in the list of symbols.
587 symbol
= FindSymbol(string
, 0);
589 // Add the new symbol.
593 symbol
= (SymbolPtr
)malloc(sizeof(Symbol
) + 1 + strlen(string
));
595 symbol
= (SymbolPtr
)AllocateBootXMemory(sizeof(Symbol
) + 1 + strlen(string
));
597 if (symbol
== 0) //return 0;
598 stop("NULL symbol!");
600 // Set the symbol's data.
601 symbol
->refCount
= 0;
602 strcpy(symbol
->string
, string
);
604 // Add the symbol to the list.
605 symbol
->next
= gSymbolsHead
;
606 gSymbolsHead
= symbol
;
609 // Update the refCount and return the string.
612 if (lastGuy
&& lastGuy
->next
!= 0) stop("last guy not last!");
613 return symbol
->string
;
616 //==========================================================================
621 FreeSymbol( char * string
)
623 SymbolPtr symbol
, prev
;
625 // Look for string in the list of symbols.
626 symbol
= FindSymbol(string
, &prev
);
627 if (symbol
== 0) return;
629 // Update the refCount.
632 if (symbol
->refCount
!= 0) return;
634 // Remove the symbol from the list.
635 if (prev
!= 0) prev
->next
= symbol
->next
;
636 else gSymbolsHead
= symbol
->next
;
638 // Free the symbol's memory.
643 //==========================================================================
647 FindSymbol( char * string
, SymbolPtr
* prevSymbol
)
649 SymbolPtr symbol
, prev
;
651 symbol
= gSymbolsHead
;
654 while (symbol
!= 0) {
655 if (!strcmp(symbol
->string
, string
)) break;
658 symbol
= symbol
->next
;
661 if ((symbol
!= 0) && (prevSymbol
!= 0)) *prevSymbol
= prev
;