xmltok.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:39k
源码类别:

Symbian

开发平台:

C/C++

  1. /*
  2. Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
  3. See the file copying.txt for copying permission.
  4. */
  5. #include "xmldef.h"
  6. #include "xmltok.h"
  7. #include "nametab.h"
  8. #ifdef XML_DTD
  9. #define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
  10. #else
  11. #define IGNORE_SECTION_TOK_VTABLE /* as nothing */
  12. #endif
  13. #define VTABLE1 
  14.   { PREFIX(prologTok), PREFIX(contentTok), 
  15.     PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, 
  16.   { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, 
  17.   PREFIX(sameName), 
  18.   PREFIX(nameMatchesAscii), 
  19.   PREFIX(nameLength), 
  20.   PREFIX(skipS), 
  21.   PREFIX(getAtts), 
  22.   PREFIX(charRefNumber), 
  23.   PREFIX(predefinedEntityName), 
  24.   PREFIX(updatePosition), 
  25.   PREFIX(isPublicId)
  26. #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
  27. #define UCS2_GET_NAMING(pages, hi, lo) 
  28.    (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
  29. /* A 2 byte UTF-8 representation splits the characters 11 bits
  30. between the bottom 5 and 6 bits of the bytes.
  31. We need 8 bits to index into pages, 3 bits to add to that index and
  32. 5 bits to generate the mask. */
  33. #define UTF8_GET_NAMING2(pages, byte) 
  34.     (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) 
  35.                       + ((((byte)[0]) & 3) << 1) 
  36.                       + ((((byte)[1]) >> 5) & 1)] 
  37.          & (1 << (((byte)[1]) & 0x1F)))
  38. /* A 3 byte UTF-8 representation splits the characters 16 bits
  39. between the bottom 4, 6 and 6 bits of the bytes.
  40. We need 8 bits to index into pages, 3 bits to add to that index and
  41. 5 bits to generate the mask. */
  42. #define UTF8_GET_NAMING3(pages, byte) 
  43.   (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) 
  44.                              + ((((byte)[1]) >> 2) & 0xF)] 
  45.        << 3) 
  46.                       + ((((byte)[1]) & 3) << 1) 
  47.                       + ((((byte)[2]) >> 5) & 1)] 
  48.          & (1 << (((byte)[2]) & 0x1F)))
  49. #define UTF8_GET_NAMING(pages, p, n) 
  50.   ((n) == 2 
  51.   ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) 
  52.   : ((n) == 3 
  53.      ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) 
  54.      : 0))
  55. #define UTF8_INVALID3(p) 
  56.   ((*p) == 0xED 
  57.   ? (((p)[1] & 0x20) != 0) 
  58.   : ((*p) == 0xEF 
  59.      ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) 
  60.      : 0))
  61. #define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
  62. static
  63. int isNever(const ENCODING *enc, const char *p)
  64. {
  65.   return 0;
  66. }
  67. static
  68. int utf8_isName2(const ENCODING *enc, const char *p)
  69. {
  70.   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
  71. }
  72. static
  73. int utf8_isName3(const ENCODING *enc, const char *p)
  74. {
  75.   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
  76. }
  77. #define utf8_isName4 isNever
  78. static
  79. int utf8_isNmstrt2(const ENCODING *enc, const char *p)
  80. {
  81.   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
  82. }
  83. static
  84. int utf8_isNmstrt3(const ENCODING *enc, const char *p)
  85. {
  86.   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
  87. }
  88. #define utf8_isNmstrt4 isNever
  89. #define utf8_isInvalid2 isNever
  90. static
  91. int utf8_isInvalid3(const ENCODING *enc, const char *p)
  92. {
  93.   return UTF8_INVALID3((const unsigned char *)p);
  94. }
  95. static
  96. int utf8_isInvalid4(const ENCODING *enc, const char *p)
  97. {
  98.   return UTF8_INVALID4((const unsigned char *)p);
  99. }
  100. struct normal_encoding {
  101.   ENCODING enc;
  102.   unsigned char type[256];
  103. #ifdef XML_MIN_SIZE
  104.   int (*byteType)(const ENCODING *, const char *);
  105.   int (*isNameMin)(const ENCODING *, const char *);
  106.   int (*isNmstrtMin)(const ENCODING *, const char *);
  107.   int (*byteToAscii)(const ENCODING *, const char *);
  108.   int (*charMatches)(const ENCODING *, const char *, int);
  109. #endif /* XML_MIN_SIZE */
  110.   int (*isName2)(const ENCODING *, const char *);
  111.   int (*isName3)(const ENCODING *, const char *);
  112.   int (*isName4)(const ENCODING *, const char *);
  113.   int (*isNmstrt2)(const ENCODING *, const char *);
  114.   int (*isNmstrt3)(const ENCODING *, const char *);
  115.   int (*isNmstrt4)(const ENCODING *, const char *);
  116.   int (*isInvalid2)(const ENCODING *, const char *);
  117.   int (*isInvalid3)(const ENCODING *, const char *);
  118.   int (*isInvalid4)(const ENCODING *, const char *);
  119. };
  120. #ifdef XML_MIN_SIZE
  121. #define STANDARD_VTABLE(E) 
  122.  E ## byteType, 
  123.  E ## isNameMin, 
  124.  E ## isNmstrtMin, 
  125.  E ## byteToAscii, 
  126.  E ## charMatches,
  127. #else
  128. #define STANDARD_VTABLE(E) /* as nothing */
  129. #endif
  130. #define NORMAL_VTABLE(E) 
  131.  E ## isName2, 
  132.  E ## isName3, 
  133.  E ## isName4, 
  134.  E ## isNmstrt2, 
  135.  E ## isNmstrt3, 
  136.  E ## isNmstrt4, 
  137.  E ## isInvalid2, 
  138.  E ## isInvalid3, 
  139.  E ## isInvalid4
  140. static int checkCharRefNumber(int);
  141. #include "xmltok_impl.h"
  142. #include "ascii.h"
  143. #ifdef XML_MIN_SIZE
  144. #define sb_isNameMin isNever
  145. #define sb_isNmstrtMin isNever
  146. #endif
  147. #ifdef XML_MIN_SIZE
  148. #define MINBPC(enc) ((enc)->minBytesPerChar)
  149. #else
  150. /* minimum bytes per character */
  151. #define MINBPC(enc) 1
  152. #endif
  153. #define SB_BYTE_TYPE(enc, p) 
  154.   (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
  155. #ifdef XML_MIN_SIZE
  156. static
  157. int sb_byteType(const ENCODING *enc, const char *p)
  158. {
  159.   return SB_BYTE_TYPE(enc, p);
  160. }
  161. #define BYTE_TYPE(enc, p) 
  162.  (((const struct normal_encoding *)(enc))->byteType(enc, p))
  163. #else
  164. #define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
  165. #endif
  166. #ifdef XML_MIN_SIZE
  167. #define BYTE_TO_ASCII(enc, p) 
  168.  (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
  169. static
  170. int sb_byteToAscii(const ENCODING *enc, const char *p)
  171. {
  172.   return *p;
  173. }
  174. #else
  175. #define BYTE_TO_ASCII(enc, p) (*(p))
  176. #endif
  177. #define IS_NAME_CHAR(enc, p, n) 
  178.  (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
  179. #define IS_NMSTRT_CHAR(enc, p, n) 
  180.  (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
  181. #define IS_INVALID_CHAR(enc, p, n) 
  182.  (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
  183. #ifdef XML_MIN_SIZE
  184. #define IS_NAME_CHAR_MINBPC(enc, p) 
  185.  (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
  186. #define IS_NMSTRT_CHAR_MINBPC(enc, p) 
  187.  (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
  188. #else
  189. #define IS_NAME_CHAR_MINBPC(enc, p) (0)
  190. #define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
  191. #endif
  192. #ifdef XML_MIN_SIZE
  193. #define CHAR_MATCHES(enc, p, c) 
  194.  (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
  195. static
  196. int sb_charMatches(const ENCODING *enc, const char *p, int c)
  197. {
  198.   return *p == c;
  199. }
  200. #else
  201. /* c is an ASCII character */
  202. #define CHAR_MATCHES(enc, p, c) (*(p) == c)
  203. #endif
  204. #define PREFIX(ident) normal_ ## ident
  205. #include "xmltok_impl.c"
  206. #undef MINBPC
  207. #undef BYTE_TYPE
  208. #undef BYTE_TO_ASCII
  209. #undef CHAR_MATCHES
  210. #undef IS_NAME_CHAR
  211. #undef IS_NAME_CHAR_MINBPC
  212. #undef IS_NMSTRT_CHAR
  213. #undef IS_NMSTRT_CHAR_MINBPC
  214. #undef IS_INVALID_CHAR
  215. enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
  216.   UTF8_cval1 = 0x00,
  217.   UTF8_cval2 = 0xc0,
  218.   UTF8_cval3 = 0xe0,
  219.   UTF8_cval4 = 0xf0
  220. };
  221. static
  222. void utf8_toUtf8(const ENCODING *enc,
  223.  const char **fromP, const char *fromLim,
  224.  char **toP, const char *toLim)
  225. {
  226.   char *to;
  227.   const char *from;
  228.   if (fromLim - *fromP > toLim - *toP) {
  229.     /* Avoid copying partial characters. */
  230.     for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
  231.       if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
  232. break;
  233.   }
  234.   for (to = *toP, from = *fromP; from != fromLim; from++, to++)
  235.     *to = *from;
  236.   *fromP = from;
  237.   *toP = to;
  238. }
  239. static
  240. void utf8_toUtf16(const ENCODING *enc,
  241.   const char **fromP, const char *fromLim,
  242.   unsigned short **toP, const unsigned short *toLim)
  243. {
  244.   unsigned short *to = *toP;
  245.   const char *from = *fromP;
  246.   while (from != fromLim && to != toLim) {
  247.     switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
  248.     case BT_LEAD2:
  249.       *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
  250.       from += 2;
  251.       break;
  252.     case BT_LEAD3:
  253.       *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
  254.       from += 3;
  255.       break;
  256.     case BT_LEAD4:
  257.       {
  258. unsigned long n;
  259. if (to + 1 == toLim)
  260.   break;
  261. n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
  262. n -= 0x10000;
  263. to[0] = (unsigned short)((n >> 10) | 0xD800);
  264. to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
  265. to += 2;
  266. from += 4;
  267.       }
  268.       break;
  269.     default:
  270.       *to++ = *from++;
  271.       break;
  272.     }
  273.   }
  274.   *fromP = from;
  275.   *toP = to;
  276. }
  277. #ifdef XML_NS
  278. static const struct normal_encoding utf8_encoding_ns = {
  279.   { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
  280.   {
  281. #include "asciitab.h"
  282. #include "utf8tab.h"
  283.   },
  284.   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
  285. };
  286. #endif
  287. static const struct normal_encoding utf8_encoding = {
  288.   { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
  289.   {
  290. #define BT_COLON BT_NMSTRT
  291. #include "asciitab.h"
  292. #undef BT_COLON
  293. #include "utf8tab.h"
  294.   },
  295.   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
  296. };
  297. #ifdef XML_NS
  298. static const struct normal_encoding internal_utf8_encoding_ns = {
  299.   { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
  300.   {
  301. #include "iasciitab.h"
  302. #include "utf8tab.h"
  303.   },
  304.   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
  305. };
  306. #endif
  307. static const struct normal_encoding internal_utf8_encoding = {
  308.   { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
  309.   {
  310. #define BT_COLON BT_NMSTRT
  311. #include "iasciitab.h"
  312. #undef BT_COLON
  313. #include "utf8tab.h"
  314.   },
  315.   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
  316. };
  317. static
  318. void latin1_toUtf8(const ENCODING *enc,
  319.    const char **fromP, const char *fromLim,
  320.    char **toP, const char *toLim)
  321. {
  322.   for (;;) {
  323.     unsigned char c;
  324.     if (*fromP == fromLim)
  325.       break;
  326.     c = (unsigned char)**fromP;
  327.     if (c & 0x80) {
  328.       if (toLim - *toP < 2)
  329. break;
  330.       *(*toP)++ = ((c >> 6) | UTF8_cval2);
  331.       *(*toP)++ = ((c & 0x3f) | 0x80);
  332.       (*fromP)++;
  333.     }
  334.     else {
  335.       if (*toP == toLim)
  336. break;
  337.       *(*toP)++ = *(*fromP)++;
  338.     }
  339.   }
  340. }
  341. static
  342. void latin1_toUtf16(const ENCODING *enc,
  343.     const char **fromP, const char *fromLim,
  344.     unsigned short **toP, const unsigned short *toLim)
  345. {
  346.   while (*fromP != fromLim && *toP != toLim)
  347.     *(*toP)++ = (unsigned char)*(*fromP)++;
  348. }
  349. #ifdef XML_NS
  350. static const struct normal_encoding latin1_encoding_ns = {
  351.   { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
  352.   {
  353. #include "asciitab.h"
  354. #include "latin1tab.h"
  355.   },
  356.   STANDARD_VTABLE(sb_)
  357. };
  358. #endif
  359. static const struct normal_encoding latin1_encoding = {
  360.   { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
  361.   {
  362. #define BT_COLON BT_NMSTRT
  363. #include "asciitab.h"
  364. #undef BT_COLON
  365. #include "latin1tab.h"
  366.   },
  367.   STANDARD_VTABLE(sb_)
  368. };
  369. static
  370. void ascii_toUtf8(const ENCODING *enc,
  371.   const char **fromP, const char *fromLim,
  372.   char **toP, const char *toLim)
  373. {
  374.   while (*fromP != fromLim && *toP != toLim)
  375.     *(*toP)++ = *(*fromP)++;
  376. }
  377. #ifdef XML_NS
  378. static const struct normal_encoding ascii_encoding_ns = {
  379.   { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
  380.   {
  381. #include "asciitab.h"
  382. /* BT_NONXML == 0 */
  383.   },
  384.   STANDARD_VTABLE(sb_)
  385. };
  386. #endif
  387. static const struct normal_encoding ascii_encoding = {
  388.   { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
  389.   {
  390. #define BT_COLON BT_NMSTRT
  391. #include "asciitab.h"
  392. #undef BT_COLON
  393. /* BT_NONXML == 0 */
  394.   },
  395.   STANDARD_VTABLE(sb_)
  396. };
  397. static int unicode_byte_type(char hi, char lo)
  398. {
  399.   switch ((unsigned char)hi) {
  400.   case 0xD8: case 0xD9: case 0xDA: case 0xDB:
  401.     return BT_LEAD4;
  402.   case 0xDC: case 0xDD: case 0xDE: case 0xDF:
  403.     return BT_TRAIL;
  404.   case 0xFF:
  405.     switch ((unsigned char)lo) {
  406.     case 0xFF:
  407.     case 0xFE:
  408.       return BT_NONXML;
  409.     }
  410.     break;
  411.   }
  412.   return BT_NONASCII;
  413. }
  414. #define DEFINE_UTF16_TO_UTF8(E) 
  415. static 
  416. void E ## toUtf8(const ENCODING *enc, 
  417.  const char **fromP, const char *fromLim, 
  418.  char **toP, const char *toLim) 
  419.   const char *from; 
  420.   for (from = *fromP; from != fromLim; from += 2) { 
  421.     int plane; 
  422.     unsigned char lo2; 
  423.     unsigned char lo = GET_LO(from); 
  424.     unsigned char hi = GET_HI(from); 
  425.     switch (hi) { 
  426.     case 0: 
  427.       if (lo < 0x80) { 
  428.         if (*toP == toLim) { 
  429.           *fromP = from; 
  430.   return; 
  431.         } 
  432.         *(*toP)++ = lo; 
  433.         break; 
  434.       } 
  435.       /* fall through */ 
  436.     case 0x1: case 0x2: case 0x3: 
  437.     case 0x4: case 0x5: case 0x6: case 0x7: 
  438.       if (toLim -  *toP < 2) { 
  439.         *fromP = from; 
  440. return; 
  441.       } 
  442.       *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); 
  443.       *(*toP)++ = ((lo & 0x3f) | 0x80); 
  444.       break; 
  445.     default: 
  446.       if (toLim -  *toP < 3)  { 
  447.         *fromP = from; 
  448. return; 
  449.       } 
  450.       /* 16 bits divided 4, 6, 6 amongst 3 bytes */ 
  451.       *(*toP)++ = ((hi >> 4) | UTF8_cval3); 
  452.       *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); 
  453.       *(*toP)++ = ((lo & 0x3f) | 0x80); 
  454.       break; 
  455.     case 0xD8: case 0xD9: case 0xDA: case 0xDB: 
  456.       if (toLim -  *toP < 4) { 
  457. *fromP = from; 
  458. return; 
  459.       } 
  460.       plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; 
  461.       *(*toP)++ = ((plane >> 2) | UTF8_cval4); 
  462.       *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); 
  463.       from += 2; 
  464.       lo2 = GET_LO(from); 
  465.       *(*toP)++ = (((lo & 0x3) << 4) 
  466.            | ((GET_HI(from) & 0x3) << 2) 
  467.    | (lo2 >> 6) 
  468.    | 0x80); 
  469.       *(*toP)++ = ((lo2 & 0x3f) | 0x80); 
  470.       break; 
  471.     } 
  472.   } 
  473.   *fromP = from; 
  474. }
  475. #define DEFINE_UTF16_TO_UTF16(E) 
  476. static 
  477. void E ## toUtf16(const ENCODING *enc, 
  478.   const char **fromP, const char *fromLim, 
  479.   unsigned short **toP, const unsigned short *toLim) 
  480.   /* Avoid copying first half only of surrogate */ 
  481.   if (fromLim - *fromP > ((toLim - *toP) << 1) 
  482.       && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) 
  483.     fromLim -= 2; 
  484.   for (; *fromP != fromLim && *toP != toLim; *fromP += 2) 
  485.     *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); 
  486. }
  487. #define SET2(ptr, ch) 
  488.   (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
  489. #define GET_LO(ptr) ((unsigned char)(ptr)[0])
  490. #define GET_HI(ptr) ((unsigned char)(ptr)[1])
  491. DEFINE_UTF16_TO_UTF8(little2_)
  492. DEFINE_UTF16_TO_UTF16(little2_)
  493. #undef SET2
  494. #undef GET_LO
  495. #undef GET_HI
  496. #define SET2(ptr, ch) 
  497.   (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
  498. #define GET_LO(ptr) ((unsigned char)(ptr)[1])
  499. #define GET_HI(ptr) ((unsigned char)(ptr)[0])
  500. DEFINE_UTF16_TO_UTF8(big2_)
  501. DEFINE_UTF16_TO_UTF16(big2_)
  502. #undef SET2
  503. #undef GET_LO
  504. #undef GET_HI
  505. #define LITTLE2_BYTE_TYPE(enc, p) 
  506.  ((p)[1] == 0 
  507.   ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] 
  508.   : unicode_byte_type((p)[1], (p)[0]))
  509. #define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
  510. #define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
  511. #define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) 
  512.   UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
  513. #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) 
  514.   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
  515. #ifdef XML_MIN_SIZE
  516. static
  517. int little2_byteType(const ENCODING *enc, const char *p)
  518. {
  519.   return LITTLE2_BYTE_TYPE(enc, p);
  520. }
  521. static
  522. int little2_byteToAscii(const ENCODING *enc, const char *p)
  523. {
  524.   return LITTLE2_BYTE_TO_ASCII(enc, p);
  525. }
  526. static
  527. int little2_charMatches(const ENCODING *enc, const char *p, int c)
  528. {
  529.   return LITTLE2_CHAR_MATCHES(enc, p, c);
  530. }
  531. static
  532. int little2_isNameMin(const ENCODING *enc, const char *p)
  533. {
  534.   return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
  535. }
  536. static
  537. int little2_isNmstrtMin(const ENCODING *enc, const char *p)
  538. {
  539.   return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
  540. }
  541. #undef VTABLE
  542. #define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
  543. #else /* not XML_MIN_SIZE */
  544. #undef PREFIX
  545. #define PREFIX(ident) little2_ ## ident
  546. #define MINBPC(enc) 2
  547. /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
  548. #define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
  549. #define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) 
  550. #define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
  551. #define IS_NAME_CHAR(enc, p, n) 0
  552. #define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
  553. #define IS_NMSTRT_CHAR(enc, p, n) (0)
  554. #define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
  555. #include "xmltok_impl.c"
  556. #undef MINBPC
  557. #undef BYTE_TYPE
  558. #undef BYTE_TO_ASCII
  559. #undef CHAR_MATCHES
  560. #undef IS_NAME_CHAR
  561. #undef IS_NAME_CHAR_MINBPC
  562. #undef IS_NMSTRT_CHAR
  563. #undef IS_NMSTRT_CHAR_MINBPC
  564. #undef IS_INVALID_CHAR
  565. #endif /* not XML_MIN_SIZE */
  566. #ifdef XML_NS
  567. static const struct normal_encoding little2_encoding_ns = { 
  568.   { VTABLE, 2, 0,
  569. #if XML_BYTE_ORDER == 12
  570.     1
  571. #else
  572.     0
  573. #endif
  574.   },
  575.   {
  576. #include "asciitab.h"
  577. #include "latin1tab.h"
  578.   },
  579.   STANDARD_VTABLE(little2_)
  580. };
  581. #endif
  582. static const struct normal_encoding little2_encoding = { 
  583.   { VTABLE, 2, 0,
  584. #if XML_BYTE_ORDER == 12
  585.     1
  586. #else
  587.     0
  588. #endif
  589.   },
  590.   {
  591. #define BT_COLON BT_NMSTRT
  592. #include "asciitab.h"
  593. #undef BT_COLON
  594. #include "latin1tab.h"
  595.   },
  596.   STANDARD_VTABLE(little2_)
  597. };
  598. #if XML_BYTE_ORDER != 21
  599. #ifdef XML_NS
  600. static const struct normal_encoding internal_little2_encoding_ns = { 
  601.   { VTABLE, 2, 0, 1 },
  602.   {
  603. #include "iasciitab.h"
  604. #include "latin1tab.h"
  605.   },
  606.   STANDARD_VTABLE(little2_)
  607. };
  608. #endif
  609. static const struct normal_encoding internal_little2_encoding = { 
  610.   { VTABLE, 2, 0, 1 },
  611.   {
  612. #define BT_COLON BT_NMSTRT
  613. #include "iasciitab.h"
  614. #undef BT_COLON
  615. #include "latin1tab.h"
  616.   },
  617.   STANDARD_VTABLE(little2_)
  618. };
  619. #endif
  620. #define BIG2_BYTE_TYPE(enc, p) 
  621.  ((p)[0] == 0 
  622.   ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] 
  623.   : unicode_byte_type((p)[0], (p)[1]))
  624. #define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
  625. #define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
  626. #define BIG2_IS_NAME_CHAR_MINBPC(enc, p) 
  627.   UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
  628. #define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) 
  629.   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
  630. #ifdef XML_MIN_SIZE
  631. static
  632. int big2_byteType(const ENCODING *enc, const char *p)
  633. {
  634.   return BIG2_BYTE_TYPE(enc, p);
  635. }
  636. static
  637. int big2_byteToAscii(const ENCODING *enc, const char *p)
  638. {
  639.   return BIG2_BYTE_TO_ASCII(enc, p);
  640. }
  641. static
  642. int big2_charMatches(const ENCODING *enc, const char *p, int c)
  643. {
  644.   return BIG2_CHAR_MATCHES(enc, p, c);
  645. }
  646. static
  647. int big2_isNameMin(const ENCODING *enc, const char *p)
  648. {
  649.   return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
  650. }
  651. static
  652. int big2_isNmstrtMin(const ENCODING *enc, const char *p)
  653. {
  654.   return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
  655. }
  656. #undef VTABLE
  657. #define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
  658. #else /* not XML_MIN_SIZE */
  659. #undef PREFIX
  660. #define PREFIX(ident) big2_ ## ident
  661. #define MINBPC(enc) 2
  662. /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
  663. #define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
  664. #define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) 
  665. #define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
  666. #define IS_NAME_CHAR(enc, p, n) 0
  667. #define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
  668. #define IS_NMSTRT_CHAR(enc, p, n) (0)
  669. #define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
  670. #include "xmltok_impl.c"
  671. #undef MINBPC
  672. #undef BYTE_TYPE
  673. #undef BYTE_TO_ASCII
  674. #undef CHAR_MATCHES
  675. #undef IS_NAME_CHAR
  676. #undef IS_NAME_CHAR_MINBPC
  677. #undef IS_NMSTRT_CHAR
  678. #undef IS_NMSTRT_CHAR_MINBPC
  679. #undef IS_INVALID_CHAR
  680. #endif /* not XML_MIN_SIZE */
  681. #ifdef XML_NS
  682. static const struct normal_encoding big2_encoding_ns = {
  683.   { VTABLE, 2, 0,
  684. #if XML_BYTE_ORDER == 21
  685.   1
  686. #else
  687.   0
  688. #endif
  689.   },
  690.   {
  691. #include "asciitab.h"
  692. #include "latin1tab.h"
  693.   },
  694.   STANDARD_VTABLE(big2_)
  695. };
  696. #endif
  697. static const struct normal_encoding big2_encoding = {
  698.   { VTABLE, 2, 0,
  699. #if XML_BYTE_ORDER == 21
  700.   1
  701. #else
  702.   0
  703. #endif
  704.   },
  705.   {
  706. #define BT_COLON BT_NMSTRT
  707. #include "asciitab.h"
  708. #undef BT_COLON
  709. #include "latin1tab.h"
  710.   },
  711.   STANDARD_VTABLE(big2_)
  712. };
  713. #if XML_BYTE_ORDER != 12
  714. #ifdef XML_NS
  715. static const struct normal_encoding internal_big2_encoding_ns = {
  716.   { VTABLE, 2, 0, 1 },
  717.   {
  718. #include "iasciitab.h"
  719. #include "latin1tab.h"
  720.   },
  721.   STANDARD_VTABLE(big2_)
  722. };
  723. #endif
  724. static const struct normal_encoding internal_big2_encoding = {
  725.   { VTABLE, 2, 0, 1 },
  726.   {
  727. #define BT_COLON BT_NMSTRT
  728. #include "iasciitab.h"
  729. #undef BT_COLON
  730. #include "latin1tab.h"
  731.   },
  732.   STANDARD_VTABLE(big2_)
  733. };
  734. #endif
  735. #undef PREFIX
  736. static
  737. int streqci(const char *s1, const char *s2)
  738. {
  739.   for (;;) {
  740.     char c1 = *s1++;
  741.     char c2 = *s2++;
  742.     if (ASCII_a <= c1 && c1 <= ASCII_z)
  743.       c1 += ASCII_A - ASCII_a;
  744.     if (ASCII_a <= c2 && c2 <= ASCII_z)
  745.       c2 += ASCII_A - ASCII_a;
  746.     if (c1 != c2)
  747.       return 0;
  748.     if (!c1)
  749.       break;
  750.   }
  751.   return 1;
  752. }
  753. static
  754. void initUpdatePosition(const ENCODING *enc, const char *ptr,
  755. const char *end, POSITION *pos)
  756. {
  757.   normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
  758. }
  759. static
  760. int toAscii(const ENCODING *enc, const char *ptr, const char *end)
  761. {
  762.   char buf[1];
  763.   char *p = buf;
  764.   XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
  765.   if (p == buf)
  766.     return -1;
  767.   else
  768.     return buf[0];
  769. }
  770. static
  771. int isSpace(int c)
  772. {
  773.   switch (c) {
  774.   case 0x20:
  775.   case 0xD:
  776.   case 0xA:
  777.   case 0x9:
  778.     return 1;
  779.   }
  780.   return 0;
  781. }
  782. /* Return 1 if there's just optional white space
  783. or there's an S followed by name=val. */
  784. static
  785. int parsePseudoAttribute(const ENCODING *enc,
  786.  const char *ptr,
  787.  const char *end,
  788.  const char **namePtr,
  789.  const char **nameEndPtr,
  790.  const char **valPtr,
  791.  const char **nextTokPtr)
  792. {
  793.   int c;
  794.   char open;
  795.   if (ptr == end) {
  796.     *namePtr = 0;
  797.     return 1;
  798.   }
  799.   if (!isSpace(toAscii(enc, ptr, end))) {
  800.     *nextTokPtr = ptr;
  801.     return 0;
  802.   }
  803.   do {
  804.     ptr += enc->minBytesPerChar;
  805.   } while (isSpace(toAscii(enc, ptr, end)));
  806.   if (ptr == end) {
  807.     *namePtr = 0;
  808.     return 1;
  809.   }
  810.   *namePtr = ptr;
  811.   for (;;) {
  812.     c = toAscii(enc, ptr, end);
  813.     if (c == -1) {
  814.       *nextTokPtr = ptr;
  815.       return 0;
  816.     }
  817.     if (c == ASCII_EQUALS) {
  818.       *nameEndPtr = ptr;
  819.       break;
  820.     }
  821.     if (isSpace(c)) {
  822.       *nameEndPtr = ptr;
  823.       do {
  824. ptr += enc->minBytesPerChar;
  825.       } while (isSpace(c = toAscii(enc, ptr, end)));
  826.       if (c != ASCII_EQUALS) {
  827. *nextTokPtr = ptr;
  828. return 0;
  829.       }
  830.       break;
  831.     }
  832.     ptr += enc->minBytesPerChar;
  833.   }
  834.   if (ptr == *namePtr) {
  835.     *nextTokPtr = ptr;
  836.     return 0;
  837.   }
  838.   ptr += enc->minBytesPerChar;
  839.   c = toAscii(enc, ptr, end);
  840.   while (isSpace(c)) {
  841.     ptr += enc->minBytesPerChar;
  842.     c = toAscii(enc, ptr, end);
  843.   }
  844.   if (c != ASCII_QUOT && c != ASCII_APOS) {
  845.     *nextTokPtr = ptr;
  846.     return 0;
  847.   }
  848.   open = c;
  849.   ptr += enc->minBytesPerChar;
  850.   *valPtr = ptr;
  851.   for (;; ptr += enc->minBytesPerChar) {
  852.     c = toAscii(enc, ptr, end);
  853.     if (c == open)
  854.       break;
  855.     if (!(ASCII_a <= c && c <= ASCII_z)
  856. && !(ASCII_A <= c && c <= ASCII_Z)
  857. && !(ASCII_0 <= c && c <= ASCII_9)
  858. && c != ASCII_PERIOD
  859. && c != ASCII_MINUS
  860. && c != ASCII_UNDERSCORE) {
  861.       *nextTokPtr = ptr;
  862.       return 0;
  863.     }
  864.   }
  865.   *nextTokPtr = ptr + enc->minBytesPerChar;
  866.   return 1;
  867. }
  868. static const char KW_version[] = {
  869.   ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, ''
  870. };
  871. static const char KW_encoding[] = {
  872.   ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, ''
  873. };
  874. static const char KW_standalone[] = {
  875.   ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, ''
  876. };
  877. static const char KW_yes[] = {
  878.   ASCII_y, ASCII_e, ASCII_s,  ''
  879. };
  880. static const char KW_no[] = {
  881.   ASCII_n, ASCII_o,  ''
  882. };
  883. static
  884. int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
  885.                                      const char *,
  886.      const char *),
  887.    int isGeneralTextEntity,
  888.    const ENCODING *enc,
  889.    const char *ptr,
  890.    const char *end,
  891.    const char **badPtr,
  892.    const char **versionPtr,
  893.    const char **encodingName,
  894.    const ENCODING **encoding,
  895.    int *standalone)
  896. {
  897.   const char *val = 0;
  898.   const char *name = 0;
  899.   const char *nameEnd = 0;
  900.   ptr += 5 * enc->minBytesPerChar;
  901.   end -= 2 * enc->minBytesPerChar;
  902.   if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) {
  903.     *badPtr = ptr;
  904.     return 0;
  905.   }
  906.   if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
  907.     if (!isGeneralTextEntity) {
  908.       *badPtr = name;
  909.       return 0;
  910.     }
  911.   }
  912.   else {
  913.     if (versionPtr)
  914.       *versionPtr = val;
  915.     if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
  916.       *badPtr = ptr;
  917.       return 0;
  918.     }
  919.     if (!name) {
  920.       if (isGeneralTextEntity) {
  921. /* a TextDecl must have an EncodingDecl */
  922. *badPtr = ptr;
  923. return 0;
  924.       }
  925.       return 1;
  926.     }
  927.   }
  928.   if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
  929.     int c = toAscii(enc, val, end);
  930.     if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
  931.       *badPtr = val;
  932.       return 0;
  933.     }
  934.     if (encodingName)
  935.       *encodingName = val;
  936.     if (encoding)
  937.       *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
  938.     if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
  939.       *badPtr = ptr;
  940.       return 0;
  941.     }
  942.     if (!name)
  943.       return 1;
  944.   }
  945.   if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) {
  946.     *badPtr = name;
  947.     return 0;
  948.   }
  949.   if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
  950.     if (standalone)
  951.       *standalone = 1;
  952.   }
  953.   else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
  954.     if (standalone)
  955.       *standalone = 0;
  956.   }
  957.   else {
  958.     *badPtr = val;
  959.     return 0;
  960.   }
  961.   while (isSpace(toAscii(enc, ptr, end)))
  962.     ptr += enc->minBytesPerChar;
  963.   if (ptr != end) {
  964.     *badPtr = ptr;
  965.     return 0;
  966.   }
  967.   return 1;
  968. }
  969. static
  970. int checkCharRefNumber(int result)
  971. {
  972.   switch (result >> 8) {
  973.   case 0xD8: case 0xD9: case 0xDA: case 0xDB:
  974.   case 0xDC: case 0xDD: case 0xDE: case 0xDF:
  975.     return -1;
  976.   case 0:
  977.     if (latin1_encoding.type[result] == BT_NONXML)
  978.       return -1;
  979.     break;
  980.   case 0xFF:
  981.     if (result == 0xFFFE || result == 0xFFFF)
  982.       return -1;
  983.     break;
  984.   }
  985.   return result;
  986. }
  987. int XmlUtf8Encode(int c, char *buf)
  988. {
  989.   enum {
  990.     /* minN is minimum legal resulting value for N byte sequence */
  991.     min2 = 0x80,
  992.     min3 = 0x800,
  993.     min4 = 0x10000
  994.   };
  995.   if (c < 0)
  996.     return 0;
  997.   if (c < min2) {
  998.     buf[0] = (c | UTF8_cval1);
  999.     return 1;
  1000.   }
  1001.   if (c < min3) {
  1002.     buf[0] = ((c >> 6) | UTF8_cval2);
  1003.     buf[1] = ((c & 0x3f) | 0x80);
  1004.     return 2;
  1005.   }
  1006.   if (c < min4) {
  1007.     buf[0] = ((c >> 12) | UTF8_cval3);
  1008.     buf[1] = (((c >> 6) & 0x3f) | 0x80);
  1009.     buf[2] = ((c & 0x3f) | 0x80);
  1010.     return 3;
  1011.   }
  1012.   if (c < 0x110000) {
  1013.     buf[0] = ((c >> 18) | UTF8_cval4);
  1014.     buf[1] = (((c >> 12) & 0x3f) | 0x80);
  1015.     buf[2] = (((c >> 6) & 0x3f) | 0x80);
  1016.     buf[3] = ((c & 0x3f) | 0x80);
  1017.     return 4;
  1018.   }
  1019.   return 0;
  1020. }
  1021. int XmlUtf16Encode(int charNum, unsigned short *buf)
  1022. {
  1023.   if (charNum < 0)
  1024.     return 0;
  1025.   if (charNum < 0x10000) {
  1026.     buf[0] = charNum;
  1027.     return 1;
  1028.   }
  1029.   if (charNum < 0x110000) {
  1030.     charNum -= 0x10000;
  1031.     buf[0] = (charNum >> 10) + 0xD800;
  1032.     buf[1] = (charNum & 0x3FF) + 0xDC00;
  1033.     return 2;
  1034.   }
  1035.   return 0;
  1036. }
  1037. struct unknown_encoding {
  1038.   struct normal_encoding normal;
  1039.   int (*convert)(void *userData, const char *p);
  1040.   void *userData;
  1041.   unsigned short utf16[256];
  1042.   char utf8[256][4];
  1043. };
  1044. int XmlSizeOfUnknownEncoding(void)
  1045. {
  1046.   return sizeof(struct unknown_encoding);
  1047. }
  1048. static
  1049. int unknown_isName(const ENCODING *enc, const char *p)
  1050. {
  1051.   int c = ((const struct unknown_encoding *)enc)
  1052.   ->convert(((const struct unknown_encoding *)enc)->userData, p);
  1053.   if (c & ~0xFFFF)
  1054.     return 0;
  1055.   return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
  1056. }
  1057. static
  1058. int unknown_isNmstrt(const ENCODING *enc, const char *p)
  1059. {
  1060.   int c = ((const struct unknown_encoding *)enc)
  1061.   ->convert(((const struct unknown_encoding *)enc)->userData, p);
  1062.   if (c & ~0xFFFF)
  1063.     return 0;
  1064.   return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
  1065. }
  1066. static
  1067. int unknown_isInvalid(const ENCODING *enc, const char *p)
  1068. {
  1069.   int c = ((const struct unknown_encoding *)enc)
  1070.    ->convert(((const struct unknown_encoding *)enc)->userData, p);
  1071.   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
  1072. }
  1073. static
  1074. void unknown_toUtf8(const ENCODING *enc,
  1075.     const char **fromP, const char *fromLim,
  1076.     char **toP, const char *toLim)
  1077. {
  1078.   char buf[XML_UTF8_ENCODE_MAX];
  1079.   for (;;) {
  1080.     const char *utf8;
  1081.     int n;
  1082.     if (*fromP == fromLim)
  1083.       break;
  1084.     utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
  1085.     n = *utf8++;
  1086.     if (n == 0) {
  1087.       int c = ((const struct unknown_encoding *)enc)
  1088.       ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
  1089.       n = XmlUtf8Encode(c, buf);
  1090.       if (n > toLim - *toP)
  1091. break;
  1092.       utf8 = buf;
  1093.       *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
  1094.          - (BT_LEAD2 - 2);
  1095.     }
  1096.     else {
  1097.       if (n > toLim - *toP)
  1098. break;
  1099.       (*fromP)++;
  1100.     }
  1101.     do {
  1102.       *(*toP)++ = *utf8++;
  1103.     } while (--n != 0);
  1104.   }
  1105. }
  1106. static
  1107. void unknown_toUtf16(const ENCODING *enc,
  1108.      const char **fromP, const char *fromLim,
  1109.      unsigned short **toP, const unsigned short *toLim)
  1110. {
  1111.   while (*fromP != fromLim && *toP != toLim) {
  1112.     unsigned short c
  1113.       = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
  1114.     if (c == 0) {
  1115.       c = (unsigned short)((const struct unknown_encoding *)enc)
  1116.    ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
  1117.       *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
  1118.          - (BT_LEAD2 - 2);
  1119.     }
  1120.     else
  1121.       (*fromP)++;
  1122.     *(*toP)++ = c;
  1123.   }
  1124. }
  1125. ENCODING *
  1126. XmlInitUnknownEncoding(void *mem,
  1127.        int *table,
  1128.        int (*convert)(void *userData, const char *p),
  1129.        void *userData)
  1130. {
  1131.   int i;
  1132.   struct unknown_encoding *e = (struct unknown_encoding*) mem; /* Helix expat change */
  1133.   for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
  1134.     ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
  1135.   for (i = 0; i < 128; i++)
  1136.     if (latin1_encoding.type[i] != BT_OTHER
  1137.         && latin1_encoding.type[i] != BT_NONXML
  1138. && table[i] != i)
  1139.       return 0;
  1140.   for (i = 0; i < 256; i++) {
  1141.     int c = table[i];
  1142.     if (c == -1) {
  1143.       e->normal.type[i] = BT_MALFORM;
  1144.       /* This shouldn't really get used. */
  1145.       e->utf16[i] = 0xFFFF;
  1146.       e->utf8[i][0] = 1;
  1147.       e->utf8[i][1] = 0;
  1148.     }
  1149.     else if (c < 0) {
  1150.       if (c < -4)
  1151. return 0;
  1152.       e->normal.type[i] = BT_LEAD2 - (c + 2);
  1153.       e->utf8[i][0] = 0;
  1154.       e->utf16[i] = 0;
  1155.     }
  1156.     else if (c < 0x80) {
  1157.       if (latin1_encoding.type[c] != BT_OTHER
  1158.   && latin1_encoding.type[c] != BT_NONXML
  1159.   && c != i)
  1160. return 0;
  1161.       e->normal.type[i] = latin1_encoding.type[c];
  1162.       e->utf8[i][0] = 1;
  1163.       e->utf8[i][1] = (char)c;
  1164.       e->utf16[i] = c == 0 ? 0xFFFF : c;
  1165.     }
  1166.     else if (checkCharRefNumber(c) < 0) {
  1167.       e->normal.type[i] = BT_NONXML;
  1168.       /* This shouldn't really get used. */
  1169.       e->utf16[i] = 0xFFFF;
  1170.       e->utf8[i][0] = 1;
  1171.       e->utf8[i][1] = 0;
  1172.     }
  1173.     else {
  1174.       if (c > 0xFFFF)
  1175. return 0;
  1176.       if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
  1177. e->normal.type[i] = BT_NMSTRT;
  1178.       else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
  1179. e->normal.type[i] = BT_NAME;
  1180.       else
  1181. e->normal.type[i] = BT_OTHER;
  1182.       e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
  1183.       e->utf16[i] = c;
  1184.     }
  1185.   }
  1186.   e->userData = userData;
  1187.   e->convert = convert;
  1188.   if (convert) {
  1189.     e->normal.isName2 = unknown_isName;
  1190.     e->normal.isName3 = unknown_isName;
  1191.     e->normal.isName4 = unknown_isName;
  1192.     e->normal.isNmstrt2 = unknown_isNmstrt;
  1193.     e->normal.isNmstrt3 = unknown_isNmstrt;
  1194.     e->normal.isNmstrt4 = unknown_isNmstrt;
  1195.     e->normal.isInvalid2 = unknown_isInvalid;
  1196.     e->normal.isInvalid3 = unknown_isInvalid;
  1197.     e->normal.isInvalid4 = unknown_isInvalid;
  1198.   }
  1199.   e->normal.enc.utf8Convert = unknown_toUtf8;
  1200.   e->normal.enc.utf16Convert = unknown_toUtf16;
  1201.   return &(e->normal.enc);
  1202. }
  1203. /* If this enumeration is changed, getEncodingIndex and encodings
  1204. must also be changed. */
  1205. enum {
  1206.   UNKNOWN_ENC = -1,
  1207.   ISO_8859_1_ENC = 0,
  1208.   US_ASCII_ENC,
  1209.   UTF_8_ENC,
  1210.   UTF_16_ENC,
  1211.   UTF_16BE_ENC,
  1212.   UTF_16LE_ENC,
  1213.   /* must match encodingNames up to here */
  1214.   NO_ENC
  1215. };
  1216. static const char KW_ISO_8859_1[] = {
  1217.   ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, ''
  1218. };
  1219. static const char KW_US_ASCII[] = {
  1220.   ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, ''
  1221. };
  1222. static const char KW_UTF_8[] = {
  1223.   ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, ''
  1224. };
  1225. static const char KW_UTF_16[] = {
  1226.   ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ''
  1227. };
  1228. static const char KW_UTF_16BE[] = {
  1229.   ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, ''
  1230. };
  1231. static const char KW_UTF_16LE[] = {
  1232.   ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, ''
  1233. };
  1234. static
  1235. int getEncodingIndex(const char *name)
  1236. {
  1237.     static const char * const encodingNames[] = { /* Helix expat change */
  1238.     KW_ISO_8859_1,
  1239.     KW_US_ASCII,
  1240.     KW_UTF_8,
  1241.     KW_UTF_16,
  1242.     KW_UTF_16BE,
  1243.     KW_UTF_16LE,
  1244.   };
  1245.   int i;
  1246.   if (name == 0)
  1247.     return NO_ENC;
  1248.   for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
  1249.     if (streqci(name, (const char*) encodingNames[i])) /* Helix expat change */
  1250.       return i;
  1251.   return UNKNOWN_ENC;
  1252. }
  1253. /* For binary compatibility, we store the index of the encoding specified
  1254. at initialization in the isUtf16 member. */
  1255. #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
  1256. #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
  1257. /* This is what detects the encoding.
  1258. encodingTable maps from encoding indices to encodings;
  1259. INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
  1260. state is XML_CONTENT_STATE if we're parsing an external text entity,
  1261. and XML_PROLOG_STATE otherwise.
  1262. */
  1263. static
  1264. int initScan(const ENCODING **encodingTable,
  1265.      const INIT_ENCODING *enc,
  1266.      int state,
  1267.      const char *ptr,
  1268.      const char *end,
  1269.      const char **nextTokPtr)
  1270. {
  1271.   const ENCODING **encPtr;
  1272.   if (ptr == end)
  1273.     return XML_TOK_NONE;
  1274.   encPtr = enc->encPtr;
  1275.   if (ptr + 1 == end) {
  1276.     /* only a single byte available for auto-detection */
  1277. #ifndef XML_DTD /* FIXME */
  1278.     /* a well-formed document entity must have more than one byte */
  1279.     if (state != XML_CONTENT_STATE)
  1280.       return XML_TOK_PARTIAL;
  1281. #endif
  1282.     /* so we're parsing an external text entity... */
  1283.     /* if UTF-16 was externally specified, then we need at least 2 bytes */
  1284.     switch (INIT_ENC_INDEX(enc)) {
  1285.     case UTF_16_ENC:
  1286.     case UTF_16LE_ENC:
  1287.     case UTF_16BE_ENC:
  1288.       return XML_TOK_PARTIAL;
  1289.     }
  1290.     switch ((unsigned char)*ptr) {
  1291.     case 0xFE:
  1292.     case 0xFF:
  1293.     case 0xEF: /* possibly first byte of UTF-8 BOM */
  1294.       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
  1295.   && state == XML_CONTENT_STATE)
  1296. break;
  1297.       /* fall through */
  1298.     case 0x00:
  1299.     case 0x3C:
  1300.       return XML_TOK_PARTIAL;
  1301.     }
  1302.   }
  1303.   else {
  1304.     switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
  1305.     case 0xFEFF:
  1306.       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
  1307.   && state == XML_CONTENT_STATE)
  1308. break;
  1309.       *nextTokPtr = ptr + 2;
  1310.       *encPtr = encodingTable[UTF_16BE_ENC];
  1311.       return XML_TOK_BOM;
  1312.     /* 00 3C is handled in the default case */
  1313.     case 0x3C00:
  1314.       if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
  1315.    || INIT_ENC_INDEX(enc) == UTF_16_ENC)
  1316.   && state == XML_CONTENT_STATE)
  1317. break;
  1318.       *encPtr = encodingTable[UTF_16LE_ENC];
  1319.       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
  1320.     case 0xFFFE:
  1321.       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
  1322.   && state == XML_CONTENT_STATE)
  1323. break;
  1324.       *nextTokPtr = ptr + 2;
  1325.       *encPtr = encodingTable[UTF_16LE_ENC];
  1326.       return XML_TOK_BOM;
  1327.     case 0xEFBB:
  1328.       /* Maybe a UTF-8 BOM (EF BB BF) */
  1329.       /* If there's an explicitly specified (external) encoding
  1330.          of ISO-8859-1 or some flavour of UTF-16
  1331.          and this is an external text entity,
  1332.  don't look for the BOM,
  1333.          because it might be a legal data. */
  1334.       if (state == XML_CONTENT_STATE) {
  1335. int e = INIT_ENC_INDEX(enc);
  1336. if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
  1337.   break;
  1338.       }
  1339.       if (ptr + 2 == end)
  1340. return XML_TOK_PARTIAL;
  1341.       if ((unsigned char)ptr[2] == 0xBF) {
  1342. *encPtr = encodingTable[UTF_8_ENC];
  1343. return XML_TOK_BOM;
  1344.       }
  1345.       break;
  1346.     default:
  1347.       if (ptr[0] == '') {
  1348. /* 0 isn't a legal data character. Furthermore a document entity can only
  1349.    start with ASCII characters.  So the only way this can fail to be big-endian
  1350.    UTF-16 if it it's an external parsed general entity that's labelled as
  1351.    UTF-16LE. */
  1352. if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
  1353.   break;
  1354. *encPtr = encodingTable[UTF_16BE_ENC];
  1355. return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
  1356.       }
  1357.       else if (ptr[1] == '') {
  1358. /* We could recover here in the case:
  1359.     - parsing an external entity
  1360.     - second byte is 0
  1361.     - no externally specified encoding
  1362.     - no encoding declaration
  1363.    by assuming UTF-16LE.  But we don't, because this would mean when
  1364.    presented just with a single byte, we couldn't reliably determine
  1365.    whether we needed further bytes. */
  1366. if (state == XML_CONTENT_STATE)
  1367.   break;
  1368. *encPtr = encodingTable[UTF_16LE_ENC];
  1369. return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
  1370.       }
  1371.       break;
  1372.     }
  1373.   }
  1374.   *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
  1375.   return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
  1376. }
  1377. #define NS(x) x
  1378. #define ns(x) x
  1379. #include "xmltok_ns.c"
  1380. #undef NS
  1381. #undef ns
  1382. #ifdef XML_NS
  1383. #define NS(x) x ## NS
  1384. #define ns(x) x ## _ns
  1385. #include "xmltok_ns.c"
  1386. #undef NS
  1387. #undef ns
  1388. ENCODING *
  1389. XmlInitUnknownEncodingNS(void *mem,
  1390.          int *table,
  1391.          int (*convert)(void *userData, const char *p),
  1392.          void *userData)
  1393. {
  1394.   ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
  1395.   if (enc)
  1396.     ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
  1397.   return enc;
  1398. }
  1399. #endif /* XML_NS */