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 1.2 (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
;
114 //==========================================================================
116 // Expects to see one dictionary in the XML file.
117 // Puts the first dictionary it finds in the
118 // tag pointer and returns 0, or returns -1 if not found.
121 XMLParseFile( char * buffer
, TagPtr
* dict
)
129 length
= XMLParseNextTag(buffer
+ pos
, &tag
);
130 if (length
== -1) break;
134 if (tag
== 0) continue;
135 if (tag
->type
== kTagTypeDict
) break;
146 //==========================================================================
150 XMLParseNextTag( char * buffer
, TagPtr
* tag
)
155 length
= GetNextTag(buffer
, &tagName
, 0);
156 if (length
== -1) return -1;
159 if (!strncmp(tagName
, kXMLTagPList
, 6))
163 else if (!strcmp(tagName
, kXMLTagDict
))
165 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeDict
, 0);
167 else if (!strcmp(tagName
, kXMLTagDict
"/"))
169 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeDict
, 1);
171 else if (!strcmp(tagName
, kXMLTagKey
))
173 length
= ParseTagKey(buffer
+ pos
, tag
);
175 else if (!strcmp(tagName
, kXMLTagString
))
177 length
= ParseTagString(buffer
+ pos
, tag
);
179 else if (!strcmp(tagName
, kXMLTagInteger
))
181 length
= ParseTagInteger(buffer
+ pos
, tag
);
183 else if (!strcmp(tagName
, kXMLTagData
))
185 length
= ParseTagData(buffer
+ pos
, tag
);
187 else if (!strcmp(tagName
, kXMLTagDate
))
189 length
= ParseTagDate(buffer
+ pos
, tag
);
191 else if (!strcmp(tagName
, kXMLTagFalse
))
193 length
= ParseTagBoolean(buffer
+ pos
, tag
, kTagTypeFalse
);
195 else if (!strcmp(tagName
, kXMLTagTrue
))
197 length
= ParseTagBoolean(buffer
+ pos
, tag
, kTagTypeTrue
);
199 else if (!strcmp(tagName
, kXMLTagArray
))
201 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeArray
, 0);
203 else if (!strcmp(tagName
, kXMLTagArray
"/"))
205 length
= ParseTagList(buffer
+ pos
, tag
, kTagTypeArray
, 1);
213 if (length
== -1) return -1;
218 //==========================================================================
222 ParseTagList( char * buffer
, TagPtr
* tag
, long type
, long empty
)
225 TagPtr tagList
, tmpTag
;
234 length
= XMLParseNextTag(buffer
+ pos
, &tmpTag
);
235 if (length
== -1) break;
239 if (tmpTag
== 0) break;
240 tmpTag
->tagNext
= tagList
;
260 tmpTag
->tag
= tagList
;
268 //==========================================================================
272 ParseTagKey( char * buffer
, TagPtr
* tag
)
274 long length
, length2
;
276 TagPtr tmpTag
, subTag
;
278 length
= FixDataMatchingTag(buffer
, kXMLTagKey
);
279 if (length
== -1) return -1;
281 length2
= XMLParseNextTag(buffer
+ length
, &subTag
);
282 if (length2
== -1) return -1;
291 string
= NewSymbol(buffer
);
299 tmpTag
->type
= kTagTypeKey
;
300 tmpTag
->string
= string
;
301 tmpTag
->tag
= subTag
;
306 return length
+ length2
;
309 //==========================================================================
313 ParseTagString( char * buffer
, TagPtr
* tag
)
319 length
= FixDataMatchingTag(buffer
, kXMLTagString
);
320 if (length
== -1) return -1;
323 if (tmpTag
== 0) return -1;
325 string
= NewSymbol(buffer
);
332 tmpTag
->type
= kTagTypeString
;
333 tmpTag
->string
= string
;
341 //==========================================================================
345 ParseTagInteger( char * buffer
, TagPtr
* tag
)
347 long length
, integer
;
350 length
= FixDataMatchingTag(buffer
, kXMLTagInteger
);
351 if (length
== -1) return -1;
354 if (tmpTag
== 0) return -1;
358 tmpTag
->type
= kTagTypeInteger
;
359 tmpTag
->string
= (char *)integer
;
368 //==========================================================================
372 ParseTagData( char * buffer
, TagPtr
* tag
)
377 length
= FixDataMatchingTag(buffer
, kXMLTagData
);
378 if (length
== -1) return -1;
381 if (tmpTag
== 0) return -1;
383 tmpTag
->type
= kTagTypeData
;
393 //==========================================================================
397 ParseTagDate( char * buffer
, TagPtr
* tag
)
402 length
= FixDataMatchingTag(buffer
, kXMLTagDate
);
403 if (length
== -1) return -1;
406 if (tmpTag
== 0) return -1;
408 tmpTag
->type
= kTagTypeDate
;
418 //==========================================================================
422 ParseTagBoolean( char * buffer
, TagPtr
* tag
, long type
)
427 if (tmpTag
== 0) return -1;
439 //==========================================================================
443 GetNextTag( char * buffer
, char ** tag
, long * start
)
447 if (tag
== 0) return -1;
449 // Find the start of the tag.
451 while ((buffer
[cnt
] != '\0') && (buffer
[cnt
] != '<')) cnt
++;
452 if (buffer
[cnt
] == '\0') return -1;
454 // Find the end of the tag.
456 while ((buffer
[cnt2
] != '\0') && (buffer
[cnt2
] != '>')) cnt2
++;
457 if (buffer
[cnt2
] == '\0') return -1;
460 *tag
= buffer
+ cnt
+ 1;
462 if (start
) *start
= cnt
;
467 //==========================================================================
468 // FixDataMatchingTag
469 // Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.
470 // Returns the length of the data found, counting the end tag,
471 // or -1 if the end tag was not found.
474 FixDataMatchingTag( char * buffer
, char * tag
)
476 long length
, start
, stop
;
482 length
= GetNextTag(buffer
+ start
, &endTag
, &stop
);
483 if (length
== -1) return -1;
485 if ((*endTag
== '/') && !strcmp(endTag
+ 1, tag
)) break;
489 buffer
[start
+ stop
] = '\0';
491 return start
+ length
;
494 //==========================================================================
497 #define kTagsPerBlock (0x1000)
499 static TagPtr gTagsFree
;
510 tag
= (TagPtr
)malloc(kTagsPerBlock
* sizeof(Tag
));
512 tag
= (TagPtr
)AllocateBootXMemory(kTagsPerBlock
* sizeof(Tag
));
514 if (tag
== 0) return 0;
516 // Initalize the new tags.
517 for (cnt
= 0; cnt
< kTagsPerBlock
; cnt
++)
519 tag
[cnt
].type
= kTagTypeNone
;
522 tag
[cnt
].tagNext
= tag
+ cnt
+ 1;
524 tag
[kTagsPerBlock
- 1].tagNext
= 0;
530 gTagsFree
= tag
->tagNext
;
535 //==========================================================================
539 XMLFreeTag( TagPtr tag
)
542 if (tag
== 0) return;
544 if (tag
->string
) FreeSymbol(tag
->string
);
546 XMLFreeTag(tag
->tag
);
547 XMLFreeTag(tag
->tagNext
);
549 // Clear and free the tag.
550 tag
->type
= kTagTypeNone
;
553 tag
->tagNext
= gTagsFree
;
560 //==========================================================================
569 typedef struct Symbol Symbol
, *SymbolPtr
;
571 static SymbolPtr
FindSymbol(char * string
, SymbolPtr
* prevSymbol
);
573 static SymbolPtr gSymbolsHead
;
575 //==========================================================================
579 NewSymbol( char * string
)
581 static SymbolPtr lastGuy
= 0;
584 // Look for string in the list of symbols.
585 symbol
= FindSymbol(string
, 0);
587 // Add the new symbol.
591 symbol
= (SymbolPtr
)malloc(sizeof(Symbol
) + 1 + strlen(string
));
593 symbol
= (SymbolPtr
)AllocateBootXMemory(sizeof(Symbol
) + 1 + strlen(string
));
595 if (symbol
== 0) //return 0;
596 stop("NULL symbol!");
598 // Set the symbol's data.
599 symbol
->refCount
= 0;
600 strcpy(symbol
->string
, string
);
602 // Add the symbol to the list.
603 symbol
->next
= gSymbolsHead
;
604 gSymbolsHead
= symbol
;
607 // Update the refCount and return the string.
610 if (lastGuy
&& lastGuy
->next
!= 0) stop("last guy not last!");
611 return symbol
->string
;
614 //==========================================================================
619 FreeSymbol( char * string
)
621 SymbolPtr symbol
, prev
;
623 // Look for string in the list of symbols.
624 symbol
= FindSymbol(string
, &prev
);
625 if (symbol
== 0) return;
627 // Update the refCount.
630 if (symbol
->refCount
!= 0) return;
632 // Remove the symbol from the list.
633 if (prev
!= 0) prev
->next
= symbol
->next
;
634 else gSymbolsHead
= symbol
->next
;
636 // Free the symbol's memory.
641 //==========================================================================
645 FindSymbol( char * string
, SymbolPtr
* prevSymbol
)
647 SymbolPtr symbol
, prev
;
649 symbol
= gSymbolsHead
;
652 while (symbol
!= 0) {
653 if (!strcmp(symbol
->string
, string
)) break;
656 symbol
= symbol
->next
;
659 if ((symbol
!= 0) && (prevSymbol
!= 0)) *prevSymbol
= prev
;