| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680 | 
							- /*
 
-                             __  __            _
 
-                          ___\ \/ /_ __   __ _| |_
 
-                         / _ \\  /| '_ \ / _` | __|
 
-                        |  __//  \| |_) | (_| | |_
 
-                         \___/_/\_\ .__/ \__,_|\__|
 
-                                  |_| XML parser
 
-    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
 
-    Copyright (c) 2000      Clark Cooper <[email protected]>
 
-    Copyright (c) 2001-2003 Fred L. Drake, Jr. <[email protected]>
 
-    Copyright (c) 2002      Greg Stein <[email protected]>
 
-    Copyright (c) 2002-2016 Karl Waclawek <[email protected]>
 
-    Copyright (c) 2005-2009 Steven Solie <[email protected]>
 
-    Copyright (c) 2016-2021 Sebastian Pipping <[email protected]>
 
-    Copyright (c) 2016      Pascal Cuoq <[email protected]>
 
-    Copyright (c) 2016      Don Lewis <[email protected]>
 
-    Copyright (c) 2017      Rhodri James <[email protected]>
 
-    Copyright (c) 2017      Alexander Bluhm <[email protected]>
 
-    Copyright (c) 2017      Benbuck Nason <[email protected]>
 
-    Copyright (c) 2017      José Gutiérrez de la Concha <[email protected]>
 
-    Copyright (c) 2019      David Loffredo <[email protected]>
 
-    Licensed under the MIT license:
 
-    Permission is  hereby granted,  free of charge,  to any  person obtaining
 
-    a  copy  of  this  software   and  associated  documentation  files  (the
 
-    "Software"),  to  deal in  the  Software  without restriction,  including
 
-    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
 
-    distribute, sublicense, and/or sell copies of the Software, and to permit
 
-    persons  to whom  the Software  is  furnished to  do so,  subject to  the
 
-    following conditions:
 
-    The above copyright  notice and this permission notice  shall be included
 
-    in all copies or substantial portions of the Software.
 
-    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
 
-    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
 
-    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 
-    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 
-    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
 
-    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 
-    USE OR OTHER DEALINGS IN THE SOFTWARE.
 
- */
 
- #include <stddef.h>
 
- #include <string.h> /* memcpy */
 
- #include <stdbool.h>
 
- #ifdef _WIN32
 
- #  include "winconfig.h"
 
- #endif
 
- #include <expat_config.h>
 
- #include "expat_external.h"
 
- #include "internal.h"
 
- #include "xmltok.h"
 
- #include "nametab.h"
 
- #ifdef XML_DTD
 
- #  define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
 
- #else
 
- #  define IGNORE_SECTION_TOK_VTABLE /* as nothing */
 
- #endif
 
- #define VTABLE1                                                                \
 
-   {PREFIX(prologTok), PREFIX(contentTok),                                      \
 
-    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE},                         \
 
-       {PREFIX(attributeValueTok), PREFIX(entityValueTok)},                     \
 
-       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)] & (1u << ((lo)&0x1F)))
 
- /* A 2 byte UTF-8 representation splits the characters 11 bits between
 
-    the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
 
-    pages, 3 bits to add to that index and 5 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)]         \
 
-    & (1u << (((byte)[1]) & 0x1F)))
 
- /* A 3 byte UTF-8 representation splits the characters 16 bits between
 
-    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 and 5 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)]                 \
 
-    & (1u << (((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))
 
- /* Detection of invalid UTF-8 sequences is based on Table 3.1B
 
-    of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
 
-    with the additional restriction of not allowing the Unicode
 
-    code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
 
-    Implementation details:
 
-      (A & 0x80) == 0     means A < 0x80
 
-    and
 
-      (A & 0xC0) == 0xC0  means A > 0xBF
 
- */
 
- #define UTF8_INVALID2(p)                                                       \
 
-   ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
 
- #define UTF8_INVALID3(p)                                                       \
 
-   (((p)[2] & 0x80) == 0                                                        \
 
-    || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD                          \
 
-                                       : ((p)[2] & 0xC0) == 0xC0)               \
 
-    || ((*p) == 0xE0                                                            \
 
-            ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0                          \
 
-            : ((p)[1] & 0x80) == 0                                              \
 
-                  || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
 
- #define UTF8_INVALID4(p)                                                       \
 
-   (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0     \
 
-    || ((p)[2] & 0xC0) == 0xC0                                                  \
 
-    || ((*p) == 0xF0                                                            \
 
-            ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0                          \
 
-            : ((p)[1] & 0x80) == 0                                              \
 
-                  || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
 
- static int PTRFASTCALL
 
- isNever(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   UNUSED_P(p);
 
-   return 0;
 
- }
 
- static int PTRFASTCALL
 
- utf8_isName2(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
 
- }
 
- static int PTRFASTCALL
 
- utf8_isName3(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
 
- }
 
- #define utf8_isName4 isNever
 
- static int PTRFASTCALL
 
- utf8_isNmstrt2(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
 
- }
 
- static int PTRFASTCALL
 
- utf8_isNmstrt3(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
 
- }
 
- #define utf8_isNmstrt4 isNever
 
- static int PTRFASTCALL
 
- utf8_isInvalid2(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_INVALID2((const unsigned char *)p);
 
- }
 
- static int PTRFASTCALL
 
- utf8_isInvalid3(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_INVALID3((const unsigned char *)p);
 
- }
 
- static int PTRFASTCALL
 
- utf8_isInvalid4(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return UTF8_INVALID4((const unsigned char *)p);
 
- }
 
- struct normal_encoding {
 
-   ENCODING enc;
 
-   unsigned char type[256];
 
- #ifdef XML_MIN_SIZE
 
-   int(PTRFASTCALL *byteType)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
 
-   int(PTRCALL *charMatches)(const ENCODING *, const char *, int);
 
- #endif /* XML_MIN_SIZE */
 
-   int(PTRFASTCALL *isName2)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isName3)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isName4)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
 
-   int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
 
- };
 
- #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
 
- #ifdef XML_MIN_SIZE
 
- #  define STANDARD_VTABLE(E)                                                   \
 
-     E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches,
 
- #else
 
- #  define STANDARD_VTABLE(E) /* as nothing */
 
- #endif
 
- #define NORMAL_VTABLE(E)                                                       \
 
-   E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3,              \
 
-       E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4
 
- #define NULL_VTABLE                                                            \
 
-   /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL,                  \
 
-       /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL,        \
 
-       /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
 
- static int FASTCALL checkCharRefNumber(int);
 
- #include "xmltok_impl.h"
 
- #include "ascii.h"
 
- #ifdef XML_MIN_SIZE
 
- #  define sb_isNameMin isNever
 
- #  define sb_isNmstrtMin isNever
 
- #endif
 
- #ifdef XML_MIN_SIZE
 
- #  define MINBPC(enc) ((enc)->minBytesPerChar)
 
- #else
 
- /* minimum bytes per character */
 
- #  define MINBPC(enc) 1
 
- #endif
 
- #define SB_BYTE_TYPE(enc, p)                                                   \
 
-   (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
 
- #ifdef XML_MIN_SIZE
 
- static int PTRFASTCALL
 
- sb_byteType(const ENCODING *enc, const char *p) {
 
-   return SB_BYTE_TYPE(enc, p);
 
- }
 
- #  define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
 
- #else
 
- #  define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
 
- #endif
 
- #ifdef XML_MIN_SIZE
 
- #  define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
 
- static int PTRFASTCALL
 
- sb_byteToAscii(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return *p;
 
- }
 
- #else
 
- #  define BYTE_TO_ASCII(enc, p) (*(p))
 
- #endif
 
- #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
 
- #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p))
 
- #ifdef XML_MIN_SIZE
 
- #  define IS_INVALID_CHAR(enc, p, n)                                           \
 
-     (AS_NORMAL_ENCODING(enc)->isInvalid##n                                     \
 
-      && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
 
- #else
 
- #  define IS_INVALID_CHAR(enc, p, n)                                           \
 
-     (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
 
- #endif
 
- #ifdef XML_MIN_SIZE
 
- #  define IS_NAME_CHAR_MINBPC(enc, p)                                          \
 
-     (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
 
- #  define IS_NMSTRT_CHAR_MINBPC(enc, p)                                        \
 
-     (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
 
- #else
 
- #  define IS_NAME_CHAR_MINBPC(enc, p) (0)
 
- #  define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
 
- #endif
 
- #ifdef XML_MIN_SIZE
 
- #  define CHAR_MATCHES(enc, p, c)                                              \
 
-     (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
 
- static int PTRCALL
 
- sb_charMatches(const ENCODING *enc, const char *p, int c) {
 
-   UNUSED_P(enc);
 
-   return *p == c;
 
- }
 
- #else
 
- /* c is an ASCII character */
 
- #  define CHAR_MATCHES(enc, p, c) (*(p) == c)
 
- #endif
 
- #define PREFIX(ident) normal_##ident
 
- #define XML_TOK_IMPL_C
 
- #include "xmltok_impl.c"
 
- #undef XML_TOK_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_CHAR
 
- enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
 
-        UTF8_cval1 = 0x00,
 
-        UTF8_cval2 = 0xc0,
 
-        UTF8_cval3 = 0xe0,
 
-        UTF8_cval4 = 0xf0
 
- };
 
- void
 
- _INTERNAL_trim_to_complete_utf8_characters(const char *from,
 
-                                            const char **fromLimRef) {
 
-   const char *fromLim = *fromLimRef;
 
-   size_t walked = 0;
 
-   for (; fromLim > from; fromLim--, walked++) {
 
-     const unsigned char prev = (unsigned char)fromLim[-1];
 
-     if ((prev & 0xf8u)
 
-         == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
 
-       if (walked + 1 >= 4) {
 
-         fromLim += 4 - 1;
 
-         break;
 
-       } else {
 
-         walked = 0;
 
-       }
 
-     } else if ((prev & 0xf0u)
 
-                == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
 
-       if (walked + 1 >= 3) {
 
-         fromLim += 3 - 1;
 
-         break;
 
-       } else {
 
-         walked = 0;
 
-       }
 
-     } else if ((prev & 0xe0u)
 
-                == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
 
-       if (walked + 1 >= 2) {
 
-         fromLim += 2 - 1;
 
-         break;
 
-       } else {
 
-         walked = 0;
 
-       }
 
-     } else if ((prev & 0x80u)
 
-                == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
 
-       break;
 
-     }
 
-   }
 
-   *fromLimRef = fromLim;
 
- }
 
- static enum XML_Convert_Result PTRCALL
 
- utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-             char **toP, const char *toLim) {
 
-   bool input_incomplete = false;
 
-   bool output_exhausted = false;
 
-   /* Avoid copying partial characters (due to limited space). */
 
-   const ptrdiff_t bytesAvailable = fromLim - *fromP;
 
-   const ptrdiff_t bytesStorable = toLim - *toP;
 
-   UNUSED_P(enc);
 
-   if (bytesAvailable > bytesStorable) {
 
-     fromLim = *fromP + bytesStorable;
 
-     output_exhausted = true;
 
-   }
 
-   /* Avoid copying partial characters (from incomplete input). */
 
-   {
 
-     const char *const fromLimBefore = fromLim;
 
-     _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
 
-     if (fromLim < fromLimBefore) {
 
-       input_incomplete = true;
 
-     }
 
-   }
 
-   {
 
-     const ptrdiff_t bytesToCopy = fromLim - *fromP;
 
-     memcpy(*toP, *fromP, bytesToCopy);
 
-     *fromP += bytesToCopy;
 
-     *toP += bytesToCopy;
 
-   }
 
-   if (output_exhausted) /* needs to go first */
 
-     return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-   else if (input_incomplete)
 
-     return XML_CONVERT_INPUT_INCOMPLETE;
 
-   else
 
-     return XML_CONVERT_COMPLETED;
 
- }
 
- static enum XML_Convert_Result PTRCALL
 
- utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-              unsigned short **toP, const unsigned short *toLim) {
 
-   enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
 
-   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:
 
-       if (fromLim - from < 2) {
 
-         res = XML_CONVERT_INPUT_INCOMPLETE;
 
-         goto after;
 
-       }
 
-       *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
 
-       from += 2;
 
-       break;
 
-     case BT_LEAD3:
 
-       if (fromLim - from < 3) {
 
-         res = XML_CONVERT_INPUT_INCOMPLETE;
 
-         goto after;
 
-       }
 
-       *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6)
 
-                                | (from[2] & 0x3f));
 
-       from += 3;
 
-       break;
 
-     case BT_LEAD4: {
 
-       unsigned long n;
 
-       if (toLim - to < 2) {
 
-         res = XML_CONVERT_OUTPUT_EXHAUSTED;
 
-         goto after;
 
-       }
 
-       if (fromLim - from < 4) {
 
-         res = XML_CONVERT_INPUT_INCOMPLETE;
 
-         goto after;
 
-       }
 
-       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;
 
-     }
 
-   }
 
-   if (from < fromLim)
 
-     res = XML_CONVERT_OUTPUT_EXHAUSTED;
 
- after:
 
-   *fromP = from;
 
-   *toP = to;
 
-   return res;
 
- }
 
- #ifdef XML_NS
 
- static const struct normal_encoding utf8_encoding_ns
 
-     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
 
-        {
 
- #  include "asciitab.h"
 
- #  include "utf8tab.h"
 
-        },
 
-        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
- #endif
 
- static const struct normal_encoding utf8_encoding
 
-     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
 
-        {
 
- #define BT_COLON BT_NMSTRT
 
- #include "asciitab.h"
 
- #undef BT_COLON
 
- #include "utf8tab.h"
 
-        },
 
-        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
- #ifdef XML_NS
 
- static const struct normal_encoding internal_utf8_encoding_ns
 
-     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
 
-        {
 
- #  include "iasciitab.h"
 
- #  include "utf8tab.h"
 
-        },
 
-        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
- #endif
 
- static const struct normal_encoding internal_utf8_encoding
 
-     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
 
-        {
 
- #define BT_COLON BT_NMSTRT
 
- #include "iasciitab.h"
 
- #undef BT_COLON
 
- #include "utf8tab.h"
 
-        },
 
-        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
- static enum XML_Convert_Result PTRCALL
 
- latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-               char **toP, const char *toLim) {
 
-   UNUSED_P(enc);
 
-   for (;;) {
 
-     unsigned char c;
 
-     if (*fromP == fromLim)
 
-       return XML_CONVERT_COMPLETED;
 
-     c = (unsigned char)**fromP;
 
-     if (c & 0x80) {
 
-       if (toLim - *toP < 2)
 
-         return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-       *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
 
-       *(*toP)++ = (char)((c & 0x3f) | 0x80);
 
-       (*fromP)++;
 
-     } else {
 
-       if (*toP == toLim)
 
-         return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-       *(*toP)++ = *(*fromP)++;
 
-     }
 
-   }
 
- }
 
- static enum XML_Convert_Result PTRCALL
 
- latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-                unsigned short **toP, const unsigned short *toLim) {
 
-   UNUSED_P(enc);
 
-   while (*fromP < fromLim && *toP < toLim)
 
-     *(*toP)++ = (unsigned char)*(*fromP)++;
 
-   if ((*toP == toLim) && (*fromP < fromLim))
 
-     return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-   else
 
-     return XML_CONVERT_COMPLETED;
 
- }
 
- #ifdef XML_NS
 
- static const struct normal_encoding latin1_encoding_ns
 
-     = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
 
-        {
 
- #  include "asciitab.h"
 
- #  include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(sb_) NULL_VTABLE};
 
- #endif
 
- static const struct normal_encoding latin1_encoding
 
-     = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
 
-        {
 
- #define BT_COLON BT_NMSTRT
 
- #include "asciitab.h"
 
- #undef BT_COLON
 
- #include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(sb_) NULL_VTABLE};
 
- static enum XML_Convert_Result PTRCALL
 
- ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-              char **toP, const char *toLim) {
 
-   UNUSED_P(enc);
 
-   while (*fromP < fromLim && *toP < toLim)
 
-     *(*toP)++ = *(*fromP)++;
 
-   if ((*toP == toLim) && (*fromP < fromLim))
 
-     return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-   else
 
-     return XML_CONVERT_COMPLETED;
 
- }
 
- #ifdef XML_NS
 
- static const struct normal_encoding ascii_encoding_ns
 
-     = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
 
-        {
 
- #  include "asciitab.h"
 
-            /* BT_NONXML == 0 */
 
-        },
 
-        STANDARD_VTABLE(sb_) NULL_VTABLE};
 
- #endif
 
- static const struct normal_encoding ascii_encoding
 
-     = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
 
-        {
 
- #define BT_COLON BT_NMSTRT
 
- #include "asciitab.h"
 
- #undef BT_COLON
 
-            /* BT_NONXML == 0 */
 
-        },
 
-        STANDARD_VTABLE(sb_) NULL_VTABLE};
 
- static int PTRFASTCALL
 
- unicode_byte_type(char hi, char lo) {
 
-   switch ((unsigned char)hi) {
 
-   /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */
 
-   case 0xD8:
 
-   case 0xD9:
 
-   case 0xDA:
 
-   case 0xDB:
 
-     return BT_LEAD4;
 
-   /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */
 
-   case 0xDC:
 
-   case 0xDD:
 
-   case 0xDE:
 
-   case 0xDF:
 
-     return BT_TRAIL;
 
-   case 0xFF:
 
-     switch ((unsigned char)lo) {
 
-     case 0xFF: /* noncharacter-FFFF */
 
-     case 0xFE: /* noncharacter-FFFE */
 
-       return BT_NONXML;
 
-     }
 
-     break;
 
-   }
 
-   return BT_NONASCII;
 
- }
 
- #define DEFINE_UTF16_TO_UTF8(E)                                                \
 
-   static enum XML_Convert_Result PTRCALL E##toUtf8(                            \
 
-       const ENCODING *enc, const char **fromP, const char *fromLim,            \
 
-       char **toP, const char *toLim) {                                         \
 
-     const char *from = *fromP;                                                 \
 
-     UNUSED_P(enc);                                                             \
 
-     fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */      \
 
-     for (; 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 XML_CONVERT_OUTPUT_EXHAUSTED;                               \
 
-           }                                                                    \
 
-           *(*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 XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
 
-         }                                                                      \
 
-         *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2);                      \
 
-         *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
 
-         break;                                                                 \
 
-       default:                                                                 \
 
-         if (toLim - *toP < 3) {                                                \
 
-           *fromP = from;                                                       \
 
-           return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
 
-         }                                                                      \
 
-         /* 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 XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
 
-         }                                                                      \
 
-         if (fromLim - from < 4) {                                              \
 
-           *fromP = from;                                                       \
 
-           return XML_CONVERT_INPUT_INCOMPLETE;                                 \
 
-         }                                                                      \
 
-         plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1;                   \
 
-         *(*toP)++ = (char)((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;                                                             \
 
-     if (from < fromLim)                                                        \
 
-       return XML_CONVERT_INPUT_INCOMPLETE;                                     \
 
-     else                                                                       \
 
-       return XML_CONVERT_COMPLETED;                                            \
 
-   }
 
- #define DEFINE_UTF16_TO_UTF16(E)                                               \
 
-   static enum XML_Convert_Result PTRCALL E##toUtf16(                           \
 
-       const ENCODING *enc, const char **fromP, const char *fromLim,            \
 
-       unsigned short **toP, const unsigned short *toLim) {                     \
 
-     enum XML_Convert_Result res = XML_CONVERT_COMPLETED;                       \
 
-     UNUSED_P(enc);                                                             \
 
-     fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */  \
 
-     /* Avoid copying first half only of surrogate */                           \
 
-     if (fromLim - *fromP > ((toLim - *toP) << 1)                               \
 
-         && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) {                             \
 
-       fromLim -= 2;                                                            \
 
-       res = XML_CONVERT_INPUT_INCOMPLETE;                                      \
 
-     }                                                                          \
 
-     for (; *fromP < fromLim && *toP < toLim; *fromP += 2)                      \
 
-       *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP);                      \
 
-     if ((*toP == toLim) && (*fromP < fromLim))                                 \
 
-       return XML_CONVERT_OUTPUT_EXHAUSTED;                                     \
 
-     else                                                                       \
 
-       return res;                                                              \
 
-   }
 
- #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(little2_)
 
- DEFINE_UTF16_TO_UTF16(little2_)
 
- #undef SET2
 
- #undef GET_LO
 
- #undef GET_HI
 
- #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(big2_)
 
- DEFINE_UTF16_TO_UTF16(big2_)
 
- #undef SET2
 
- #undef GET_LO
 
- #undef GET_HI
 
- #define LITTLE2_BYTE_TYPE(enc, p)                                              \
 
-   ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]  \
 
-                : unicode_byte_type((p)[1], (p)[0]))
 
- #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1)
 
- #define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c)
 
- #define LITTLE2_IS_NAME_CHAR_MINBPC(p)                                         \
 
-   UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
 
- #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)                                       \
 
-   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
 
- #ifdef XML_MIN_SIZE
 
- static int PTRFASTCALL
 
- little2_byteType(const ENCODING *enc, const char *p) {
 
-   return LITTLE2_BYTE_TYPE(enc, p);
 
- }
 
- static int PTRFASTCALL
 
- little2_byteToAscii(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return LITTLE2_BYTE_TO_ASCII(p);
 
- }
 
- static int PTRCALL
 
- little2_charMatches(const ENCODING *enc, const char *p, int c) {
 
-   UNUSED_P(enc);
 
-   return LITTLE2_CHAR_MATCHES(p, c);
 
- }
 
- static int PTRFASTCALL
 
- little2_isNameMin(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return LITTLE2_IS_NAME_CHAR_MINBPC(p);
 
- }
 
- static int PTRFASTCALL
 
- little2_isNmstrtMin(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
 
- }
 
- #  undef VTABLE
 
- #  define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
 
- #else /* not XML_MIN_SIZE */
 
- #  undef PREFIX
 
- #  define PREFIX(ident) little2_##ident
 
- #  define MINBPC(enc) 2
 
- /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
 
- #  define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
 
- #  define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
 
- #  define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
 
- #  define IS_NAME_CHAR(enc, p, n) 0
 
- #  define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
 
- #  define IS_NMSTRT_CHAR(enc, p, n) (0)
 
- #  define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
 
- #  define XML_TOK_IMPL_C
 
- #  include "xmltok_impl.c"
 
- #  undef XML_TOK_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_CHAR
 
- #endif /* not XML_MIN_SIZE */
 
- #ifdef XML_NS
 
- static const struct normal_encoding little2_encoding_ns
 
-     = {{VTABLE, 2, 0,
 
- #  if BYTEORDER == 1234
 
-         1
 
- #  else
 
-         0
 
- #  endif
 
-        },
 
-        {
 
- #  include "asciitab.h"
 
- #  include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(little2_) NULL_VTABLE};
 
- #endif
 
- static const struct normal_encoding little2_encoding
 
-     = {{VTABLE, 2, 0,
 
- #if BYTEORDER == 1234
 
-         1
 
- #else
 
-         0
 
- #endif
 
-        },
 
-        {
 
- #define BT_COLON BT_NMSTRT
 
- #include "asciitab.h"
 
- #undef BT_COLON
 
- #include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(little2_) NULL_VTABLE};
 
- #if BYTEORDER != 4321
 
- #  ifdef XML_NS
 
- static const struct normal_encoding internal_little2_encoding_ns
 
-     = {{VTABLE, 2, 0, 1},
 
-        {
 
- #    include "iasciitab.h"
 
- #    include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(little2_) NULL_VTABLE};
 
- #  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"
 
-        },
 
-        STANDARD_VTABLE(little2_) NULL_VTABLE};
 
- #endif
 
- #define BIG2_BYTE_TYPE(enc, p)                                                 \
 
-   ((p)[0] == 0                                                                 \
 
-        ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]]        \
 
-        : unicode_byte_type((p)[0], (p)[1]))
 
- #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1)
 
- #define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c)
 
- #define BIG2_IS_NAME_CHAR_MINBPC(p)                                            \
 
-   UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
 
- #define BIG2_IS_NMSTRT_CHAR_MINBPC(p)                                          \
 
-   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
 
- #ifdef XML_MIN_SIZE
 
- static int PTRFASTCALL
 
- big2_byteType(const ENCODING *enc, const char *p) {
 
-   return BIG2_BYTE_TYPE(enc, p);
 
- }
 
- static int PTRFASTCALL
 
- big2_byteToAscii(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return BIG2_BYTE_TO_ASCII(p);
 
- }
 
- static int PTRCALL
 
- big2_charMatches(const ENCODING *enc, const char *p, int c) {
 
-   UNUSED_P(enc);
 
-   return BIG2_CHAR_MATCHES(p, c);
 
- }
 
- static int PTRFASTCALL
 
- big2_isNameMin(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return BIG2_IS_NAME_CHAR_MINBPC(p);
 
- }
 
- static int PTRFASTCALL
 
- big2_isNmstrtMin(const ENCODING *enc, const char *p) {
 
-   UNUSED_P(enc);
 
-   return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
 
- }
 
- #  undef VTABLE
 
- #  define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
 
- #else /* not XML_MIN_SIZE */
 
- #  undef PREFIX
 
- #  define PREFIX(ident) big2_##ident
 
- #  define MINBPC(enc) 2
 
- /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
 
- #  define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
 
- #  define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
 
- #  define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
 
- #  define IS_NAME_CHAR(enc, p, n) 0
 
- #  define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
 
- #  define IS_NMSTRT_CHAR(enc, p, n) (0)
 
- #  define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
 
- #  define XML_TOK_IMPL_C
 
- #  include "xmltok_impl.c"
 
- #  undef XML_TOK_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_CHAR
 
- #endif /* not XML_MIN_SIZE */
 
- #ifdef XML_NS
 
- static const struct normal_encoding big2_encoding_ns
 
-     = {{VTABLE, 2, 0,
 
- #  if BYTEORDER == 4321
 
-         1
 
- #  else
 
-         0
 
- #  endif
 
-        },
 
-        {
 
- #  include "asciitab.h"
 
- #  include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(big2_) NULL_VTABLE};
 
- #endif
 
- static const struct normal_encoding big2_encoding
 
-     = {{VTABLE, 2, 0,
 
- #if BYTEORDER == 4321
 
-         1
 
- #else
 
-         0
 
- #endif
 
-        },
 
-        {
 
- #define BT_COLON BT_NMSTRT
 
- #include "asciitab.h"
 
- #undef BT_COLON
 
- #include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(big2_) NULL_VTABLE};
 
- #if BYTEORDER != 1234
 
- #  ifdef XML_NS
 
- static const struct normal_encoding internal_big2_encoding_ns
 
-     = {{VTABLE, 2, 0, 1},
 
-        {
 
- #    include "iasciitab.h"
 
- #    include "latin1tab.h"
 
-        },
 
-        STANDARD_VTABLE(big2_) NULL_VTABLE};
 
- #  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"
 
-        },
 
-        STANDARD_VTABLE(big2_) NULL_VTABLE};
 
- #endif
 
- #undef PREFIX
 
- static int FASTCALL
 
- streqci(const char *s1, const char *s2) {
 
-   for (;;) {
 
-     char c1 = *s1++;
 
-     char c2 = *s2++;
 
-     if (ASCII_a <= c1 && c1 <= ASCII_z)
 
-       c1 += ASCII_A - ASCII_a;
 
-     if (ASCII_a <= c2 && c2 <= ASCII_z)
 
-       /* The following line will never get executed.  streqci() is
 
-        * only called from two places, both of which guarantee to put
 
-        * upper-case strings into s2.
 
-        */
 
-       c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
 
-     if (c1 != c2)
 
-       return 0;
 
-     if (! c1)
 
-       break;
 
-   }
 
-   return 1;
 
- }
 
- static void PTRCALL
 
- initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
 
-                    POSITION *pos) {
 
-   UNUSED_P(enc);
 
-   normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
 
- }
 
- 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 FASTCALL
 
- isSpace(int c) {
 
-   switch (c) {
 
-   case 0x20:
 
-   case 0xD:
 
-   case 0xA:
 
-   case 0x9:
 
-     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 **nameEndPtr,
 
-                      const char **valPtr, const char **nextTokPtr) {
 
-   int c;
 
-   char open;
 
-   if (ptr == end) {
 
-     *namePtr = NULL;
 
-     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 = NULL;
 
-     return 1;
 
-   }
 
-   *namePtr = ptr;
 
-   for (;;) {
 
-     c = toAscii(enc, ptr, end);
 
-     if (c == -1) {
 
-       *nextTokPtr = ptr;
 
-       return 0;
 
-     }
 
-     if (c == ASCII_EQUALS) {
 
-       *nameEndPtr = ptr;
 
-       break;
 
-     }
 
-     if (isSpace(c)) {
 
-       *nameEndPtr = ptr;
 
-       do {
 
-         ptr += enc->minBytesPerChar;
 
-       } while (isSpace(c = toAscii(enc, ptr, end)));
 
-       if (c != ASCII_EQUALS) {
 
-         *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 != ASCII_QUOT && c != ASCII_APOS) {
 
-     *nextTokPtr = ptr;
 
-     return 0;
 
-   }
 
-   open = (char)c;
 
-   ptr += enc->minBytesPerChar;
 
-   *valPtr = ptr;
 
-   for (;; ptr += enc->minBytesPerChar) {
 
-     c = toAscii(enc, ptr, end);
 
-     if (c == open)
 
-       break;
 
-     if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)
 
-         && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD
 
-         && c != ASCII_MINUS && c != ASCII_UNDERSCORE) {
 
-       *nextTokPtr = ptr;
 
-       return 0;
 
-     }
 
-   }
 
-   *nextTokPtr = ptr + enc->minBytesPerChar;
 
-   return 1;
 
- }
 
- static const char KW_version[]
 
-     = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'};
 
- static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d,
 
-                                    ASCII_i, ASCII_n, ASCII_g, '\0'};
 
- static const char KW_standalone[]
 
-     = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a,
 
-        ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'};
 
- static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'};
 
- static const char KW_no[] = {ASCII_n, ASCII_o, '\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 **versionEndPtr, const char **encodingName,
 
-                const ENCODING **encoding, int *standalone) {
 
-   const char *val = NULL;
 
-   const char *name = NULL;
 
-   const char *nameEnd = NULL;
 
-   ptr += 5 * enc->minBytesPerChar;
 
-   end -= 2 * enc->minBytesPerChar;
 
-   if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
 
-       || ! name) {
 
-     *badPtr = ptr;
 
-     return 0;
 
-   }
 
-   if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
 
-     if (! isGeneralTextEntity) {
 
-       *badPtr = name;
 
-       return 0;
 
-     }
 
-   } else {
 
-     if (versionPtr)
 
-       *versionPtr = val;
 
-     if (versionEndPtr)
 
-       *versionEndPtr = ptr;
 
-     if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
 
-       *badPtr = ptr;
 
-       return 0;
 
-     }
 
-     if (! name) {
 
-       if (isGeneralTextEntity) {
 
-         /* a TextDecl must have an EncodingDecl */
 
-         *badPtr = ptr;
 
-         return 0;
 
-       }
 
-       return 1;
 
-     }
 
-   }
 
-   if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
 
-     int c = toAscii(enc, val, end);
 
-     if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) {
 
-       *badPtr = val;
 
-       return 0;
 
-     }
 
-     if (encodingName)
 
-       *encodingName = val;
 
-     if (encoding)
 
-       *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
 
-     if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
 
-       *badPtr = ptr;
 
-       return 0;
 
-     }
 
-     if (! name)
 
-       return 1;
 
-   }
 
-   if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
 
-       || isGeneralTextEntity) {
 
-     *badPtr = name;
 
-     return 0;
 
-   }
 
-   if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
 
-     if (standalone)
 
-       *standalone = 1;
 
-   } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
 
-     if (standalone)
 
-       *standalone = 0;
 
-   } else {
 
-     *badPtr = val;
 
-     return 0;
 
-   }
 
-   while (isSpace(toAscii(enc, ptr, end)))
 
-     ptr += enc->minBytesPerChar;
 
-   if (ptr != end) {
 
-     *badPtr = ptr;
 
-     return 0;
 
-   }
 
-   return 1;
 
- }
 
- static int FASTCALL
 
- checkCharRefNumber(int result) {
 
-   switch (result >> 8) {
 
-   case 0xD8:
 
-   case 0xD9:
 
-   case 0xDA:
 
-   case 0xDB:
 
-   case 0xDC:
 
-   case 0xDD:
 
-   case 0xDE:
 
-   case 0xDF:
 
-     return -1;
 
-   case 0:
 
-     if (latin1_encoding.type[result] == BT_NONXML)
 
-       return -1;
 
-     break;
 
-   case 0xFF:
 
-     if (result == 0xFFFE || result == 0xFFFF)
 
-       return -1;
 
-     break;
 
-   }
 
-   return result;
 
- }
 
- int FASTCALL
 
- XmlUtf8Encode(int c, char *buf) {
 
-   enum {
 
-     /* minN is minimum legal resulting value for N byte sequence */
 
-     min2 = 0x80,
 
-     min3 = 0x800,
 
-     min4 = 0x10000
 
-   };
 
-   if (c < 0)
 
-     return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
 
-   if (c < min2) {
 
-     buf[0] = (char)(c | UTF8_cval1);
 
-     return 1;
 
-   }
 
-   if (c < min3) {
 
-     buf[0] = (char)((c >> 6) | UTF8_cval2);
 
-     buf[1] = (char)((c & 0x3f) | 0x80);
 
-     return 2;
 
-   }
 
-   if (c < min4) {
 
-     buf[0] = (char)((c >> 12) | UTF8_cval3);
 
-     buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
 
-     buf[2] = (char)((c & 0x3f) | 0x80);
 
-     return 3;
 
-   }
 
-   if (c < 0x110000) {
 
-     buf[0] = (char)((c >> 18) | UTF8_cval4);
 
-     buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
 
-     buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
 
-     buf[3] = (char)((c & 0x3f) | 0x80);
 
-     return 4;
 
-   }
 
-   return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
 
- }
 
- int FASTCALL
 
- XmlUtf16Encode(int charNum, unsigned short *buf) {
 
-   if (charNum < 0)
 
-     return 0;
 
-   if (charNum < 0x10000) {
 
-     buf[0] = (unsigned short)charNum;
 
-     return 1;
 
-   }
 
-   if (charNum < 0x110000) {
 
-     charNum -= 0x10000;
 
-     buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
 
-     buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
 
-     return 2;
 
-   }
 
-   return 0;
 
- }
 
- struct unknown_encoding {
 
-   struct normal_encoding normal;
 
-   CONVERTER convert;
 
-   void *userData;
 
-   unsigned short utf16[256];
 
-   char utf8[256][4];
 
- };
 
- #define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc))
 
- int
 
- XmlSizeOfUnknownEncoding(void) {
 
-   return sizeof(struct unknown_encoding);
 
- }
 
- static int PTRFASTCALL
 
- unknown_isName(const ENCODING *enc, const char *p) {
 
-   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
 
-   int c = uenc->convert(uenc->userData, p);
 
-   if (c & ~0xFFFF)
 
-     return 0;
 
-   return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
 
- }
 
- static int PTRFASTCALL
 
- unknown_isNmstrt(const ENCODING *enc, const char *p) {
 
-   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
 
-   int c = uenc->convert(uenc->userData, p);
 
-   if (c & ~0xFFFF)
 
-     return 0;
 
-   return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
 
- }
 
- static int PTRFASTCALL
 
- unknown_isInvalid(const ENCODING *enc, const char *p) {
 
-   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
 
-   int c = uenc->convert(uenc->userData, p);
 
-   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
 
- }
 
- static enum XML_Convert_Result PTRCALL
 
- unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-                char **toP, const char *toLim) {
 
-   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
 
-   char buf[XML_UTF8_ENCODE_MAX];
 
-   for (;;) {
 
-     const char *utf8;
 
-     int n;
 
-     if (*fromP == fromLim)
 
-       return XML_CONVERT_COMPLETED;
 
-     utf8 = uenc->utf8[(unsigned char)**fromP];
 
-     n = *utf8++;
 
-     if (n == 0) {
 
-       int c = uenc->convert(uenc->userData, *fromP);
 
-       n = XmlUtf8Encode(c, buf);
 
-       if (n > toLim - *toP)
 
-         return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-       utf8 = buf;
 
-       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
 
-                  - (BT_LEAD2 - 2));
 
-     } else {
 
-       if (n > toLim - *toP)
 
-         return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-       (*fromP)++;
 
-     }
 
-     memcpy(*toP, utf8, n);
 
-     *toP += n;
 
-   }
 
- }
 
- static enum XML_Convert_Result PTRCALL
 
- unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
 
-                 unsigned short **toP, const unsigned short *toLim) {
 
-   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
 
-   while (*fromP < fromLim && *toP < toLim) {
 
-     unsigned short c = uenc->utf16[(unsigned char)**fromP];
 
-     if (c == 0) {
 
-       c = (unsigned short)uenc->convert(uenc->userData, *fromP);
 
-       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
 
-                  - (BT_LEAD2 - 2));
 
-     } else
 
-       (*fromP)++;
 
-     *(*toP)++ = c;
 
-   }
 
-   if ((*toP == toLim) && (*fromP < fromLim))
 
-     return XML_CONVERT_OUTPUT_EXHAUSTED;
 
-   else
 
-     return XML_CONVERT_COMPLETED;
 
- }
 
- ENCODING *
 
- XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
 
-                        void *userData) {
 
-   int i;
 
-   struct unknown_encoding *e = (struct unknown_encoding *)mem;
 
-   memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding));
 
-   for (i = 0; i < 128; i++)
 
-     if (latin1_encoding.type[i] != BT_OTHER
 
-         && latin1_encoding.type[i] != BT_NONXML && table[i] != i)
 
-       return 0;
 
-   for (i = 0; i < 256; i++) {
 
-     int c = table[i];
 
-     if (c == -1) {
 
-       e->normal.type[i] = BT_MALFORM;
 
-       /* This shouldn't really get used. */
 
-       e->utf16[i] = 0xFFFF;
 
-       e->utf8[i][0] = 1;
 
-       e->utf8[i][1] = 0;
 
-     } else if (c < 0) {
 
-       if (c < -4)
 
-         return 0;
 
-       /* Multi-byte sequences need a converter function */
 
-       if (! convert)
 
-         return 0;
 
-       e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
 
-       e->utf8[i][0] = 0;
 
-       e->utf16[i] = 0;
 
-     } else if (c < 0x80) {
 
-       if (latin1_encoding.type[c] != BT_OTHER
 
-           && latin1_encoding.type[c] != BT_NONXML && c != i)
 
-         return 0;
 
-       e->normal.type[i] = latin1_encoding.type[c];
 
-       e->utf8[i][0] = 1;
 
-       e->utf8[i][1] = (char)c;
 
-       e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
 
-     } else if (checkCharRefNumber(c) < 0) {
 
-       e->normal.type[i] = BT_NONXML;
 
-       /* This shouldn't really get used. */
 
-       e->utf16[i] = 0xFFFF;
 
-       e->utf8[i][0] = 1;
 
-       e->utf8[i][1] = 0;
 
-     } else {
 
-       if (c > 0xFFFF)
 
-         return 0;
 
-       if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
 
-         e->normal.type[i] = BT_NMSTRT;
 
-       else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
 
-         e->normal.type[i] = BT_NAME;
 
-       else
 
-         e->normal.type[i] = BT_OTHER;
 
-       e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
 
-       e->utf16[i] = (unsigned short)c;
 
-     }
 
-   }
 
-   e->userData = userData;
 
-   e->convert = convert;
 
-   if (convert) {
 
-     e->normal.isName2 = unknown_isName;
 
-     e->normal.isName3 = unknown_isName;
 
-     e->normal.isName4 = unknown_isName;
 
-     e->normal.isNmstrt2 = unknown_isNmstrt;
 
-     e->normal.isNmstrt3 = unknown_isNmstrt;
 
-     e->normal.isNmstrt4 = unknown_isNmstrt;
 
-     e->normal.isInvalid2 = unknown_isInvalid;
 
-     e->normal.isInvalid3 = unknown_isInvalid;
 
-     e->normal.isInvalid4 = unknown_isInvalid;
 
-   }
 
-   e->normal.enc.utf8Convert = unknown_toUtf8;
 
-   e->normal.enc.utf16Convert = unknown_toUtf16;
 
-   return &(e->normal.enc);
 
- }
 
- /* If this enumeration is changed, getEncodingIndex and encodings
 
- must also be changed. */
 
- enum {
 
-   UNKNOWN_ENC = -1,
 
-   ISO_8859_1_ENC = 0,
 
-   US_ASCII_ENC,
 
-   UTF_8_ENC,
 
-   UTF_16_ENC,
 
-   UTF_16BE_ENC,
 
-   UTF_16LE_ENC,
 
-   /* must match encodingNames up to here */
 
-   NO_ENC
 
- };
 
- static const char KW_ISO_8859_1[]
 
-     = {ASCII_I, ASCII_S, ASCII_O,     ASCII_MINUS, ASCII_8, ASCII_8,
 
-        ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1,     '\0'};
 
- static const char KW_US_ASCII[]
 
-     = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S,
 
-        ASCII_C, ASCII_I, ASCII_I,     '\0'};
 
- static const char KW_UTF_8[]
 
-     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'};
 
- static const char KW_UTF_16[]
 
-     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'};
 
- static const char KW_UTF_16BE[]
 
-     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
 
-        ASCII_6, ASCII_B, ASCII_E, '\0'};
 
- static const char KW_UTF_16LE[]
 
-     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
 
-        ASCII_6, ASCII_L, ASCII_E, '\0'};
 
- static int FASTCALL
 
- getEncodingIndex(const char *name) {
 
-   static const char *const encodingNames[] = {
 
-       KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE,
 
-   };
 
-   int i;
 
-   if (name == NULL)
 
-     return NO_ENC;
 
-   for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++)
 
-     if (streqci(name, encodingNames[i]))
 
-       return i;
 
-   return UNKNOWN_ENC;
 
- }
 
- /* For binary compatibility, we store the index of the encoding
 
-    specified at initialization in the isUtf16 member.
 
- */
 
- #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
 
- #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
 
- /* This is what detects the encoding.  encodingTable maps from
 
-    encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
 
-    the external (protocol) specified encoding; state is
 
-    XML_CONTENT_STATE if we're parsing an external text entity, and
 
-    XML_PROLOG_STATE otherwise.
 
- */
 
- static int
 
- initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
 
-          int state, const char *ptr, const char *end, const char **nextTokPtr) {
 
-   const ENCODING **encPtr;
 
-   if (ptr >= end)
 
-     return XML_TOK_NONE;
 
-   encPtr = enc->encPtr;
 
-   if (ptr + 1 == end) {
 
-     /* only a single byte available for auto-detection */
 
- #ifndef XML_DTD /* FIXME */
 
-     /* a well-formed document entity must have more than one byte */
 
-     if (state != XML_CONTENT_STATE)
 
-       return XML_TOK_PARTIAL;
 
- #endif
 
-     /* so we're parsing an external text entity... */
 
-     /* if UTF-16 was externally specified, then we need at least 2 bytes */
 
-     switch (INIT_ENC_INDEX(enc)) {
 
-     case UTF_16_ENC:
 
-     case UTF_16LE_ENC:
 
-     case UTF_16BE_ENC:
 
-       return XML_TOK_PARTIAL;
 
-     }
 
-     switch ((unsigned char)*ptr) {
 
-     case 0xFE:
 
-     case 0xFF:
 
-     case 0xEF: /* possibly first byte of UTF-8 BOM */
 
-       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
 
-         break;
 
-       /* fall through */
 
-     case 0x00:
 
-     case 0x3C:
 
-       return XML_TOK_PARTIAL;
 
-     }
 
-   } else {
 
-     switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
 
-     case 0xFEFF:
 
-       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
 
-         break;
 
-       *nextTokPtr = ptr + 2;
 
-       *encPtr = encodingTable[UTF_16BE_ENC];
 
-       return XML_TOK_BOM;
 
-     /* 00 3C is handled in the default case */
 
-     case 0x3C00:
 
-       if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
 
-            || INIT_ENC_INDEX(enc) == UTF_16_ENC)
 
-           && state == XML_CONTENT_STATE)
 
-         break;
 
-       *encPtr = encodingTable[UTF_16LE_ENC];
 
-       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
 
-     case 0xFFFE:
 
-       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
 
-         break;
 
-       *nextTokPtr = ptr + 2;
 
-       *encPtr = encodingTable[UTF_16LE_ENC];
 
-       return XML_TOK_BOM;
 
-     case 0xEFBB:
 
-       /* Maybe a UTF-8 BOM (EF BB BF) */
 
-       /* If there's an explicitly specified (external) encoding
 
-          of ISO-8859-1 or some flavour of UTF-16
 
-          and this is an external text entity,
 
-          don't look for the BOM,
 
-          because it might be a legal data.
 
-       */
 
-       if (state == XML_CONTENT_STATE) {
 
-         int e = INIT_ENC_INDEX(enc);
 
-         if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC
 
-             || e == UTF_16_ENC)
 
-           break;
 
-       }
 
-       if (ptr + 2 == end)
 
-         return XML_TOK_PARTIAL;
 
-       if ((unsigned char)ptr[2] == 0xBF) {
 
-         *nextTokPtr = ptr + 3;
 
-         *encPtr = encodingTable[UTF_8_ENC];
 
-         return XML_TOK_BOM;
 
-       }
 
-       break;
 
-     default:
 
-       if (ptr[0] == '\0') {
 
-         /* 0 isn't a legal data character. Furthermore a document
 
-            entity can only start with ASCII characters.  So the only
 
-            way this can fail to be big-endian UTF-16 if it it's an
 
-            external parsed general entity that's labelled as
 
-            UTF-16LE.
 
-         */
 
-         if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
 
-           break;
 
-         *encPtr = encodingTable[UTF_16BE_ENC];
 
-         return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
 
-       } else if (ptr[1] == '\0') {
 
-         /* We could recover here in the case:
 
-             - parsing an external entity
 
-             - second byte is 0
 
-             - no externally specified encoding
 
-             - no encoding declaration
 
-            by assuming UTF-16LE.  But we don't, because this would mean when
 
-            presented just with a single byte, we couldn't reliably determine
 
-            whether we needed further bytes.
 
-         */
 
-         if (state == XML_CONTENT_STATE)
 
-           break;
 
-         *encPtr = encodingTable[UTF_16LE_ENC];
 
-         return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
 
-       }
 
-       break;
 
-     }
 
-   }
 
-   *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
 
-   return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
 
- }
 
- #define NS(x) x
 
- #define ns(x) x
 
- #define XML_TOK_NS_C
 
- #include "xmltok_ns.c"
 
- #undef XML_TOK_NS_C
 
- #undef NS
 
- #undef ns
 
- #ifdef XML_NS
 
- #  define NS(x) x##NS
 
- #  define ns(x) x##_ns
 
- #  define XML_TOK_NS_C
 
- #  include "xmltok_ns.c"
 
- #  undef XML_TOK_NS_C
 
- #  undef NS
 
- #  undef ns
 
- ENCODING *
 
- XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
 
-                          void *userData) {
 
-   ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
 
-   if (enc)
 
-     ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
 
-   return enc;
 
- }
 
- #endif /* XML_NS */
 
 
  |