xmltok.c

来自「ARM上的如果你对底层感兴趣」· C语言 代码 · 共 1,445 行 · 第 1/3 页

C
1,445
字号
}

#define PREFIX(ident) little2_ ## ident
#define MINBPC 2
#define BYTE_TYPE(enc, p) \
 ((p)[1] == 0 \
  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
  : unicode_byte_type((p)[1], (p)[0]))
#define BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
#define CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
#define IS_NAME_CHAR(enc, p, n) (0)
#define IS_NAME_CHAR_MINBPC(enc, p) \
  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
#define IS_NMSTRT_CHAR(enc, p, n) (0)
#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])

#include "xmltok_impl.c"

#define SET2(ptr, ch) \
  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
#define GET_LO(ptr) ((unsigned char)(ptr)[0])
#define GET_HI(ptr) ((unsigned char)(ptr)[1])

DEFINE_UTF16_TO_UTF8
DEFINE_UTF16_TO_UTF16

#undef SET2
#undef GET_LO
#undef GET_HI
#undef MINBPC
#undef BYTE_TYPE
#undef BYTE_TO_ASCII
#undef CHAR_MATCHES
#undef IS_NAME_CHAR
#undef IS_NAME_CHAR_MINBPC
#undef IS_NMSTRT_CHAR
#undef IS_NMSTRT_CHAR_MINBPC
#undef IS_INVALID_CHAR

#ifdef XMLNS

static const struct normal_encoding little2_encoding_ns = { 
  { VTABLE, 2, 0,
#if BYTE_ORDER == 12
    1
#else
    0
#endif
  },
  {
#include "asciitab.h"
#include "latin1tab.h"
  }
};

#endif

static const struct normal_encoding little2_encoding = { 
  { VTABLE, 2, 0,
#if BYTE_ORDER == 12
    1
#else
    0
#endif
  },
  {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  }
};

#if BYTE_ORDER != 21

#ifdef XMLNS

static const struct normal_encoding internal_little2_encoding_ns = { 
  { VTABLE, 2, 0, 1 },
  {
#include "iasciitab.h"
#include "latin1tab.h"
  }
};

#endif

static const struct normal_encoding internal_little2_encoding = { 
  { VTABLE, 2, 0, 1 },
  {
#define BT_COLON BT_NMSTRT
#include "iasciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  }
};

#endif

#undef PREFIX

#define PREFIX(ident) big2_ ## ident
#define MINBPC 2
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
#define BYTE_TYPE(enc, p) \
 ((p)[0] == 0 \
  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
  : unicode_byte_type((p)[0], (p)[1]))
#define BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
#define CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
#define IS_NAME_CHAR(enc, p, n) 0
#define IS_NAME_CHAR_MINBPC(enc, p) \
  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
#define IS_NMSTRT_CHAR(enc, p, n) (0)
#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])

#include "xmltok_impl.c"

#define SET2(ptr, ch) \
  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
#define GET_LO(ptr) ((unsigned char)(ptr)[1])
#define GET_HI(ptr) ((unsigned char)(ptr)[0])

DEFINE_UTF16_TO_UTF8
DEFINE_UTF16_TO_UTF16

#undef SET2
#undef GET_LO
#undef GET_HI
#undef MINBPC
#undef BYTE_TYPE
#undef BYTE_TO_ASCII
#undef CHAR_MATCHES
#undef IS_NAME_CHAR
#undef IS_NAME_CHAR_MINBPC
#undef IS_NMSTRT_CHAR
#undef IS_NMSTRT_CHAR_MINBPC
#undef IS_INVALID_CHAR

#ifdef XMLNS

static const struct normal_encoding big2_encoding_ns = {
  { VTABLE, 2, 0,
#if BYTE_ORDER == 21
  1
#else
  0
#endif
  },
  {
#include "asciitab.h"
#include "latin1tab.h"
  }
};

#endif

static const struct normal_encoding big2_encoding = {
  { VTABLE, 2, 0,
#if BYTE_ORDER == 21
  1
#else
  0
#endif
  },
  {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  }
};

#if BYTE_ORDER != 12

#ifdef XMLNS

static const struct normal_encoding internal_big2_encoding_ns = {
  { VTABLE, 2, 0, 1 },
  {
#include "iasciitab.h"
#include "latin1tab.h"
  }
};

#endif

static const struct normal_encoding internal_big2_encoding = {
  { VTABLE, 2, 0, 1 },
  {
#define BT_COLON BT_NMSTRT
#include "iasciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  }
};

#endif

#undef PREFIX

static
int streqci(const char *s1, const char *s2)
{
  for (;;) {
    char c1 = *s1++;
    char c2 = *s2++;
    if ('a' <= c1 && c1 <= 'z')
      c1 += 'A' - 'a';
    if ('a' <= c2 && c2 <= 'z')
      c2 += 'A' - 'a';
    if (c1 != c2)
      return 0;
    if (!c1)
      break;
  }
  return 1;
}

static
int initScan(const ENCODING *enc, int state, const char *ptr, const char *end,
	     const char **nextTokPtr)
{
  const ENCODING **encPtr;

  if (ptr == end)
    return XML_TOK_NONE;
  encPtr = ((const INIT_ENCODING *)enc)->encPtr;
  if (ptr + 1 == end) {
    switch ((unsigned char)*ptr) {
    case 0xFE:
    case 0xFF:
    case 0x00:
    case 0x3C:
      return XML_TOK_PARTIAL;
    }
  }
  else {
    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
    case 0x003C:
      *encPtr = &big2_encoding.enc;
      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
    case 0xFEFF:
      *nextTokPtr = ptr + 2;
      *encPtr = &big2_encoding.enc;
      return XML_TOK_BOM;
    case 0x3C00:
      *encPtr = &little2_encoding.enc;
      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
    case 0xFFFE:
      *nextTokPtr = ptr + 2;
      *encPtr = &little2_encoding.enc;
      return XML_TOK_BOM;
    }
  }
  *encPtr = &utf8_encoding.enc;
  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
}

static
int initScanProlog(const ENCODING *enc, const char *ptr, const char *end,
		   const char **nextTokPtr)
{
  return initScan(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
}

static
int initScanContent(const ENCODING *enc, const char *ptr, const char *end,
		    const char **nextTokPtr)
{
  return initScan(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
}

static
void initUpdatePosition(const ENCODING *enc, const char *ptr,
			const char *end, POSITION *pos)
{
  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
}

const ENCODING *XmlGetUtf8InternalEncoding()
{
  return &internal_utf8_encoding.enc;
}

const ENCODING *XmlGetUtf16InternalEncoding()
{
#if BYTE_ORDER == 12
  return &internal_little2_encoding.enc;
#elif BYTE_ORDER == 21
  return &internal_big2_encoding.enc;
#else
  const short n = 1;
  return *(const char *)&n ? &internal_little2_encoding.enc : &internal_big2_encoding.enc;
#endif
}

int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
{
  if (name) {
    if (streqci(name, "ISO-8859-1")) {
      *encPtr = &latin1_encoding.enc;
      return 1;
    }
    if (streqci(name, "UTF-8")) {
      *encPtr = &utf8_encoding.enc;
      return 1;
    }
    if (streqci(name, "US-ASCII")) {
      *encPtr = &ascii_encoding.enc;
      return 1;
    }
    if (!streqci(name, "UTF-16"))
      return 0;
  }
  p->initEnc.scanners[XML_PROLOG_STATE] = initScanProlog;
  p->initEnc.scanners[XML_CONTENT_STATE] = initScanContent;
  p->initEnc.updatePosition = initUpdatePosition;
  p->initEnc.minBytesPerChar = 1;
  p->encPtr = encPtr;
  *encPtr = &(p->initEnc);
  return 1;
}

static
int toAscii(const ENCODING *enc, const char *ptr, const char *end)
{
  char buf[1];
  char *p = buf;
  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
  if (p == buf)
    return -1;
  else
    return buf[0];
}

static
int isSpace(int c)
{
  switch (c) {
  case ' ':
  case '\r':
  case '\n':
  case '\t':
    return 1;
  }
  return 0;
}

/* Return 1 if there's just optional white space
or there's an S followed by name=val. */
static
int parsePseudoAttribute(const ENCODING *enc,
			 const char *ptr,
			 const char *end,
			 const char **namePtr,
			 const char **valPtr,
			 const char **nextTokPtr)
{
  int c;
  char open;
  if (ptr == end) {
    *namePtr = 0;
    return 1;
  }
  if (!isSpace(toAscii(enc, ptr, end))) {
    *nextTokPtr = ptr;
    return 0;
  }
  do {
    ptr += enc->minBytesPerChar;
  } while (isSpace(toAscii(enc, ptr, end)));
  if (ptr == end) {
    *namePtr = 0;
    return 1;
  }
  *namePtr = ptr;
  for (;;) {
    c = toAscii(enc, ptr, end);
    if (c == -1) {
      *nextTokPtr = ptr;
      return 0;
    }
    if (c == '=')
      break;
    if (isSpace(c)) {
      do {
	ptr += enc->minBytesPerChar;
      } while (isSpace(c = toAscii(enc, ptr, end)));
      if (c != '=') {
	*nextTokPtr = ptr;
	return 0;
      }
      break;
    }
    ptr += enc->minBytesPerChar;
  }
  if (ptr == *namePtr) {
    *nextTokPtr = ptr;
    return 0;
  }
  ptr += enc->minBytesPerChar;
  c = toAscii(enc, ptr, end);
  while (isSpace(c)) {
    ptr += enc->minBytesPerChar;
    c = toAscii(enc, ptr, end);
  }
  if (c != '"' && c != '\'') {
    *nextTokPtr = ptr;
    return 0;
  }
  open = c;
  ptr += enc->minBytesPerChar;
  *valPtr = ptr;
  for (;; ptr += enc->minBytesPerChar) {
    c = toAscii(enc, ptr, end);
    if (c == open)
      break;
    if (!('a' <= c && c <= 'z')
	&& !('A' <= c && c <= 'Z')
	&& !('0' <= c && c <= '9')
	&& c != '.'
	&& c != '-'
	&& c != '_') {
      *nextTokPtr = ptr;
      return 0;
    }
  }
  *nextTokPtr = ptr + enc->minBytesPerChar;
  return 1;
}

static
const ENCODING *findEncoding(const ENCODING *enc, const char *ptr, const char *end)
{
#define ENCODING_MAX 128
  char buf[ENCODING_MAX];
  char *p = buf;
  int i;
  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
  if (ptr != end)
    return 0;
  *p = 0;
  for (i = 0; buf[i]; i++) {
    if ('a' <= buf[i] && buf[i] <= 'z')
      buf[i] +=  'A' - 'a';
  }
  if (streqci(buf, "UTF-8"))
    return &utf8_encoding.enc;
  if (streqci(buf, "ISO-8859-1"))
    return &latin1_encoding.enc;
  if (streqci(buf, "US-ASCII"))
    return &ascii_encoding.enc;
  if (streqci(buf, "UTF-16")) {
    static const unsigned short n = 1;
    if (enc->minBytesPerChar == 2)
      return enc;
    return &big2_encoding.enc;
  }
  return 0;  
}

static
int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
		                                     const char *,
						     const char *),
		   int isGeneralTextEntity,
		   const ENCODING *enc,
		   const char *ptr,
		   const char *end,
		   const char **badPtr,
		   const char **versionPtr,
		   const char **encodingName,
		   const ENCODING **encoding,
		   int *standalone)
{
  const char *val = 0;
  const char *name = 0;
  ptr += 5 * enc->minBytesPerChar;
  end -= 2 * enc->minBytesPerChar;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?