⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icxmlparser.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2003-2005, 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 + -