?? icxmlparser.c
字號:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "icStringBuffer.h"
#include "icInputStream.h"
#include "icTable.h"
#include "icStack.h"
#include "icXmlNode.h"
#include "icXmlParser.h"
#include "errorctx.h"
/* This function classifies a char as either whitespace, '<', '>', '/',
* '=', '"', '&', ';', or other.
* <p>The return value is one of the following.
* <pre>
* <code>
* 0 (whitespace)
* VOLT_IC_CHAR_OPEN_ANGLE_BRACKET
* VOLT_IC_CHAR_CLOSE_ANGLE_BRACKET
* VOLT_IC_CHAR_SLASH
* VOLT_IC_CHAR_EQUAL
* VOLT_IC_CHAR_QUOTE
* VOLT_IC_CHAR_AMPERSAND
* VOLT_IC_CHAR_SEMICOLON
* VOLT_IC_CHAR_OTHER
* </code>
* </pre>
* Note that
*/
static int icClassifyChar (int theChar);
#define VOLT_IC_CHAR_OPEN_ANGLE_BRACKET 0x0001
#define VOLT_IC_CHAR_CLOSE_ANGLE_BRACKET 0x0002
#define VOLT_IC_CHAR_SLASH 0x0004
#define VOLT_IC_CHAR_EQUAL 0x0008
#define VOLT_IC_CHAR_QUOTE 0x0010
#define VOLT_IC_CHAR_AMPERSAND 0x0020
#define VOLT_IC_CHAR_SEMICOLON 0x0040
#define VOLT_IC_CHAR_OTHER 0x8000
/* The caller reads a char, then passes that char to this function.
*/
static int icXmlParserParseChar (
icXmlParser *parser,
int theChar,
VoltLibCtx *libCtx
);
static int icXmlHandleStartTag (
icXmlParser *parser,
char *tag_name,
icTable *attributes,
int is_empty,
VoltLibCtx *libCtx
);
static int icXmlHandleEndTag (
icXmlParser *parser,
char *tag_name,
VoltLibCtx *libCtx
);
static int icXmlHandleText (
icXmlParser *parser,
char *text,
VoltLibCtx *libCtx
);
static int translate_entity (
char *entity_name,
VoltLibCtx *libCtx
);
int icXmlParserCreate (
icXmlParser **parser,
VoltLibCtx *libCtx
)
{
int status;
icXmlParser *newParser = (icXmlParser *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
newParser = (icXmlParser *)Z3Malloc (sizeof (icXmlParser));
if (newParser == (icXmlParser *)0)
break;
Z2Memset (newParser, 0, sizeof (icXmlParser));
newParser->handle_start_tag = icXmlHandleStartTag;
newParser->handle_end_tag = icXmlHandleEndTag;
newParser->handle_text = icXmlHandleText;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icStackCreate (&(newParser->tag_stack), libCtx);
if (status != 0)
break;
*parser = newParser;
} while (0);
if (status == 0)
return (0);
/* If there was an error, free memory we allocated.
*/
icXmlParserFree (&newParser, libCtx);
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, errorType, fnctLine,
"icXmlParserCreate", (char *)0)
return (status);
}
void icXmlParserFree (
icXmlParser **parser,
VoltLibCtx *libCtx
)
{
icXmlParser *theParser;
/* Anything to free?
*/
if (parser == (icXmlParser **)0)
return;
if (*parser == (icXmlParser *)0)
return;
theParser = *parser;
icStringBufferFree (&(theParser->tag_name), libCtx);
icStringBufferFree (&(theParser->attribute_name), libCtx);
icStringBufferFree (&(theParser->attribute_value), libCtx);
icTableFree (&(theParser->attributes), libCtx);
icStringBufferFree (&(theParser->text), libCtx);
icStringBufferFree (&(theParser->entity_name), libCtx);
icXmlNodeFree (&(theParser->main), libCtx);
icStackFree (&(theParser->tag_stack), libCtx);
Z2Free (*parser);
*parser = (icXmlParser *)0;
}
int icXmlParserParse (
icXmlParser *parser,
icInputStream *in,
VoltLibCtx *libCtx
)
{
int status, bytesRead;
char theChar;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Skip the whitespace.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = icInputStreamSkipWhitespace (in, &bytesRead, libCtx);
/* Now process the bytes.
*/
while (status == 0)
{
/* Read a byte. If there are no more bytes, we're done.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = icInputStreamRead (in, &theChar, 1, &bytesRead, libCtx);
if (status != 0)
break;
if (bytesRead == 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = icXmlParserParseChar (parser, (int)theChar, libCtx);
}
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, 0, fnctLine,
"icXmlParserParse", (char *)0)
return (status);
}
/* Ok ... arguably this is one of the most heinous looking pieces of code
* you've been forced to bear witness upon in your life but fret not ...
* things are better than they seem. While the design on this monster
* isn't clear from the code, if you draw the DFA all becomes lucid.
* EOS is not an error and should be checked for outside this function.
*/
static int icXmlParserParseChar (
icXmlParser *parser,
int theChar,
VoltLibCtx *libCtx
)
{
int status, charClass, entityChar;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
charClass = icClassifyChar (theChar);
status = 0;
switch (parser->state)
{
case 0:
parser->state = 10;
if (charClass == VOLT_IC_CHAR_OPEN_ANGLE_BRACKET)
parser->state = 1;
break;
case 1:
parser->is_empty_tag = 0;
/* We're expecting the first character of a tag, so if it's close
* angle bracket or whitespace, error.
*/
parser->state = 10;
if ( (charClass == 0) ||
(charClass == VOLT_IC_CHAR_CLOSE_ANGLE_BRACKET) )
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferCreate (&(parser->tag_name), libCtx);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = icTableCreate (&(parser->attributes), libCtx);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferAppend (parser->tag_name, theChar, libCtx);
if (status != 0)
break;
parser->state = 2;
break;
case 2:
parser->state = 7;
if (charClass == VOLT_IC_CHAR_CLOSE_ANGLE_BRACKET)
break;
parser->state = 8;
if (charClass == VOLT_IC_CHAR_SLASH)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
if (charClass == 0)
{
parser->state = 3;
icStringBufferFree (&(parser->attribute_name), libCtx);
icStringBufferFree (&(parser->attribute_value), libCtx);
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferCreate (&(parser->attribute_name), libCtx);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferCreate (&(parser->attribute_value), libCtx);
break;
}
parser->state = 2;
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferAppend (parser->tag_name, theChar, libCtx);
break;
case 3:
if (charClass == 0)
break;
parser->state = 7;
if (charClass == VOLT_IC_CHAR_CLOSE_ANGLE_BRACKET)
break;
parser->state = 8;
if (charClass == VOLT_IC_CHAR_SLASH)
break;
parser->state = 4;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferAppend (parser->attribute_name, theChar, libCtx);
break;
case 4:
parser->state = 10;
if ( (charClass == VOLT_IC_CHAR_CLOSE_ANGLE_BRACKET) ||
(charClass == VOLT_IC_CHAR_SLASH) )
break;
parser->state = 5;
if (charClass == VOLT_IC_CHAR_EQUAL)
break;
parser->state = 4;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferAppend (parser->attribute_name, theChar, libCtx);
break;
case 5:
parser->state = 10;
if (charClass == VOLT_IC_CHAR_QUOTE)
parser->state = 6;
break;
case 6:
VOLT_SET_ERROR_TYPE (errorType, 0)
if (charClass != VOLT_IC_CHAR_QUOTE)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = icStringBufferAppend (
parser->attribute_value, theChar, libCtx);
break;
}
parser->state = 3;
VOLT_SET_FNCT_LINE (fnctLine)
status = icTablePut (
parser->attributes, parser->attribute_name->str,
parser->attribute_value->str, libCtx);
if (status != 0)
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -