📄 xmltok.c
字号:
/*The contents of this file are subject to the Mozilla Public LicenseVersion 1.0 (the "License"); you may not use this file except incompliance with the License. You may obtain a copy of the License athttp://www.mozilla.org/MPL/Software distributed under the License is distributed on an "AS IS"basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See theLicense for the specific language governing rights and limitationsunder the License.The Original Code is expat.The Initial Developer of the Original Code is James Clark.Portions created by James Clark are Copyright (C) 1998James Clark. All Rights Reserved.Contributor(s):*/#include "xmldef.h"#include "xmltok.h"#include "nametab.h"#define VTABLE1 \ { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ PREFIX(sameName), \ PREFIX(nameMatchesAscii), \ PREFIX(nameLength), \ PREFIX(skipS), \ PREFIX(getAtts), \ PREFIX(charRefNumber), \ PREFIX(predefinedEntityName), \ PREFIX(updatePosition), \ PREFIX(isPublicId)#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)#define UCS2_GET_NAMING(pages, hi, lo) \ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))/* A 2 byte UTF-8 representation splits the characters 11 bitsbetween the bottom 5 and 6 bits of the bytes.We need 8 bits to index into pages, 3 bits to add to that index and5 bits to generate the mask. */#define UTF8_GET_NAMING2(pages, byte) \ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) \ + ((((byte)[1]) >> 5) & 1)] \ & (1 << (((byte)[1]) & 0x1F)))/* A 3 byte UTF-8 representation splits the characters 16 bitsbetween the bottom 4, 6 and 6 bits of the bytes.We need 8 bits to index into pages, 3 bits to add to that index and5 bits to generate the mask. */#define UTF8_GET_NAMING3(pages, byte) \ (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ + ((((byte)[1]) >> 2) & 0xF)] \ << 3) \ + ((((byte)[1]) & 3) << 1) \ + ((((byte)[2]) >> 5) & 1)] \ & (1 << (((byte)[2]) & 0x1F)))#define UTF8_GET_NAMING(pages, p, n) \ ((n) == 2 \ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ : ((n) == 3 \ ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ : 0))#define UTF8_INVALID3(p) \ ((*p) == 0xED \ ? (((p)[1] & 0x20) != 0) \ : ((*p) == 0xEF \ ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \ : 0))#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)staticint isNever(const ENCODING *enc, const char *p){ return 0;}staticint utf8_isName2(const ENCODING *enc, const char *p){ return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);}staticint utf8_isName3(const ENCODING *enc, const char *p){ return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);}#define utf8_isName4 isNeverstaticint utf8_isNmstrt2(const ENCODING *enc, const char *p){ return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);}staticint utf8_isNmstrt3(const ENCODING *enc, const char *p){ return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);}#define utf8_isNmstrt4 isNever#define utf8_isInvalid2 isNeverstaticint utf8_isInvalid3(const ENCODING *enc, const char *p){ return UTF8_INVALID3((const unsigned char *)p);}staticint utf8_isInvalid4(const ENCODING *enc, const char *p){ return UTF8_INVALID4((const unsigned char *)p);}struct normal_encoding { ENCODING enc; unsigned char type[256]; int (*isName2)(const ENCODING *, const char *); int (*isName3)(const ENCODING *, const char *); int (*isName4)(const ENCODING *, const char *); int (*isNmstrt2)(const ENCODING *, const char *); int (*isNmstrt3)(const ENCODING *, const char *); int (*isNmstrt4)(const ENCODING *, const char *); int (*isInvalid2)(const ENCODING *, const char *); int (*isInvalid3)(const ENCODING *, const char *); int (*isInvalid4)(const ENCODING *, const char *);};#define NORMAL_VTABLE(E) \ E ## isName2, \ E ## isName3, \ E ## isName4, \ E ## isNmstrt2, \ E ## isNmstrt3, \ E ## isNmstrt4, \ E ## isInvalid2, \ E ## isInvalid3, \ E ## isInvalid4 static int checkCharRefNumber(int);#include "xmltok_impl.h"/* minimum bytes per character */#define MINBPC 1#define BYTE_TYPE(enc, p) \ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])#define BYTE_TO_ASCII(enc, p) (*p)#define IS_NAME_CHAR(enc, p, n) \ (((const struct normal_encoding *)(enc))->isName ## n(enc, p))#define IS_NMSTRT_CHAR(enc, p, n) \ (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))#define IS_INVALID_CHAR(enc, p, n) \ (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))#define IS_NAME_CHAR_MINBPC(enc, p) (0)#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)/* c is an ASCII character */#define CHAR_MATCHES(enc, p, c) (*(p) == c)#define PREFIX(ident) normal_ ## ident#include "xmltok_impl.c"#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_CHARenum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ UTF8_cval1 = 0x00, UTF8_cval2 = 0xc0, UTF8_cval3 = 0xe0, UTF8_cval4 = 0xf0};staticvoid utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim){ char *to; const char *from; if (fromLim - *fromP > toLim - *toP) { /* Avoid copying partial characters. */ for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) break; } for (to = *toP, from = *fromP; from != fromLim; from++, to++) *to = *from; *fromP = from; *toP = to;}staticvoid utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim){ unsigned short *to = *toP; const char *from = *fromP; while (from != fromLim && to != toLim) { switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { case BT_LEAD2: *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f); from += 2; break; case BT_LEAD3: *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f); from += 3; break; case BT_LEAD4: { unsigned long n; if (to + 1 == toLim) break; n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); n -= 0x10000; to[0] = (unsigned short)((n >> 10) | 0xD800); to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); to += 2; from += 4; } break; default: *to++ = *from++; break; } } *fromP = from; *toP = to;}static const struct normal_encoding utf8_encoding = { { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, {#include "asciitab.h"#include "utf8tab.h" }, NORMAL_VTABLE(utf8_)};static const struct normal_encoding internal_utf8_encoding = { { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, {#include "iasciitab.h"#include "utf8tab.h" }, NORMAL_VTABLE(utf8_)};staticvoid latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim){ for (;;) { unsigned char c; if (*fromP == fromLim) break; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2) break; *(*toP)++ = ((c >> 6) | UTF8_cval2); *(*toP)++ = ((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim) break; *(*toP)++ = *(*fromP)++; } }}staticvoid latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim){ while (*fromP != fromLim && *toP != toLim) *(*toP)++ = (unsigned char)*(*fromP)++;}static const struct normal_encoding latin1_encoding = { { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, {#include "asciitab.h"#include "latin1tab.h" }};staticvoid ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim){ while (*fromP != fromLim && *toP != toLim) *(*toP)++ = *(*fromP)++;}static const struct normal_encoding ascii_encoding = { { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, {#include "asciitab.h"/* BT_NONXML == 0 */ }};#undef PREFIXstatic int unicode_byte_type(char hi, char lo){ switch ((unsigned char)hi) { case 0xD8: case 0xD9: case 0xDA: case 0xDB: return BT_LEAD4; case 0xDC: case 0xDD: case 0xDE: case 0xDF: return BT_TRAIL; case 0xFF: switch ((unsigned char)lo) { case 0xFF: case 0xFE: return BT_NONXML; } break; } return BT_NONASCII;}#define DEFINE_UTF16_TO_UTF8 \static \void PREFIX(toUtf8)(const ENCODING *enc, \ const char **fromP, const char *fromLim, \ char **toP, const char *toLim) \{ \ const char *from; \ for (from = *fromP; from != fromLim; from += 2) { \ int plane; \ unsigned char lo2; \ unsigned char lo = GET_LO(from); \ unsigned char hi = GET_HI(from); \ switch (hi) { \ case 0: \ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \ return; \ } \ *(*toP)++ = lo; \ break; \ } \ /* fall through */ \ case 0x1: case 0x2: case 0x3: \ case 0x4: case 0x5: case 0x6: case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \ return; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ default: \ if (toLim - *toP < 3) { \ *fromP = from; \ return; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \ return; \ } \ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ from += 2; \ lo2 = GET_LO(from); \ *(*toP)++ = (((lo & 0x3) << 4) \ | ((GET_HI(from) & 0x3) << 2) \ | (lo2 >> 6) \ | 0x80); \ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ break; \ } \ } \ *fromP = from; \}#define DEFINE_UTF16_TO_UTF16 \static \void PREFIX(toUtf16)(const ENCODING *enc, \ const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) \{ \ /* Avoid copying first half only of surrogate */ \ if (fromLim - *fromP > ((toLim - *toP) << 1) \ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ fromLim -= 2; \ for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \}#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_UTF8DEFINE_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_CHARstatic const struct normal_encoding little2_encoding = { { VTABLE, 2, 0,#if BYTE_ORDER == 12 1#else 0#endif },#include "asciitab.h"#include "latin1tab.h"};#if BYTE_ORDER != 21static const struct normal_encoding internal_little2_encoding = { { VTABLE, 2, 0, 1 },#include "iasciitab.h"#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_UTF8DEFINE_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_CHARstatic const struct normal_encoding big2_encoding = { { VTABLE, 2, 0,#if BYTE_ORDER == 21 1#else 0#endif },#include "asciitab.h"#include "latin1tab.h"};#if BYTE_ORDER != 12static const struct normal_encoding internal_big2_encoding = { { VTABLE, 2, 0, 1 },#include "iasciitab.h"#include "latin1tab.h"};#endif#undef PREFIXstaticint 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -