227 lines
4.1 KiB
C
227 lines
4.1 KiB
C
/** @file
|
|
XML parser
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2015, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
#include "UiControls.h"
|
|
|
|
#define TAG 1
|
|
#define CONTENT 2
|
|
#define QUOTE 3
|
|
|
|
#define MAX_ATTRIBS 128
|
|
|
|
STATIC
|
|
BOOLEAN
|
|
IsSpace (
|
|
INT32 c
|
|
)
|
|
{
|
|
return ((c<=' ' && (c==' ' || (c<=13 && c>=9))));
|
|
}
|
|
|
|
STATIC
|
|
VOID
|
|
ParserContent (
|
|
CHAR16 *Str,
|
|
SAX_PARSER_CONTENT_CALLBACK ContentCb,
|
|
VOID *Data
|
|
)
|
|
{
|
|
while (*Str != '\0' && IsSpace (*Str)) {
|
|
Str++;
|
|
}
|
|
|
|
if (*Str == '\0') {
|
|
return ;
|
|
}
|
|
|
|
if (ContentCb != NULL) {
|
|
(*ContentCb)(Data, Str);
|
|
}
|
|
}
|
|
|
|
|
|
STATIC
|
|
VOID
|
|
ParseElement (
|
|
IN OUT CHAR16 *Str,
|
|
IN SAX_PARSER_START_CALLBACK StartCb,
|
|
IN SAX_PARSER_END_CALLBACK EndCb,
|
|
IN OUT VOID *Data
|
|
)
|
|
{
|
|
CHAR16 *AttrNames[MAX_ATTRIBS];
|
|
CHAR16 *AttrValues[MAX_ATTRIBS];
|
|
UINTN AttrNum;
|
|
CHAR16 *TagName;
|
|
BOOLEAN IsStart;
|
|
BOOLEAN IsEnd;
|
|
CHAR16 QuoteChar;
|
|
|
|
AttrNum = 0;
|
|
TagName = NULL;
|
|
IsStart = FALSE;
|
|
IsEnd = FALSE;
|
|
|
|
//
|
|
// trim white space after the '<'
|
|
//
|
|
while (*Str != '\0' && IsSpace (*Str)) {
|
|
Str++;
|
|
}
|
|
|
|
//
|
|
// start tag or end tag
|
|
//
|
|
if (*Str == L'/') {
|
|
Str++;
|
|
IsEnd = TRUE;
|
|
} else {
|
|
IsStart = TRUE;
|
|
}
|
|
|
|
//
|
|
// commonts or preprocessor
|
|
//
|
|
if (*Str == '\0' || *Str == L'?' || *Str == '!') {
|
|
return ;
|
|
}
|
|
|
|
|
|
TagName = Str;
|
|
while (*Str !='\0' && !IsSpace (*Str) && *Str != '/') {
|
|
Str++;
|
|
}
|
|
|
|
if (*Str != '\0') {
|
|
if (*Str == '/') {
|
|
IsEnd = TRUE;
|
|
}
|
|
*Str++ = L'\0';
|
|
}
|
|
|
|
while (!IsEnd && *Str != '\0' && AttrNum < (MAX_ATTRIBS - 1)) {
|
|
|
|
while (*Str != '\0' && IsSpace (*Str)) {
|
|
Str++;
|
|
}
|
|
|
|
if (*Str == '\0') {
|
|
break;
|
|
}
|
|
|
|
if (*Str == '/') {
|
|
IsEnd = TRUE;
|
|
break;
|
|
}
|
|
|
|
AttrNames[AttrNum] = Str++;
|
|
AttrValues[AttrNum] = NULL;
|
|
while (*Str !='\0' && !IsSpace (*Str) && *Str != '=') {
|
|
Str++;
|
|
}
|
|
|
|
if (*Str != '\0') {
|
|
*Str++ = '\0';
|
|
}
|
|
|
|
//
|
|
// beginning of the value
|
|
//
|
|
while (*Str != '\0' && *Str != '\"' && *Str != '\'') {
|
|
Str++;
|
|
}
|
|
|
|
if (*Str == '\0') {
|
|
break;
|
|
}
|
|
|
|
QuoteChar = *Str;
|
|
Str++;
|
|
AttrValues[AttrNum++] = Str;
|
|
while (*Str != '\0' && *Str != QuoteChar) {
|
|
if (*Str == '\\' && *(Str + 1) == QuoteChar) {
|
|
Str += 2;
|
|
continue;
|
|
}
|
|
Str++;
|
|
}
|
|
if (*Str != '\0') {
|
|
*Str++ = '\0';
|
|
}
|
|
}
|
|
AttrNames[AttrNum] = NULL;
|
|
AttrValues[AttrNum++] = NULL;
|
|
|
|
if (IsStart && StartCb) {
|
|
(*StartCb)(Data, TagName, AttrNames, AttrValues);
|
|
}
|
|
if (IsEnd && EndCb) {
|
|
(*EndCb)(Data, TagName);
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
SaxParser (
|
|
CHAR16 *XMLBuffer,
|
|
SAX_PARSER_START_CALLBACK StartCb,
|
|
SAX_PARSER_CONTENT_CALLBACK ContentCb,
|
|
SAX_PARSER_END_CALLBACK EndCb,
|
|
VOID *Data
|
|
)
|
|
{
|
|
CHAR16 *Str;
|
|
CHAR16 *Mark;
|
|
UINTN State;
|
|
CHAR16 QuoteChar;
|
|
|
|
Str = XMLBuffer;
|
|
Mark = Str;
|
|
State = CONTENT;
|
|
QuoteChar = 0;
|
|
|
|
while (*Str != '\0') {
|
|
|
|
if (*Str == '<' && State == CONTENT) {
|
|
*Str++ = '\0';
|
|
ParserContent (Mark, ContentCb, Data);
|
|
Mark = Str;
|
|
State = TAG;
|
|
} else if (*Str == '\\' && State == QUOTE) {
|
|
if (*(Str + 1) == QuoteChar) {
|
|
Str += 2;
|
|
continue;
|
|
}
|
|
Str++;
|
|
} else if (*Str == '\"' || *Str == '\'') {
|
|
if (State == TAG) {
|
|
State = QUOTE;
|
|
QuoteChar = *Str;
|
|
} else if (State == QUOTE && *Str == QuoteChar) {
|
|
State = TAG;
|
|
}
|
|
Str++;
|
|
} else if (*Str == '>' && State == TAG) {
|
|
*Str++ = '\0';
|
|
ParseElement (Mark, StartCb, EndCb, Data);
|
|
Mark = Str;
|
|
State = CONTENT;
|
|
} else {
|
|
Str++;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|