hexpat 0.19.10 → 0.20.13
raw patch · 36 files changed
Files
- Text/XML/Expat/Annotated.hs +9/−72
- Text/XML/Expat/Cursor.hs +1/−1
- Text/XML/Expat/Extended.hs +1/−1
- Text/XML/Expat/Format.hs +1/−16
- Text/XML/Expat/IO.hs +0/−9
- Text/XML/Expat/Internal/DocumentClass.hs +1/−1
- Text/XML/Expat/Internal/Glue.c +245/−0
- Text/XML/Expat/Internal/IO.hs +108/−666
- Text/XML/Expat/Internal/NodeClass.hs +1/−10
- Text/XML/Expat/Namespaced.hs +0/−9
- Text/XML/Expat/NodeClass.hs +0/−9
- Text/XML/Expat/Proc.hs +1/−1
- Text/XML/Expat/Qualified.hs +0/−9
- Text/XML/Expat/SAX.hs +145/−309
- Text/XML/Expat/Tree.hs +46/−172
- cbits/README +139/−0
- cbits/amigaconfig.h +0/−32
- cbits/expat.h +56/−12
- cbits/expat_external.h +18/−1
- cbits/internal.h +22/−0
- cbits/macconfig.h +0/−53
- cbits/siphash.h +344/−0
- cbits/winconfig.h +10/−0
- cbits/xmlparse.c +6816/−6274
- cbits/xmlrole.c +112/−118
- cbits/xmltok.c +172/−76
- cbits/xmltok.h +8/−2
- cbits/xmltok_impl.c +111/−115
- hexpat.cabal +69/−46
- test/ROADS.xml +1008/−0
- test/hexpat-tests.cabal +5/−5
- test/readRoads.hs +20/−0
- test/suite/Text/XML/Expat/Cursor/Tests.hs +2/−2
- test/suite/Text/XML/Expat/ParallelTest.hs +11/−13
- test/suite/Text/XML/Expat/ParseFormat.hs +2/−2
- test/suite/Text/XML/Expat/UnitTests.hs +73/−29
Text/XML/Expat/Annotated.hs view
@@ -49,24 +49,10 @@ saxToTreeG, -- * Abstraction of string types- GenericXMLString(..),-- -- * Deprecated- eAttrs,- parseSAX,- parseSAXThrowing,- parseSAXLocations,- parseSAXLocationsThrowing,- parseTree,- parseTree',- parseTreeThrowing,- unannotate,- ParserOptions,- defaultParserOptions+ GenericXMLString(..) ) where -import Control.Arrow-import qualified Text.XML.Expat.Tree as Tree+import Control.Arrow (first) import Text.XML.Expat.SAX ( Encoding(..) , GenericXMLString(..) , ParseOptions(..)@@ -74,13 +60,7 @@ , SAXEvent(..) , XMLParseError(..) , XMLParseException(..)- , XMLParseLocation(..)- , parseSAX- , parseSAXThrowing- , parseSAXLocations- , parseSAXLocationsThrowing- , ParserOptions- , defaultParserOptions )+ , XMLParseLocation(..) ) import qualified Text.XML.Expat.SAX as SAX import Text.XML.Expat.Internal.Namespaced import Text.XML.Expat.Internal.NodeClass@@ -91,7 +71,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L-import Data.List.Class+import Data.List.Class (List(..), ListItem(..), cons, foldlL, joinM) import Data.Monoid @@ -99,8 +79,8 @@ -- that it has an extra piece of information of your choice attached to each -- Element. ----- @c@ is the container type for the element's children, which is [] in the--- @hexpat@ package, and a monadic list type for @hexpat-iteratee@.+-- @c@ is the container type for the element's children, which would normally be [],+-- but could potentially be a monadic list type to allow for chunked I/O. -- -- @tag@ is the tag type, which can either be one of several string types, -- or a special type from the @Text.XML.Expat.Namespaced@ or@@ -153,10 +133,6 @@ Text t1 == Text t2 = t1 == t2 _ == _ = False -eAttrs :: Node a tag text -> [(tag, text)]-{-# DEPRECATED eAttrs "use eAttributes instead" #-}-eAttrs = eAttributes- instance (NFData tag, NFData text, NFData a) => NFData (NodeG a [] tag text) where rnf (Element nam att chi ann) = rnf (nam, att, chi, ann) rnf (Text txt) = rnf txt@@ -223,13 +199,6 @@ instance (Functor c, List c) => MkElementClass (NodeG ()) c where mkElement name attrs children = Element name attrs children () --- | Convert an annotated tree (/Annotated/ module) into a non-annotated--- tree (/Tree/ module). DEPRECATED in favour of 'fromElement'.-unannotate :: Functor c => NodeG a c tag text -> Tree.NodeG c tag text-{-# DEPRECATED unannotate "use fromElement instead" #-}-unannotate (Element na at ch _) = (Tree.Element na at (fmap unannotate ch))-unannotate (Text t) = Tree.Text t- -- | Type alias for an annotated node with unqualified tag names where -- tag and text are the same string type type UNode a text = Node a text text@@ -339,18 +308,6 @@ -> ItemM l (NodeG XMLParseLocation l tag text) parseG opts = saxToTreeG . SAX.parseLocationsG opts --- | DEPRECATED: Use 'parse' instead.------ Lazily parse XML to tree. Note that forcing the XMLParseError return value--- will force the entire parse. Therefore, to ensure lazy operation, don't--- check the error status until you have processed the tree.-parseTree :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> (LNode tag text, Maybe XMLParseError)-{-# DEPRECATED parseTree "use Text.XML.Annotated.parse instead" #-}-parseTree mEnc = parse (ParseOptions mEnc Nothing)- -- | Lazily parse XML to tree. In the event of an error, throw 'XMLParseException'. -- -- @parseThrowing@ can throw an exception from pure code, which is generally a bad@@ -364,32 +321,12 @@ -> LNode tag text parseThrowing opts bs = fst $ saxToTree $ SAX.parseLocationsThrowing opts bs --- | DEPRECATED: use 'parseThrowing' instead------ Lazily parse XML to tree. In the event of an error, throw 'XMLParseException'.-parseTreeThrowing :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> LNode tag text-{-# DEPRECATED parseTreeThrowing "use Text.XML.Annotated.parseThrowing instead" #-}-parseTreeThrowing mEnc = parseThrowing (ParseOptions mEnc Nothing)- -- | Strictly parse XML to tree. Returns error message or valid parsed tree. parse' :: (GenericXMLString tag, GenericXMLString text) => ParseOptions tag text -- ^ Parse options -> B.ByteString -- ^ Input text (a strict ByteString) -> Either XMLParseError (LNode tag text)-parse' opts bs = case parse opts (L.fromChunks [bs]) of- (_, Just err) -> Left err- (root, Nothing) -> Right root ---- | DEPRECATED: use 'parse' instead.------ Strictly parse XML to tree. Returns error message or valid parsed tree.-parseTree' :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> B.ByteString -- ^ Input text (a strict ByteString)- -> Either XMLParseError (LNode tag text)-{-# DEPRECATED parseTree' "use Text.XML.Expat.parse' instead" #-}-parseTree' mEnc = parse' (ParseOptions mEnc Nothing)+parse' opts doc = case parse opts (L.fromChunks [doc]) of+ (xml, Nothing) -> Right xml+ (_, Just err) -> Left err
Text/XML/Expat/Cursor.hs view
@@ -97,7 +97,7 @@ import Data.Maybe(isNothing) import Data.Monoid import Data.Functor.Identity-import Data.List.Class+import Data.List.Class (List(..), ListItem(..), cons, foldlL, lengthL) data Tag tag text = Tag { tagName :: tag , tagAttribs :: Attributes tag text
Text/XML/Expat/Extended.hs view
@@ -80,7 +80,7 @@ import Control.DeepSeq import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L-import Data.List.Class+import Data.List.Class (List, foldlL, joinM) import Data.Maybe import Data.Monoid
Text/XML/Expat/Format.hs view
@@ -28,9 +28,6 @@ formatDocument, formatDocument', formatDocumentG,- -- * Deprecated names- formatTree,- formatTree', -- * Low level xmlHeader, treeToSAX,@@ -52,18 +49,12 @@ import qualified Data.ByteString.Lazy as L import Data.ByteString.Internal (c2w, w2c) import Data.Char (isSpace)-import Data.List.Class+import Data.List.Class (List(..), ListItem(..), fromList) import Data.Monoid import Data.Word import Data.Text (Text) import Text.XML.Expat.Tree (UNode) --- | DEPRECATED: Renamed to 'format'.-formatTree :: (NodeClass n [], GenericXMLString tag, GenericXMLString text) =>- n [] tag text- -> L.ByteString-formatTree = format- -- | Format document with <?xml.. header - lazy variant that returns lazy ByteString. format :: (NodeClass n [], GenericXMLString tag, GenericXMLString text) => n [] tag text@@ -77,12 +68,6 @@ n c tag text -> c B.ByteString formatG node = cons xmlHeader $ formatNodeG node---- | DEPRECATED: Renamed to 'format''.-formatTree' :: (NodeClass n [], GenericXMLString tag, GenericXMLString text) =>- n [] tag text- -> B.ByteString-formatTree' = B.concat . L.toChunks . formatTree -- | Format document with <?xml.. header - strict variant that returns strict ByteString. format' :: (NodeClass n [], GenericXMLString tag, GenericXMLString text) =>
− Text/XML/Expat/IO.hs
@@ -1,9 +0,0 @@-{-# OPTIONS_HADDOCK hide #-}-module Text.XML.Expat.IO- {-# DEPRECATED "Renamed to Text.XML.Expat.Internal.IO" #-}- (- module Text.XML.Expat.Internal.IO- ) where--import Text.XML.Expat.Internal.IO-
Text/XML/Expat/Internal/DocumentClass.hs view
@@ -6,7 +6,7 @@ import Text.XML.Expat.Internal.NodeClass (NodeClass) import Control.DeepSeq import Control.Monad (mzero)-import Data.List.Class+import Data.List.Class (List) -- | XML declaration, consisting of version, encoding and standalone.
+ Text/XML/Expat/Internal/Glue.c view
@@ -0,0 +1,245 @@+#include <expat.h>+#include <unistd.h>+#include <stdint.h>+#include <string.h>++typedef struct {+ XML_Parser parser;+ XML_Char* (*decoder)(const XML_Char*);+ int locations;+} MyParser;++typedef struct {+ size_t offset;+ size_t capacity;+ uint8_t* block;+ MyParser* mp;+} Block;++/*!+ * Allocate the specified amount of room in the buffer.+ */+static void* alloc(Block* blk, size_t room)+{+ size_t minCapacity = blk->offset + room;+ size_t start = blk->offset;+ {+ int changed = 0;+ size_t capacity = blk->capacity;+ while (capacity < minCapacity) {+ capacity = capacity * 2;+ changed = 1;+ }+ if (changed) {+ blk->capacity = capacity;+ blk->block = realloc(blk->block, capacity);+ }+ }+ blk->offset += room;+ return blk->block + start;+}++static void pushType(Block* blk, uint32_t type)+{+ *(uint32_t*)alloc(blk, 4) = type;+ if (blk->mp->locations) {+ int64_t* loc = alloc(blk, 32);+ loc[0] = (int64_t)XML_GetCurrentLineNumber(blk->mp->parser);+ loc[1] = (int64_t)XML_GetCurrentColumnNumber(blk->mp->parser);+ loc[2] = (int64_t)XML_GetCurrentByteIndex(blk->mp->parser);+ loc[3] = (int64_t)XML_GetCurrentByteCount(blk->mp->parser);+ }+}++#define ROUND_UP_32(x) (((x) + 3) & ~3)++static void startElement(+ void *userData,+ const XML_Char *name,+ const XML_Char **atts)+{+ Block* blk = userData;+ size_t nameLen = strlen(name) + 1;+ size_t nAtts, i;+ for (nAtts = 0; atts[nAtts] != NULL; nAtts += 2) ;+ pushType(blk, 1);+ *(uint32_t*)alloc(blk, 4) = nAtts;+ memcpy(alloc(blk, nameLen), name, nameLen);+ for (i = 0; i < nAtts; i++) {+ size_t attLen = strlen(atts[i]) + 1;+ memcpy(alloc(blk, attLen), atts[i], attLen);+ }+ blk->offset = ROUND_UP_32(blk->offset);+}++static void endElement(void *userData, const XML_Char *name)+{+ Block* blk = userData;+ size_t nameLen = strlen(name) + 1;+ pushType(blk, 2);+ memcpy(alloc(blk, nameLen), name, nameLen);+ blk->offset = ROUND_UP_32(blk->offset);+}++static void characterData(+ void *userData,+ const XML_Char *s,+ int len)+{+ Block* blk = userData;+ pushType(blk, 3);+ *(uint32_t*)alloc(blk, 4) = len;+ memcpy(alloc(blk, (size_t)len), s, (size_t)len);+ blk->offset = ROUND_UP_32(blk->offset);+}++static void xmlDeclHandler(void *userData,+ const XML_Char *version,+ const XML_Char *encoding,+ int standalone)+{+ Block* blk = userData;+ int verLen = strlen(version) + 1;+ pushType(blk, 4);+ memcpy(alloc(blk, verLen), version, verLen);+ if (encoding != NULL) {+ int encLen = strlen(encoding)+1;+ uint8_t* pEnc = alloc(blk, encLen+1);+ pEnc[0] = 1;+ memcpy(pEnc+1, encoding, encLen);+ }+ else+ *(uint8_t*)alloc(blk, 1) = 0;+ *(int8_t*)alloc(blk, 1) = (int8_t)standalone;+ blk->offset = ROUND_UP_32(blk->offset);+}++static void startCData(void* userData)+{+ Block* blk = userData;+ pushType(blk, 5);+}++static void endCData(void* userData)+{+ Block* blk = userData;+ pushType(blk, 6);+}++static void processingInstruction(void *userData, const XML_Char *target, const XML_Char *data)+{+ Block* blk = userData;+ int targetLen = strlen(target) + 1;+ int dataLen = strlen(data) + 1;+ pushType(blk, 7);+ memcpy(alloc(blk, targetLen), target, targetLen);+ memcpy(alloc(blk, dataLen), data, dataLen);+ blk->offset = ROUND_UP_32(blk->offset);+}++static void comment(void* userData, const XML_Char *text)+{+ Block* blk = userData;+ int textLen = strlen(text) + 1;+ pushType(blk, 8);+ memcpy(alloc(blk, textLen), text, textLen);+ blk->offset = ROUND_UP_32(blk->offset);+}++MyParser* hexpatNewParser(const XML_Char* encoding, int locations)+{+ MyParser* mp = malloc(sizeof(MyParser));+ XML_Parser p = XML_ParserCreate(encoding);+ XML_SetStartElementHandler(p, startElement);+ XML_SetEndElementHandler(p, endElement);+ XML_SetCharacterDataHandler(p, characterData);+ XML_SetXmlDeclHandler(p, xmlDeclHandler);+ XML_SetCdataSectionHandler(p, startCData, endCData);+ XML_SetProcessingInstructionHandler(p, processingInstruction);+ XML_SetCommentHandler(p, comment);+ mp->parser = p;+ mp->locations = locations;+ return mp;+}++void hexpatFreeParser(MyParser* mp)+{+ XML_ParserFree(mp->parser);+ free(mp);+}++static int externalEntityRef(XML_Parser parser,+ const XML_Char *context,+ const XML_Char *base,+ const XML_Char *systemId,+ const XML_Char *publicId)+{+ if (systemId == NULL && publicId == NULL) {+ XML_Parser eep = XML_ExternalEntityParserCreate(parser, context, NULL);+ enum XML_Status ret = XML_Parse(eep, "", 0, XML_TRUE);+ if (ret == XML_STATUS_OK) {+ XML_ParserFree(eep);+ }+ else {+ XML_ParserFree(eep);+ XML_StopParser(parser, 0);+ }+ }+ else+ XML_StopParser(parser, 0);+}++static void skippedEntity(void *userData,+ const XML_Char *entityName,+ int is_parameter_entity)+{+ Block* blk = userData;+ if (is_parameter_entity)+ XML_StopParser(blk->mp->parser, 0);+ else {+ XML_Char* out = blk->mp->decoder(entityName);+ if (out != NULL) {+ characterData(blk, out, strlen(out));+ free(out);+ }+ else+ XML_StopParser(blk->mp->parser, 0);+ }+}++enum XML_Status hexpatParse(+ MyParser* mp,+ const char* s,+ int len,+ int isFinal,+ uint8_t** buffer,+ int* length)+{+ enum XML_Status ret;+ Block blk;+ blk.offset = 0;+ blk.capacity = 256;+ blk.block = malloc(blk.capacity);+ blk.mp = mp;+ XML_SetUserData(mp->parser, &blk);+ ret = XML_Parse(mp->parser, s, len, isFinal);+ *(uint32_t*)alloc(&blk, 4) = 0;+ *buffer = blk.block;+ *length = (int)blk.offset;+ return ret;+}++void hexpatSetEntityHandler(+ MyParser* mp,+ XML_Char* (*decoder)(const XML_Char*))+{+ mp->decoder = decoder;+ XML_UseForeignDTD(mp->parser, XML_TRUE);+ XML_SetExternalEntityRefHandler(mp->parser, externalEntityRef);+ XML_SetSkippedEntityHandler(mp->parser, skippedEntity);+}++XML_Parser hexpatGetParser(MyParser* mp)+{+ return mp->parser;+}
Text/XML/Expat/Internal/IO.hs view
@@ -1,94 +1,32 @@ {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}+{-# OPTIONS_GHC -fno-cse -fno-full-laziness #-} + -- | Low-level interface to Expat. Unless speed is paramount, this should -- normally be avoided in favour of the interfaces provided by--- 'Text.XML.Expat.SAX' and 'Text.XML.Expat.Tree', etc. Basic usage is:------ (1) Make a new parser: 'newParser'.------ (2) Set up callbacks on the parser: 'setStartElementHandler', etc.------ (3) Feed data into the parser: 'parse', 'parse'' or 'parseChunk'. Some of--- these functions must be wrapped in 'withParser'.-+-- 'Text.XML.Expat.SAX' and 'Text.XML.Expat.Tree', etc. module Text.XML.Expat.Internal.IO (- -- ** Parser Setup- Parser, newParser,-- -- ** Parsing- parse, parse',- withParser,- ParserPtr, Parser_struct,- parseChunk,+ HParser,+ hexpatNewParser,+ encodingToString, Encoding(..), XMLParseError(..),- getParseLocation,- XMLParseLocation(..),-- -- ** Parser Callbacks- XMLDeclarationHandler,- StartElementHandler,- EndElementHandler,- CharacterDataHandler,- ExternalEntityRefHandler,- SkippedEntityHandler,- StartCDataHandler,- EndCDataHandler,- CommentHandler,- ProcessingInstructionHandler,- setXMLDeclarationHandler,- setStartElementHandler,- setEndElementHandler,- setCharacterDataHandler,- setStartCDataHandler,- setEndCDataHandler,- setProcessingInstructionHandler,- setCommentHandler,- setExternalEntityRefHandler,- setSkippedEntityHandler,- setUseForeignDTD,-- -- ** Lower-level interface- parseExternalEntityReference,- ExpatHandlers,-- -- ** Helpers- encodingToString+ XMLParseLocation(..) ) where -import Control.Concurrent-import Control.Exception (bracket)+import Control.Applicative import Control.DeepSeq-import Control.Monad-import qualified Data.ByteString as BS-import qualified Data.ByteString.Lazy as BSL-import Data.IORef-import Foreign hiding (unsafePerformIO)+import qualified Data.ByteString as B+import qualified Data.ByteString.Internal as I+import Data.Int+import Data.Word+import Foreign import Foreign.C-import System.IO.Unsafe (unsafePerformIO) --- |Opaque parser type. data Parser_struct type ParserPtr = Ptr Parser_struct-data Parser = Parser- { _parserObj :: ForeignPtr Parser_struct- , _xmlDeclarationHandler :: IORef CXMLDeclarationHandler- , _startElementHandler :: IORef CStartElementHandler- , _endElementHandler :: IORef CEndElementHandler- , _cdataHandler :: IORef CCharacterDataHandler- , _externalEntityRefHandler :: IORef (Maybe CExternalEntityRefHandler)- , _skippedEntityHandler :: IORef (Maybe CSkippedEntityHandler)- , _startCDataHandler :: IORef CStartCDataHandler- , _endCDataHandler :: IORef CEndCDataHandler- , _processingInstructionHandler :: IORef CProcessingInstructionHandler- , _commentHandler :: IORef CCommentHandler- } -instance Show Parser where- showsPrec _ (Parser fp _ _ _ _ _ _ _ _ _ _) = showsPrec 0 fp---- |Encoding types available for the document encoding. data Encoding = ASCII | UTF8 | UTF16 | ISO88591 encodingToString :: Encoding -> String encodingToString ASCII = "US-ASCII"@@ -100,99 +38,16 @@ withOptEncoding Nothing f = f nullPtr withOptEncoding (Just enc) f = withCString (encodingToString enc) f --parserCreate :: Maybe Encoding -> IO (ParserPtr)-parserCreate a1 =- withOptEncoding a1 $ \a1' -> do- pp <- parserCreate'_ a1'- xmlSetUserData pp pp- return pp---- | Create a 'Parser'.-newParser :: Maybe Encoding -> IO Parser-newParser enc = do- ptr <- parserCreate enc- fptr <- newForeignPtr parserFree ptr- nullXMLDeclH <- newIORef nullCXMLDeclarationHandler- nullStartH <- newIORef nullCStartElementHandler- nullEndH <- newIORef nullCEndElementHandler- nullCharH <- newIORef nullCCharacterDataHandler- extH <- newIORef Nothing- skipH <- newIORef Nothing- nullSCDataH <- newIORef nullCStartCDataHandler- nullECDataH <- newIORef nullCEndCDataHandler- nullPIH <- newIORef nullCProcessingInstructionHandler- nullCommentH <- newIORef nullCCommentHandler-- return $ Parser fptr nullXMLDeclH nullStartH nullEndH nullCharH extH skipH - nullSCDataH nullECDataH nullPIH nullCommentH- -setUseForeignDTD :: Parser -> Bool -> IO ()-setUseForeignDTD p b = withParser p $ \p' -> xmlUseForeignDTD p' b'- where- b' = if b then 1 else 0- -- ByteString.useAsCStringLen is almost what we need, but C2HS wants a CInt -- instead of an Int.-withBStringLen :: BS.ByteString -> ((CString, CInt) -> IO a) -> IO a+withBStringLen :: B.ByteString -> ((CString, CInt) -> IO a) -> IO a withBStringLen bs f = do- BS.useAsCStringLen bs $ \(str, len) -> f (str, fromIntegral len)+ B.useAsCStringLen bs $ \(str, len) -> f (str, fromIntegral len) unStatus :: CInt -> Bool unStatus 0 = False unStatus _ = True --- |@parse data@ feeds /lazy/ ByteString data into a 'Parser'. It returns--- Nothing on success, or Just the parse error.-parse :: Parser -> BSL.ByteString -> IO (Maybe XMLParseError)-parse parser bs = withParser parser $ \pp -> do- let- doParseChunks [] = doParseChunk pp BS.empty True- doParseChunks (c:cs) = do- ok <- doParseChunk pp c False- if ok- then doParseChunks cs- else return False- ok <- doParseChunks (BSL.toChunks bs)- if ok- then return Nothing- else Just `fmap` getError pp---- |@parse data@ feeds /strict/ ByteString data into a 'Parser'. It returns--- Nothing on success, or Just the parse error.-parse' :: Parser -> BS.ByteString -> IO (Maybe XMLParseError)-parse' parser bs = withParser parser $ \pp -> do- ok <- doParseChunk pp bs True- if ok- then return Nothing- else Just `fmap` getError pp--parseExternalEntityReference :: Parser- -> CString -- ^ context- -> Maybe Encoding -- ^ encoding- -> CStringLen -- ^ text- -> IO Bool-parseExternalEntityReference parser context encoding (text,sz) =- withParser parser $ \pp -> do- extp <- withOptEncoding encoding $- xmlExternalEntityParserCreate pp context- e <- doParseChunk'_ extp text (fromIntegral sz) 1- parserFree' extp- return $ e == 1---- |@parseChunk data False@ feeds /strict/ ByteString data into a--- 'Parser'. The end of the data is indicated by passing @True@ for the--- final parameter. It returns Nothing on success, or Just the parse error.-parseChunk :: ParserPtr- -> BS.ByteString- -> Bool- -> IO (Maybe XMLParseError)-parseChunk pp xml final = do- ok <- doParseChunk pp xml final- if ok- then return Nothing- else Just `fmap` getError pp- getError :: ParserPtr -> IO XMLParseError getError pp = do code <- xmlGetErrorCode pp@@ -201,146 +56,10 @@ loc <- getParseLocation pp return $ XMLParseError err loc -data ExpatHandlers = ExpatHandlers- (FunPtr CXMLDeclarationHandler)- (FunPtr CStartElementHandler)- (FunPtr CEndElementHandler)- (FunPtr CCharacterDataHandler)- (Maybe (FunPtr CExternalEntityRefHandler))- (Maybe (FunPtr CSkippedEntityHandler))- (FunPtr CStartCDataHandler)- (FunPtr CEndCDataHandler)- (FunPtr CProcessingInstructionHandler)- (FunPtr CCommentHandler)---- | Most of the low-level functions take a ParserPtr so are required to be--- called inside @withParser@.-withParser :: Parser- -> (ParserPtr -> IO a) -- ^ Computation where parseChunk and other low-level functions may be used- -> IO a-withParser parser@(Parser fp _ _ _ _ _ _ _ _ _ _) code = withForeignPtr fp $ \pp -> do- bracket- (unsafeSetHandlers parser pp)- unsafeReleaseHandlers- (\_ -> code pp)- where- unsafeSetHandlers :: Parser -> ParserPtr -> IO ExpatHandlers- unsafeSetHandlers (Parser _ xmlDeclRef startRef endRef charRef extRef skipRef - startCDataRef endCDataRef processingInstructionRef commentRef) pp =- do- cXMLDeclH <- mkCXMLDeclarationHandler =<< readIORef xmlDeclRef- cStartH <- mkCStartElementHandler =<< readIORef startRef- cEndH <- mkCEndElementHandler =<< readIORef endRef- cCharH <- mkCCharacterDataHandler =<< readIORef charRef- mExtH <- readIORef extRef >>=- maybe (return Nothing)- (\h -> liftM Just $ mkCExternalEntityRefHandler h)- - mSkipH <- readIORef skipRef >>=- maybe (return Nothing)- (\h -> liftM Just $ mkCSkippedEntityHandler h)- - cStartCDataH <- mkCStartCDataHandler =<< readIORef startCDataRef- cEndCDataH <- mkCEndCDataHandler =<< readIORef endCDataRef- - cProcessingInstructionH <- mkCProcessingInstructionHandler =<< readIORef processingInstructionRef- cCommentH <- mkCCommentHandler =<< readIORef commentRef- - xmlSetxmldeclhandler pp cXMLDeclH- xmlSetstartelementhandler pp cStartH- xmlSetendelementhandler pp cEndH- xmlSetcharacterdatahandler pp cCharH- xmlSetstartcdatahandler pp cStartCDataH- xmlSetendcdatahandler pp cEndCDataH- xmlSetprocessinginstructionhandler pp cProcessingInstructionH- xmlSetcommenthandler pp cCommentH- maybe (return ())- (xmlSetExternalEntityRefHandler pp)- mExtH- maybe (return ())- (xmlSetSkippedEntityHandler pp)- mSkipH- - return $ ExpatHandlers cXMLDeclH cStartH cEndH cCharH mExtH mSkipH - cStartCDataH cEndCDataH cProcessingInstructionH cCommentH- - unsafeReleaseHandlers :: ExpatHandlers -> IO ()- unsafeReleaseHandlers (ExpatHandlers cXMLDeclH cStartH cEndH cCharH mcExtH mcSkipH - cStartCDataH cEndCDataH cProcessingInstructionH cCommentH) = do- freeHaskellFunPtr cXMLDeclH- freeHaskellFunPtr cStartH- freeHaskellFunPtr cEndH- freeHaskellFunPtr cCharH- maybe (return ()) freeHaskellFunPtr mcExtH- maybe (return ()) freeHaskellFunPtr mcSkipH- freeHaskellFunPtr cStartCDataH- freeHaskellFunPtr cEndCDataH- freeHaskellFunPtr cProcessingInstructionH- freeHaskellFunPtr cCommentH- -- |Obtain C value from Haskell 'Bool'. -- cFromBool :: Num a => Bool -> a-cFromBool = fromBool--doParseChunk :: ParserPtr -> BS.ByteString -> Bool -> IO (Bool)-doParseChunk = ensureBoundThread $ \a1 a2 a3 ->- withBStringLen a2 $ \(a2'1, a2'2) ->- let {a3' = cFromBool a3} in- doParseChunk'_ a1 a2'1 a2'2 a3' >>= \res ->- let {res' = unStatus res} in- return (res')--data WorkerIface = WorkerIface (MVar (ParserPtr, BS.ByteString, Bool)) (MVar Bool)--workerIfaceRef :: IORef (Maybe WorkerIface)-{-# NOINLINE workerIfaceRef #-}-workerIfaceRef = unsafePerformIO $ newIORef Nothing---- If the calling thread is not bound, we delegate to a bound thread, because--- otherwise we get a thread explosion (this is true in ghc-6.12.X).--- See test/thread-leak/ directory for a test case.-ensureBoundThread :: (ParserPtr -> BS.ByteString -> Bool -> IO Bool)- -> ParserPtr- -> BS.ByteString- -> Bool- -> IO Bool-ensureBoundThread doit p bs last = do- bound <- isCurrentThreadBound- if rtsSupportsBoundThreads && not bound- then delegate- else doit p bs last- where- delegate = do- mIface <- readIORef workerIfaceRef- case mIface of- Just iface -> pipeTo iface- Nothing -> do- inV <- newEmptyMVar- outV <- newEmptyMVar- let iface = WorkerIface inV outV- justSetItGlobally <- atomicModifyIORef workerIfaceRef $ \mIface ->- case mIface of- Just _ -> (mIface, False)- Nothing -> (Just iface, True) - if justSetItGlobally- then do- _ <- forkOS $ worker iface- pipeTo iface- else- -- If it wasn't changed, then this is because we got a race- -- condition with another thread. We resolve this by trying- -- again. We'll succeed on the second attempt. The mvars- -- we allocated here will be GC'd.- delegate-- pipeTo (WorkerIface inV outV) =- putMVar inV (p, bs, last) >> takeMVar outV-- worker (WorkerIface inV outV) = forever $- putMVar outV =<< uncurry3 doit =<< takeMVar inV- where- uncurry3 f (a, b, c) = f a b c +cFromBool = fromBool -- | Parse error, consisting of message text and error location data XMLParseError = XMLParseError String XMLParseLocation deriving (Eq, Show)@@ -373,373 +92,6 @@ xmlByteCount = fromIntegral count } --- | The type of the \"XML declaration\" callback. Parameters are version,--- encoding (which can be nullPtr), and standalone declaration, where -1 = no--- declaration, 0 = "no" and 1 = "yes". Return True to continue parsing as--- normal, or False to terminate the parse.-type XMLDeclarationHandler = ParserPtr -> CString -> CString -> CInt -> IO Bool---- | The type of the \"element started\" callback. The first parameter is the--- element name; the second are the (attribute, value) pairs. Return True to--- continue parsing as normal, or False to terminate the parse.-type StartElementHandler = ParserPtr -> CString -> [(CString, CString)] -> IO Bool---- | The type of the \"element ended\" callback. The parameter is the element--- name. Return True to continue parsing as normal, or False to terminate the--- parse.-type EndElementHandler = ParserPtr -> CString -> IO Bool---- | The type of the \"character data\" callback. The parameter is the--- character data processed. This callback may be called more than once while--- processing a single conceptual block of text. Return True to continue--- parsing as normal, or False to terminate the parse.-type CharacterDataHandler = ParserPtr -> CStringLen -> IO Bool---- | The type of the \"start cdata\" callback. Return True to continue--- parsing as normal, or False to terminate the parse.-type StartCDataHandler = ParserPtr -> IO Bool---- | The type of the \"end cdata\" callback. Return True to continue--- parsing as normal, or False to terminate the parse.-type EndCDataHandler = ParserPtr -> IO Bool---- | The type of the \"processing instruction\" callback. The first parameter--- is the first word in the processing instruction. The second parameter is--- the rest of the characters in the processing instruction after skipping all--- whitespace after the initial word. Return True to continue parsing as normal,--- or False to terminate the parse.-type ProcessingInstructionHandler = ParserPtr -> CString -> CString -> IO Bool---- | The type of the \"comment\" callback. The parameter is the comment text.--- Return True to continue parsing as normal, or False to terminate the parse.-type CommentHandler = ParserPtr -> CString -> IO Bool---- | The type of the \"external entity reference\" callback. See the expat--- documentation.-type ExternalEntityRefHandler = Parser- -> CString -- context- -> CString -- base- -> CString -- systemID- -> CString -- publicID- -> IO Bool---- | Set a skipped entity handler. This is called in two situations:------ 1. An entity reference is encountered for which no declaration has been read--- and this is not an error.------ 2. An internal entity reference is read, but not expanded, because--- @XML_SetDefaultHandler@ has been called.-type SkippedEntityHandler = ParserPtr- -> CString -- entityName- -> Int -- is a parameter entity?- -> IO Bool---type CXMLDeclarationHandler = ParserPtr -> CString -> CString -> CInt -> IO ()--nullCXMLDeclarationHandler :: CXMLDeclarationHandler-nullCXMLDeclarationHandler _ _ _ _ = return ()--foreign import ccall safe "wrapper"- mkCXMLDeclarationHandler :: CXMLDeclarationHandler- -> IO (FunPtr CXMLDeclarationHandler)--wrapXMLDeclarationHandler :: Parser -> XMLDeclarationHandler -> CXMLDeclarationHandler-wrapXMLDeclarationHandler parser handler = h- where- h pp ver enc sd | ver /= nullPtr = do- stillRunning <- handler pp ver enc sd- unless stillRunning $ stopp parser- {- From expat.h:- The XML declaration handler is called for *both* XML declarations- and text declarations. The way to distinguish is that the version- parameter will be NULL for text declarations.- -}- h _ _ _ _ = return () -- text declaration (ignore)---- | Attach a XMLDeclarationHandler to a Parser.-setXMLDeclarationHandler :: Parser -> XMLDeclarationHandler -> IO ()-setXMLDeclarationHandler parser@(Parser _ xmlDeclRef _ _ _ _ _ _ _ _ _) handler =- writeIORef xmlDeclRef $ wrapXMLDeclarationHandler parser handler---type CStartElementHandler = ParserPtr -> CString -> Ptr CString -> IO ()--nullCStartElementHandler :: CStartElementHandler-nullCStartElementHandler _ _ _ = return ()--foreign import ccall safe "wrapper"- mkCStartElementHandler :: CStartElementHandler- -> IO (FunPtr CStartElementHandler)--wrapStartElementHandler :: Parser -> StartElementHandler -> CStartElementHandler-wrapStartElementHandler parser handler = h- where- h pp cname cattrs = do- cattrlist <- peekArray0 nullPtr cattrs- stillRunning <- handler pp cname (pairwise cattrlist)- unless stillRunning $ stopp parser---- | Attach a StartElementHandler to a Parser.-setStartElementHandler :: Parser -> StartElementHandler -> IO ()-setStartElementHandler parser@(Parser _ _ startRef _ _ _ _ _ _ _ _) handler =- writeIORef startRef $ wrapStartElementHandler parser handler---type CEndElementHandler = ParserPtr -> CString -> IO ()--nullCEndElementHandler :: CEndElementHandler-nullCEndElementHandler _ _ = return ()--foreign import ccall safe "wrapper"- mkCEndElementHandler :: CEndElementHandler- -> IO (FunPtr CEndElementHandler)-wrapEndElementHandler :: Parser -> EndElementHandler -> CEndElementHandler-wrapEndElementHandler parser handler = h- where- h pp cname = do- stillRunning <- handler pp cname- unless stillRunning $ stopp parser---- | Attach an EndElementHandler to a Parser.-setEndElementHandler :: Parser -> EndElementHandler -> IO ()-setEndElementHandler parser@(Parser _ _ _ endRef _ _ _ _ _ _ _) handler =- writeIORef endRef $ wrapEndElementHandler parser handler---type CCharacterDataHandler = ParserPtr -> CString -> CInt -> IO ()--nullCCharacterDataHandler :: CCharacterDataHandler-nullCCharacterDataHandler _ _ _ = return ()--foreign import ccall safe "wrapper"- mkCCharacterDataHandler :: CCharacterDataHandler- -> IO (FunPtr CCharacterDataHandler)-wrapCharacterDataHandler :: Parser -> CharacterDataHandler -> CCharacterDataHandler-wrapCharacterDataHandler parser handler = h- where- h pp cdata len = do- stillRunning <- handler pp (cdata, fromIntegral len)- unless stillRunning $ stopp parser---- | Attach an CharacterDataHandler to a Parser.-setCharacterDataHandler :: Parser -> CharacterDataHandler -> IO ()-setCharacterDataHandler parser@(Parser _ _ _ _ charRef _ _ _ _ _ _) handler =- writeIORef charRef $ wrapCharacterDataHandler parser handler---type CStartCDataHandler = ParserPtr -> IO ()--nullCStartCDataHandler :: CStartCDataHandler-nullCStartCDataHandler _ = return ()--foreign import ccall safe "wrapper"- mkCStartCDataHandler :: CStartCDataHandler- -> IO (FunPtr CStartCDataHandler)--wrapStartCDataHandler :: Parser -> StartCDataHandler -> CStartCDataHandler-wrapStartCDataHandler parser handler = h- where- h pp = do- stillRunning <- handler pp- unless stillRunning $ stopp parser---- | Attach a StartCDataHandler to a Parser.-setStartCDataHandler :: Parser -> StartCDataHandler -> IO ()-setStartCDataHandler parser@(Parser _ _ _ _ _ _ _ startCData _ _ _) handler =- writeIORef startCData $ wrapStartCDataHandler parser handler---type CEndCDataHandler = ParserPtr -> IO ()--nullCEndCDataHandler :: CEndCDataHandler-nullCEndCDataHandler _ = return ()--foreign import ccall safe "wrapper"- mkCEndCDataHandler :: CEndCDataHandler- -> IO (FunPtr CEndCDataHandler)--wrapEndCDataHandler :: Parser -> EndCDataHandler -> CEndCDataHandler-wrapEndCDataHandler parser handler = h- where- h pp = do- stillRunning <- handler pp- unless stillRunning $ stopp parser---- | Attach a EndCDataHandler to a Parser.-setEndCDataHandler :: Parser -> EndCDataHandler -> IO ()-setEndCDataHandler parser@(Parser _ _ _ _ _ _ _ _ endCData _ _) handler =- writeIORef endCData $ wrapEndCDataHandler parser handler---type CProcessingInstructionHandler = ParserPtr -> CString -> CString -> IO ()--nullCProcessingInstructionHandler :: CProcessingInstructionHandler-nullCProcessingInstructionHandler _ _ _ = return ()--foreign import ccall safe "wrapper"- mkCProcessingInstructionHandler :: CProcessingInstructionHandler- -> IO (FunPtr CProcessingInstructionHandler)- -wrapProcessingInstructionHandler :: Parser -> ProcessingInstructionHandler -> CProcessingInstructionHandler-wrapProcessingInstructionHandler parser handler = h- where- h pp ctarget cdata = do- stillRunning <- handler pp ctarget cdata- unless stillRunning $ stopp parser---- | Attach a ProcessingInstructionHandler to a Parser.-setProcessingInstructionHandler :: Parser -> ProcessingInstructionHandler -> IO ()-setProcessingInstructionHandler parser@(Parser _ _ _ _ _ _ _ _ _ piRef _) handler =- writeIORef piRef $ wrapProcessingInstructionHandler parser handler---type CCommentHandler = ParserPtr -> CString -> IO ()--nullCCommentHandler :: CCommentHandler-nullCCommentHandler _ _ = return ()--foreign import ccall safe "wrapper"- mkCCommentHandler :: CCommentHandler- -> IO (FunPtr CCommentHandler)- -wrapCommentHandler :: Parser -> CommentHandler -> CCommentHandler-wrapCommentHandler parser handler = h- where- h pp cdata = do- stillRunning <- handler pp cdata- unless stillRunning $ stopp parser---- | Attach a CommentHandler to a Parser.-setCommentHandler :: Parser -> CommentHandler -> IO ()-setCommentHandler parser@(Parser _ _ _ _ _ _ _ _ _ _ commentRef) handler =- writeIORef commentRef $ wrapCommentHandler parser handler---pairwise :: [a] -> [(a,a)]-pairwise (x1:x2:xs) = (x1,x2) : pairwise xs-pairwise _ = []--stopp :: Parser -> IO ()-stopp parser = withParser parser $ \p -> xmlStopParser p 0----------------------------------------------------------------------------------- C imports--foreign import ccall unsafe "XML_ParserCreate"- parserCreate'_ :: Ptr CChar -> IO ParserPtr- -foreign import ccall unsafe "XML_SetUserData"- xmlSetUserData :: ParserPtr -> ParserPtr -> IO ()--foreign import ccall unsafe "XML_SetXmlDeclHandler"- xmlSetxmldeclhandler :: ParserPtr -> FunPtr CXMLDeclarationHandler -> IO ()--foreign import ccall unsafe "XML_SetStartElementHandler"- xmlSetstartelementhandler :: ParserPtr -> ((FunPtr (ParserPtr -> ((Ptr CChar) -> ((Ptr (Ptr CChar)) -> (IO ())))) -> (IO ())))--foreign import ccall unsafe "XML_SetEndElementHandler"- xmlSetendelementhandler :: ParserPtr -> ((FunPtr (ParserPtr -> ((Ptr CChar) -> (IO ()))) -> (IO ())))- -foreign import ccall unsafe "XML_SetCharacterDataHandler"- xmlSetcharacterdatahandler :: ParserPtr -> ((FunPtr (ParserPtr -> ((Ptr CChar) -> (CInt -> (IO ())))) -> (IO ())))- -foreign import ccall unsafe "XML_SetStartCdataSectionHandler"- xmlSetstartcdatahandler :: ParserPtr -> FunPtr CStartCDataHandler -> IO ()--foreign import ccall unsafe "XML_SetEndCdataSectionHandler"- xmlSetendcdatahandler :: ParserPtr -> FunPtr CStartCDataHandler -> IO ()- -foreign import ccall unsafe "XML_SetCommentHandler"- xmlSetcommenthandler :: ParserPtr -> ((FunPtr (ParserPtr -> ((Ptr CChar) -> (IO ()))) -> (IO ())))- -foreign import ccall unsafe "XML_SetProcessingInstructionHandler"- xmlSetprocessinginstructionhandler :: ParserPtr -> ((FunPtr (ParserPtr -> ((Ptr CChar) -> ((Ptr CChar) -> (IO ())))) -> (IO ())))--foreign import ccall safe "XML_Parse"- doParseChunk'_ :: ParserPtr -> ((Ptr CChar) -> (CInt -> (CInt -> (IO CInt))))--foreign import ccall unsafe "XML_UseForeignDTD"- xmlUseForeignDTD :: ParserPtr -- ^ parser- -> CChar -- ^ use foreign DTD? (external entity ref- -- handler will be called with publicID &- -- systemID set to null- -> IO ()--foreign import ccall "&XML_ParserFree" parserFree :: FunPtr (ParserPtr -> IO ())-foreign import ccall "XML_ParserFree" parserFree' :: ParserPtr -> IO ()--type CExternalEntityRefHandler = ParserPtr -- parser- -> Ptr CChar -- context- -> Ptr CChar -- base- -> Ptr CChar -- systemID- -> Ptr CChar -- publicID- -> IO ()--foreign import ccall unsafe "wrapper"- mkCExternalEntityRefHandler :: CExternalEntityRefHandler- -> IO (FunPtr CExternalEntityRefHandler)---foreign import ccall unsafe "XML_SetExternalEntityRefHandler"- xmlSetExternalEntityRefHandler :: ParserPtr- -> FunPtr CExternalEntityRefHandler- -> IO ()--foreign import ccall unsafe "XML_SetSkippedEntityHandler"- xmlSetSkippedEntityHandler :: ParserPtr- -> FunPtr CSkippedEntityHandler- -> IO ()--foreign import ccall unsafe "XML_ExternalEntityParserCreate"- xmlExternalEntityParserCreate :: ParserPtr- -> CString -- ^ context- -> CString -- ^ encoding- -> IO ParserPtr--type CSkippedEntityHandler = ParserPtr -- user data pointer- -> CString -- entity name- -> CInt -- is a parameter entity?- -> IO ()--foreign import ccall safe "wrapper"- mkCSkippedEntityHandler :: CSkippedEntityHandler- -> IO (FunPtr CSkippedEntityHandler)---wrapExternalEntityRefHandler :: Parser- -> ExternalEntityRefHandler- -> CExternalEntityRefHandler-wrapExternalEntityRefHandler parser handler = h- where- h _ context base systemID publicID = do- stillRunning <- handler parser context base systemID publicID- unless stillRunning $ stopp parser---wrapSkippedEntityHandler :: Parser- -> SkippedEntityHandler- -> CSkippedEntityHandler-wrapSkippedEntityHandler parser handler = h- where- h pp entityName i = do- stillRunning <- handler pp entityName (fromIntegral i)- unless stillRunning $ stopp parser---setExternalEntityRefHandler :: Parser -> ExternalEntityRefHandler -> IO ()-setExternalEntityRefHandler parser h =- writeIORef ref $ Just $ wrapExternalEntityRefHandler parser h- where- ref = _externalEntityRefHandler parser--setSkippedEntityHandler :: Parser -> SkippedEntityHandler -> IO ()-setSkippedEntityHandler parser h =- writeIORef ref $ Just $ wrapSkippedEntityHandler parser h- where- ref = _skippedEntityHandler parser- -- Note on word sizes: -- -- on expat 2.0:@@ -774,6 +126,96 @@ :: ParserPtr -> IO CInt foreign import ccall unsafe "expat.h XML_ErrorString" xmlErrorString :: CInt -> IO CString-foreign import ccall unsafe "expat.h XML_StopParser" xmlStopParser- :: ParserPtr -> CInt -> IO ()++type HParser = B.ByteString -> Bool -> IO (ForeignPtr Word8, CInt, Maybe XMLParseError)++foreign import ccall unsafe "hexpatNewParser"+ _hexpatNewParser :: Ptr CChar -> CInt -> IO MyParserPtr++foreign import ccall unsafe "hexpatGetParser"+ _hexpatGetParser :: MyParserPtr -> ParserPtr++data MyParser_struct+type MyParserPtr = Ptr MyParser_struct++foreign import ccall "&hexpatFreeParser" hexpatFreeParser :: FunPtr (MyParserPtr -> IO ())++hexpatNewParser :: Maybe Encoding+ -> Maybe (B.ByteString -> Maybe B.ByteString) -- ^ Entity decoder+ -> Bool -- ^ Whether to include input locations+ -> IO (HParser, IO XMLParseLocation)+hexpatNewParser enc mDecoder locations =+ withOptEncoding enc $ \cEnc -> do+ parser <- newForeignPtr hexpatFreeParser =<< _hexpatNewParser cEnc (cFromBool locations)+ return (parse parser, withForeignPtr parser $ \mp -> getParseLocation $ _hexpatGetParser mp)+ where+ parse parser = case mDecoder of+ Nothing -> \text final ->+ alloca $ \ppData ->+ alloca $ \pLen ->+ withBStringLen text $ \(textBuf, textLen) ->+ withForeignPtr parser $ \pp -> do+ ok <- unStatus <$> _hexpatParseUnsafe pp textBuf textLen (cFromBool final) ppData pLen+ pData <- peek ppData+ len <- peek pLen+ err <- if ok+ then return Nothing+ else Just <$> getError (_hexpatGetParser pp)+ fpData <- newForeignPtr funPtrFree pData+ return (fpData, len, err)+ Just decoder -> \text final ->+ alloca $ \ppData ->+ alloca $ \pLen ->+ withBStringLen text $ \(textBuf, textLen) ->+ withForeignPtr parser $ \pp -> do+ eh <- mkCEntityHandler . wrapCEntityHandler $ decoder+ _hexpatSetEntityHandler pp eh+ ok <- unStatus <$> _hexpatParseSafe pp textBuf textLen (cFromBool final) ppData pLen+ freeHaskellFunPtr eh+ pData <- peek ppData+ len <- peek pLen+ err <- if ok+ then return Nothing+ else Just <$> getError (_hexpatGetParser pp)+ fpData <- newForeignPtr funPtrFree pData+ return (fpData, len, err)++foreign import ccall unsafe "hexpatParse"+ _hexpatParseUnsafe :: MyParserPtr -> Ptr CChar -> CInt -> CInt -> Ptr (Ptr Word8) -> Ptr CInt -> IO CInt++foreign import ccall safe "hexpatParse"+ _hexpatParseSafe :: MyParserPtr -> Ptr CChar -> CInt -> CInt -> Ptr (Ptr Word8) -> Ptr CInt -> IO CInt++type CEntityHandler = Ptr CChar -> IO (Ptr CChar)++foreign import ccall safe "wrapper"+ mkCEntityHandler :: CEntityHandler+ -> IO (FunPtr CEntityHandler)++peekByteStringLen :: CStringLen -> IO B.ByteString+{-# INLINE peekByteStringLen #-}+peekByteStringLen (cstr, len) =+ I.create (fromIntegral len) $ \ptr ->+ I.memcpy ptr (castPtr cstr) (fromIntegral len)++wrapCEntityHandler :: (B.ByteString -> Maybe B.ByteString) -> CEntityHandler+wrapCEntityHandler handler = h+ where+ h cname = do+ sz <- fromIntegral <$> I.c_strlen cname+ name <- peekByteStringLen (cname, sz)+ case handler name of+ Just text -> do+ let (fp, offset, len) = I.toForeignPtr text+ withForeignPtr fp $ \ctextBS -> do+ ctext <- mallocBytes (len + 1) :: IO CString+ I.memcpy (castPtr ctext) (ctextBS `plusPtr` offset) (fromIntegral len)+ poke (ctext `plusPtr` len) (0 :: CChar)+ return ctext+ Nothing -> return nullPtr++foreign import ccall unsafe "hexpatSetEntityHandler"+ _hexpatSetEntityHandler :: MyParserPtr -> FunPtr CEntityHandler -> IO ()++foreign import ccall "&free" funPtrFree :: FunPtr (Ptr Word8 -> IO ())
Text/XML/Expat/Internal/NodeClass.hs view
@@ -7,7 +7,7 @@ import Control.Monad (mzero, liftM) import Data.Functor.Identity-import Data.List.Class+import Data.List.Class (List(..), ListItem(..), cons, fromList, mapL, toList) import Data.Monoid (Monoid) import Text.XML.Expat.SAX (GenericXMLString) @@ -108,15 +108,6 @@ -- | Generic text node constructor. mkText :: text -> n c tag text---- | DEPRECATED. Map an element non-recursively, allowing the tag type to be changed.-mapElement :: NodeClass n c =>- ((tag, [(tag, text)], c (n c tag text))- -> (tag', [(tag', text)], c (n c tag' text)))- -> n c tag text- -> n c tag' text-{-# DEPRECATED mapElement "renamed to modifyElement" #-}-mapElement = modifyElement -- | Change a list of nodes recursively from one container type to another, with -- a specified function to convert the container type.
− Text/XML/Expat/Namespaced.hs
@@ -1,9 +0,0 @@-{-# OPTIONS_HADDOCK hide #-}-module Text.XML.Expat.Namespaced- {-# DEPRECATED "Use Text.XML.Expat.Text or Text.XML.Expat.Annotated instead" #-}- (- module Text.XML.Expat.Internal.Namespaced- ) where--import Text.XML.Expat.Internal.Namespaced-
− Text/XML/Expat/NodeClass.hs
@@ -1,9 +0,0 @@-{-# OPTIONS_HADDOCK hide #-}-module Text.XML.Expat.NodeClass- {-# DEPRECATED "Use Text.XML.Expat.Text or Text.XML.Expat.Annotated instead" #-}- (- module Text.XML.Expat.Internal.NodeClass- ) where--import Text.XML.Expat.Internal.NodeClass-
Text/XML/Expat/Proc.hs view
@@ -6,7 +6,7 @@ import Text.XML.Expat.SAX import Control.Monad-import Data.List.Class+import Data.List.Class (filter) import Data.Maybe(listToMaybe) import Data.Monoid import Prelude hiding (filter)
− Text/XML/Expat/Qualified.hs
@@ -1,9 +0,0 @@-{-# OPTIONS_HADDOCK hide #-}-module Text.XML.Expat.Qualified- {-# DEPRECATED "Use Text.XML.Expat.Text or Text.XML.Expat.Annotated instead" #-}- (- module Text.XML.Expat.Internal.Qualified- ) where--import Text.XML.Expat.Internal.Qualified-
Text/XML/Expat/SAX.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE DeriveDataTypeable, TypeSynonymInstances, CPP, ScopedTypeVariables, FlexibleInstances #-}+{-# LANGUAGE DeriveDataTypeable, TypeSynonymInstances, CPP, ScopedTypeVariables, FlexibleInstances, GADTs #-}+{-# OPTIONS_GHC -fno-cse -fno-full-laziness #-} -- hexpat, a Haskell wrapper for expat -- Copyright (C) 2008 Evan Martin <martine@danga.com>@@ -16,7 +17,6 @@ ParseOptions(..), SAXEvent(..), - textFromCString, parse, parseG, parseLocations,@@ -28,41 +28,36 @@ -- * Variants that throw exceptions XMLParseException(..), - -- * Helpers- setEntityDecoder,- -- * Abstraction of string types- GenericXMLString(..),-- -- * Deprecated parse functions- parseSAX,- parseSAXLocations,- parseSAXLocationsThrowing,- parseSAXThrowing,- ParserOptions,- defaultParserOptions+ GenericXMLString(..) ) where -import Text.XML.Expat.Internal.IO hiding (parse)+import Control.Concurrent.MVar+import Control.Exception as Exc+import Text.XML.Expat.Internal.IO+import Data.Bits import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Internal as I-import Data.IORef+import Data.Int import Data.ByteString.Internal (c2w, w2c, c_strlen) import qualified Data.Monoid as M import qualified Data.Text as T import qualified Data.Text.Encoding as TE import qualified Codec.Binary.UTF8.String as U8+import Data.List.Class (List(..), ListItem(..), cons, fromList, mapL) import Data.Typeable-import Data.List.Class hiding (tail)-import Control.Exception.Extensible as Exc+import Data.Word import Control.Applicative import Control.DeepSeq import Control.Monad import System.IO.Unsafe-import Foreign.C.String+import Foreign.C+import Foreign.ForeignPtr+import Foreign.Marshal.Array import Foreign.Ptr+import Foreign.Storable data ParseOptions tag text = ParseOptions@@ -74,18 +69,10 @@ -- be decoded into text using the supplied lookup function } -{-# DEPRECATED ParserOptions "renamed to ParseOptions" #-}-type ParserOptions tag text = ParseOptions tag text- defaultParseOptions :: ParseOptions tag text defaultParseOptions = ParseOptions Nothing Nothing --- | DEPRECATED. Renamed to defaultParseOptions.-defaultParserOptions :: ParseOptions tag text-{-# DEPRECATED defaultParserOptions "renamed to defaultParseOptions" #-}-defaultParserOptions = defaultParseOptions - -- | An abstraction for any string type you want to use as xml text (that is, -- attribute values or element text content). If you want to use a -- new string type with /hexpat/, you must make it an instance of@@ -98,7 +85,7 @@ gxHead :: s -> Char gxTail :: s -> s gxBreakOn :: Char -> s -> (s, s)- gxFromCStringLen :: CStringLen -> IO s+ gxFromByteString :: B.ByteString -> s gxToByteString :: s -> B.ByteString instance GenericXMLString String where@@ -109,7 +96,7 @@ gxHead = head gxTail = tail gxBreakOn c = break (==c)- gxFromCStringLen cstr = U8.decode . B.unpack <$> peekByteStringLen cstr+ gxFromByteString = U8.decode . B.unpack gxToByteString = B.pack . map c2w . U8.encodeString instance GenericXMLString B.ByteString where@@ -120,7 +107,7 @@ gxHead = w2c . B.head gxTail = B.tail gxBreakOn c = B.break (== c2w c)- gxFromCStringLen = peekByteStringLen+ gxFromByteString = id gxToByteString = id instance GenericXMLString T.Text where@@ -140,16 +127,9 @@ #else gxBreakOn c = T.breakBy (==c) #endif- gxFromCStringLen cstr = TE.decodeUtf8 <$> peekByteStringLen cstr+ gxFromByteString = TE.decodeUtf8 gxToByteString = TE.encodeUtf8 -peekByteStringLen :: CStringLen -> IO B.ByteString-{-# INLINE peekByteStringLen #-}-peekByteStringLen (cstr, len) =- I.create (fromIntegral len) $ \ptr ->- I.memcpy ptr (castPtr cstr) (fromIntegral len)-- data SAXEvent tag text = XMLDeclaration text (Maybe text) (Maybe Bool) | StartElement tag [(tag, text)] |@@ -173,139 +153,150 @@ rnf (Comment text) = rnf text rnf (FailDocument err) = rnf err --- | Converts a 'CString' to a 'GenericXMLString' type.-textFromCString :: GenericXMLString text => CString -> IO text-{-# INLINE textFromCString #-}-textFromCString cstr = do- len <- c_strlen cstr- gxFromCStringLen (cstr, fromIntegral len)---- | A helper for configuring the hexpat parser to use the specified entity--- decoder.-setEntityDecoder :: (GenericXMLString tag, GenericXMLString text)- => Parser- -> (tag -> Maybe text) -- ^ Entity decoder- -> (ParserPtr -> text -> IO ()) -- ^ Code to insert character data into the document- -> IO ()-setEntityDecoder parser decoder insertText = do- setUseForeignDTD parser True- setExternalEntityRefHandler parser eh- setSkippedEntityHandler parser skip-- where- skip _ _ 1 = return False- skip pp entityName 0 = do- en <- textFromCString entityName- let mbt = decoder en- maybe (return False)- (\t -> do- insertText pp t- return True)- mbt- skip _ _ _ = undefined-- eh pp ctx _ systemID publicID =- if systemID == nullPtr && publicID == nullPtr- then withCStringLen "" $ \c -> do- parseExternalEntityReference pp ctx Nothing c- else return False- -- | Parse a generalized list of ByteStrings containing XML to SAX events. -- In the event of an error, FailDocument is the last element of the output list. parseG :: forall tag text l . (GenericXMLString tag, GenericXMLString text, List l) => ParseOptions tag text -- ^ Parse options -> l ByteString -- ^ Input text (a lazy ByteString) -> l (SAXEvent tag text)-parseG opts inputBlocks = runParser inputBlocks parser queueRef cacheRef- where- (parser, queueRef, cacheRef) = unsafePerformIO $ do- let enc = overrideEncoding opts- let mEntityDecoder = entityDecoder opts-- parser <- newParser enc- queueRef <- newIORef []-- case mEntityDecoder of- Just deco -> setEntityDecoder parser deco $ \_ txt -> do- modifyIORef queueRef (CharacterData txt:)- Nothing -> return ()-- setXMLDeclarationHandler parser $ \_ cVer cEnc cSd -> do- ver <- textFromCString cVer- mEnc <- if cEnc == nullPtr- then return Nothing- else Just <$> textFromCString cEnc- let sd = if cSd < 0- then Nothing- else Just $ if cSd /= 0 then True else False- modifyIORef queueRef (XMLDeclaration ver mEnc sd:)- return True-- setStartElementHandler parser $ \_ cName cAttrs -> do- name <- textFromCString cName- attrs <- forM cAttrs $ \(cAttrName,cAttrValue) -> do- attrName <- textFromCString cAttrName- attrValue <- textFromCString cAttrValue- return (attrName, attrValue)- modifyIORef queueRef (StartElement name attrs:)- return True+{-# NOINLINE parseG #-}+parseG opts inputBlocks = mapL (return . fst) $ parseImpl opts inputBlocks False noExtra failureA+ where noExtra _ offset = return ((), offset)+ failureA _ = return () - setEndElementHandler parser $ \_ cName -> do- name <- textFromCString cName- modifyIORef queueRef (EndElement name:)- return True+-- | Parse a generalized list of ByteStrings containing XML to SAX events.+-- In the event of an error, FailDocument is the last element of the output list.+parseLocationsG :: forall tag text l . (GenericXMLString tag, GenericXMLString text, List l) =>+ ParseOptions tag text -- ^ Parse options+ -> l ByteString -- ^ Input text (a lazy ByteString)+ -> l (SAXEvent tag text, XMLParseLocation)+{-# NOINLINE parseLocationsG #-}+parseLocationsG opts inputBlocks = parseImpl opts inputBlocks True fetchLocation id+ where+ fetchLocation pBuf offset = do+ [a, b, c, d] <- peekArray 4 (pBuf `plusPtr` offset :: Ptr Int64)+ return (XMLParseLocation a b c d, offset + 32) - setCharacterDataHandler parser $ \_ cText -> do- txt <- gxFromCStringLen cText- modifyIORef queueRef (CharacterData txt:)- return True- - setStartCDataHandler parser $ \_ -> do- modifyIORef queueRef (StartCData :)- return True- - setEndCDataHandler parser $ \_ -> do- modifyIORef queueRef (EndCData :)- return True- - setProcessingInstructionHandler parser $ \_ cTarget cText -> do- target <- textFromCString cTarget- txt <- textFromCString cText- modifyIORef queueRef (ProcessingInstruction target txt :)- return True- - setCommentHandler parser $ \_ cText -> do- txt <- textFromCString cText- modifyIORef queueRef (Comment txt :)- return True+parseImpl :: forall a tag text l . (GenericXMLString tag, GenericXMLString text, List l) =>+ ParseOptions tag text -- ^ Parse options+ -> l ByteString -- ^ Input text (a lazy ByteString)+ -> Bool -- ^ True to add locations to binary output+ -> (Ptr Word8 -> Int -> IO (a, Int)) -- ^ Fetch extra data+ -> (IO XMLParseLocation -> IO a) -- ^ Fetch a value for failure case + -> l (SAXEvent tag text, a)+parseImpl opts inputBlocks addLocations extra failureA = runParser inputBlocks parse cacheRef+ where+ (parse, getLocation, cacheRef) = unsafePerformIO $ do+ (parse, getLocation) <- hexpatNewParser+ (overrideEncoding opts)+ ((\decode -> fmap gxToByteString . decode . gxFromByteString) <$> entityDecoder opts)+ addLocations - cacheRef <- newIORef Nothing- return (parser, queueRef, cacheRef)+ cacheRef <- newMVar Nothing+ return (parse, getLocation, cacheRef) - runParser iblks parser queueRef cacheRef = joinL $ do+ runParser iblks parse cacheRef = joinL $ do li <- runList iblks return $ unsafePerformIO $ do- mCached <- readIORef cacheRef+ mCached <- takeMVar cacheRef case mCached of- Just l -> return l+ Just l -> do+ putMVar cacheRef mCached+ return l Nothing -> do- rema <- case li of- Nil -> do- mError <- withParser parser $ \pp -> parseChunk pp B.empty True- return $ handleFailure mError mzero- Cons blk t -> unsafeInterleaveIO $ do- mError <- withParser parser $ \pp -> parseChunk pp blk False- cacheRef' <- newIORef Nothing- return $ handleFailure mError (runParser t parser queueRef cacheRef')- queue <- readIORef queueRef- writeIORef queueRef []- let l = fromList (reverse queue) `mplus` rema- writeIORef cacheRef (Just l)+ (saxen, rema) <- case li of+ Nil -> do+ (buf, len, mError) <- parse B.empty True+ saxen <- parseBuf buf len extra+ rema <- handleFailure mError mzero+ return (saxen, rema)+ Cons blk t -> {-unsafeInterleaveIO $-} do+ (buf, len, mError) <- parse blk False+ saxen <- parseBuf buf len extra+ cacheRef' <- newMVar Nothing+ rema <- handleFailure mError (runParser t parse cacheRef')+ return (saxen, rema)+ let l = fromList saxen `mplus` rema+ putMVar cacheRef (Just l) return l where- handleFailure (Just err) _ = FailDocument err `cons` mzero- handleFailure Nothing l = l+ handleFailure (Just err) _ = do a <- failureA getLocation+ return $ (FailDocument err, a) `cons` mzero+ handleFailure Nothing l = return l +parseBuf :: (GenericXMLString tag, GenericXMLString text) =>+ ForeignPtr Word8 -> CInt -> (Ptr Word8 -> Int -> IO (a, Int)) -> IO [(SAXEvent tag text, a)]+parseBuf buf _ processExtra = withForeignPtr buf $ \pBuf -> doit [] pBuf 0+ where+ roundUp32 offset = (offset + 3) .&. complement 3+ doit acc pBuf offset0 = offset0 `seq` do+ typ <- peek (pBuf `plusPtr` offset0 :: Ptr Word32)+ (a, offset) <- processExtra pBuf (offset0 + 4)+ case typ of+ 0 -> return (reverse acc)+ 1 -> do+ nAtts <- peek (pBuf `plusPtr` offset :: Ptr Word32)+ let pName = pBuf `plusPtr` (offset + 4)+ lName <- fromIntegral <$> c_strlen pName+ let name = gxFromByteString $ I.fromForeignPtr buf (offset + 4) lName+ (atts, offset') <- foldM (\(atts, offset) _ -> do+ let pAtt = pBuf `plusPtr` offset+ lAtt <- fromIntegral <$> c_strlen pAtt+ let att = gxFromByteString $ I.fromForeignPtr buf offset lAtt+ offset' = offset + lAtt + 1+ pValue = pBuf `plusPtr` offset'+ lValue <- fromIntegral <$> c_strlen pValue+ let value = gxFromByteString $ I.fromForeignPtr buf offset' lValue+ return ((att, value):atts, offset' + lValue + 1)+ ) ([], offset + 4 + lName + 1) [1,3..nAtts]+ doit ((StartElement name (reverse atts), a) : acc) pBuf (roundUp32 offset')+ 2 -> do+ let pName = pBuf `plusPtr` offset+ lName <- fromIntegral <$> c_strlen pName+ let name = gxFromByteString $ I.fromForeignPtr buf offset lName+ offset' = offset + lName + 1+ doit ((EndElement name, a) : acc) pBuf (roundUp32 offset')+ 3 -> do+ len <- fromIntegral <$> peek (pBuf `plusPtr` offset :: Ptr Word32)+ let text = gxFromByteString $ I.fromForeignPtr buf (offset + 4) len+ offset' = offset + 4 + len+ doit ((CharacterData text, a) : acc) pBuf (roundUp32 offset')+ 4 -> do+ let pEnc = pBuf `plusPtr` offset+ lEnc <- fromIntegral <$> c_strlen pEnc+ let enc = gxFromByteString $ I.fromForeignPtr buf offset lEnc+ offset' = offset + lEnc + 1+ pVer = pBuf `plusPtr` offset'+ pVerFirst <- peek (castPtr pVer :: Ptr Word8)+ (mVer, offset'') <- case pVerFirst of+ 0 -> return (Nothing, offset' + 1)+ 1 -> do+ lVer <- fromIntegral <$> c_strlen (pVer `plusPtr` 1)+ return (Just $ gxFromByteString $ I.fromForeignPtr buf (offset' + 1) lVer, offset' + 1 + lVer + 1)+ _ -> error "hexpat: bad data from C land"+ cSta <- peek (pBuf `plusPtr` offset'' :: Ptr Int8)+ let sta = if cSta < 0 then Nothing else+ if cSta == 0 then Just False else+ Just True+ doit ((XMLDeclaration enc mVer sta, a) : acc) pBuf (roundUp32 (offset'' + 1))+ 5 -> doit ((StartCData, a) : acc) pBuf offset+ 6 -> doit ((EndCData, a) : acc) pBuf offset+ 7 -> do+ let pTarget = pBuf `plusPtr` offset+ lTarget <- fromIntegral <$> c_strlen pTarget+ let target = gxFromByteString $ I.fromForeignPtr buf offset lTarget+ offset' = offset + lTarget + 1+ pData = pBuf `plusPtr` offset'+ lData <- fromIntegral <$> c_strlen pData+ let dat = gxFromByteString $ I.fromForeignPtr buf offset' lData+ doit ((ProcessingInstruction target dat, a) : acc) pBuf (roundUp32 (offset' + lData + 1))+ 8 -> do+ let pText = pBuf `plusPtr` offset+ lText <- fromIntegral <$> c_strlen pText+ let text = gxFromByteString $ I.fromForeignPtr buf offset lText+ doit ((Comment text, a) : acc) pBuf (roundUp32 (offset + lText + 1))+ _ -> error "hexpat: bad data from C land"+ -- | Lazily parse XML to SAX events. In the event of an error, FailDocument is -- the last element of the output list. parse :: (GenericXMLString tag, GenericXMLString text) =>@@ -315,132 +306,12 @@ parse opts input = parseG opts (L.toChunks input) --- | DEPRECATED: Use 'parse' instead.------ Lazily parse XML to SAX events. In the event of an error, FailDocument is--- the last element of the output list. Deprecated in favour of new--- 'Text.XML.Expat.SAX.parse'-parseSAX :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> [SAXEvent tag text]-{-# DEPRECATED parseSAX "use Text.XML.Expat.SAX.parse instead" #-}-parseSAX enc = parse (ParseOptions enc Nothing)-- -- | An exception indicating an XML parse error, used by the /..Throwing/ variants. data XMLParseException = XMLParseException XMLParseError deriving (Eq, Show, Typeable) instance Exception XMLParseException where ---- | Parse a generalized list of ByteStrings containing XML to SAX events.--- In the event of an error, FailDocument is the last element of the output list.-parseLocationsG :: forall tag text l . (GenericXMLString tag, GenericXMLString text, List l) =>- ParseOptions tag text -- ^ Parse options- -> l ByteString -- ^ Input text (a lazy ByteString)- -> l (SAXEvent tag text, XMLParseLocation)-parseLocationsG opts inputBlocks = runParser inputBlocks parser queueRef cacheRef- where- (parser, queueRef, cacheRef) = unsafePerformIO $ do- let enc = overrideEncoding opts- let mEntityDecoder = entityDecoder opts-- parser <- newParser enc- queueRef <- newIORef []-- case mEntityDecoder of- Just deco -> setEntityDecoder parser deco $ \pp txt -> do- loc <- getParseLocation pp- modifyIORef queueRef ((CharacterData txt, loc):)- Nothing -> return ()-- setXMLDeclarationHandler parser $ \pp cVer cEnc cSd -> do- ver <- textFromCString cVer- mEnc <- if cEnc == nullPtr- then return Nothing- else Just <$> textFromCString cEnc- let sd = if cSd < 0- then Nothing- else Just $ if cSd /= 0 then True else False- loc <- getParseLocation pp- modifyIORef queueRef ((XMLDeclaration ver mEnc sd, loc):)- return True-- setStartElementHandler parser $ \pp cName cAttrs -> do- name <- textFromCString cName- attrs <- forM cAttrs $ \(cAttrName,cAttrValue) -> do- attrName <- textFromCString cAttrName- attrValue <- textFromCString cAttrValue- return (attrName, attrValue)- loc <- getParseLocation pp- modifyIORef queueRef ((StartElement name attrs,loc):)- return True-- setEndElementHandler parser $ \pp cName -> do- name <- textFromCString cName- loc <- getParseLocation pp- modifyIORef queueRef ((EndElement name, loc):)- return True-- setCharacterDataHandler parser $ \pp cText -> do- txt <- gxFromCStringLen cText- loc <- getParseLocation pp- modifyIORef queueRef ((CharacterData txt, loc):)- return True- - setStartCDataHandler parser $ \pp -> do- loc <- getParseLocation pp- modifyIORef queueRef ((StartCData, loc):)- return True- - setEndCDataHandler parser $ \pp -> do- loc <- getParseLocation pp- modifyIORef queueRef ((EndCData,loc):)- return True- - setProcessingInstructionHandler parser $ \pp cTarget cText -> do- target <- textFromCString cTarget- txt <- textFromCString cText- loc <- getParseLocation pp- modifyIORef queueRef ((ProcessingInstruction target txt, loc):)- return True- - setCommentHandler parser $ \pp cText -> do- txt <- textFromCString cText- loc <- getParseLocation pp- modifyIORef queueRef ((Comment txt, loc):)- return True-- cacheRef <- newIORef Nothing- return (parser, queueRef, cacheRef)-- runParser iblks parser queueRef cacheRef = joinL $ do- li <- runList iblks- return $ unsafePerformIO $ do- mCached <- readIORef cacheRef- case mCached of- Just l -> return l- Nothing -> do- rema <- case li of- Nil -> do- mError <- withParser parser $ \pp -> parseChunk pp B.empty True- handleFailure mError mzero- Cons blk t -> unsafeInterleaveIO $ do- mError <- withParser parser $ \pp -> parseChunk pp blk False- cacheRef' <- newIORef Nothing- handleFailure mError (runParser t parser queueRef cacheRef')- queue <- readIORef queueRef- writeIORef queueRef []- let l = fromList (reverse queue) `mplus` rema- writeIORef cacheRef (Just l)- return l- where- handleFailure (Just err) _ = do loc <- withParser parser getParseLocation- return $ (FailDocument err, loc) `cons` mzero- handleFailure Nothing l = return l- -- | A variant of parseSAX that gives a document location with each SAX event. parseLocations :: (GenericXMLString tag, GenericXMLString text) => ParseOptions tag text -- ^ Parse options@@ -448,17 +319,7 @@ -> [(SAXEvent tag text, XMLParseLocation)] parseLocations opts input = parseLocationsG opts (L.toChunks input) --- | DEPRECATED: Use 'parseLocations' instead.------ A variant of parseSAX that gives a document location with each SAX event.-parseSAXLocations :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> [(SAXEvent tag text, XMLParseLocation)]-{-# DEPRECATED parseSAXLocations "use Text.XML.Expat.SAX.parseLocations instead" #-}-parseSAXLocations enc = parseLocations (ParseOptions enc Nothing) - -- | Lazily parse XML to SAX events. In the event of an error, throw -- 'XMLParseException'. --@@ -477,18 +338,6 @@ freakOut other = other --- | DEPRECATED: Use 'parseThrowing' instead.------ Lazily parse XML to SAX events. In the event of an error, throw--- 'XMLParseException'.-parseSAXThrowing :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> [SAXEvent tag text]-{-# DEPRECATED parseSAXThrowing "use Text.XML.Expat.SAX.parseThrowing instead" #-}-parseSAXThrowing mEnc = parseThrowing (ParseOptions mEnc Nothing)-- -- | A variant of parseSAX that gives a document location with each SAX event. -- In the event of an error, throw 'XMLParseException'. --@@ -505,16 +354,3 @@ where freakOut (FailDocument err, _) = Exc.throw $ XMLParseException err freakOut other = other----- | DEPRECATED: Used 'parseLocationsThrowing' instead.------ A variant of parseSAX that gives a document location with each SAX event.--- In the event of an error, throw 'XMLParseException'.-parseSAXLocationsThrowing :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> [(SAXEvent tag text, XMLParseLocation)]-{-# DEPRECATED parseSAXLocationsThrowing "use Text.XML.Expat.SAX.parseLocationsThrowing instead" #-}-parseSAXLocationsThrowing mEnc =- parseLocationsThrowing (ParseOptions mEnc Nothing)
Text/XML/Expat/Tree.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE DeriveDataTypeable, TypeSynonymInstances, FlexibleInstances,- MultiParamTypeClasses, TypeFamilies #-}+ MultiParamTypeClasses, TypeFamilies, ScopedTypeVariables #-} -- hexpat, a Haskell wrapper for expat -- Copyright (C) 2008 Evan Martin <martine@danga.com>@@ -128,60 +128,35 @@ saxToTreeG, -- * Abstraction of string types- GenericXMLString(..),-- -- * Deprecated- eAttrs,- Nodes,- UNodes,- QNodes,- NNodes,- parseTree,- parseTree',- parseSAX,- parseSAXLocations,- parseTreeThrowing,- parseSAXThrowing,- parseSAXLocationsThrowing,- ParserOptions,- defaultParserOptions+ GenericXMLString(..) ) where -import Text.XML.Expat.Internal.IO hiding (parse,parse')-import qualified Text.XML.Expat.Internal.IO as IO-import Text.XML.Expat.SAX ( ParseOptions(..)- , XMLParseException(..)- , SAXEvent(..)- , defaultParseOptions- , textFromCString- , parseSAX- , parseSAXLocations- , parseSAXLocationsThrowing- , parseSAXThrowing+import Text.XML.Expat.SAX ( Encoding(..) , GenericXMLString(..)- , setEntityDecoder- , ParserOptions- , defaultParserOptions )+ , ParseOptions(..)+ , defaultParseOptions+ , SAXEvent(..)+ , XMLParseError(..)+ , XMLParseException(..)+ , XMLParseLocation(..) ) import qualified Text.XML.Expat.SAX as SAX import Text.XML.Expat.Internal.Namespaced import Text.XML.Expat.Internal.NodeClass import Text.XML.Expat.Internal.Qualified import Control.Arrow-import Control.Monad (forM, mplus, mzero)+import Control.Monad (mplus, mzero) import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as L-import Data.IORef import Data.List.Class import Data.Monoid (Monoid,mempty,mappend) import Control.DeepSeq-import System.IO.Unsafe -- | The tree representation of the XML document. ----- @c@ is the container type for the element's children, which is [] in the--- @hexpat@ package, and a monadic list type for @hexpat-iteratee@.+-- @c@ is the container type for the element's children, which would normally be [],+-- but could potentially be a monadic list type to allow for chunked I/O. -- -- @tag@ is the tag type, which can either be one of several string types, -- or a special type from the @Text.XML.Expat.Namespaced@ or@@ -221,46 +196,17 @@ -- @ListOf (UNode Text)@. type Node tag text = NodeG [] tag text -eAttrs :: Node tag text -> [(tag, text)]-{-# DEPRECATED eAttrs "use eAttributes instead" #-}-eAttrs = eAttributes- instance (NFData tag, NFData text) => NFData (NodeG [] tag text) where rnf (Element nam att chi) = rnf (nam, att, chi) rnf (Text txt) = rnf txt --- | DEPRECATED: Use [Node tag text] instead.------ Type alias for nodes.-type Nodes tag text = [Node tag text]-{-# DEPRECATED Nodes "use [Node tag text] instead" #-}---- | DEPRECATED: Use [UNode text] instead.------ Type alias for nodes with unqualified tag names where tag and--- text are the same string type. DEPRECATED.-type UNodes text = Nodes text text-{-# DEPRECATED UNodes "use [UNode text] instead" #-}- -- | Type alias for a node with unqualified tag names where tag and -- text are the same string type. type UNode text = Node text text --- | DEPRECATED: Use [QNode text] instead.------ Type alias for nodes where qualified names are used for tags-{-# DEPRECATED QNodes "use [QNode text] instead" #-}-type QNodes text = [Node (QName text) text]- -- | Type alias for a node where qualified names are used for tags type QNode text = Node (QName text) text --- | DEPRECATED: Use [NNode text] instead.------ Type alias for nodes where namespaced names are used for tags.-{-# DEPRECATED NNodes "use [NNode text] instead" #-}-type NNodes text = [Node (NName text) text]- -- | Type alias for a node where namespaced names are used for tags type NNode text = Node (NName text) text @@ -328,65 +274,9 @@ ParseOptions tag text -- ^ Parse options -> ByteString -- ^ Input text (a strict ByteString) -> Either XMLParseError (Node tag text)-parse' opts doc = unsafePerformIO $ runParse where- runParse = do- let enc = overrideEncoding opts- let mEntityDecoder = entityDecoder opts-- parser <- newParser enc-- -- We maintain the invariant that the stack always has one element,- -- whose only child at the end of parsing is the root of the actual tree.- let emptyString = gxFromString ""- stack <- newIORef [Element emptyString [] []]-- case mEntityDecoder of- Just deco -> setEntityDecoder parser deco $ \_ txt -> do- modifyIORef stack (text txt)- Nothing -> return ()-- setStartElementHandler parser $ \_ cName cAttrs -> do- name <- textFromCString cName- attrs <- forM cAttrs $ \(cAttrName,cAttrValue) -> do- attrName <- textFromCString cAttrName- attrValue <- textFromCString cAttrValue- return (attrName, attrValue)- modifyIORef stack (start name attrs)- return True- setEndElementHandler parser $ \_ _ -> do- modifyIORef stack end- return True- setCharacterDataHandler parser $ \_ cText -> do- txt <- gxFromCStringLen cText- modifyIORef stack (text txt)- return True- mError <- IO.parse' parser doc- case mError of- Just err -> return $ Left err- Nothing -> do- [Element _ _ [root]] <- readIORef stack- return $ Right root-- start name attrs stack = Element name attrs [] : stack- text str (cur:rest) = modifyChildren (Text str:) cur : rest- text _ [] = impossible- end (cur:parent:rest) =- let node = modifyChildren reverse cur in- modifyChildren (node:) parent : rest- end _ = impossible- impossible = error "parse' impossible"----- | DEPRECATED: use 'parse' instead.------ Strictly parse XML to tree. Returns error message or valid parsed tree.-parseTree' :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> ByteString -- ^ Input text (a strict ByteString)- -> Either XMLParseError (Node tag text)-{-# DEPRECATED parseTree' "use Text.XML.Expat.parse' instead" #-}-parseTree' enc = parse' (ParseOptions enc Nothing)-+parse' opts doc = case parse opts (L.fromChunks [doc]) of+ (xml, Nothing) -> Right xml+ (_, Just err) -> Left err -- | A lower level function that lazily converts a SAX stream into a tree structure. saxToTree :: GenericXMLString tag =>@@ -414,34 +304,42 @@ -- | A lower level function that converts a generalized SAX stream into a tree structure. -- Ignores parse errors.-saxToTreeG :: (GenericXMLString tag, List l) =>+saxToTreeG :: forall tag text l . (GenericXMLString tag, List l) => l (SAXEvent tag text) -> ItemM l (NodeG l tag text) saxToTreeG events = do- (elts, _) <- process events- findRoot elts+ li <- runList (process events)+ case li of+ Cons elt@(Element _ _ _ ) _ -> return elt+ _ -> return $ Element (gxFromString "") mzero mzero where- findRoot elts = do- li <- runList elts- case li of- Cons elt@(Element _ _ _ ) _ -> return elt- Cons _ rema -> findRoot rema- Nil -> return $ Element (gxFromString "") mzero mzero- process events = do- li <- runList events- case li of- Nil -> return (mzero, mzero)- Cons (StartElement name attrs) rema -> do- (children, rema') <- process rema- (out, rema'') <- process rema'- return (Element name attrs children `cons` out, rema'')- Cons (EndElement _) rema -> return (mzero, rema)- Cons (CharacterData txt) rema -> do- (out, rema') <- process rema- return (Text txt `cons` out, rema')- --Cons (FailDocument err) rema = (mzero, mzero)- Cons _ rema -> process rema+ process :: l (SAXEvent tag text) -> l (NodeG l tag text)+ process events = joinL $ process_ events+ where+ process_ :: l (SAXEvent tag text) -> ItemM l (l (NodeG l tag text))+ process_ events = do+ li <- runList events+ case li of+ Nil -> return mzero+ Cons (StartElement name attrs) rema -> do+ return $ Element name attrs (process rema) `cons` process (stripElement rema)+ Cons (EndElement _) _ -> return mzero+ Cons (CharacterData txt) rema -> return $ Text txt `cons` process rema+ Cons _ rema -> process_ rema + stripElement :: l (SAXEvent tag text) -> l (SAXEvent tag text)+ stripElement events = joinL $ stripElement_ 0 events+ where+ stripElement_ :: Int -> l (SAXEvent tag text) -> ItemM l (l (SAXEvent tag text))+ stripElement_ level events = level `seq` do+ li <- runList events+ case li of+ Nil -> return mzero+ Cons (StartElement _ _) rema -> stripElement_ (level+1) rema+ Cons (EndElement _) rema -> if level == 0 then return rema + else stripElement_ (level-1) rema+ Cons _ rema -> stripElement_ level rema+ -- | Lazily parse XML to tree. Note that forcing the XMLParseError return value -- will force the entire parse. Therefore, to ensure lazy operation, don't -- check the error status until you have processed the tree.@@ -460,19 +358,6 @@ -> ItemM l (NodeG l tag text) parseG opts = saxToTreeG . SAX.parseG opts --- | DEPREACTED: Use 'parse' instead.------ Lazily parse XML to tree. Note that forcing the XMLParseError return value--- will force the entire parse. Therefore, to ensure lazy operation, don't--- check the error status until you have processed the tree.-parseTree :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> (Node tag text, Maybe XMLParseError)-{-# DEPRECATED parseTree "use Text.XML.Expat.Tree.parse instead" #-}-parseTree mEnc = parse (ParseOptions mEnc Nothing)-- -- | Lazily parse XML to tree. In the event of an error, throw 'XMLParseException'. -- -- @parseThrowing@ can throw an exception from pure code, which is generally a bad@@ -485,14 +370,3 @@ -> L.ByteString -- ^ Input text (a lazy ByteString) -> Node tag text parseThrowing opts bs = fst $ saxToTree $ SAX.parseThrowing opts bs----- | DEPRECATED: Use 'parseThrowing' instead.------ Lazily parse XML to tree. In the event of an error, throw 'XMLParseException'.-parseTreeThrowing :: (GenericXMLString tag, GenericXMLString text) =>- Maybe Encoding -- ^ Optional encoding override- -> L.ByteString -- ^ Input text (a lazy ByteString)- -> Node tag text-{-# DEPRECATED parseTreeThrowing "use Text.XML.Expat.Tree.parseThrowing instead" #-}-parseTreeThrowing mEnc = parseThrowing (ParseOptions mEnc Nothing)
+ cbits/README view
@@ -0,0 +1,139 @@++ Expat, Release 2.2.1++This is Expat, a C library for parsing XML, written by James Clark.+Expat is a stream-oriented XML parser. This means that you register+handlers with the parser before starting the parse. These handlers+are called when the parser discovers the associated structures in the+document being parsed. A start tag is an example of the kind of+structures for which you may register handlers.++Windows users should use the expat_win32bin package, which includes+both precompiled libraries and executables, and source code for+developers.++Expat is free software. You may copy, distribute, and modify it under+the terms of the License contained in the file COPYING distributed+with this package. This license is the same as the MIT/X Consortium+license.++Versions of Expat that have an odd minor version (the middle number in+the release above), are development releases and should be considered+as beta software. Releases with even minor version numbers are+intended to be production grade software.++If you are building Expat from a check-out from the CVS repository,+you need to run a script that generates the configure script using the+GNU autoconf and libtool tools. To do this, you need to have+autoconf 2.58 or newer. Run the script like this:++ ./buildconf.sh++Once this has been done, follow the same instructions as for building+from a source distribution.++To build Expat from a source distribution, you first run the+configuration shell script in the top level distribution directory:++ ./configure++There are many options which you may provide to configure (which you+can discover by running configure with the --help option). But the+one of most interest is the one that sets the installation directory.+By default, the configure script will set things up to install+libexpat into /usr/local/lib, expat.h into /usr/local/include, and+xmlwf into /usr/local/bin. If, for example, you'd prefer to install+into /home/me/mystuff/lib, /home/me/mystuff/include, and+/home/me/mystuff/bin, you can tell configure about that with:++ ./configure --prefix=/home/me/mystuff+ +Another interesting option is to enable 64-bit integer support for+line and column numbers and the over-all byte index:++ ./configure CPPFLAGS=-DXML_LARGE_SIZE+ +However, such a modification would be a breaking change to the ABI+and is therefore not recommended for general use - e.g. as part of+a Linux distribution - but rather for builds with special requirements.++After running the configure script, the "make" command will build+things and "make install" will install things into their proper+location. Have a look at the "Makefile" to learn about additional+"make" options. Note that you need to have write permission into+the directories into which things will be installed.++If you are interested in building Expat to provide document+information in UTF-16 encoding rather than the default UTF-8, follow+these instructions (after having run "make distclean"):++ 1. For UTF-16 output as unsigned short (and version/error+ strings as char), run:++ ./configure CPPFLAGS=-DXML_UNICODE++ For UTF-16 output as wchar_t (incl. version/error strings),+ run:++ ./configure CFLAGS="-g -O2 -fshort-wchar" \+ CPPFLAGS=-DXML_UNICODE_WCHAR_T++ 2. Edit the MakeFile, changing:++ LIBRARY = libexpat.la++ to:++ LIBRARY = libexpatw.la++ (Note the additional "w" in the library name.)++ 3. Run "make buildlib" (which builds the library only).+ Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".++ 4. Run "make installlib" (which installs the library only).+ Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".+ +Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default+value for DESTDIR, and the rest of the make file using only DESTDIR.+It works as follows:+ $ make install DESTDIR=/path/to/image+overrides the in-makefile set DESTDIR, while both+ $ INSTALL_ROOT=/path/to/image make install+ $ make install INSTALL_ROOT=/path/to/image+use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the+environment, because variable-setting priority is+1) commandline+2) in-makefile+3) environment ++Note: This only applies to the Expat library itself, building UTF-16 versions+of xmlwf and the tests is currently not supported. ++Note for Solaris users: The "ar" command is usually located in+"/usr/ccs/bin", which is not in the default PATH. You will need to+add this to your path for the "make" command, and probably also switch+to GNU make (the "make" found in /usr/ccs/bin does not seem to work+properly -- apparently it does not understand .PHONY directives). If+you're using ksh or bash, use this command to build:++ PATH=/usr/ccs/bin:$PATH make++When using Expat with a project using autoconf for configuration, you+can use the probing macro in conftools/expat.m4 to determine how to+include Expat. See the comments at the top of that file for more+information.++A reference manual is available in the file doc/reference.html in this+distribution.++The homepage for this project is http://www.libexpat.org/. There+are links there to connect you to the bug reports page. If you need+to report a bug when you don't have access to a browser, you may also+send a bug report by email to expat-bugs@mail.libexpat.org.++Discussion related to the direction of future expat development takes+place on expat-discuss@mail.libexpat.org. Archives of this list and+other Expat-related lists may be found at:++ http://mail.libexpat.org/mailman/listinfo/
− cbits/amigaconfig.h
@@ -1,32 +0,0 @@-#ifndef AMIGACONFIG_H-#define AMIGACONFIG_H--/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */-#define BYTEORDER 4321--/* Define to 1 if you have the `bcopy' function. */-#define HAVE_BCOPY 1--/* Define to 1 if you have the <check.h> header file. */-#undef HAVE_CHECK_H--/* Define to 1 if you have the `memmove' function. */-#define HAVE_MEMMOVE 1--/* Define to 1 if you have the <unistd.h> header file. */-#define HAVE_UNISTD_H 1--/* whether byteorder is bigendian */-#define WORDS_BIGENDIAN--/* Define to specify how much context to retain around the current parse- point. */-#define XML_CONTEXT_BYTES 1024--/* Define to make parameter entity parsing functionality available. */-#define XML_DTD--/* Define to make XML Namespaces functionality available. */-#define XML_NS--#endif /* AMIGACONFIG_H */
cbits/expat.h view
@@ -95,7 +95,9 @@ /* Added in 2.0. */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS,- XML_ERROR_RESERVED_NAMESPACE_URI+ XML_ERROR_RESERVED_NAMESPACE_URI,+ /* Added in 2.2.1. */+ XML_ERROR_INVALID_ARGUMENT }; enum XML_Content_Type {@@ -342,7 +344,7 @@ XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE- This handler has been superceded by the EntityDeclHandler above.+ This handler has been superseded by the EntityDeclHandler above. It is provided here for backward compatibility. This is called for a declaration of an unparsed (NDATA) entity.@@ -706,6 +708,7 @@ be called, despite an external subset being parsed. Note: If XML_DTD is not defined when Expat is compiled, returns XML_ERROR_FEATURE_REQUIRES_XML_DTD.+ Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);@@ -729,19 +732,43 @@ to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 2; thus this correspondds to an index into the atts array passed to the- XML_StartElementHandler.+ XML_StartElementHandler. Returns -1 if parser == NULL. */ XMLPARSEAPI(int) XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Returns the index of the ID attribute passed in the last call to- XML_StartElementHandler, or -1 if there is no ID attribute. Each- attribute/value pair counts as 2; thus this correspondds to an- index into the atts array passed to the XML_StartElementHandler.+ XML_StartElementHandler, or -1 if there is no ID attribute or+ parser == NULL. Each attribute/value pair counts as 2; thus this+ correspondds to an index into the atts array passed to the+ XML_StartElementHandler. */ XMLPARSEAPI(int) XML_GetIdAttributeIndex(XML_Parser parser); +#ifdef XML_ATTR_INFO+/* Source file byte offsets for the start and end of attribute names and values.+ The value indices are exclusive of surrounding quotes; thus in a UTF-8 source+ file an attribute value of "blah" will yield:+ info->valueEnd - info->valueStart = 4 bytes.+*/+typedef struct {+ XML_Index nameStart; /* Offset to beginning of the attribute name. */+ XML_Index nameEnd; /* Offset after the attribute name's last byte. */+ XML_Index valueStart; /* Offset to beginning of the attribute value. */+ XML_Index valueEnd; /* Offset after the attribute value's last byte. */+} XML_AttrInfo;++/* Returns an array of XML_AttrInfo structures for the attribute/value pairs+ passed in last call to the XML_StartElementHandler that were specified+ in the start-tag rather than defaulted. Each attribute/value pair counts+ as 1; thus the number of entries in the array is+ XML_GetSpecifiedAttributeCount(parser) / 2.+*/+XMLPARSEAPI(const XML_AttrInfo *)+XML_GetAttributeInfo(XML_Parser parser);+#endif+ /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other).@@ -878,11 +905,22 @@ entities is requested; otherwise it will return non-zero. Note: If XML_SetParamEntityParsing is called after XML_Parse or XML_ParseBuffer, then it has no effect and will always return 0.+ Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing parsing); +/* Sets the hash salt to use for internal hash calculations.+ Helps in preventing DoS attacks based on predicting hash+ function behavior. This must be called before parsing is started.+ Returns 1 if successful, 0 when called after parsing has started.+ Note: If parser == NULL, the function will do nothing and return 0.+*/+XMLPARSEAPI(int)+XML_SetHashSalt(XML_Parser parser,+ unsigned long hash_salt);+ /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then XML_GetErrorCode returns information about the error. */@@ -904,6 +942,10 @@ the location is the location of the character at which the error was detected; otherwise the location is the location of the last parse event, as described above.++ Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber+ return 0 to indicate an error.+ Note: XML_GetCurrentByteIndex returns -1 to indicate an error. */ XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);@@ -941,9 +983,12 @@ /* Exposing the memory handling functions used in Expat */ XMLPARSEAPI(void *)+XML_ATTR_MALLOC+XML_ATTR_ALLOC_SIZE(2) XML_MemMalloc(XML_Parser parser, size_t size); XMLPARSEAPI(void *)+XML_ATTR_ALLOC_SIZE(3) XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); XMLPARSEAPI(void)@@ -984,7 +1029,8 @@ XML_FEATURE_SIZEOF_XML_CHAR, XML_FEATURE_SIZEOF_XML_LCHAR, XML_FEATURE_NS,- XML_FEATURE_LARGE_SIZE+ XML_FEATURE_LARGE_SIZE,+ XML_FEATURE_ATTR_INFO /* Additional features must be added to the end of this enum. */ }; @@ -998,13 +1044,11 @@ XML_GetFeatureList(void); -/* Expat follows the GNU/Linux convention of odd number minor version for- beta/development releases and even number minor version for stable- releases. Micro is bumped with each release, and set to 0 with each- change to major or minor version.+/* Expat follows the semantic versioning convention.+ See http://semver.org. */ #define XML_MAJOR_VERSION 2-#define XML_MINOR_VERSION 0+#define XML_MINOR_VERSION 2 #define XML_MICRO_VERSION 1 #ifdef __cplusplus
cbits/expat_external.h view
@@ -65,13 +65,27 @@ #endif #endif /* not defined XML_STATIC */ +#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)+#define XMLIMPORT __attribute__ ((visibility ("default")))+#endif /* If we didn't define it above, define it away: */ #ifndef XMLIMPORT #define XMLIMPORT #endif +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))+#define XML_ATTR_MALLOC __attribute__((__malloc__))+#else+#define XML_ATTR_MALLOC+#endif +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))+#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))+#else+#define XML_ATTR_ALLOC_SIZE(x)+#endif+ #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL #ifdef __cplusplus@@ -79,7 +93,10 @@ #endif #ifdef XML_UNICODE_WCHAR_T-#define XML_UNICODE+# define XML_UNICODE+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)+# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"+# endif #endif #ifdef XML_UNICODE /* Information is UTF-16 encoded. */
cbits/internal.h view
@@ -71,3 +71,25 @@ #define inline #endif #endif++#ifndef UNUSED_P+# ifdef __GNUC__+# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))+# else+# define UNUSED_P(p) UNUSED_ ## p+# endif+#endif+++#ifdef __cplusplus+extern "C" {+#endif+++void+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);+++#ifdef __cplusplus+}+#endif
− cbits/macconfig.h
@@ -1,53 +0,0 @@-/*================================================================-** Copyright 2000, Clark Cooper-** All rights reserved.-**-** This is free software. You are permitted to copy, distribute, or modify-** it under the terms of the MIT/X license (contained in the COPYING file-** with this distribution.)-**-*/--#ifndef MACCONFIG_H-#define MACCONFIG_H---/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */-#define BYTEORDER 4321--/* Define to 1 if you have the `bcopy' function. */-#undef HAVE_BCOPY--/* Define to 1 if you have the `memmove' function. */-#define HAVE_MEMMOVE--/* Define to 1 if you have a working `mmap' system call. */-#undef HAVE_MMAP--/* Define to 1 if you have the <unistd.h> header file. */-#undef HAVE_UNISTD_H--/* whether byteorder is bigendian */-#define WORDS_BIGENDIAN--/* Define to specify how much context to retain around the current parse- point. */-#undef XML_CONTEXT_BYTES--/* Define to make parameter entity parsing functionality available. */-#define XML_DTD--/* Define to make XML Namespaces functionality available. */-#define XML_NS--/* Define to empty if `const' does not conform to ANSI C. */-#undef const--/* Define to `long' if <sys/types.h> does not define. */-#define off_t long--/* Define to `unsigned' if <sys/types.h> does not define. */-#undef size_t---#endif /* ifndef MACCONFIG_H */
+ cbits/siphash.h view
@@ -0,0 +1,344 @@+/* ==========================================================================+ * siphash.h - SipHash-2-4 in a single header file+ * --------------------------------------------------------------------------+ * Derived by William Ahern from the reference implementation[1] published[2]+ * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind.+ * by Jean-Philippe Aumasson and Daniel J. Berstein.+ * Minimal changes by Sebastian Pipping on top, details below.+ * Licensed under the CC0 Public Domain Dedication license.+ *+ * 1. https://www.131002.net/siphash/siphash24.c+ * 2. https://www.131002.net/siphash/+ * --------------------------------------------------------------------------+ * HISTORY:+ *+ * 2017-06-10 (Sebastian Pipping)+ * - Clarify license note in the header+ * - Address C89 issues:+ * - Stop using inline keyword (and let compiler decide)+ * - Turn integer suffix ULL to UL+ * - Replace _Bool by int+ * - Turn macro siphash24 into a function+ * - Address invalid conversion (void pointer) by explicit cast+ * - Always expose sip24_valid (for self-tests)+ *+ * 2012-11-04 - Born. (William Ahern)+ * --------------------------------------------------------------------------+ * USAGE:+ *+ * SipHash-2-4 takes as input two 64-bit words as the key, some number of+ * message bytes, and outputs a 64-bit word as the message digest. This+ * implementation employs two data structures: a struct sipkey for+ * representing the key, and a struct siphash for representing the hash+ * state.+ *+ * For converting a 16-byte unsigned char array to a key, use either the+ * macro sip_keyof or the routine sip_tokey. The former instantiates a+ * compound literal key, while the latter requires a key object as a+ * parameter.+ *+ * unsigned char secret[16];+ * arc4random_buf(secret, sizeof secret);+ * struct sipkey *key = sip_keyof(secret);+ *+ * For hashing a message, use either the convenience macro siphash24 or the+ * routines sip24_init, sip24_update, and sip24_final.+ *+ * struct siphash state;+ * void *msg;+ * size_t len;+ * uint64_t hash;+ *+ * sip24_init(&state, key);+ * sip24_update(&state, msg, len);+ * hash = sip24_final(&state);+ *+ * or+ *+ * hash = siphash24(msg, len, key);+ *+ * To convert the 64-bit hash value to a canonical 8-byte little-endian+ * binary representation, use either the macro sip_binof or the routine+ * sip_tobin. The former instantiates and returns a compound literal array,+ * while the latter requires an array object as a parameter.+ * --------------------------------------------------------------------------+ * NOTES:+ *+ * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers+ * lacking compound literal support. Instead, you must use the lower-level+ * interfaces which take as parameters the temporary state objects.+ *+ * o Uppercase macros may evaluate parameters more than once. Lowercase+ * macros should not exhibit any such side effects.+ * ==========================================================================+ */+#ifndef SIPHASH_H+#define SIPHASH_H++#include <stddef.h> /* size_t */+#include <stdint.h> /* uint64_t uint32_t uint8_t */+++#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))++#define SIP_U32TO8_LE(p, v) \+ (p)[0] = (uint8_t)((v) >> 0); (p)[1] = (uint8_t)((v) >> 8); \+ (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);++#define SIP_U64TO8_LE(p, v) \+ SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \+ SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));++#define SIP_U8TO64_LE(p) \+ (((uint64_t)((p)[0]) << 0) | \+ ((uint64_t)((p)[1]) << 8) | \+ ((uint64_t)((p)[2]) << 16) | \+ ((uint64_t)((p)[3]) << 24) | \+ ((uint64_t)((p)[4]) << 32) | \+ ((uint64_t)((p)[5]) << 40) | \+ ((uint64_t)((p)[6]) << 48) | \+ ((uint64_t)((p)[7]) << 56))+++#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }++struct siphash {+ uint64_t v0, v1, v2, v3;++ unsigned char buf[8], *p;+ uint64_t c;+}; /* struct siphash */+++#define SIP_KEYLEN 16++struct sipkey {+ uint64_t k[2];+}; /* struct sipkey */++#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))++static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {+ key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);+ key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);+ return key;+} /* sip_tokey() */+++#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))++static void *sip_tobin(void *dst, uint64_t u64) {+ SIP_U64TO8_LE((unsigned char *)dst, u64);+ return dst;+} /* sip_tobin() */+++static void sip_round(struct siphash *H, const int rounds) {+ int i;++ for (i = 0; i < rounds; i++) {+ H->v0 += H->v1;+ H->v1 = SIP_ROTL(H->v1, 13);+ H->v1 ^= H->v0;+ H->v0 = SIP_ROTL(H->v0, 32);++ H->v2 += H->v3;+ H->v3 = SIP_ROTL(H->v3, 16);+ H->v3 ^= H->v2;++ H->v0 += H->v3;+ H->v3 = SIP_ROTL(H->v3, 21);+ H->v3 ^= H->v0;++ H->v2 += H->v1;+ H->v1 = SIP_ROTL(H->v1, 17);+ H->v1 ^= H->v2;+ H->v2 = SIP_ROTL(H->v2, 32);+ }+} /* sip_round() */+++static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) {+ H->v0 = 0x736f6d6570736575UL ^ key->k[0];+ H->v1 = 0x646f72616e646f6dUL ^ key->k[1];+ H->v2 = 0x6c7967656e657261UL ^ key->k[0];+ H->v3 = 0x7465646279746573UL ^ key->k[1];++ H->p = H->buf;+ H->c = 0;++ return H;+} /* sip24_init() */+++#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])++static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) {+ const unsigned char *p = (const unsigned char *)src, *pe = p + len;+ uint64_t m;++ do {+ while (p < pe && H->p < sip_endof(H->buf))+ *H->p++ = *p++;++ if (H->p < sip_endof(H->buf))+ break;++ m = SIP_U8TO64_LE(H->buf);+ H->v3 ^= m;+ sip_round(H, 2);+ H->v0 ^= m;++ H->p = H->buf;+ H->c += 8;+ } while (p < pe);++ return H;+} /* sip24_update() */+++static uint64_t sip24_final(struct siphash *H) {+ char left = H->p - H->buf;+ uint64_t b = (H->c + left) << 56;++ switch (left) {+ case 7: b |= (uint64_t)H->buf[6] << 48;+ case 6: b |= (uint64_t)H->buf[5] << 40;+ case 5: b |= (uint64_t)H->buf[4] << 32;+ case 4: b |= (uint64_t)H->buf[3] << 24;+ case 3: b |= (uint64_t)H->buf[2] << 16;+ case 2: b |= (uint64_t)H->buf[1] << 8;+ case 1: b |= (uint64_t)H->buf[0] << 0;+ case 0: break;+ }++ H->v3 ^= b;+ sip_round(H, 2);+ H->v0 ^= b;+ H->v2 ^= 0xff;+ sip_round(H, 4);++ return H->v0 ^ H->v1 ^ H->v2 ^ H->v3;+} /* sip24_final() */+++static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) {+ struct siphash state = SIPHASH_INITIALIZER;+ return sip24_final(sip24_update(sip24_init(&state, key), src, len));+} /* siphash24() */+++/*+ * SipHash-2-4 output with+ * k = 00 01 02 ...+ * and+ * in = (empty string)+ * in = 00 (1 byte)+ * in = 00 01 (2 bytes)+ * in = 00 01 02 (3 bytes)+ * ...+ * in = 00 01 02 ... 3e (63 bytes)+ */+static int sip24_valid(void) {+ static const unsigned char vectors[64][8] = {+ { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },+ { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },+ { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },+ { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },+ { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },+ { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },+ { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },+ { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },+ { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },+ { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },+ { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },+ { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },+ { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },+ { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },+ { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },+ { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },+ { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },+ { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },+ { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },+ { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },+ { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },+ { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },+ { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },+ { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },+ { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },+ { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },+ { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },+ { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },+ { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },+ { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },+ { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },+ { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },+ { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },+ { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },+ { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },+ { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },+ { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },+ { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },+ { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },+ { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },+ { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },+ { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },+ { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },+ { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },+ { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },+ { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },+ { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },+ { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },+ { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },+ { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },+ { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },+ { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },+ { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },+ { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },+ { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },+ { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },+ { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },+ { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },+ { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },+ { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },+ { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },+ { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },+ { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },+ { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }+ };+ unsigned char in[64];+ struct sipkey k;+ size_t i;++ sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017");++ for (i = 0; i < sizeof in; ++i) {+ in[i] = i;++ if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))+ return 0;+ }++ return 1;+} /* sip24_valid() */+++#if SIPHASH_MAIN++#include <stdio.h>++int main(void) {+ int ok = sip24_valid();++ if (ok)+ puts("OK");+ else+ puts("FAIL");++ return !ok;+} /* main() */++#endif /* SIPHASH_MAIN */+++#endif /* SIPHASH_H */
cbits/winconfig.h view
@@ -17,6 +17,12 @@ #include <memory.h> #include <string.h> ++#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */+# include <expat_config.h>+#else /* !defined(HAVE_EXPAT_CONFIG_H) */++ #define XML_NS 1 #define XML_DTD 1 #define XML_CONTEXT_BYTES 1024@@ -26,5 +32,9 @@ /* Windows has memmove() available. */ #define HAVE_MEMMOVE+++#endif /* !defined(HAVE_EXPAT_CONFIG_H) */+ #endif /* ndef WINCONFIG_H */
cbits/xmlparse.c view
@@ -1,6279 +1,6821 @@ /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd See the file COPYING for copying permission.-*/--#include <stddef.h>-#include <string.h> /* memset(), memcpy() */-#include <assert.h>--#define XML_BUILDING_EXPAT 1--#ifdef COMPILED_FROM_DSP-#include "winconfig.h"-#elif defined(MACOS_CLASSIC)-#include "macconfig.h"-#elif defined(__amigaos4__)-#include "amigaconfig.h"-#elif defined(__WATCOMC__)-#include "watcomconfig.h"-#elif defined(HAVE_EXPAT_CONFIG_H)-#include <expat_config.h>-#endif /* ndef COMPILED_FROM_DSP */--#include "ascii.h"-#include "expat.h"--#ifdef XML_UNICODE-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX-#define XmlConvert XmlUtf16Convert-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS-#define XmlEncode XmlUtf16Encode-/* Using pointer subtraction to convert to integer type. */-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))-typedef unsigned short ICHAR;-#else-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX-#define XmlConvert XmlUtf8Convert-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS-#define XmlEncode XmlUtf8Encode-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)-typedef char ICHAR;-#endif---#ifndef XML_NS--#define XmlInitEncodingNS XmlInitEncoding-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding-#undef XmlGetInternalEncodingNS-#define XmlGetInternalEncodingNS XmlGetInternalEncoding-#define XmlParseXmlDeclNS XmlParseXmlDecl--#endif--#ifdef XML_UNICODE--#ifdef XML_UNICODE_WCHAR_T-#define XML_T(x) (const wchar_t)x-#define XML_L(x) L ## x-#else-#define XML_T(x) (const unsigned short)x-#define XML_L(x) x-#endif--#else--#define XML_T(x) x-#define XML_L(x) x--#endif--/* Round up n to be a multiple of sz, where sz is a power of 2. */-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))--/* Handle the case where memmove() doesn't exist. */-#ifndef HAVE_MEMMOVE-#ifdef HAVE_BCOPY-#define memmove(d,s,l) bcopy((s),(d),(l))-#else-#error memmove does not exist on this platform, nor is a substitute available-#endif /* HAVE_BCOPY */-#endif /* HAVE_MEMMOVE */--#include "internal.h"-#include "xmltok.h"-#include "xmlrole.h"--typedef const XML_Char *KEY;--typedef struct {- KEY name;-} NAMED;--typedef struct {- NAMED **v;- unsigned char power;- size_t size;- size_t used;- const XML_Memory_Handling_Suite *mem;-} HASH_TABLE;--/* Basic character hash algorithm, taken from Python's string hash:- h = h * 1000003 ^ character, the constant being a prime number.--*/-#ifdef XML_UNICODE-#define CHAR_HASH(h, c) \- (((h) * 0xF4243) ^ (unsigned short)(c))-#else-#define CHAR_HASH(h, c) \- (((h) * 0xF4243) ^ (unsigned char)(c))-#endif--/* For probing (after a collision) we need a step size relative prime- to the hash table size, which is a power of 2. We use double-hashing,- since we can calculate a second hash value cheaply by taking those bits- of the first hash value that were discarded (masked out) when the table- index was calculated: index = hash & mask, where mask = table->size - 1.- We limit the maximum step size to table->size / 4 (mask >> 2) and make- it odd, since odd numbers are always relative prime to a power of 2.-*/-#define SECOND_HASH(hash, mask, power) \- ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))-#define PROBE_STEP(hash, mask, power) \- ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))--typedef struct {- NAMED **p;- NAMED **end;-} HASH_TABLE_ITER;--#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */-#define INIT_DATA_BUF_SIZE 1024-#define INIT_ATTS_SIZE 16-#define INIT_ATTS_VERSION 0xFFFFFFFF-#define INIT_BLOCK_SIZE 1024-#define INIT_BUFFER_SIZE 1024--#define EXPAND_SPARE 24--typedef struct binding {- struct prefix *prefix;- struct binding *nextTagBinding;- struct binding *prevPrefixBinding;- const struct attribute_id *attId;- XML_Char *uri;- int uriLen;- int uriAlloc;-} BINDING;--typedef struct prefix {- const XML_Char *name;- BINDING *binding;-} PREFIX;--typedef struct {- const XML_Char *str;- const XML_Char *localPart;- const XML_Char *prefix;- int strLen;- int uriLen;- int prefixLen;-} TAG_NAME;--/* TAG represents an open element.- The name of the element is stored in both the document and API- encodings. The memory buffer 'buf' is a separately-allocated- memory area which stores the name. During the XML_Parse()/- XMLParseBuffer() when the element is open, the memory for the 'raw'- version of the name (in the document encoding) is shared with the- document buffer. If the element is open across calls to- XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to- contain the 'raw' name as well.-- A parser re-uses these structures, maintaining a list of allocated- TAG objects in a free list.-*/-typedef struct tag {- struct tag *parent; /* parent of this element */- const char *rawName; /* tagName in the original encoding */- int rawNameLength;- TAG_NAME name; /* tagName in the API encoding */- char *buf; /* buffer for name components */- char *bufEnd; /* end of the buffer */- BINDING *bindings;-} TAG;--typedef struct {- const XML_Char *name;- const XML_Char *textPtr;- int textLen; /* length in XML_Chars */- int processed; /* # of processed bytes - when suspended */- const XML_Char *systemId;- const XML_Char *base;- const XML_Char *publicId;- const XML_Char *notation;- XML_Bool open;- XML_Bool is_param;- XML_Bool is_internal; /* true if declared in internal subset outside PE */-} ENTITY;--typedef struct {- enum XML_Content_Type type;- enum XML_Content_Quant quant;- const XML_Char * name;- int firstchild;- int lastchild;- int childcnt;- int nextsib;-} CONTENT_SCAFFOLD;--#define INIT_SCAFFOLD_ELEMENTS 32--typedef struct block {- struct block *next;- int size;- XML_Char s[1];-} BLOCK;--typedef struct {- BLOCK *blocks;- BLOCK *freeBlocks;- const XML_Char *end;- XML_Char *ptr;- XML_Char *start;- const XML_Memory_Handling_Suite *mem;-} STRING_POOL;--/* The XML_Char before the name is used to determine whether- an attribute has been specified. */-typedef struct attribute_id {- XML_Char *name;- PREFIX *prefix;- XML_Bool maybeTokenized;- XML_Bool xmlns;-} ATTRIBUTE_ID;--typedef struct {- const ATTRIBUTE_ID *id;- XML_Bool isCdata;- const XML_Char *value;-} DEFAULT_ATTRIBUTE;--typedef struct {- unsigned long version;- unsigned long hash;- const XML_Char *uriName;-} NS_ATT;--typedef struct {- const XML_Char *name;- PREFIX *prefix;- const ATTRIBUTE_ID *idAtt;- int nDefaultAtts;- int allocDefaultAtts;- DEFAULT_ATTRIBUTE *defaultAtts;-} ELEMENT_TYPE;--typedef struct {- HASH_TABLE generalEntities;- HASH_TABLE elementTypes;- HASH_TABLE attributeIds;- HASH_TABLE prefixes;- STRING_POOL pool;- STRING_POOL entityValuePool;- /* false once a parameter entity reference has been skipped */- XML_Bool keepProcessing;- /* true once an internal or external PE reference has been encountered;- this includes the reference to an external subset */- XML_Bool hasParamEntityRefs;- XML_Bool standalone;-#ifdef XML_DTD- /* indicates if external PE has been read */- XML_Bool paramEntityRead;- HASH_TABLE paramEntities;-#endif /* XML_DTD */- PREFIX defaultPrefix;- /* === scaffolding for building content model === */- XML_Bool in_eldecl;- CONTENT_SCAFFOLD *scaffold;- unsigned contentStringLen;- unsigned scaffSize;- unsigned scaffCount;- int scaffLevel;- int *scaffIndex;-} DTD;--typedef struct open_internal_entity {- const char *internalEventPtr;- const char *internalEventEndPtr;- struct open_internal_entity *next;- ENTITY *entity;- int startTagLevel;- XML_Bool betweenDecl; /* WFC: PE Between Declarations */-} OPEN_INTERNAL_ENTITY;--typedef enum XML_Error PTRCALL Processor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr);--static Processor prologProcessor;-static Processor prologInitProcessor;-static Processor contentProcessor;-static Processor cdataSectionProcessor;-#ifdef XML_DTD-static Processor ignoreSectionProcessor;-static Processor externalParEntProcessor;-static Processor externalParEntInitProcessor;-static Processor entityValueProcessor;-static Processor entityValueInitProcessor;-#endif /* XML_DTD */-static Processor epilogProcessor;-static Processor errorProcessor;-static Processor externalEntityInitProcessor;-static Processor externalEntityInitProcessor2;-static Processor externalEntityInitProcessor3;-static Processor externalEntityContentProcessor;-static Processor internalEntityProcessor;--static enum XML_Error-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);-static enum XML_Error-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,- const char *s, const char *next);-static enum XML_Error-initializeEncoding(XML_Parser parser);-static enum XML_Error-doProlog(XML_Parser parser, const ENCODING *enc, const char *s, - const char *end, int tok, const char *next, const char **nextPtr, - XML_Bool haveMore);-static enum XML_Error-processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl);-static enum XML_Error-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,- const char *start, const char *end, const char **endPtr, - XML_Bool haveMore);-static enum XML_Error-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,- const char *end, const char **nextPtr, XML_Bool haveMore);-#ifdef XML_DTD-static enum XML_Error-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,- const char *end, const char **nextPtr, XML_Bool haveMore);-#endif /* XML_DTD */--static enum XML_Error-storeAtts(XML_Parser parser, const ENCODING *, const char *s,- TAG_NAME *tagNamePtr, BINDING **bindingsPtr);-static enum XML_Error-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,- const XML_Char *uri, BINDING **bindingsPtr);-static int-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, - XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);-static enum XML_Error-storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,- const char *, const char *, STRING_POOL *);-static enum XML_Error-appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,- const char *, const char *, STRING_POOL *);-static ATTRIBUTE_ID *-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);-static int-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);-static enum XML_Error-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);-static int-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end);-static int-reportComment(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);-static void-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);--static const XML_Char * getContext(XML_Parser parser);-static XML_Bool-setContext(XML_Parser parser, const XML_Char *context);--static void FASTCALL normalizePublicId(XML_Char *s);--static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);-/* do not call if parentParser != NULL */-static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);-static void-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);-static int-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);-static int-copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);--static NAMED *-lookup(HASH_TABLE *table, KEY name, size_t createSize);-static void FASTCALL-hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);-static void FASTCALL hashTableClear(HASH_TABLE *);-static void FASTCALL hashTableDestroy(HASH_TABLE *);-static void FASTCALL-hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);-static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);--static void FASTCALL-poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);-static void FASTCALL poolClear(STRING_POOL *);-static void FASTCALL poolDestroy(STRING_POOL *);-static XML_Char *-poolAppend(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end);-static XML_Char *-poolStoreString(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end);-static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);-static const XML_Char * FASTCALL-poolCopyString(STRING_POOL *pool, const XML_Char *s);-static const XML_Char *-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);-static const XML_Char * FASTCALL-poolAppendString(STRING_POOL *pool, const XML_Char *s);--static int FASTCALL nextScaffoldPart(XML_Parser parser);-static XML_Content * build_model(XML_Parser parser);-static ELEMENT_TYPE *-getElementType(XML_Parser parser, const ENCODING *enc,- const char *ptr, const char *end);--static XML_Parser-parserCreate(const XML_Char *encodingName,- const XML_Memory_Handling_Suite *memsuite,- const XML_Char *nameSep,- DTD *dtd);-static void-parserInit(XML_Parser parser, const XML_Char *encodingName);--#define poolStart(pool) ((pool)->start)-#define poolEnd(pool) ((pool)->ptr)-#define poolLength(pool) ((pool)->ptr - (pool)->start)-#define poolChop(pool) ((void)--(pool->ptr))-#define poolLastChar(pool) (((pool)->ptr)[-1])-#define poolDiscard(pool) ((pool)->ptr = (pool)->start)-#define poolFinish(pool) ((pool)->start = (pool)->ptr)-#define poolAppendChar(pool, c) \- (((pool)->ptr == (pool)->end && !poolGrow(pool)) \- ? 0 \- : ((*((pool)->ptr)++ = c), 1))--struct XML_ParserStruct {- /* The first member must be userData so that the XML_GetUserData- macro works. */- void *m_userData;- void *m_handlerArg;- char *m_buffer;- const XML_Memory_Handling_Suite m_mem;- /* first character to be parsed */- const char *m_bufferPtr;- /* past last character to be parsed */- char *m_bufferEnd;- /* allocated end of buffer */- const char *m_bufferLim;- XML_Index m_parseEndByteIndex;- const char *m_parseEndPtr;- XML_Char *m_dataBuf;- XML_Char *m_dataBufEnd;- XML_StartElementHandler m_startElementHandler;- XML_EndElementHandler m_endElementHandler;- XML_CharacterDataHandler m_characterDataHandler;- XML_ProcessingInstructionHandler m_processingInstructionHandler;- XML_CommentHandler m_commentHandler;- XML_StartCdataSectionHandler m_startCdataSectionHandler;- XML_EndCdataSectionHandler m_endCdataSectionHandler;- XML_DefaultHandler m_defaultHandler;- XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;- XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;- XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;- XML_NotationDeclHandler m_notationDeclHandler;- XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;- XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;- XML_NotStandaloneHandler m_notStandaloneHandler;- XML_ExternalEntityRefHandler m_externalEntityRefHandler;- XML_Parser m_externalEntityRefHandlerArg;- XML_SkippedEntityHandler m_skippedEntityHandler;- XML_UnknownEncodingHandler m_unknownEncodingHandler;- XML_ElementDeclHandler m_elementDeclHandler;- XML_AttlistDeclHandler m_attlistDeclHandler;- XML_EntityDeclHandler m_entityDeclHandler;- XML_XmlDeclHandler m_xmlDeclHandler;- const ENCODING *m_encoding;- INIT_ENCODING m_initEncoding;- const ENCODING *m_internalEncoding;- const XML_Char *m_protocolEncodingName;- XML_Bool m_ns;- XML_Bool m_ns_triplets;- void *m_unknownEncodingMem;- void *m_unknownEncodingData;- void *m_unknownEncodingHandlerData;- void (XMLCALL *m_unknownEncodingRelease)(void *);- PROLOG_STATE m_prologState;- Processor *m_processor;- enum XML_Error m_errorCode;- const char *m_eventPtr;- const char *m_eventEndPtr;- const char *m_positionPtr;- OPEN_INTERNAL_ENTITY *m_openInternalEntities;- OPEN_INTERNAL_ENTITY *m_freeInternalEntities;- XML_Bool m_defaultExpandInternalEntities;- int m_tagLevel;- ENTITY *m_declEntity;- const XML_Char *m_doctypeName;- const XML_Char *m_doctypeSysid;- const XML_Char *m_doctypePubid;- const XML_Char *m_declAttributeType;- const XML_Char *m_declNotationName;- const XML_Char *m_declNotationPublicId;- ELEMENT_TYPE *m_declElementType;- ATTRIBUTE_ID *m_declAttributeId;- XML_Bool m_declAttributeIsCdata;- XML_Bool m_declAttributeIsId;- DTD *m_dtd;- const XML_Char *m_curBase;- TAG *m_tagStack;- TAG *m_freeTagList;- BINDING *m_inheritedBindings;- BINDING *m_freeBindingList;- int m_attsSize;- int m_nSpecifiedAtts;- int m_idAttIndex;- ATTRIBUTE *m_atts;- NS_ATT *m_nsAtts;- unsigned long m_nsAttsVersion;- unsigned char m_nsAttsPower;- POSITION m_position;- STRING_POOL m_tempPool;- STRING_POOL m_temp2Pool;- char *m_groupConnector;- unsigned int m_groupSize;- XML_Char m_namespaceSeparator;- XML_Parser m_parentParser;- XML_ParsingStatus m_parsingStatus;-#ifdef XML_DTD- XML_Bool m_isParamEntity;- XML_Bool m_useForeignDTD;- enum XML_ParamEntityParsing m_paramEntityParsing;-#endif-};--#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))-#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))-#define FREE(p) (parser->m_mem.free_fcn((p)))--#define userData (parser->m_userData)-#define handlerArg (parser->m_handlerArg)-#define startElementHandler (parser->m_startElementHandler)-#define endElementHandler (parser->m_endElementHandler)-#define characterDataHandler (parser->m_characterDataHandler)-#define processingInstructionHandler \- (parser->m_processingInstructionHandler)-#define commentHandler (parser->m_commentHandler)-#define startCdataSectionHandler \- (parser->m_startCdataSectionHandler)-#define endCdataSectionHandler (parser->m_endCdataSectionHandler)-#define defaultHandler (parser->m_defaultHandler)-#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)-#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)-#define unparsedEntityDeclHandler \- (parser->m_unparsedEntityDeclHandler)-#define notationDeclHandler (parser->m_notationDeclHandler)-#define startNamespaceDeclHandler \- (parser->m_startNamespaceDeclHandler)-#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)-#define notStandaloneHandler (parser->m_notStandaloneHandler)-#define externalEntityRefHandler \- (parser->m_externalEntityRefHandler)-#define externalEntityRefHandlerArg \- (parser->m_externalEntityRefHandlerArg)-#define internalEntityRefHandler \- (parser->m_internalEntityRefHandler)-#define skippedEntityHandler (parser->m_skippedEntityHandler)-#define unknownEncodingHandler (parser->m_unknownEncodingHandler)-#define elementDeclHandler (parser->m_elementDeclHandler)-#define attlistDeclHandler (parser->m_attlistDeclHandler)-#define entityDeclHandler (parser->m_entityDeclHandler)-#define xmlDeclHandler (parser->m_xmlDeclHandler)-#define encoding (parser->m_encoding)-#define initEncoding (parser->m_initEncoding)-#define internalEncoding (parser->m_internalEncoding)-#define unknownEncodingMem (parser->m_unknownEncodingMem)-#define unknownEncodingData (parser->m_unknownEncodingData)-#define unknownEncodingHandlerData \- (parser->m_unknownEncodingHandlerData)-#define unknownEncodingRelease (parser->m_unknownEncodingRelease)-#define protocolEncodingName (parser->m_protocolEncodingName)-#define ns (parser->m_ns)-#define ns_triplets (parser->m_ns_triplets)-#define prologState (parser->m_prologState)-#define processor (parser->m_processor)-#define errorCode (parser->m_errorCode)-#define eventPtr (parser->m_eventPtr)-#define eventEndPtr (parser->m_eventEndPtr)-#define positionPtr (parser->m_positionPtr)-#define position (parser->m_position)-#define openInternalEntities (parser->m_openInternalEntities)-#define freeInternalEntities (parser->m_freeInternalEntities)-#define defaultExpandInternalEntities \- (parser->m_defaultExpandInternalEntities)-#define tagLevel (parser->m_tagLevel)-#define buffer (parser->m_buffer)-#define bufferPtr (parser->m_bufferPtr)-#define bufferEnd (parser->m_bufferEnd)-#define parseEndByteIndex (parser->m_parseEndByteIndex)-#define parseEndPtr (parser->m_parseEndPtr)-#define bufferLim (parser->m_bufferLim)-#define dataBuf (parser->m_dataBuf)-#define dataBufEnd (parser->m_dataBufEnd)-#define _dtd (parser->m_dtd)-#define curBase (parser->m_curBase)-#define declEntity (parser->m_declEntity)-#define doctypeName (parser->m_doctypeName)-#define doctypeSysid (parser->m_doctypeSysid)-#define doctypePubid (parser->m_doctypePubid)-#define declAttributeType (parser->m_declAttributeType)-#define declNotationName (parser->m_declNotationName)-#define declNotationPublicId (parser->m_declNotationPublicId)-#define declElementType (parser->m_declElementType)-#define declAttributeId (parser->m_declAttributeId)-#define declAttributeIsCdata (parser->m_declAttributeIsCdata)-#define declAttributeIsId (parser->m_declAttributeIsId)-#define freeTagList (parser->m_freeTagList)-#define freeBindingList (parser->m_freeBindingList)-#define inheritedBindings (parser->m_inheritedBindings)-#define tagStack (parser->m_tagStack)-#define atts (parser->m_atts)-#define attsSize (parser->m_attsSize)-#define nSpecifiedAtts (parser->m_nSpecifiedAtts)-#define idAttIndex (parser->m_idAttIndex)-#define nsAtts (parser->m_nsAtts)-#define nsAttsVersion (parser->m_nsAttsVersion)-#define nsAttsPower (parser->m_nsAttsPower)-#define tempPool (parser->m_tempPool)-#define temp2Pool (parser->m_temp2Pool)-#define groupConnector (parser->m_groupConnector)-#define groupSize (parser->m_groupSize)-#define namespaceSeparator (parser->m_namespaceSeparator)-#define parentParser (parser->m_parentParser)-#define ps_parsing (parser->m_parsingStatus.parsing)-#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)-#ifdef XML_DTD-#define isParamEntity (parser->m_isParamEntity)-#define useForeignDTD (parser->m_useForeignDTD)-#define paramEntityParsing (parser->m_paramEntityParsing)-#endif /* XML_DTD */--XML_Parser XMLCALL-XML_ParserCreate(const XML_Char *encodingName)-{- return XML_ParserCreate_MM(encodingName, NULL, NULL);-}--XML_Parser XMLCALL-XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)-{- XML_Char tmp[2];- *tmp = nsSep;- return XML_ParserCreate_MM(encodingName, NULL, tmp);-}--static const XML_Char implicitContext[] = {- ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,- ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, - ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,- ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,- ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,- ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'-};--XML_Parser XMLCALL-XML_ParserCreate_MM(const XML_Char *encodingName,- const XML_Memory_Handling_Suite *memsuite,- const XML_Char *nameSep)-{- XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);- if (parser != NULL && ns) {- /* implicit context only set for root parser, since child- parsers (i.e. external entity parsers) will inherit it- */- if (!setContext(parser, implicitContext)) {- XML_ParserFree(parser);- return NULL;- }- }- return parser;-}--static XML_Parser-parserCreate(const XML_Char *encodingName,- const XML_Memory_Handling_Suite *memsuite,- const XML_Char *nameSep,- DTD *dtd)-{- XML_Parser parser;-- if (memsuite) {- XML_Memory_Handling_Suite *mtemp;- parser = (XML_Parser)- memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));- if (parser != NULL) {- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);- mtemp->malloc_fcn = memsuite->malloc_fcn;- mtemp->realloc_fcn = memsuite->realloc_fcn;- mtemp->free_fcn = memsuite->free_fcn;- }- }- else {- XML_Memory_Handling_Suite *mtemp;- parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));- if (parser != NULL) {- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);- mtemp->malloc_fcn = malloc;- mtemp->realloc_fcn = realloc;- mtemp->free_fcn = free;- }- }-- if (!parser)- return parser;-- buffer = NULL;- bufferLim = NULL;-- attsSize = INIT_ATTS_SIZE;- atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));- if (atts == NULL) {- FREE(parser);- return NULL;- }- dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));- if (dataBuf == NULL) {- FREE(atts);- FREE(parser);- return NULL;- }- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;-- if (dtd)- _dtd = dtd;- else {- _dtd = dtdCreate(&parser->m_mem);- if (_dtd == NULL) {- FREE(dataBuf);- FREE(atts);- FREE(parser);- return NULL;- }- }-- freeBindingList = NULL;- freeTagList = NULL;- freeInternalEntities = NULL;-- groupSize = 0;- groupConnector = NULL;-- unknownEncodingHandler = NULL;- unknownEncodingHandlerData = NULL;-- namespaceSeparator = ASCII_EXCL;- ns = XML_FALSE;- ns_triplets = XML_FALSE;-- nsAtts = NULL;- nsAttsVersion = 0;- nsAttsPower = 0;-- poolInit(&tempPool, &(parser->m_mem));- poolInit(&temp2Pool, &(parser->m_mem));- parserInit(parser, encodingName);-- if (encodingName && !protocolEncodingName) {- XML_ParserFree(parser);- return NULL;- }-- if (nameSep) {- ns = XML_TRUE;- internalEncoding = XmlGetInternalEncodingNS();- namespaceSeparator = *nameSep;- }- else {- internalEncoding = XmlGetInternalEncoding();- }-- return parser;-}--static void-parserInit(XML_Parser parser, const XML_Char *encodingName)-{- processor = prologInitProcessor;- XmlPrologStateInit(&prologState);- protocolEncodingName = (encodingName != NULL- ? poolCopyString(&tempPool, encodingName)- : NULL);- curBase = NULL;- XmlInitEncoding(&initEncoding, &encoding, 0);- userData = NULL;- handlerArg = NULL;- startElementHandler = NULL;- endElementHandler = NULL;- characterDataHandler = NULL;- processingInstructionHandler = NULL;- commentHandler = NULL;- startCdataSectionHandler = NULL;- endCdataSectionHandler = NULL;- defaultHandler = NULL;- startDoctypeDeclHandler = NULL;- endDoctypeDeclHandler = NULL;- unparsedEntityDeclHandler = NULL;- notationDeclHandler = NULL;- startNamespaceDeclHandler = NULL;- endNamespaceDeclHandler = NULL;- notStandaloneHandler = NULL;- externalEntityRefHandler = NULL;- externalEntityRefHandlerArg = parser;- skippedEntityHandler = NULL;- elementDeclHandler = NULL;- attlistDeclHandler = NULL;- entityDeclHandler = NULL;- xmlDeclHandler = NULL;- bufferPtr = buffer;- bufferEnd = buffer;- parseEndByteIndex = 0;- parseEndPtr = NULL;- declElementType = NULL;- declAttributeId = NULL;- declEntity = NULL;- doctypeName = NULL;- doctypeSysid = NULL;- doctypePubid = NULL;- declAttributeType = NULL;- declNotationName = NULL;- declNotationPublicId = NULL;- declAttributeIsCdata = XML_FALSE;- declAttributeIsId = XML_FALSE;- memset(&position, 0, sizeof(POSITION));- errorCode = XML_ERROR_NONE;- eventPtr = NULL;- eventEndPtr = NULL;- positionPtr = NULL;- openInternalEntities = NULL;- defaultExpandInternalEntities = XML_TRUE;- tagLevel = 0;- tagStack = NULL;- inheritedBindings = NULL;- nSpecifiedAtts = 0;- unknownEncodingMem = NULL;- unknownEncodingRelease = NULL;- unknownEncodingData = NULL;- parentParser = NULL;- ps_parsing = XML_INITIALIZED;-#ifdef XML_DTD- isParamEntity = XML_FALSE;- useForeignDTD = XML_FALSE;- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;-#endif-}--/* moves list of bindings to freeBindingList */-static void FASTCALL-moveToFreeBindingList(XML_Parser parser, BINDING *bindings)-{- while (bindings) {- BINDING *b = bindings;- bindings = bindings->nextTagBinding;- b->nextTagBinding = freeBindingList;- freeBindingList = b;- }-}--XML_Bool XMLCALL-XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)-{- TAG *tStk;- OPEN_INTERNAL_ENTITY *openEntityList;- if (parentParser)- return XML_FALSE;- /* move tagStack to freeTagList */- tStk = tagStack;- while (tStk) {- TAG *tag = tStk;- tStk = tStk->parent;- tag->parent = freeTagList;- moveToFreeBindingList(parser, tag->bindings);- tag->bindings = NULL;- freeTagList = tag;- }- /* move openInternalEntities to freeInternalEntities */- openEntityList = openInternalEntities;- while (openEntityList) {- OPEN_INTERNAL_ENTITY *openEntity = openEntityList;- openEntityList = openEntity->next;- openEntity->next = freeInternalEntities;- freeInternalEntities = openEntity;- }- moveToFreeBindingList(parser, inheritedBindings);- FREE(unknownEncodingMem);- if (unknownEncodingRelease)- unknownEncodingRelease(unknownEncodingData);- poolClear(&tempPool);- poolClear(&temp2Pool);- parserInit(parser, encodingName);- dtdReset(_dtd, &parser->m_mem);- return setContext(parser, implicitContext);-}--enum XML_Status XMLCALL-XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)-{- /* Block after XML_Parse()/XML_ParseBuffer() has been called.- XXX There's no way for the caller to determine which of the- XXX possible error cases caused the XML_STATUS_ERROR return.- */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return XML_STATUS_ERROR;- if (encodingName == NULL)- protocolEncodingName = NULL;- else {- protocolEncodingName = poolCopyString(&tempPool, encodingName);- if (!protocolEncodingName)- return XML_STATUS_ERROR;- }- return XML_STATUS_OK;-}--XML_Parser XMLCALL-XML_ExternalEntityParserCreate(XML_Parser oldParser,- const XML_Char *context,- const XML_Char *encodingName)-{- XML_Parser parser = oldParser;- DTD *newDtd = NULL;- DTD *oldDtd = _dtd;- XML_StartElementHandler oldStartElementHandler = startElementHandler;- XML_EndElementHandler oldEndElementHandler = endElementHandler;- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;- XML_ProcessingInstructionHandler oldProcessingInstructionHandler- = processingInstructionHandler;- XML_CommentHandler oldCommentHandler = commentHandler;- XML_StartCdataSectionHandler oldStartCdataSectionHandler- = startCdataSectionHandler;- XML_EndCdataSectionHandler oldEndCdataSectionHandler- = endCdataSectionHandler;- XML_DefaultHandler oldDefaultHandler = defaultHandler;- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler- = unparsedEntityDeclHandler;- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler- = startNamespaceDeclHandler;- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler- = endNamespaceDeclHandler;- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;- XML_ExternalEntityRefHandler oldExternalEntityRefHandler- = externalEntityRefHandler;- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;- XML_UnknownEncodingHandler oldUnknownEncodingHandler- = unknownEncodingHandler;- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;- ELEMENT_TYPE * oldDeclElementType = declElementType;-- void *oldUserData = userData;- void *oldHandlerArg = handlerArg;- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;-#ifdef XML_DTD- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;- int oldInEntityValue = prologState.inEntityValue;-#endif- XML_Bool oldns_triplets = ns_triplets;--#ifdef XML_DTD- if (!context)- newDtd = oldDtd;-#endif /* XML_DTD */-- /* Note that the magical uses of the pre-processor to make field- access look more like C++ require that `parser' be overwritten- here. This makes this function more painful to follow than it- would be otherwise.- */- if (ns) {- XML_Char tmp[2];- *tmp = namespaceSeparator;- parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);- }- else {- parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);- }-- if (!parser)- return NULL;-- startElementHandler = oldStartElementHandler;- endElementHandler = oldEndElementHandler;- characterDataHandler = oldCharacterDataHandler;- processingInstructionHandler = oldProcessingInstructionHandler;- commentHandler = oldCommentHandler;- startCdataSectionHandler = oldStartCdataSectionHandler;- endCdataSectionHandler = oldEndCdataSectionHandler;- defaultHandler = oldDefaultHandler;- unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;- notationDeclHandler = oldNotationDeclHandler;- startNamespaceDeclHandler = oldStartNamespaceDeclHandler;- endNamespaceDeclHandler = oldEndNamespaceDeclHandler;- notStandaloneHandler = oldNotStandaloneHandler;- externalEntityRefHandler = oldExternalEntityRefHandler;- skippedEntityHandler = oldSkippedEntityHandler;- unknownEncodingHandler = oldUnknownEncodingHandler;- elementDeclHandler = oldElementDeclHandler;- attlistDeclHandler = oldAttlistDeclHandler;- entityDeclHandler = oldEntityDeclHandler;- xmlDeclHandler = oldXmlDeclHandler;- declElementType = oldDeclElementType;- userData = oldUserData;- if (oldUserData == oldHandlerArg)- handlerArg = userData;- else- handlerArg = parser;- if (oldExternalEntityRefHandlerArg != oldParser)- externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;- defaultExpandInternalEntities = oldDefaultExpandInternalEntities;- ns_triplets = oldns_triplets;- parentParser = oldParser;-#ifdef XML_DTD- paramEntityParsing = oldParamEntityParsing;- prologState.inEntityValue = oldInEntityValue;- if (context) {-#endif /* XML_DTD */- if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)- || !setContext(parser, context)) {- XML_ParserFree(parser);- return NULL;- }- processor = externalEntityInitProcessor;-#ifdef XML_DTD- }- else {- /* The DTD instance referenced by _dtd is shared between the document's- root parser and external PE parsers, therefore one does not need to- call setContext. In addition, one also *must* not call setContext,- because this would overwrite existing prefix->binding pointers in- _dtd with ones that get destroyed with the external PE parser.- This would leave those prefixes with dangling pointers.- */- isParamEntity = XML_TRUE;- XmlPrologStateInitExternalEntity(&prologState);- processor = externalParEntInitProcessor;- }-#endif /* XML_DTD */- return parser;-}--static void FASTCALL-destroyBindings(BINDING *bindings, XML_Parser parser)-{- for (;;) {- BINDING *b = bindings;- if (!b)- break;- bindings = b->nextTagBinding;- FREE(b->uri);- FREE(b);- }-}--void XMLCALL-XML_ParserFree(XML_Parser parser)-{- TAG *tagList;- OPEN_INTERNAL_ENTITY *entityList;- if (parser == NULL)- return;- /* free tagStack and freeTagList */- tagList = tagStack;- for (;;) {- TAG *p;- if (tagList == NULL) {- if (freeTagList == NULL)- break;- tagList = freeTagList;- freeTagList = NULL;- }- p = tagList;- tagList = tagList->parent;- FREE(p->buf);- destroyBindings(p->bindings, parser);- FREE(p);- }- /* free openInternalEntities and freeInternalEntities */- entityList = openInternalEntities;- for (;;) {- OPEN_INTERNAL_ENTITY *openEntity;- if (entityList == NULL) {- if (freeInternalEntities == NULL)- break;- entityList = freeInternalEntities;- freeInternalEntities = NULL;- }- openEntity = entityList;- entityList = entityList->next;- FREE(openEntity);- }-- destroyBindings(freeBindingList, parser);- destroyBindings(inheritedBindings, parser);- poolDestroy(&tempPool);- poolDestroy(&temp2Pool);-#ifdef XML_DTD- /* external parameter entity parsers share the DTD structure- parser->m_dtd with the root parser, so we must not destroy it- */- if (!isParamEntity && _dtd)-#else- if (_dtd)-#endif /* XML_DTD */- dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);- FREE((void *)atts);- FREE(groupConnector);- FREE(buffer);- FREE(dataBuf);- FREE(nsAtts);- FREE(unknownEncodingMem);- if (unknownEncodingRelease)- unknownEncodingRelease(unknownEncodingData);- FREE(parser);-}--void XMLCALL-XML_UseParserAsHandlerArg(XML_Parser parser)-{- handlerArg = parser;-}--enum XML_Error XMLCALL-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)-{-#ifdef XML_DTD- /* block after XML_Parse()/XML_ParseBuffer() has been called */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;- useForeignDTD = useDTD;- return XML_ERROR_NONE;-#else- return XML_ERROR_FEATURE_REQUIRES_XML_DTD;-#endif-}--void XMLCALL-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)-{- /* block after XML_Parse()/XML_ParseBuffer() has been called */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return;- ns_triplets = do_nst ? XML_TRUE : XML_FALSE;-}--void XMLCALL-XML_SetUserData(XML_Parser parser, void *p)-{- if (handlerArg == userData)- handlerArg = userData = p;- else- userData = p;-}--enum XML_Status XMLCALL-XML_SetBase(XML_Parser parser, const XML_Char *p)-{- if (p) {- p = poolCopyString(&_dtd->pool, p);- if (!p)- return XML_STATUS_ERROR;- curBase = p;- }- else- curBase = NULL;- return XML_STATUS_OK;-}--const XML_Char * XMLCALL-XML_GetBase(XML_Parser parser)-{- return curBase;-}--int XMLCALL-XML_GetSpecifiedAttributeCount(XML_Parser parser)-{- return nSpecifiedAtts;-}--int XMLCALL-XML_GetIdAttributeIndex(XML_Parser parser)-{- return idAttIndex;-}--void XMLCALL-XML_SetElementHandler(XML_Parser parser,- XML_StartElementHandler start,- XML_EndElementHandler end)-{- startElementHandler = start;- endElementHandler = end;-}--void XMLCALL-XML_SetStartElementHandler(XML_Parser parser,- XML_StartElementHandler start) {- startElementHandler = start;-}--void XMLCALL-XML_SetEndElementHandler(XML_Parser parser,- XML_EndElementHandler end) {- endElementHandler = end;-}--void XMLCALL-XML_SetCharacterDataHandler(XML_Parser parser,- XML_CharacterDataHandler handler)-{- characterDataHandler = handler;-}--void XMLCALL-XML_SetProcessingInstructionHandler(XML_Parser parser,- XML_ProcessingInstructionHandler handler)-{- processingInstructionHandler = handler;-}--void XMLCALL-XML_SetCommentHandler(XML_Parser parser,- XML_CommentHandler handler)-{- commentHandler = handler;-}--void XMLCALL-XML_SetCdataSectionHandler(XML_Parser parser,- XML_StartCdataSectionHandler start,- XML_EndCdataSectionHandler end)-{- startCdataSectionHandler = start;- endCdataSectionHandler = end;-}--void XMLCALL-XML_SetStartCdataSectionHandler(XML_Parser parser,- XML_StartCdataSectionHandler start) {- startCdataSectionHandler = start;-}--void XMLCALL-XML_SetEndCdataSectionHandler(XML_Parser parser,- XML_EndCdataSectionHandler end) {- endCdataSectionHandler = end;-}--void XMLCALL-XML_SetDefaultHandler(XML_Parser parser,- XML_DefaultHandler handler)-{- defaultHandler = handler;- defaultExpandInternalEntities = XML_FALSE;-}--void XMLCALL-XML_SetDefaultHandlerExpand(XML_Parser parser,- XML_DefaultHandler handler)-{- defaultHandler = handler;- defaultExpandInternalEntities = XML_TRUE;-}--void XMLCALL-XML_SetDoctypeDeclHandler(XML_Parser parser,- XML_StartDoctypeDeclHandler start,- XML_EndDoctypeDeclHandler end)-{- startDoctypeDeclHandler = start;- endDoctypeDeclHandler = end;-}--void XMLCALL-XML_SetStartDoctypeDeclHandler(XML_Parser parser,- XML_StartDoctypeDeclHandler start) {- startDoctypeDeclHandler = start;-}--void XMLCALL-XML_SetEndDoctypeDeclHandler(XML_Parser parser,- XML_EndDoctypeDeclHandler end) {- endDoctypeDeclHandler = end;-}--void XMLCALL-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,- XML_UnparsedEntityDeclHandler handler)-{- unparsedEntityDeclHandler = handler;-}--void XMLCALL-XML_SetNotationDeclHandler(XML_Parser parser,- XML_NotationDeclHandler handler)-{- notationDeclHandler = handler;-}--void XMLCALL-XML_SetNamespaceDeclHandler(XML_Parser parser,- XML_StartNamespaceDeclHandler start,- XML_EndNamespaceDeclHandler end)-{- startNamespaceDeclHandler = start;- endNamespaceDeclHandler = end;-}--void XMLCALL-XML_SetStartNamespaceDeclHandler(XML_Parser parser,- XML_StartNamespaceDeclHandler start) {- startNamespaceDeclHandler = start;-}--void XMLCALL-XML_SetEndNamespaceDeclHandler(XML_Parser parser,- XML_EndNamespaceDeclHandler end) {- endNamespaceDeclHandler = end;-}--void XMLCALL-XML_SetNotStandaloneHandler(XML_Parser parser,- XML_NotStandaloneHandler handler)-{- notStandaloneHandler = handler;-}--void XMLCALL-XML_SetExternalEntityRefHandler(XML_Parser parser,- XML_ExternalEntityRefHandler handler)-{- externalEntityRefHandler = handler;-}--void XMLCALL-XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)-{- if (arg)- externalEntityRefHandlerArg = (XML_Parser)arg;- else- externalEntityRefHandlerArg = parser;-}--void XMLCALL-XML_SetSkippedEntityHandler(XML_Parser parser,- XML_SkippedEntityHandler handler)-{- skippedEntityHandler = handler;-}--void XMLCALL-XML_SetUnknownEncodingHandler(XML_Parser parser,- XML_UnknownEncodingHandler handler,- void *data)-{- unknownEncodingHandler = handler;- unknownEncodingHandlerData = data;-}--void XMLCALL-XML_SetElementDeclHandler(XML_Parser parser,- XML_ElementDeclHandler eldecl)-{- elementDeclHandler = eldecl;-}--void XMLCALL-XML_SetAttlistDeclHandler(XML_Parser parser,- XML_AttlistDeclHandler attdecl)-{- attlistDeclHandler = attdecl;-}--void XMLCALL-XML_SetEntityDeclHandler(XML_Parser parser,- XML_EntityDeclHandler handler)-{- entityDeclHandler = handler;-}--void XMLCALL-XML_SetXmlDeclHandler(XML_Parser parser,- XML_XmlDeclHandler handler) {- xmlDeclHandler = handler;-}--int XMLCALL-XML_SetParamEntityParsing(XML_Parser parser,- enum XML_ParamEntityParsing peParsing)-{- /* block after XML_Parse()/XML_ParseBuffer() has been called */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return 0;-#ifdef XML_DTD- paramEntityParsing = peParsing;- return 1;-#else- return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;-#endif-}--enum XML_Status XMLCALL-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)-{- switch (ps_parsing) {- case XML_SUSPENDED:- errorCode = XML_ERROR_SUSPENDED;- return XML_STATUS_ERROR;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return XML_STATUS_ERROR;- default:- ps_parsing = XML_PARSING;- }-- if (len == 0) {- ps_finalBuffer = (XML_Bool)isFinal;- if (!isFinal)- return XML_STATUS_OK;- positionPtr = bufferPtr;- parseEndPtr = bufferEnd;-- /* If data are left over from last buffer, and we now know that these- data are the final chunk of input, then we have to check them again- to detect errors based on that fact.- */- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);-- if (errorCode == XML_ERROR_NONE) {- switch (ps_parsing) {- case XML_SUSPENDED:- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);- positionPtr = bufferPtr;- return XML_STATUS_SUSPENDED;- case XML_INITIALIZED: - case XML_PARSING:- ps_parsing = XML_FINISHED;- /* fall through */- default:- return XML_STATUS_OK;- }- }- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }-#ifndef XML_CONTEXT_BYTES- else if (bufferPtr == bufferEnd) {- const char *end;- int nLeftOver;- enum XML_Error result;- parseEndByteIndex += len;- positionPtr = s;- ps_finalBuffer = (XML_Bool)isFinal;-- errorCode = processor(parser, s, parseEndPtr = s + len, &end);-- if (errorCode != XML_ERROR_NONE) {- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- else {- switch (ps_parsing) {- case XML_SUSPENDED:- result = XML_STATUS_SUSPENDED;- break;- case XML_INITIALIZED:- case XML_PARSING:- result = XML_STATUS_OK;- if (isFinal) {- ps_parsing = XML_FINISHED;- return result;- }- }- }-- XmlUpdatePosition(encoding, positionPtr, end, &position);- nLeftOver = s + len - end;- if (nLeftOver) {- if (buffer == NULL || nLeftOver > bufferLim - buffer) {- /* FIXME avoid integer overflow */- char *temp;- temp = (buffer == NULL- ? (char *)MALLOC(len * 2)- : (char *)REALLOC(buffer, len * 2));- if (temp == NULL) {- errorCode = XML_ERROR_NO_MEMORY;- return XML_STATUS_ERROR;- }- buffer = temp;- if (!buffer) {- errorCode = XML_ERROR_NO_MEMORY;- eventPtr = eventEndPtr = NULL;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- bufferLim = buffer + len * 2;- }- memcpy(buffer, end, nLeftOver);- }- bufferPtr = buffer;- bufferEnd = buffer + nLeftOver;- positionPtr = bufferPtr;- parseEndPtr = bufferEnd;- eventPtr = bufferPtr;- eventEndPtr = bufferPtr;- return result;- }-#endif /* not defined XML_CONTEXT_BYTES */- else {- void *buff = XML_GetBuffer(parser, len);- if (buff == NULL)- return XML_STATUS_ERROR;- else {- memcpy(buff, s, len);- return XML_ParseBuffer(parser, len, isFinal);- }- }-}--enum XML_Status XMLCALL-XML_ParseBuffer(XML_Parser parser, int len, int isFinal)-{- const char *start;- enum XML_Status result = XML_STATUS_OK;-- switch (ps_parsing) {- case XML_SUSPENDED:- errorCode = XML_ERROR_SUSPENDED;- return XML_STATUS_ERROR;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return XML_STATUS_ERROR;- default:- ps_parsing = XML_PARSING;- }-- start = bufferPtr;- positionPtr = start;- bufferEnd += len;- parseEndPtr = bufferEnd;- parseEndByteIndex += len;- ps_finalBuffer = (XML_Bool)isFinal;-- errorCode = processor(parser, start, parseEndPtr, &bufferPtr);-- if (errorCode != XML_ERROR_NONE) {- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- else {- switch (ps_parsing) {- case XML_SUSPENDED:- result = XML_STATUS_SUSPENDED;- break;- case XML_INITIALIZED: - case XML_PARSING:- if (isFinal) {- ps_parsing = XML_FINISHED;- return result;- }- default: ; /* should not happen */- }- }-- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);- positionPtr = bufferPtr;- return result;-}--void * XMLCALL-XML_GetBuffer(XML_Parser parser, int len)-{- switch (ps_parsing) {- case XML_SUSPENDED:- errorCode = XML_ERROR_SUSPENDED;- return NULL;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return NULL;- default: ;- }-- if (len > bufferLim - bufferEnd) {- /* FIXME avoid integer overflow */- int neededSize = len + (int)(bufferEnd - bufferPtr);-#ifdef XML_CONTEXT_BYTES- int keep = (int)(bufferPtr - buffer);-- if (keep > XML_CONTEXT_BYTES)- keep = XML_CONTEXT_BYTES;- neededSize += keep;-#endif /* defined XML_CONTEXT_BYTES */- if (neededSize <= bufferLim - buffer) {-#ifdef XML_CONTEXT_BYTES- if (keep < bufferPtr - buffer) {- int offset = (int)(bufferPtr - buffer) - keep;- memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);- bufferEnd -= offset;- bufferPtr -= offset;- }-#else- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);- bufferEnd = buffer + (bufferEnd - bufferPtr);- bufferPtr = buffer;-#endif /* not defined XML_CONTEXT_BYTES */- }- else {- char *newBuf;- int bufferSize = (int)(bufferLim - bufferPtr);- if (bufferSize == 0)- bufferSize = INIT_BUFFER_SIZE;- do {- bufferSize *= 2;- } while (bufferSize < neededSize);- newBuf = (char *)MALLOC(bufferSize);- if (newBuf == 0) {- errorCode = XML_ERROR_NO_MEMORY;- return NULL;- }- bufferLim = newBuf + bufferSize;-#ifdef XML_CONTEXT_BYTES- if (bufferPtr) {- int keep = (int)(bufferPtr - buffer);- if (keep > XML_CONTEXT_BYTES)- keep = XML_CONTEXT_BYTES;- memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);- FREE(buffer);- buffer = newBuf;- bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;- bufferPtr = buffer + keep;- }- else {- bufferEnd = newBuf + (bufferEnd - bufferPtr);- bufferPtr = buffer = newBuf;- }-#else- if (bufferPtr) {- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);- FREE(buffer);- }- bufferEnd = newBuf + (bufferEnd - bufferPtr);- bufferPtr = buffer = newBuf;-#endif /* not defined XML_CONTEXT_BYTES */- }- }- return bufferEnd;-}--enum XML_Status XMLCALL-XML_StopParser(XML_Parser parser, XML_Bool resumable)-{- switch (ps_parsing) {- case XML_SUSPENDED:- if (resumable) {- errorCode = XML_ERROR_SUSPENDED;- return XML_STATUS_ERROR;- }- ps_parsing = XML_FINISHED;- break;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return XML_STATUS_ERROR;- default:- if (resumable) {-#ifdef XML_DTD- if (isParamEntity) {- errorCode = XML_ERROR_SUSPEND_PE;- return XML_STATUS_ERROR;- }-#endif- ps_parsing = XML_SUSPENDED;- }- else- ps_parsing = XML_FINISHED;- }- return XML_STATUS_OK;-}--enum XML_Status XMLCALL-XML_ResumeParser(XML_Parser parser)-{- enum XML_Status result = XML_STATUS_OK;-- if (ps_parsing != XML_SUSPENDED) {- errorCode = XML_ERROR_NOT_SUSPENDED;- return XML_STATUS_ERROR;- }- ps_parsing = XML_PARSING;-- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);-- if (errorCode != XML_ERROR_NONE) {- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- else {- switch (ps_parsing) {- case XML_SUSPENDED:- result = XML_STATUS_SUSPENDED;- break;- case XML_INITIALIZED: - case XML_PARSING:- if (ps_finalBuffer) {- ps_parsing = XML_FINISHED;- return result;- }- default: ;- }- }-- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);- positionPtr = bufferPtr;- return result;-}--void XMLCALL-XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)-{- assert(status != NULL);- *status = parser->m_parsingStatus;-}--enum XML_Error XMLCALL-XML_GetErrorCode(XML_Parser parser)-{- return errorCode;-}--XML_Index XMLCALL-XML_GetCurrentByteIndex(XML_Parser parser)-{- if (eventPtr)- return parseEndByteIndex - (parseEndPtr - eventPtr);- return -1;-}--int XMLCALL-XML_GetCurrentByteCount(XML_Parser parser)-{- if (eventEndPtr && eventPtr)- return (int)(eventEndPtr - eventPtr);- return 0;-}--const char * XMLCALL-XML_GetInputContext(XML_Parser parser, int *offset, int *size)-{-#ifdef XML_CONTEXT_BYTES- if (eventPtr && buffer) {- *offset = (int)(eventPtr - buffer);- *size = (int)(bufferEnd - buffer);- return buffer;- }-#endif /* defined XML_CONTEXT_BYTES */- return (char *) 0;-}--XML_Size XMLCALL-XML_GetCurrentLineNumber(XML_Parser parser)-{- if (eventPtr && eventPtr >= positionPtr) {- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);- positionPtr = eventPtr;- }- return position.lineNumber + 1;-}--XML_Size XMLCALL-XML_GetCurrentColumnNumber(XML_Parser parser)-{- if (eventPtr && eventPtr >= positionPtr) {- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);- positionPtr = eventPtr;- }- return position.columnNumber;-}--void XMLCALL-XML_FreeContentModel(XML_Parser parser, XML_Content *model)-{- FREE(model);-}--void * XMLCALL-XML_MemMalloc(XML_Parser parser, size_t size)-{- return MALLOC(size);-}--void * XMLCALL-XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)-{- return REALLOC(ptr, size);-}--void XMLCALL-XML_MemFree(XML_Parser parser, void *ptr)-{- FREE(ptr);-}--void XMLCALL-XML_DefaultCurrent(XML_Parser parser)-{- if (defaultHandler) {- if (openInternalEntities)- reportDefault(parser,- internalEncoding,- openInternalEntities->internalEventPtr,- openInternalEntities->internalEventEndPtr);- else- reportDefault(parser, encoding, eventPtr, eventEndPtr);- }-}--const XML_LChar * XMLCALL-XML_ErrorString(enum XML_Error code)-{- static const XML_LChar* const message[] = {- 0,- XML_L("out of memory"),- XML_L("syntax error"),- XML_L("no element found"),- XML_L("not well-formed (invalid token)"),- XML_L("unclosed token"),- XML_L("partial character"),- XML_L("mismatched tag"),- XML_L("duplicate attribute"),- XML_L("junk after document element"),- XML_L("illegal parameter entity reference"),- XML_L("undefined entity"),- XML_L("recursive entity reference"),- XML_L("asynchronous entity"),- XML_L("reference to invalid character number"),- XML_L("reference to binary entity"),- XML_L("reference to external entity in attribute"),- XML_L("XML or text declaration not at start of entity"),- XML_L("unknown encoding"),- XML_L("encoding specified in XML declaration is incorrect"),- XML_L("unclosed CDATA section"),- XML_L("error in processing external entity reference"),- XML_L("document is not standalone"),- XML_L("unexpected parser state - please send a bug report"),- XML_L("entity declared in parameter entity"),- XML_L("requested feature requires XML_DTD support in Expat"),- XML_L("cannot change setting once parsing has begun"),- XML_L("unbound prefix"),- XML_L("must not undeclare prefix"),- XML_L("incomplete markup in parameter entity"),- XML_L("XML declaration not well-formed"),- XML_L("text declaration not well-formed"),- XML_L("illegal character(s) in public id"),- XML_L("parser suspended"),- XML_L("parser not suspended"),- XML_L("parsing aborted"),- XML_L("parsing finished"),- XML_L("cannot suspend in external parameter entity"),- XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),- XML_L("reserved prefix (xmlns) must not be declared or undeclared"),- XML_L("prefix must not be bound to one of the reserved namespace names")- };- if (code > 0 && code < sizeof(message)/sizeof(message[0]))- return message[code];- return NULL;-}--const XML_LChar * XMLCALL-XML_ExpatVersion(void) {-- /* V1 is used to string-ize the version number. However, it would- string-ize the actual version macro *names* unless we get them- substituted before being passed to V1. CPP is defined to expand- a macro, then rescan for more expansions. Thus, we use V2 to expand- the version macros, then CPP will expand the resulting V1() macro- with the correct numerals. */- /* ### I'm assuming cpp is portable in this respect... */--#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)-#define V2(a,b,c) XML_L("expat_")V1(a,b,c)-- return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);--#undef V1-#undef V2-}--XML_Expat_Version XMLCALL-XML_ExpatVersionInfo(void)-{- XML_Expat_Version version;-- version.major = XML_MAJOR_VERSION;- version.minor = XML_MINOR_VERSION;- version.micro = XML_MICRO_VERSION;-- return version;-}--const XML_Feature * XMLCALL-XML_GetFeatureList(void)-{- static const XML_Feature features[] = {- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),- sizeof(XML_Char)},- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),- sizeof(XML_LChar)},-#ifdef XML_UNICODE- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},-#endif-#ifdef XML_UNICODE_WCHAR_T- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},-#endif-#ifdef XML_DTD- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},-#endif-#ifdef XML_CONTEXT_BYTES- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),- XML_CONTEXT_BYTES},-#endif-#ifdef XML_MIN_SIZE- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},-#endif-#ifdef XML_NS- {XML_FEATURE_NS, XML_L("XML_NS"), 0},-#endif-#ifdef XML_LARGE_SIZE- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},-#endif - {XML_FEATURE_END, NULL, 0}- };-- return features;-}--/* Initially tag->rawName always points into the parse buffer;- for those TAG instances opened while the current parse buffer was- processed, and not yet closed, we need to store tag->rawName in a more- permanent location, since the parse buffer is about to be discarded.-*/-static XML_Bool-storeRawNames(XML_Parser parser)-{- TAG *tag = tagStack;- while (tag) {- int bufSize;- int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);- char *rawNameBuf = tag->buf + nameLen;- /* Stop if already stored. Since tagStack is a stack, we can stop- at the first entry that has already been copied; everything- below it in the stack is already been accounted for in a- previous call to this function.- */- if (tag->rawName == rawNameBuf)- break;- /* For re-use purposes we need to ensure that the- size of tag->buf is a multiple of sizeof(XML_Char).- */- bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));- if (bufSize > tag->bufEnd - tag->buf) {- char *temp = (char *)REALLOC(tag->buf, bufSize);- if (temp == NULL)- return XML_FALSE;- /* if tag->name.str points to tag->buf (only when namespace- processing is off) then we have to update it- */- if (tag->name.str == (XML_Char *)tag->buf)- tag->name.str = (XML_Char *)temp;- /* if tag->name.localPart is set (when namespace processing is on)- then update it as well, since it will always point into tag->buf- */- if (tag->name.localPart)- tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -- (XML_Char *)tag->buf);- tag->buf = temp;- tag->bufEnd = temp + bufSize;- rawNameBuf = temp + nameLen;- }- memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);- tag->rawName = rawNameBuf;- tag = tag->parent;- }- return XML_TRUE;-}--static enum XML_Error PTRCALL-contentProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doContent(parser, 0, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer);- if (result == XML_ERROR_NONE) {- if (!storeRawNames(parser))- return XML_ERROR_NO_MEMORY;- }- return result;-}--static enum XML_Error PTRCALL-externalEntityInitProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = initializeEncoding(parser);- if (result != XML_ERROR_NONE)- return result;- processor = externalEntityInitProcessor2;- return externalEntityInitProcessor2(parser, start, end, endPtr);-}--static enum XML_Error PTRCALL-externalEntityInitProcessor2(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- const char *next = start; /* XmlContentTok doesn't always set the last arg */- int tok = XmlContentTok(encoding, start, end, &next);- switch (tok) {- case XML_TOK_BOM:- /* If we are at the end of the buffer, this would cause the next stage,- i.e. externalEntityInitProcessor3, to pass control directly to- doContent (by detecting XML_TOK_NONE) without processing any xml text- declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.- */- if (next == end && !ps_finalBuffer) {- *endPtr = next;- return XML_ERROR_NONE;- }- start = next;- break;- case XML_TOK_PARTIAL:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- eventPtr = start;- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- eventPtr = start;- return XML_ERROR_PARTIAL_CHAR;- }- processor = externalEntityInitProcessor3;- return externalEntityInitProcessor3(parser, start, end, endPtr);-}--static enum XML_Error PTRCALL-externalEntityInitProcessor3(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- int tok;- const char *next = start; /* XmlContentTok doesn't always set the last arg */- eventPtr = start;- tok = XmlContentTok(encoding, start, end, &next);- eventEndPtr = next;-- switch (tok) {- case XML_TOK_XML_DECL:- {- enum XML_Error result;- result = processXmlDecl(parser, 1, start, next);- if (result != XML_ERROR_NONE)- return result;- switch (ps_parsing) {- case XML_SUSPENDED: - *endPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default:- start = next;- }- }- break;- case XML_TOK_PARTIAL:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- }- processor = externalEntityContentProcessor;- tagLevel = 1;- return externalEntityContentProcessor(parser, start, end, endPtr);-}--static enum XML_Error PTRCALL-externalEntityContentProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doContent(parser, 1, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer);- if (result == XML_ERROR_NONE) {- if (!storeRawNames(parser))- return XML_ERROR_NO_MEMORY;- }- return result;-}--static enum XML_Error-doContent(XML_Parser parser,- int startTagLevel,- const ENCODING *enc,- const char *s,- const char *end,- const char **nextPtr,- XML_Bool haveMore)-{- /* save one level of indirection */- DTD * const dtd = _dtd; -- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- *eventPP = s;-- for (;;) {- const char *next = s; /* XmlContentTok doesn't always set the last arg */- int tok = XmlContentTok(enc, s, end, &next);- *eventEndPP = next;- switch (tok) {- case XML_TOK_TRAILING_CR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- *eventEndPP = end;- if (characterDataHandler) {- XML_Char c = 0xA;- characterDataHandler(handlerArg, &c, 1);- }- else if (defaultHandler)- reportDefault(parser, enc, s, end);- /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */- if (startTagLevel == 0)- return XML_ERROR_NO_ELEMENTS;- if (tagLevel != startTagLevel)- return XML_ERROR_ASYNC_ENTITY;- *nextPtr = end;- return XML_ERROR_NONE;- case XML_TOK_NONE:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- if (startTagLevel > 0) {- if (tagLevel != startTagLevel)- return XML_ERROR_ASYNC_ENTITY;- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_NO_ELEMENTS;- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_ENTITY_REF:- {- const XML_Char *name;- ENTITY *entity;- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (ch) {- if (characterDataHandler)- characterDataHandler(handlerArg, &ch, 1);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- name = poolStoreString(&dtd->pool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name)- return XML_ERROR_NO_MEMORY;- entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);- poolDiscard(&dtd->pool);- /* First, determine if a check for an existing declaration is needed;- if yes, check that the entity exists, and that it is internal,- otherwise call the skipped entity or default handler.- */- if (!dtd->hasParamEntityRefs || dtd->standalone) {- if (!entity)- return XML_ERROR_UNDEFINED_ENTITY;- else if (!entity->is_internal)- return XML_ERROR_ENTITY_DECLARED_IN_PE;- }- else if (!entity) {- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, name, 0);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- if (entity->open)- return XML_ERROR_RECURSIVE_ENTITY_REF;- if (entity->notation)- return XML_ERROR_BINARY_ENTITY_REF;- if (entity->textPtr) {- enum XML_Error result;- if (!defaultExpandInternalEntities) {- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, entity->name, 0);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- result = processInternalEntity(parser, entity, XML_FALSE);- if (result != XML_ERROR_NONE)- return result;- }- else if (externalEntityRefHandler) {- const XML_Char *context;- entity->open = XML_TRUE;- context = getContext(parser);- entity->open = XML_FALSE;- if (!context)- return XML_ERROR_NO_MEMORY;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- context,- entity->base,- entity->systemId,- entity->publicId))- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- poolDiscard(&tempPool);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- case XML_TOK_START_TAG_NO_ATTS:- /* fall through */- case XML_TOK_START_TAG_WITH_ATTS:- {- TAG *tag;- enum XML_Error result;- XML_Char *toPtr;- if (freeTagList) {- tag = freeTagList;- freeTagList = freeTagList->parent;- }- else {- tag = (TAG *)MALLOC(sizeof(TAG));- if (!tag)- return XML_ERROR_NO_MEMORY;- tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);- if (!tag->buf) {- FREE(tag);- return XML_ERROR_NO_MEMORY;- }- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;- }- tag->bindings = NULL;- tag->parent = tagStack;- tagStack = tag;- tag->name.localPart = NULL;- tag->name.prefix = NULL;- tag->rawName = s + enc->minBytesPerChar;- tag->rawNameLength = XmlNameLength(enc, tag->rawName);- ++tagLevel;- {- const char *rawNameEnd = tag->rawName + tag->rawNameLength;- const char *fromPtr = tag->rawName;- toPtr = (XML_Char *)tag->buf;- for (;;) {- int bufSize;- int convLen;- XmlConvert(enc,- &fromPtr, rawNameEnd,- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);- convLen = (int)(toPtr - (XML_Char *)tag->buf);- if (fromPtr == rawNameEnd) {- tag->name.strLen = convLen;- break;- }- bufSize = (int)(tag->bufEnd - tag->buf) << 1;- {- char *temp = (char *)REALLOC(tag->buf, bufSize);- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- tag->buf = temp;- tag->bufEnd = temp + bufSize;- toPtr = (XML_Char *)temp + convLen;- }- }- }- tag->name.str = (XML_Char *)tag->buf;- *toPtr = XML_T('\0');- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));- if (result)- return result;- if (startElementHandler)- startElementHandler(handlerArg, tag->name.str,- (const XML_Char **)atts);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- poolClear(&tempPool);- break;- }- case XML_TOK_EMPTY_ELEMENT_NO_ATTS:- /* fall through */- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:- {- const char *rawName = s + enc->minBytesPerChar;- enum XML_Error result;- BINDING *bindings = NULL;- XML_Bool noElmHandlers = XML_TRUE;- TAG_NAME name;- name.str = poolStoreString(&tempPool, enc, rawName,- rawName + XmlNameLength(enc, rawName));- if (!name.str)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- result = storeAtts(parser, enc, s, &name, &bindings);- if (result)- return result;- poolFinish(&tempPool);- if (startElementHandler) {- startElementHandler(handlerArg, name.str, (const XML_Char **)atts);- noElmHandlers = XML_FALSE;- }- if (endElementHandler) {- if (startElementHandler)- *eventPP = *eventEndPP;- endElementHandler(handlerArg, name.str);- noElmHandlers = XML_FALSE;- }- if (noElmHandlers && defaultHandler)- reportDefault(parser, enc, s, next);- poolClear(&tempPool);- while (bindings) {- BINDING *b = bindings;- if (endNamespaceDeclHandler)- endNamespaceDeclHandler(handlerArg, b->prefix->name);- bindings = bindings->nextTagBinding;- b->nextTagBinding = freeBindingList;- freeBindingList = b;- b->prefix->binding = b->prevPrefixBinding;- }- }- if (tagLevel == 0)- return epilogProcessor(parser, next, end, nextPtr);- break;- case XML_TOK_END_TAG:- if (tagLevel == startTagLevel)- return XML_ERROR_ASYNC_ENTITY;- else {- int len;- const char *rawName;- TAG *tag = tagStack;- tagStack = tag->parent;- tag->parent = freeTagList;- freeTagList = tag;- rawName = s + enc->minBytesPerChar*2;- len = XmlNameLength(enc, rawName);- if (len != tag->rawNameLength- || memcmp(tag->rawName, rawName, len) != 0) {- *eventPP = rawName;- return XML_ERROR_TAG_MISMATCH;- }- --tagLevel;- if (endElementHandler) {- const XML_Char *localPart;- const XML_Char *prefix;- XML_Char *uri;- localPart = tag->name.localPart;- if (ns && localPart) {- /* localPart and prefix may have been overwritten in- tag->name.str, since this points to the binding->uri- buffer which gets re-used; so we have to add them again- */- uri = (XML_Char *)tag->name.str + tag->name.uriLen;- /* don't need to check for space - already done in storeAtts() */- while (*localPart) *uri++ = *localPart++;- prefix = (XML_Char *)tag->name.prefix;- if (ns_triplets && prefix) {- *uri++ = namespaceSeparator;- while (*prefix) *uri++ = *prefix++;- }- *uri = XML_T('\0');- }- endElementHandler(handlerArg, tag->name.str);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- while (tag->bindings) {- BINDING *b = tag->bindings;- if (endNamespaceDeclHandler)- endNamespaceDeclHandler(handlerArg, b->prefix->name);- tag->bindings = tag->bindings->nextTagBinding;- b->nextTagBinding = freeBindingList;- freeBindingList = b;- b->prefix->binding = b->prevPrefixBinding;- }- if (tagLevel == 0)- return epilogProcessor(parser, next, end, nextPtr);- }- break;- case XML_TOK_CHAR_REF:- {- int n = XmlCharRefNumber(enc, s);- if (n < 0)- return XML_ERROR_BAD_CHAR_REF;- if (characterDataHandler) {- XML_Char buf[XML_ENCODE_MAX];- characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- }- break;- case XML_TOK_XML_DECL:- return XML_ERROR_MISPLACED_XML_PI;- case XML_TOK_DATA_NEWLINE:- if (characterDataHandler) {- XML_Char c = 0xA;- characterDataHandler(handlerArg, &c, 1);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- case XML_TOK_CDATA_SECT_OPEN:- {- enum XML_Error result;- if (startCdataSectionHandler)- startCdataSectionHandler(handlerArg);-#if 0- /* Suppose you doing a transformation on a document that involves- changing only the character data. You set up a defaultHandler- and a characterDataHandler. The defaultHandler simply copies- characters through. The characterDataHandler does the- transformation and writes the characters out escaping them as- necessary. This case will fail to work if we leave out the- following two lines (because & and < inside CDATA sections will- be incorrectly escaped).-- However, now we have a start/endCdataSectionHandler, so it seems- easier to let the user deal with this.- */- else if (characterDataHandler)- characterDataHandler(handlerArg, dataBuf, 0);-#endif- else if (defaultHandler)- reportDefault(parser, enc, s, next);- result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);- if (result != XML_ERROR_NONE)- return result;- else if (!next) {- processor = cdataSectionProcessor;- return result;- }- }- break;- case XML_TOK_TRAILING_RSQB:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- if (characterDataHandler) {- if (MUST_CONVERT(enc, s)) {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);- characterDataHandler(handlerArg, dataBuf,- (int)(dataPtr - (ICHAR *)dataBuf));- }- else- characterDataHandler(handlerArg,- (XML_Char *)s,- (int)((XML_Char *)end - (XML_Char *)s));- }- else if (defaultHandler)- reportDefault(parser, enc, s, end);- /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */- if (startTagLevel == 0) {- *eventPP = end;- return XML_ERROR_NO_ELEMENTS;- }- if (tagLevel != startTagLevel) {- *eventPP = end;- return XML_ERROR_ASYNC_ENTITY;- }- *nextPtr = end;- return XML_ERROR_NONE;- case XML_TOK_DATA_CHARS: - {- XML_CharacterDataHandler charDataHandler = characterDataHandler;- if (charDataHandler) {- if (MUST_CONVERT(enc, s)) {- for (;;) {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);- *eventEndPP = s;- charDataHandler(handlerArg, dataBuf,- (int)(dataPtr - (ICHAR *)dataBuf));- if (s == next)- break;- *eventPP = s;- }- }- else- charDataHandler(handlerArg,- (XML_Char *)s,- (int)((XML_Char *)next - (XML_Char *)s));- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- }- break;- case XML_TOK_PI:- if (!reportProcessingInstruction(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_COMMENT:- if (!reportComment(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- break;- default:- if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- *eventPP = s = next;- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default: ;- }- }- /* not reached */-}--/* Precondition: all arguments must be non-NULL;- Purpose:- - normalize attributes- - check attributes for well-formedness- - generate namespace aware attribute names (URI, prefix)- - build list of attributes for startElementHandler- - default attributes- - process namespace declarations (check and report them)- - generate namespace aware element name (URI, prefix)-*/-static enum XML_Error-storeAtts(XML_Parser parser, const ENCODING *enc,- const char *attStr, TAG_NAME *tagNamePtr,- BINDING **bindingsPtr)-{- DTD * const dtd = _dtd; /* save one level of indirection */- ELEMENT_TYPE *elementType;- int nDefaultAtts;- const XML_Char **appAtts; /* the attribute list for the application */- int attIndex = 0;- int prefixLen;- int i;- int n;- XML_Char *uri;- int nPrefixes = 0;- BINDING *binding;- const XML_Char *localPart;-- /* lookup the element type name */- elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);- if (!elementType) {- const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);- if (!name)- return XML_ERROR_NO_MEMORY;- elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,- sizeof(ELEMENT_TYPE));- if (!elementType)- return XML_ERROR_NO_MEMORY;- if (ns && !setElementTypePrefix(parser, elementType))- return XML_ERROR_NO_MEMORY;- }- nDefaultAtts = elementType->nDefaultAtts;-- /* get the attributes from the tokenizer */- n = XmlGetAttributes(enc, attStr, attsSize, atts);- if (n + nDefaultAtts > attsSize) {- int oldAttsSize = attsSize;- ATTRIBUTE *temp;- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;- temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- atts = temp;- if (n > oldAttsSize)- XmlGetAttributes(enc, attStr, n, atts);- }-- appAtts = (const XML_Char **)atts;- for (i = 0; i < n; i++) {- /* add the name and value to the attribute list */- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,- atts[i].name- + XmlNameLength(enc, atts[i].name));- if (!attId)- return XML_ERROR_NO_MEMORY;- /* Detect duplicate attributes by their QNames. This does not work when- namespace processing is turned on and different prefixes for the same- namespace are used. For this case we have a check further down.- */- if ((attId->name)[-1]) {- if (enc == encoding)- eventPtr = atts[i].name;- return XML_ERROR_DUPLICATE_ATTRIBUTE;- }- (attId->name)[-1] = 1;- appAtts[attIndex++] = attId->name;- if (!atts[i].normalized) {- enum XML_Error result;- XML_Bool isCdata = XML_TRUE;-- /* figure out whether declared as other than CDATA */- if (attId->maybeTokenized) {- int j;- for (j = 0; j < nDefaultAtts; j++) {- if (attId == elementType->defaultAtts[j].id) {- isCdata = elementType->defaultAtts[j].isCdata;- break;- }- }- }-- /* normalize the attribute value */- result = storeAttributeValue(parser, enc, isCdata,- atts[i].valuePtr, atts[i].valueEnd,- &tempPool);- if (result)- return result;- appAtts[attIndex] = poolStart(&tempPool);- poolFinish(&tempPool);- }- else {- /* the value did not need normalizing */- appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,- atts[i].valueEnd);- if (appAtts[attIndex] == 0)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- }- /* handle prefixed attribute names */- if (attId->prefix) {- if (attId->xmlns) {- /* deal with namespace declarations here */- enum XML_Error result = addBinding(parser, attId->prefix, attId,- appAtts[attIndex], bindingsPtr);- if (result)- return result;- --attIndex;- }- else {- /* deal with other prefixed names later */- attIndex++;- nPrefixes++;- (attId->name)[-1] = 2;- }- }- else- attIndex++;- }-- /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */- nSpecifiedAtts = attIndex;- if (elementType->idAtt && (elementType->idAtt->name)[-1]) {- for (i = 0; i < attIndex; i += 2)- if (appAtts[i] == elementType->idAtt->name) {- idAttIndex = i;- break;- }- }- else- idAttIndex = -1;-- /* do attribute defaulting */- for (i = 0; i < nDefaultAtts; i++) {- const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;- if (!(da->id->name)[-1] && da->value) {- if (da->id->prefix) {- if (da->id->xmlns) {- enum XML_Error result = addBinding(parser, da->id->prefix, da->id,- da->value, bindingsPtr);- if (result)- return result;- }- else {- (da->id->name)[-1] = 2;- nPrefixes++;- appAtts[attIndex++] = da->id->name;- appAtts[attIndex++] = da->value;- }- }- else {- (da->id->name)[-1] = 1;- appAtts[attIndex++] = da->id->name;- appAtts[attIndex++] = da->value;- }- }- }- appAtts[attIndex] = 0;-- /* expand prefixed attribute names, check for duplicates,- and clear flags that say whether attributes were specified */- i = 0;- if (nPrefixes) {- int j; /* hash table index */- unsigned long version = nsAttsVersion;- int nsAttsSize = (int)1 << nsAttsPower;- /* size of hash table must be at least 2 * (# of prefixed attributes) */- if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */- NS_ATT *temp;- /* hash table size must also be a power of 2 and >= 8 */- while (nPrefixes >> nsAttsPower++);- if (nsAttsPower < 3)- nsAttsPower = 3;- nsAttsSize = (int)1 << nsAttsPower;- temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));- if (!temp)- return XML_ERROR_NO_MEMORY;- nsAtts = temp;- version = 0; /* force re-initialization of nsAtts hash table */- }- /* using a version flag saves us from initializing nsAtts every time */- if (!version) { /* initialize version flags when version wraps around */- version = INIT_ATTS_VERSION;- for (j = nsAttsSize; j != 0; )- nsAtts[--j].version = version;- }- nsAttsVersion = --version;-- /* expand prefixed names and check for duplicates */- for (; i < attIndex; i += 2) {- const XML_Char *s = appAtts[i];- if (s[-1] == 2) { /* prefixed */- ATTRIBUTE_ID *id;- const BINDING *b;- unsigned long uriHash = 0;- ((XML_Char *)s)[-1] = 0; /* clear flag */- id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);- b = id->prefix->binding;- if (!b)- return XML_ERROR_UNBOUND_PREFIX;-- /* as we expand the name we also calculate its hash value */- for (j = 0; j < b->uriLen; j++) {- const XML_Char c = b->uri[j];- if (!poolAppendChar(&tempPool, c))- return XML_ERROR_NO_MEMORY;- uriHash = CHAR_HASH(uriHash, c);- }- while (*s++ != XML_T(ASCII_COLON))- ;- do { /* copies null terminator */- const XML_Char c = *s;- if (!poolAppendChar(&tempPool, *s))- return XML_ERROR_NO_MEMORY;- uriHash = CHAR_HASH(uriHash, c);- } while (*s++);-- { /* Check hash table for duplicate of expanded name (uriName).- Derived from code in lookup(HASH_TABLE *table, ...).- */- unsigned char step = 0;- unsigned long mask = nsAttsSize - 1;- j = uriHash & mask; /* index into hash table */- while (nsAtts[j].version == version) {- /* for speed we compare stored hash values first */- if (uriHash == nsAtts[j].hash) {- const XML_Char *s1 = poolStart(&tempPool);- const XML_Char *s2 = nsAtts[j].uriName;- /* s1 is null terminated, but not s2 */- for (; *s1 == *s2 && *s1 != 0; s1++, s2++);- if (*s1 == 0)- return XML_ERROR_DUPLICATE_ATTRIBUTE;- }- if (!step)- step = PROBE_STEP(uriHash, mask, nsAttsPower);- j < step ? (j += nsAttsSize - step) : (j -= step);- }- }-- if (ns_triplets) { /* append namespace separator and prefix */- tempPool.ptr[-1] = namespaceSeparator;- s = b->prefix->name;- do {- if (!poolAppendChar(&tempPool, *s))- return XML_ERROR_NO_MEMORY;- } while (*s++);- }-- /* store expanded name in attribute list */- s = poolStart(&tempPool);- poolFinish(&tempPool);- appAtts[i] = s;-- /* fill empty slot with new version, uriName and hash value */- nsAtts[j].version = version;- nsAtts[j].hash = uriHash;- nsAtts[j].uriName = s;-- if (!--nPrefixes) {- i += 2;- break;- }- }- else /* not prefixed */- ((XML_Char *)s)[-1] = 0; /* clear flag */- }- }- /* clear flags for the remaining attributes */- for (; i < attIndex; i += 2)- ((XML_Char *)(appAtts[i]))[-1] = 0;- for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)- binding->attId->name[-1] = 0;-- if (!ns)- return XML_ERROR_NONE;-- /* expand the element type name */- if (elementType->prefix) {- binding = elementType->prefix->binding;- if (!binding)- return XML_ERROR_UNBOUND_PREFIX;- localPart = tagNamePtr->str;- while (*localPart++ != XML_T(ASCII_COLON))- ;- }- else if (dtd->defaultPrefix.binding) {- binding = dtd->defaultPrefix.binding;- localPart = tagNamePtr->str;- }- else- return XML_ERROR_NONE;- prefixLen = 0;- if (ns_triplets && binding->prefix->name) {- for (; binding->prefix->name[prefixLen++];)- ; /* prefixLen includes null terminator */- }- tagNamePtr->localPart = localPart;- tagNamePtr->uriLen = binding->uriLen;- tagNamePtr->prefix = binding->prefix->name;- tagNamePtr->prefixLen = prefixLen;- for (i = 0; localPart[i++];)- ; /* i includes null terminator */- n = i + binding->uriLen + prefixLen;- if (n > binding->uriAlloc) {- TAG *p;- uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));- if (!uri)- return XML_ERROR_NO_MEMORY;- binding->uriAlloc = n + EXPAND_SPARE;- memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));- for (p = tagStack; p; p = p->parent)- if (p->name.str == binding->uri)- p->name.str = uri;- FREE(binding->uri);- binding->uri = uri;- }- /* if namespaceSeparator != '\0' then uri includes it already */- uri = binding->uri + binding->uriLen;- memcpy(uri, localPart, i * sizeof(XML_Char));- /* we always have a namespace separator between localPart and prefix */- if (prefixLen) {- uri += i - 1;- *uri = namespaceSeparator; /* replace null terminator */- memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));- }- tagNamePtr->str = binding->uri;- return XML_ERROR_NONE;-}--/* addBinding() overwrites the value of prefix->binding without checking.- Therefore one must keep track of the old value outside of addBinding().-*/-static enum XML_Error-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,- const XML_Char *uri, BINDING **bindingsPtr)-{- static const XML_Char xmlNamespace[] = {- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, - ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,- ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,- ASCII_e, '\0'- };- static const int xmlLen = - (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;- static const XML_Char xmlnsNamespace[] = {- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, - ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, - ASCII_SLASH, '\0'- };- static const int xmlnsLen = - (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;-- XML_Bool mustBeXML = XML_FALSE;- XML_Bool isXML = XML_TRUE;- XML_Bool isXMLNS = XML_TRUE;- - BINDING *b;- int len;-- /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */- if (*uri == XML_T('\0') && prefix->name)- return XML_ERROR_UNDECLARING_PREFIX;-- if (prefix->name- && prefix->name[0] == XML_T(ASCII_x)- && prefix->name[1] == XML_T(ASCII_m)- && prefix->name[2] == XML_T(ASCII_l)) {-- /* Not allowed to bind xmlns */- if (prefix->name[3] == XML_T(ASCII_n)- && prefix->name[4] == XML_T(ASCII_s)- && prefix->name[5] == XML_T('\0'))- return XML_ERROR_RESERVED_PREFIX_XMLNS;-- if (prefix->name[3] == XML_T('\0'))- mustBeXML = XML_TRUE;- }-- for (len = 0; uri[len]; len++) {- if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))- isXML = XML_FALSE;-- if (!mustBeXML && isXMLNS - && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))- isXMLNS = XML_FALSE;- }- isXML = isXML && len == xmlLen;- isXMLNS = isXMLNS && len == xmlnsLen;-- if (mustBeXML != isXML)- return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML- : XML_ERROR_RESERVED_NAMESPACE_URI;-- if (isXMLNS)- return XML_ERROR_RESERVED_NAMESPACE_URI;-- if (namespaceSeparator)- len++;- if (freeBindingList) {- b = freeBindingList;- if (len > b->uriAlloc) {- XML_Char *temp = (XML_Char *)REALLOC(b->uri,- sizeof(XML_Char) * (len + EXPAND_SPARE));- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- b->uri = temp;- b->uriAlloc = len + EXPAND_SPARE;- }- freeBindingList = b->nextTagBinding;- }- else {- b = (BINDING *)MALLOC(sizeof(BINDING));- if (!b)- return XML_ERROR_NO_MEMORY;- b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));- if (!b->uri) {- FREE(b);- return XML_ERROR_NO_MEMORY;- }- b->uriAlloc = len + EXPAND_SPARE;- }- b->uriLen = len;- memcpy(b->uri, uri, len * sizeof(XML_Char));- if (namespaceSeparator)- b->uri[len - 1] = namespaceSeparator;- b->prefix = prefix;- b->attId = attId;- b->prevPrefixBinding = prefix->binding;- /* NULL binding when default namespace undeclared */- if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)- prefix->binding = NULL;- else- prefix->binding = b;- b->nextTagBinding = *bindingsPtr;- *bindingsPtr = b;- /* if attId == NULL then we are not starting a namespace scope */- if (attId && startNamespaceDeclHandler)- startNamespaceDeclHandler(handlerArg, prefix->name,- prefix->binding ? uri : 0);- return XML_ERROR_NONE;-}--/* The idea here is to avoid using stack for each CDATA section when- the whole file is parsed with one call.-*/-static enum XML_Error PTRCALL-cdataSectionProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doCdataSection(parser, encoding, &start, end,- endPtr, (XML_Bool)!ps_finalBuffer);- if (result != XML_ERROR_NONE)- return result;- if (start) {- if (parentParser) { /* we are parsing an external entity */- processor = externalEntityContentProcessor;- return externalEntityContentProcessor(parser, start, end, endPtr);- }- else {- processor = contentProcessor;- return contentProcessor(parser, start, end, endPtr);- }- }- return result;-}--/* startPtr gets set to non-null if the section is closed, and to null if- the section is not yet closed.-*/-static enum XML_Error-doCdataSection(XML_Parser parser,- const ENCODING *enc,- const char **startPtr,- const char *end,- const char **nextPtr,- XML_Bool haveMore)-{- const char *s = *startPtr;- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- *eventPP = s;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- *eventPP = s;- *startPtr = NULL;-- for (;;) {- const char *next;- int tok = XmlCdataSectionTok(enc, s, end, &next);- *eventEndPP = next;- switch (tok) {- case XML_TOK_CDATA_SECT_CLOSE:- if (endCdataSectionHandler)- endCdataSectionHandler(handlerArg);-#if 0- /* see comment under XML_TOK_CDATA_SECT_OPEN */- else if (characterDataHandler)- characterDataHandler(handlerArg, dataBuf, 0);-#endif- else if (defaultHandler)- reportDefault(parser, enc, s, next);- *startPtr = next;- *nextPtr = next;- if (ps_parsing == XML_FINISHED)- return XML_ERROR_ABORTED;- else- return XML_ERROR_NONE;- case XML_TOK_DATA_NEWLINE:- if (characterDataHandler) {- XML_Char c = 0xA;- characterDataHandler(handlerArg, &c, 1);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- case XML_TOK_DATA_CHARS:- {- XML_CharacterDataHandler charDataHandler = characterDataHandler;- if (charDataHandler) {- if (MUST_CONVERT(enc, s)) {- for (;;) {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);- *eventEndPP = next;- charDataHandler(handlerArg, dataBuf,- (int)(dataPtr - (ICHAR *)dataBuf));- if (s == next)- break;- *eventPP = s;- }- }- else- charDataHandler(handlerArg,- (XML_Char *)s,- (int)((XML_Char *)next - (XML_Char *)s));- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- }- break;- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_PARTIAL:- case XML_TOK_NONE:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_CDATA_SECTION;- default:- *eventPP = next;- return XML_ERROR_UNEXPECTED_STATE;- }-- *eventPP = s = next;- switch (ps_parsing) {- case XML_SUSPENDED:- *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default: ;- }- }- /* not reached */-}--#ifdef XML_DTD--/* The idea here is to avoid using stack for each IGNORE section when- the whole file is parsed with one call.-*/-static enum XML_Error PTRCALL-ignoreSectionProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, - endPtr, (XML_Bool)!ps_finalBuffer);- if (result != XML_ERROR_NONE)- return result;- if (start) {- processor = prologProcessor;- return prologProcessor(parser, start, end, endPtr);- }- return result;-}--/* startPtr gets set to non-null is the section is closed, and to null- if the section is not yet closed.-*/-static enum XML_Error-doIgnoreSection(XML_Parser parser,- const ENCODING *enc,- const char **startPtr,- const char *end,- const char **nextPtr,- XML_Bool haveMore)-{- const char *next;- int tok;- const char *s = *startPtr;- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- *eventPP = s;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- *eventPP = s;- *startPtr = NULL;- tok = XmlIgnoreSectionTok(enc, s, end, &next);- *eventEndPP = next;- switch (tok) {- case XML_TOK_IGNORE_SECT:- if (defaultHandler)- reportDefault(parser, enc, s, next);- *startPtr = next;- *nextPtr = next;- if (ps_parsing == XML_FINISHED)- return XML_ERROR_ABORTED;- else- return XML_ERROR_NONE;- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_PARTIAL:- case XML_TOK_NONE:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */- default:- *eventPP = next;- return XML_ERROR_UNEXPECTED_STATE;- }- /* not reached */-}--#endif /* XML_DTD */--static enum XML_Error-initializeEncoding(XML_Parser parser)-{- const char *s;-#ifdef XML_UNICODE- char encodingBuf[128];- if (!protocolEncodingName)- s = NULL;- else {- int i;- for (i = 0; protocolEncodingName[i]; i++) {- if (i == sizeof(encodingBuf) - 1- || (protocolEncodingName[i] & ~0x7f) != 0) {- encodingBuf[0] = '\0';- break;- }- encodingBuf[i] = (char)protocolEncodingName[i];- }- encodingBuf[i] = '\0';- s = encodingBuf;- }-#else- s = protocolEncodingName;-#endif- if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))- return XML_ERROR_NONE;- return handleUnknownEncoding(parser, protocolEncodingName);-}--static enum XML_Error-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,- const char *s, const char *next)-{- const char *encodingName = NULL;- const XML_Char *storedEncName = NULL;- const ENCODING *newEncoding = NULL;- const char *version = NULL;- const char *versionend;- const XML_Char *storedversion = NULL;- int standalone = -1;- if (!(ns- ? XmlParseXmlDeclNS- : XmlParseXmlDecl)(isGeneralTextEntity,- encoding,- s,- next,- &eventPtr,- &version,- &versionend,- &encodingName,- &newEncoding,- &standalone)) {- if (isGeneralTextEntity)- return XML_ERROR_TEXT_DECL;- else- return XML_ERROR_XML_DECL;- }- if (!isGeneralTextEntity && standalone == 1) {- _dtd->standalone = XML_TRUE;-#ifdef XML_DTD- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;-#endif /* XML_DTD */- }- if (xmlDeclHandler) {- if (encodingName != NULL) {- storedEncName = poolStoreString(&temp2Pool,- encoding,- encodingName,- encodingName- + XmlNameLength(encoding, encodingName));- if (!storedEncName)- return XML_ERROR_NO_MEMORY;- poolFinish(&temp2Pool);- }- if (version) {- storedversion = poolStoreString(&temp2Pool,- encoding,- version,- versionend - encoding->minBytesPerChar);- if (!storedversion)- return XML_ERROR_NO_MEMORY;- }- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);- }- else if (defaultHandler)- reportDefault(parser, encoding, s, next);- if (protocolEncodingName == NULL) {- if (newEncoding) {- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {- eventPtr = encodingName;- return XML_ERROR_INCORRECT_ENCODING;- }- encoding = newEncoding;- }- else if (encodingName) {- enum XML_Error result;- if (!storedEncName) {- storedEncName = poolStoreString(- &temp2Pool, encoding, encodingName,- encodingName + XmlNameLength(encoding, encodingName));- if (!storedEncName)- return XML_ERROR_NO_MEMORY;- }- result = handleUnknownEncoding(parser, storedEncName);- poolClear(&temp2Pool);- if (result == XML_ERROR_UNKNOWN_ENCODING)- eventPtr = encodingName;- return result;- }- }-- if (storedEncName || storedversion)- poolClear(&temp2Pool);-- return XML_ERROR_NONE;-}--static enum XML_Error-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)-{- if (unknownEncodingHandler) {- XML_Encoding info;- int i;- for (i = 0; i < 256; i++)- info.map[i] = -1;- info.convert = NULL;- info.data = NULL;- info.release = NULL;- if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,- &info)) {- ENCODING *enc;- unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());- if (!unknownEncodingMem) {- if (info.release)- info.release(info.data);- return XML_ERROR_NO_MEMORY;- }- enc = (ns- ? XmlInitUnknownEncodingNS- : XmlInitUnknownEncoding)(unknownEncodingMem,- info.map,- info.convert,- info.data);- if (enc) {- unknownEncodingData = info.data;- unknownEncodingRelease = info.release;- encoding = enc;- return XML_ERROR_NONE;- }- }- if (info.release != NULL)- info.release(info.data);- }- return XML_ERROR_UNKNOWN_ENCODING;-}--static enum XML_Error PTRCALL-prologInitProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- enum XML_Error result = initializeEncoding(parser);- if (result != XML_ERROR_NONE)- return result;- processor = prologProcessor;- return prologProcessor(parser, s, end, nextPtr);-}--#ifdef XML_DTD--static enum XML_Error PTRCALL-externalParEntInitProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- enum XML_Error result = initializeEncoding(parser);- if (result != XML_ERROR_NONE)- return result;-- /* we know now that XML_Parse(Buffer) has been called,- so we consider the external parameter entity read */- _dtd->paramEntityRead = XML_TRUE;-- if (prologState.inEntityValue) {- processor = entityValueInitProcessor;- return entityValueInitProcessor(parser, s, end, nextPtr);- }- else {- processor = externalParEntProcessor;- return externalParEntProcessor(parser, s, end, nextPtr);- }-}--static enum XML_Error PTRCALL-entityValueInitProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- int tok;- const char *start = s;- const char *next = start;- eventPtr = start;-- for (;;) { - tok = XmlPrologTok(encoding, start, end, &next);- eventEndPtr = next;- if (tok <= 0) {- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE: /* start == end */- default:- break;- }- /* found end of entity value - can store it now */- return storeEntityValue(parser, encoding, s, end);- }- else if (tok == XML_TOK_XML_DECL) {- enum XML_Error result;- result = processXmlDecl(parser, 0, start, next);- if (result != XML_ERROR_NONE)- return result;- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default:- *nextPtr = next;- }- /* stop scanning for text declaration - we found one */- processor = entityValueProcessor;- return entityValueProcessor(parser, next, end, nextPtr);- }- /* If we are at the end of the buffer, this would cause XmlPrologTok to- return XML_TOK_NONE on the next call, which would then cause the- function to exit with *nextPtr set to s - that is what we want for other- tokens, but not for the BOM - we would rather like to skip it;- then, when this routine is entered the next time, XmlPrologTok will- return XML_TOK_INVALID, since the BOM is still in the buffer- */- else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {- *nextPtr = next;- return XML_ERROR_NONE;- }- start = next;- eventPtr = start;- }-}--static enum XML_Error PTRCALL-externalParEntProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- const char *next = s;- int tok;-- tok = XmlPrologTok(encoding, s, end, &next);- if (tok <= 0) {- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE: /* start == end */- default:- break;- }- }- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.- However, when parsing an external subset, doProlog will not accept a BOM- as valid, and report a syntax error, so we have to skip the BOM- */- else if (tok == XML_TOK_BOM) {- s = next;- tok = XmlPrologTok(encoding, s, end, &next);- }-- processor = prologProcessor;- return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer);-}--static enum XML_Error PTRCALL-entityValueProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- const char *start = s;- const char *next = s;- const ENCODING *enc = encoding;- int tok;-- for (;;) {- tok = XmlPrologTok(enc, start, end, &next);- if (tok <= 0) {- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE: /* start == end */- default:- break;- }- /* found end of entity value - can store it now */- return storeEntityValue(parser, enc, s, end);- }- start = next;- }-}--#endif /* XML_DTD */--static enum XML_Error PTRCALL-prologProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- const char *next = s;- int tok = XmlPrologTok(encoding, s, end, &next);- return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer);-}--static enum XML_Error-doProlog(XML_Parser parser,- const ENCODING *enc,- const char *s,- const char *end,- int tok,- const char *next,- const char **nextPtr,- XML_Bool haveMore)-{-#ifdef XML_DTD- static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };-#endif /* XML_DTD */- static const XML_Char atypeCDATA[] = - { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };- static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };- static const XML_Char atypeIDREF[] =- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };- static const XML_Char atypeIDREFS[] =- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };- static const XML_Char atypeENTITY[] =- { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };- static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,- ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };- static const XML_Char atypeNMTOKEN[] = {- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };- static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,- ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };- static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,- ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };- static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };- static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };-- /* save one level of indirection */- DTD * const dtd = _dtd; -- const char **eventPP;- const char **eventEndPP;- enum XML_Content_Quant quant;-- if (enc == encoding) {- eventPP = &eventPtr;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }-- for (;;) {- int role;- XML_Bool handleDefault = XML_TRUE;- *eventPP = s;- *eventEndPP = next;- if (tok <= 0) {- if (haveMore && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE:-#ifdef XML_DTD- /* for internal PE NOT referenced between declarations */- if (enc != encoding && !openInternalEntities->betweenDecl) {- *nextPtr = s;- return XML_ERROR_NONE;- }- /* WFC: PE Between Declarations - must check that PE contains- complete markup, not only for external PEs, but also for- internal PEs if the reference occurs between declarations.- */- if (isParamEntity || enc != encoding) {- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)- == XML_ROLE_ERROR)- return XML_ERROR_INCOMPLETE_PE;- *nextPtr = s;- return XML_ERROR_NONE;- }-#endif /* XML_DTD */- return XML_ERROR_NO_ELEMENTS;- default:- tok = -tok;- next = end;- break;- }- }- role = XmlTokenRole(&prologState, tok, s, next, enc);- switch (role) {- case XML_ROLE_XML_DECL:- {- enum XML_Error result = processXmlDecl(parser, 0, s, next);- if (result != XML_ERROR_NONE)- return result;- enc = encoding;- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_DOCTYPE_NAME:- if (startDoctypeDeclHandler) {- doctypeName = poolStoreString(&tempPool, enc, s, next);- if (!doctypeName)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- doctypePubid = NULL;- handleDefault = XML_FALSE;- }- doctypeSysid = NULL; /* always initialize to NULL */- break;- case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:- if (startDoctypeDeclHandler) {- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,- doctypePubid, 1);- doctypeName = NULL;- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- break;-#ifdef XML_DTD- case XML_ROLE_TEXT_DECL:- {- enum XML_Error result = processXmlDecl(parser, 1, s, next);- if (result != XML_ERROR_NONE)- return result;- enc = encoding;- handleDefault = XML_FALSE;- }- break;-#endif /* XML_DTD */- case XML_ROLE_DOCTYPE_PUBLIC_ID:-#ifdef XML_DTD- useForeignDTD = XML_FALSE;- declEntity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;-#endif /* XML_DTD */- dtd->hasParamEntityRefs = XML_TRUE;- if (startDoctypeDeclHandler) {- if (!XmlIsPublicId(enc, s, next, eventPP))- return XML_ERROR_PUBLICID;- doctypePubid = poolStoreString(&tempPool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!doctypePubid)- return XML_ERROR_NO_MEMORY;- normalizePublicId((XML_Char *)doctypePubid);- poolFinish(&tempPool);- handleDefault = XML_FALSE;- goto alreadyChecked;- }- /* fall through */- case XML_ROLE_ENTITY_PUBLIC_ID:- if (!XmlIsPublicId(enc, s, next, eventPP))- return XML_ERROR_PUBLICID;- alreadyChecked:- if (dtd->keepProcessing && declEntity) {- XML_Char *tem = poolStoreString(&dtd->pool,- enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!tem)- return XML_ERROR_NO_MEMORY;- normalizePublicId(tem);- declEntity->publicId = tem;- poolFinish(&dtd->pool);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_DOCTYPE_CLOSE:- if (doctypeName) {- startDoctypeDeclHandler(handlerArg, doctypeName,- doctypeSysid, doctypePubid, 0);- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- /* doctypeSysid will be non-NULL in the case of a previous- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler- was not set, indicating an external subset- */-#ifdef XML_DTD- if (doctypeSysid || useForeignDTD) {- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;- dtd->hasParamEntityRefs = XML_TRUE;- if (paramEntityParsing && externalEntityRefHandler) {- ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!entity)- return XML_ERROR_NO_MEMORY;- if (useForeignDTD)- entity->base = curBase;- dtd->paramEntityRead = XML_FALSE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId))- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- if (dtd->paramEntityRead) {- if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;- }- /* if we didn't read the foreign DTD then this means that there- is no external subset and we must reset dtd->hasParamEntityRefs- */- else if (!doctypeSysid)- dtd->hasParamEntityRefs = hadParamEntityRefs;- /* end of DTD - no need to update dtd->keepProcessing */- }- useForeignDTD = XML_FALSE;- }-#endif /* XML_DTD */- if (endDoctypeDeclHandler) {- endDoctypeDeclHandler(handlerArg);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_INSTANCE_START:-#ifdef XML_DTD- /* if there is no DOCTYPE declaration then now is the- last chance to read the foreign DTD- */- if (useForeignDTD) {- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;- dtd->hasParamEntityRefs = XML_TRUE;- if (paramEntityParsing && externalEntityRefHandler) {- ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!entity)- return XML_ERROR_NO_MEMORY;- entity->base = curBase;- dtd->paramEntityRead = XML_FALSE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId))- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- if (dtd->paramEntityRead) {- if (!dtd->standalone &&- notStandaloneHandler &&- !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;- }- /* if we didn't read the foreign DTD then this means that there- is no external subset and we must reset dtd->hasParamEntityRefs- */- else- dtd->hasParamEntityRefs = hadParamEntityRefs;- /* end of DTD - no need to update dtd->keepProcessing */- }- }-#endif /* XML_DTD */- processor = contentProcessor;- return contentProcessor(parser, s, end, nextPtr);- case XML_ROLE_ATTLIST_ELEMENT_NAME:- declElementType = getElementType(parser, enc, s, next);- if (!declElementType)- return XML_ERROR_NO_MEMORY;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_NAME:- declAttributeId = getAttributeId(parser, enc, s, next);- if (!declAttributeId)- return XML_ERROR_NO_MEMORY;- declAttributeIsCdata = XML_FALSE;- declAttributeType = NULL;- declAttributeIsId = XML_FALSE;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_CDATA:- declAttributeIsCdata = XML_TRUE;- declAttributeType = atypeCDATA;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_ID:- declAttributeIsId = XML_TRUE;- declAttributeType = atypeID;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_IDREF:- declAttributeType = atypeIDREF;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:- declAttributeType = atypeIDREFS;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:- declAttributeType = atypeENTITY;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:- declAttributeType = atypeENTITIES;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:- declAttributeType = atypeNMTOKEN;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:- declAttributeType = atypeNMTOKENS;- checkAttListDeclHandler:- if (dtd->keepProcessing && attlistDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ATTRIBUTE_ENUM_VALUE:- case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:- if (dtd->keepProcessing && attlistDeclHandler) {- const XML_Char *prefix;- if (declAttributeType) {- prefix = enumValueSep;- }- else {- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE- ? notationPrefix- : enumValueStart);- }- if (!poolAppendString(&tempPool, prefix))- return XML_ERROR_NO_MEMORY;- if (!poolAppend(&tempPool, enc, s, next))- return XML_ERROR_NO_MEMORY;- declAttributeType = tempPool.start;- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:- if (dtd->keepProcessing) {- if (!defineAttribute(declElementType, declAttributeId,- declAttributeIsCdata, declAttributeIsId,- 0, parser))- return XML_ERROR_NO_MEMORY;- if (attlistDeclHandler && declAttributeType) {- if (*declAttributeType == XML_T(ASCII_LPAREN)- || (*declAttributeType == XML_T(ASCII_N)- && declAttributeType[1] == XML_T(ASCII_O))) {- /* Enumerated or Notation type */- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))- || !poolAppendChar(&tempPool, XML_T('\0')))- return XML_ERROR_NO_MEMORY;- declAttributeType = tempPool.start;- poolFinish(&tempPool);- }- *eventEndPP = s;- attlistDeclHandler(handlerArg, declElementType->name,- declAttributeId->name, declAttributeType,- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- }- break;- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:- case XML_ROLE_FIXED_ATTRIBUTE_VALUE:- if (dtd->keepProcessing) {- const XML_Char *attVal;- enum XML_Error result =- storeAttributeValue(parser, enc, declAttributeIsCdata,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar,- &dtd->pool);- if (result)- return result;- attVal = poolStart(&dtd->pool);- poolFinish(&dtd->pool);- /* ID attributes aren't allowed to have a default */- if (!defineAttribute(declElementType, declAttributeId,- declAttributeIsCdata, XML_FALSE, attVal, parser))- return XML_ERROR_NO_MEMORY;- if (attlistDeclHandler && declAttributeType) {- if (*declAttributeType == XML_T(ASCII_LPAREN)- || (*declAttributeType == XML_T(ASCII_N)- && declAttributeType[1] == XML_T(ASCII_O))) {- /* Enumerated or Notation type */- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))- || !poolAppendChar(&tempPool, XML_T('\0')))- return XML_ERROR_NO_MEMORY;- declAttributeType = tempPool.start;- poolFinish(&tempPool);- }- *eventEndPP = s;- attlistDeclHandler(handlerArg, declElementType->name,- declAttributeId->name, declAttributeType,- attVal,- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- }- break;- case XML_ROLE_ENTITY_VALUE:- if (dtd->keepProcessing) {- enum XML_Error result = storeEntityValue(parser, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (declEntity) {- declEntity->textPtr = poolStart(&dtd->entityValuePool);- declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));- poolFinish(&dtd->entityValuePool);- if (entityDeclHandler) {- *eventEndPP = s;- entityDeclHandler(handlerArg,- declEntity->name,- declEntity->is_param,- declEntity->textPtr,- declEntity->textLen,- curBase, 0, 0, 0);- handleDefault = XML_FALSE;- }- }- else- poolDiscard(&dtd->entityValuePool);- if (result != XML_ERROR_NONE)- return result;- }- break;- case XML_ROLE_DOCTYPE_SYSTEM_ID:-#ifdef XML_DTD- useForeignDTD = XML_FALSE;-#endif /* XML_DTD */- dtd->hasParamEntityRefs = XML_TRUE;- if (startDoctypeDeclHandler) {- doctypeSysid = poolStoreString(&tempPool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (doctypeSysid == NULL)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- handleDefault = XML_FALSE;- }-#ifdef XML_DTD- else- /* use externalSubsetName to make doctypeSysid non-NULL- for the case where no startDoctypeDeclHandler is set */- doctypeSysid = externalSubsetName;-#endif /* XML_DTD */- if (!dtd->standalone-#ifdef XML_DTD- && !paramEntityParsing-#endif /* XML_DTD */- && notStandaloneHandler- && !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;-#ifndef XML_DTD- break;-#else /* XML_DTD */- if (!declEntity) {- declEntity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;- declEntity->publicId = NULL;- }- /* fall through */-#endif /* XML_DTD */- case XML_ROLE_ENTITY_SYSTEM_ID:- if (dtd->keepProcessing && declEntity) {- declEntity->systemId = poolStoreString(&dtd->pool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!declEntity->systemId)- return XML_ERROR_NO_MEMORY;- declEntity->base = curBase;- poolFinish(&dtd->pool);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_ENTITY_COMPLETE:- if (dtd->keepProcessing && declEntity && entityDeclHandler) {- *eventEndPP = s;- entityDeclHandler(handlerArg,- declEntity->name,- declEntity->is_param,- 0,0,- declEntity->base,- declEntity->systemId,- declEntity->publicId,- 0);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_ENTITY_NOTATION_NAME:- if (dtd->keepProcessing && declEntity) {- declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);- if (!declEntity->notation)- return XML_ERROR_NO_MEMORY;- poolFinish(&dtd->pool);- if (unparsedEntityDeclHandler) {- *eventEndPP = s;- unparsedEntityDeclHandler(handlerArg,- declEntity->name,- declEntity->base,- declEntity->systemId,- declEntity->publicId,- declEntity->notation);- handleDefault = XML_FALSE;- }- else if (entityDeclHandler) {- *eventEndPP = s;- entityDeclHandler(handlerArg,- declEntity->name,- 0,0,0,- declEntity->base,- declEntity->systemId,- declEntity->publicId,- declEntity->notation);- handleDefault = XML_FALSE;- }- }- break;- case XML_ROLE_GENERAL_ENTITY_NAME:- {- if (XmlPredefinedEntityName(enc, s, next)) {- declEntity = NULL;- break;- }- if (dtd->keepProcessing) {- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);- if (!name)- return XML_ERROR_NO_MEMORY;- declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,- sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;- if (declEntity->name != name) {- poolDiscard(&dtd->pool);- declEntity = NULL;- }- else {- poolFinish(&dtd->pool);- declEntity->publicId = NULL;- declEntity->is_param = XML_FALSE;- /* if we have a parent parser or are reading an internal parameter- entity, then the entity declaration is not considered "internal"- */- declEntity->is_internal = !(parentParser || openInternalEntities);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- }- else {- poolDiscard(&dtd->pool);- declEntity = NULL;- }- }- break;- case XML_ROLE_PARAM_ENTITY_NAME:-#ifdef XML_DTD- if (dtd->keepProcessing) {- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);- if (!name)- return XML_ERROR_NO_MEMORY;- declEntity = (ENTITY *)lookup(&dtd->paramEntities,- name, sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;- if (declEntity->name != name) {- poolDiscard(&dtd->pool);- declEntity = NULL;- }- else {- poolFinish(&dtd->pool);- declEntity->publicId = NULL;- declEntity->is_param = XML_TRUE;- /* if we have a parent parser or are reading an internal parameter- entity, then the entity declaration is not considered "internal"- */- declEntity->is_internal = !(parentParser || openInternalEntities);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- }- else {- poolDiscard(&dtd->pool);- declEntity = NULL;- }-#else /* not XML_DTD */- declEntity = NULL;-#endif /* XML_DTD */- break;- case XML_ROLE_NOTATION_NAME:- declNotationPublicId = NULL;- declNotationName = NULL;- if (notationDeclHandler) {- declNotationName = poolStoreString(&tempPool, enc, s, next);- if (!declNotationName)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_NOTATION_PUBLIC_ID:- if (!XmlIsPublicId(enc, s, next, eventPP))- return XML_ERROR_PUBLICID;- if (declNotationName) { /* means notationDeclHandler != NULL */- XML_Char *tem = poolStoreString(&tempPool,- enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!tem)- return XML_ERROR_NO_MEMORY;- normalizePublicId(tem);- declNotationPublicId = tem;- poolFinish(&tempPool);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_NOTATION_SYSTEM_ID:- if (declNotationName && notationDeclHandler) {- const XML_Char *systemId- = poolStoreString(&tempPool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!systemId)- return XML_ERROR_NO_MEMORY;- *eventEndPP = s;- notationDeclHandler(handlerArg,- declNotationName,- curBase,- systemId,- declNotationPublicId);- handleDefault = XML_FALSE;- }- poolClear(&tempPool);- break;- case XML_ROLE_NOTATION_NO_SYSTEM_ID:- if (declNotationPublicId && notationDeclHandler) {- *eventEndPP = s;- notationDeclHandler(handlerArg,- declNotationName,- curBase,- 0,- declNotationPublicId);- handleDefault = XML_FALSE;- }- poolClear(&tempPool);- break;- case XML_ROLE_ERROR:- switch (tok) {- case XML_TOK_PARAM_ENTITY_REF:- /* PE references in internal subset are- not allowed within declarations. */ - return XML_ERROR_PARAM_ENTITY_REF;- case XML_TOK_XML_DECL:- return XML_ERROR_MISPLACED_XML_PI;- default:- return XML_ERROR_SYNTAX;- }-#ifdef XML_DTD- case XML_ROLE_IGNORE_SECT:- {- enum XML_Error result;- if (defaultHandler)- reportDefault(parser, enc, s, next);- handleDefault = XML_FALSE;- result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);- if (result != XML_ERROR_NONE)- return result;- else if (!next) {- processor = ignoreSectionProcessor;- return result;- }- }- break;-#endif /* XML_DTD */- case XML_ROLE_GROUP_OPEN:- if (prologState.level >= groupSize) {- if (groupSize) {- char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- groupConnector = temp;- if (dtd->scaffIndex) {- int *temp = (int *)REALLOC(dtd->scaffIndex,- groupSize * sizeof(int));- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- dtd->scaffIndex = temp;- }- }- else {- groupConnector = (char *)MALLOC(groupSize = 32);- if (!groupConnector)- return XML_ERROR_NO_MEMORY;- }- }- groupConnector[prologState.level] = 0;- if (dtd->in_eldecl) {- int myindex = nextScaffoldPart(parser);- if (myindex < 0)- return XML_ERROR_NO_MEMORY;- dtd->scaffIndex[dtd->scaffLevel] = myindex;- dtd->scaffLevel++;- dtd->scaffold[myindex].type = XML_CTYPE_SEQ;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_GROUP_SEQUENCE:- if (groupConnector[prologState.level] == ASCII_PIPE)- return XML_ERROR_SYNTAX;- groupConnector[prologState.level] = ASCII_COMMA;- if (dtd->in_eldecl && elementDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_GROUP_CHOICE:- if (groupConnector[prologState.level] == ASCII_COMMA)- return XML_ERROR_SYNTAX;- if (dtd->in_eldecl- && !groupConnector[prologState.level]- && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type- != XML_CTYPE_MIXED)- ) {- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type- = XML_CTYPE_CHOICE;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- groupConnector[prologState.level] = ASCII_PIPE;- break;- case XML_ROLE_PARAM_ENTITY_REF:-#ifdef XML_DTD- case XML_ROLE_INNER_PARAM_ENTITY_REF:- dtd->hasParamEntityRefs = XML_TRUE;- if (!paramEntityParsing)- dtd->keepProcessing = dtd->standalone;- else {- const XML_Char *name;- ENTITY *entity;- name = poolStoreString(&dtd->pool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name)- return XML_ERROR_NO_MEMORY;- entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);- poolDiscard(&dtd->pool);- /* first, determine if a check for an existing declaration is needed;- if yes, check that the entity exists, and that it is internal,- otherwise call the skipped entity handler- */- if (prologState.documentEntity &&- (dtd->standalone- ? !openInternalEntities- : !dtd->hasParamEntityRefs)) {- if (!entity)- return XML_ERROR_UNDEFINED_ENTITY;- else if (!entity->is_internal)- return XML_ERROR_ENTITY_DECLARED_IN_PE;- }- else if (!entity) {- dtd->keepProcessing = dtd->standalone;- /* cannot report skipped entities in declarations */- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {- skippedEntityHandler(handlerArg, name, 1);- handleDefault = XML_FALSE;- }- break;- }- if (entity->open)- return XML_ERROR_RECURSIVE_ENTITY_REF;- if (entity->textPtr) {- enum XML_Error result;- XML_Bool betweenDecl = - (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);- result = processInternalEntity(parser, entity, betweenDecl);- if (result != XML_ERROR_NONE)- return result;- handleDefault = XML_FALSE;- break;- }- if (externalEntityRefHandler) {- dtd->paramEntityRead = XML_FALSE;- entity->open = XML_TRUE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId)) {- entity->open = XML_FALSE;- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- }- entity->open = XML_FALSE;- handleDefault = XML_FALSE;- if (!dtd->paramEntityRead) {- dtd->keepProcessing = dtd->standalone;- break;- }- }- else {- dtd->keepProcessing = dtd->standalone;- break;- }- }-#endif /* XML_DTD */- if (!dtd->standalone &&- notStandaloneHandler &&- !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;- break;-- /* Element declaration stuff */-- case XML_ROLE_ELEMENT_NAME:- if (elementDeclHandler) {- declElementType = getElementType(parser, enc, s, next);- if (!declElementType)- return XML_ERROR_NO_MEMORY;- dtd->scaffLevel = 0;- dtd->scaffCount = 0;- dtd->in_eldecl = XML_TRUE;- handleDefault = XML_FALSE;- }- break;-- case XML_ROLE_CONTENT_ANY:- case XML_ROLE_CONTENT_EMPTY:- if (dtd->in_eldecl) {- if (elementDeclHandler) {- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));- if (!content)- return XML_ERROR_NO_MEMORY;- content->quant = XML_CQUANT_NONE;- content->name = NULL;- content->numchildren = 0;- content->children = NULL;- content->type = ((role == XML_ROLE_CONTENT_ANY) ?- XML_CTYPE_ANY :- XML_CTYPE_EMPTY);- *eventEndPP = s;- elementDeclHandler(handlerArg, declElementType->name, content);- handleDefault = XML_FALSE;- }- dtd->in_eldecl = XML_FALSE;- }- break;-- case XML_ROLE_CONTENT_PCDATA:- if (dtd->in_eldecl) {- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type- = XML_CTYPE_MIXED;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- break;-- case XML_ROLE_CONTENT_ELEMENT:- quant = XML_CQUANT_NONE;- goto elementContent;- case XML_ROLE_CONTENT_ELEMENT_OPT:- quant = XML_CQUANT_OPT;- goto elementContent;- case XML_ROLE_CONTENT_ELEMENT_REP:- quant = XML_CQUANT_REP;- goto elementContent;- case XML_ROLE_CONTENT_ELEMENT_PLUS:- quant = XML_CQUANT_PLUS;- elementContent:- if (dtd->in_eldecl) {- ELEMENT_TYPE *el;- const XML_Char *name;- int nameLen;- const char *nxt = (quant == XML_CQUANT_NONE- ? next- : next - enc->minBytesPerChar);- int myindex = nextScaffoldPart(parser);- if (myindex < 0)- return XML_ERROR_NO_MEMORY;- dtd->scaffold[myindex].type = XML_CTYPE_NAME;- dtd->scaffold[myindex].quant = quant;- el = getElementType(parser, enc, s, nxt);- if (!el)- return XML_ERROR_NO_MEMORY;- name = el->name;- dtd->scaffold[myindex].name = name;- nameLen = 0;- for (; name[nameLen++]; );- dtd->contentStringLen += nameLen;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- break;-- case XML_ROLE_GROUP_CLOSE:- quant = XML_CQUANT_NONE;- goto closeGroup;- case XML_ROLE_GROUP_CLOSE_OPT:- quant = XML_CQUANT_OPT;- goto closeGroup;- case XML_ROLE_GROUP_CLOSE_REP:- quant = XML_CQUANT_REP;- goto closeGroup;- case XML_ROLE_GROUP_CLOSE_PLUS:- quant = XML_CQUANT_PLUS;- closeGroup:- if (dtd->in_eldecl) {- if (elementDeclHandler)- handleDefault = XML_FALSE;- dtd->scaffLevel--;- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;- if (dtd->scaffLevel == 0) {- if (!handleDefault) {- XML_Content *model = build_model(parser);- if (!model)- return XML_ERROR_NO_MEMORY;- *eventEndPP = s;- elementDeclHandler(handlerArg, declElementType->name, model);- }- dtd->in_eldecl = XML_FALSE;- dtd->contentStringLen = 0;- }- }- break;- /* End element declaration stuff */-- case XML_ROLE_PI:- if (!reportProcessingInstruction(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- handleDefault = XML_FALSE;- break;- case XML_ROLE_COMMENT:- if (!reportComment(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- handleDefault = XML_FALSE;- break;- case XML_ROLE_NONE:- switch (tok) {- case XML_TOK_BOM:- handleDefault = XML_FALSE;- break;- }- break;- case XML_ROLE_DOCTYPE_NONE:- if (startDoctypeDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ENTITY_NONE:- if (dtd->keepProcessing && entityDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_NOTATION_NONE:- if (notationDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ATTLIST_NONE:- if (dtd->keepProcessing && attlistDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ELEMENT_NONE:- if (elementDeclHandler)- handleDefault = XML_FALSE;- break;- } /* end of big switch */-- if (handleDefault && defaultHandler)- reportDefault(parser, enc, s, next);-- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default:- s = next;- tok = XmlPrologTok(enc, s, end, &next);- }- }- /* not reached */-}--static enum XML_Error PTRCALL-epilogProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- processor = epilogProcessor;- eventPtr = s;- for (;;) {- const char *next = NULL;- int tok = XmlPrologTok(encoding, s, end, &next);- eventEndPtr = next;- switch (tok) {- /* report partial linebreak - it might be the last token */- case -XML_TOK_PROLOG_S:- if (defaultHandler) {- reportDefault(parser, encoding, s, next);- if (ps_parsing == XML_FINISHED)- return XML_ERROR_ABORTED;- }- *nextPtr = next;- return XML_ERROR_NONE;- case XML_TOK_NONE:- *nextPtr = s;- return XML_ERROR_NONE;- case XML_TOK_PROLOG_S:- if (defaultHandler)- reportDefault(parser, encoding, s, next);- break;- case XML_TOK_PI:- if (!reportProcessingInstruction(parser, encoding, s, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_COMMENT:- if (!reportComment(parser, encoding, s, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_INVALID:- eventPtr = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- if (!ps_finalBuffer) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (!ps_finalBuffer) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- default:- return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;- }- eventPtr = s = next;- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default: ;- }- }-}--static enum XML_Error-processInternalEntity(XML_Parser parser, ENTITY *entity,- XML_Bool betweenDecl)-{- const char *textStart, *textEnd;- const char *next;- enum XML_Error result;- OPEN_INTERNAL_ENTITY *openEntity;-- if (freeInternalEntities) {- openEntity = freeInternalEntities;- freeInternalEntities = openEntity->next;- }- else {- openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));- if (!openEntity)- return XML_ERROR_NO_MEMORY;- }- entity->open = XML_TRUE;- entity->processed = 0;- openEntity->next = openInternalEntities;- openInternalEntities = openEntity;- openEntity->entity = entity;- openEntity->startTagLevel = tagLevel;- openEntity->betweenDecl = betweenDecl;- openEntity->internalEventPtr = NULL;- openEntity->internalEventEndPtr = NULL;- textStart = (char *)entity->textPtr;- textEnd = (char *)(entity->textPtr + entity->textLen);--#ifdef XML_DTD- if (entity->is_param) {- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);- result = doProlog(parser, internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE);- }- else -#endif /* XML_DTD */- result = doContent(parser, tagLevel, internalEncoding, textStart, - textEnd, &next, XML_FALSE);-- if (result == XML_ERROR_NONE) {- if (textEnd != next && ps_parsing == XML_SUSPENDED) {- entity->processed = (int)(next - textStart);- processor = internalEntityProcessor;- }- else {- entity->open = XML_FALSE;- openInternalEntities = openEntity->next;- /* put openEntity back in list of free instances */- openEntity->next = freeInternalEntities;- freeInternalEntities = openEntity;- }- }- return result;-}--static enum XML_Error PTRCALL-internalEntityProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- ENTITY *entity;- const char *textStart, *textEnd;- const char *next;- enum XML_Error result;- OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;- if (!openEntity)- return XML_ERROR_UNEXPECTED_STATE;-- entity = openEntity->entity;- textStart = ((char *)entity->textPtr) + entity->processed;- textEnd = (char *)(entity->textPtr + entity->textLen);--#ifdef XML_DTD- if (entity->is_param) {- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);- result = doProlog(parser, internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE);- }- else-#endif /* XML_DTD */- result = doContent(parser, openEntity->startTagLevel, internalEncoding, - textStart, textEnd, &next, XML_FALSE); -- if (result != XML_ERROR_NONE)- return result;- else if (textEnd != next && ps_parsing == XML_SUSPENDED) {- entity->processed = (int)(next - (char *)entity->textPtr);- return result;- }- else {- entity->open = XML_FALSE;- openInternalEntities = openEntity->next;- /* put openEntity back in list of free instances */- openEntity->next = freeInternalEntities;- freeInternalEntities = openEntity;- }--#ifdef XML_DTD- if (entity->is_param) {- int tok;- processor = prologProcessor;- tok = XmlPrologTok(encoding, s, end, &next);- return doProlog(parser, encoding, s, end, tok, next, nextPtr, - (XML_Bool)!ps_finalBuffer);- }- else-#endif /* XML_DTD */- {- processor = contentProcessor;- /* see externalEntityContentProcessor vs contentProcessor */- return doContent(parser, parentParser ? 1 : 0, encoding, s, end,- nextPtr, (XML_Bool)!ps_finalBuffer); - } -}--static enum XML_Error PTRCALL-errorProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- return errorCode;-}--static enum XML_Error-storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,- const char *ptr, const char *end,- STRING_POOL *pool)-{- enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,- end, pool);- if (result)- return result;- if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)- poolChop(pool);- if (!poolAppendChar(pool, XML_T('\0')))- return XML_ERROR_NO_MEMORY;- return XML_ERROR_NONE;-}--static enum XML_Error-appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,- const char *ptr, const char *end,- STRING_POOL *pool)-{- DTD * const dtd = _dtd; /* save one level of indirection */- for (;;) {- const char *next;- int tok = XmlAttributeValueTok(enc, ptr, end, &next);- switch (tok) {- case XML_TOK_NONE:- return XML_ERROR_NONE;- case XML_TOK_INVALID:- if (enc == encoding)- eventPtr = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_CHAR_REF:- {- XML_Char buf[XML_ENCODE_MAX];- int i;- int n = XmlCharRefNumber(enc, ptr);- if (n < 0) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_BAD_CHAR_REF;- }- if (!isCdata- && n == 0x20 /* space */- && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))- break;- n = XmlEncode(n, (ICHAR *)buf);- if (!n) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_BAD_CHAR_REF;- }- for (i = 0; i < n; i++) {- if (!poolAppendChar(pool, buf[i]))- return XML_ERROR_NO_MEMORY;- }- }- break;- case XML_TOK_DATA_CHARS:- if (!poolAppend(pool, enc, ptr, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_TRAILING_CR:- next = ptr + enc->minBytesPerChar;- /* fall through */- case XML_TOK_ATTRIBUTE_VALUE_S:- case XML_TOK_DATA_NEWLINE:- if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))- break;- if (!poolAppendChar(pool, 0x20))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_ENTITY_REF:- {- const XML_Char *name;- ENTITY *entity;- char checkEntityDecl;- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,- ptr + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (ch) {- if (!poolAppendChar(pool, ch))- return XML_ERROR_NO_MEMORY;- break;- }- name = poolStoreString(&temp2Pool, enc,- ptr + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name)- return XML_ERROR_NO_MEMORY;- entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);- poolDiscard(&temp2Pool);- /* First, determine if a check for an existing declaration is needed;- if yes, check that the entity exists, and that it is internal.- */- if (pool == &dtd->pool) /* are we called from prolog? */- checkEntityDecl =-#ifdef XML_DTD- prologState.documentEntity &&-#endif /* XML_DTD */- (dtd->standalone- ? !openInternalEntities- : !dtd->hasParamEntityRefs);- else /* if (pool == &tempPool): we are called from content */- checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;- if (checkEntityDecl) {- if (!entity)- return XML_ERROR_UNDEFINED_ENTITY;- else if (!entity->is_internal)- return XML_ERROR_ENTITY_DECLARED_IN_PE;- }- else if (!entity) {- /* Cannot report skipped entity here - see comments on- skippedEntityHandler.- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, name, 0);- */- /* Cannot call the default handler because this would be- out of sync with the call to the startElementHandler.- if ((pool == &tempPool) && defaultHandler)- reportDefault(parser, enc, ptr, next);- */- break;- }- if (entity->open) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_RECURSIVE_ENTITY_REF;- }- if (entity->notation) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_BINARY_ENTITY_REF;- }- if (!entity->textPtr) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;- }- else {- enum XML_Error result;- const XML_Char *textEnd = entity->textPtr + entity->textLen;- entity->open = XML_TRUE;- result = appendAttributeValue(parser, internalEncoding, isCdata,- (char *)entity->textPtr,- (char *)textEnd, pool);- entity->open = XML_FALSE;- if (result)- return result;- }- }- break;- default:- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_UNEXPECTED_STATE;- }- ptr = next;- }- /* not reached */-}--static enum XML_Error-storeEntityValue(XML_Parser parser,- const ENCODING *enc,- const char *entityTextPtr,- const char *entityTextEnd)-{- DTD * const dtd = _dtd; /* save one level of indirection */- STRING_POOL *pool = &(dtd->entityValuePool);- enum XML_Error result = XML_ERROR_NONE;-#ifdef XML_DTD- int oldInEntityValue = prologState.inEntityValue;- prologState.inEntityValue = 1;-#endif /* XML_DTD */- /* never return Null for the value argument in EntityDeclHandler,- since this would indicate an external entity; therefore we- have to make sure that entityValuePool.start is not null */- if (!pool->blocks) {- if (!poolGrow(pool))- return XML_ERROR_NO_MEMORY;- }-- for (;;) {- const char *next;- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);- switch (tok) {- case XML_TOK_PARAM_ENTITY_REF:-#ifdef XML_DTD- if (isParamEntity || enc != encoding) {- const XML_Char *name;- ENTITY *entity;- name = poolStoreString(&tempPool, enc,- entityTextPtr + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);- poolDiscard(&tempPool);- if (!entity) {- /* not a well-formedness error - see XML 1.0: WFC Entity Declared */- /* cannot report skipped entity here - see comments on- skippedEntityHandler- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, name, 0);- */- dtd->keepProcessing = dtd->standalone;- goto endEntityValue;- }- if (entity->open) {- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_RECURSIVE_ENTITY_REF;- goto endEntityValue;- }- if (entity->systemId) {- if (externalEntityRefHandler) {- dtd->paramEntityRead = XML_FALSE;- entity->open = XML_TRUE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId)) {- entity->open = XML_FALSE;- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;- goto endEntityValue;- }- entity->open = XML_FALSE;- if (!dtd->paramEntityRead)- dtd->keepProcessing = dtd->standalone;- }- else- dtd->keepProcessing = dtd->standalone;- }- else {- entity->open = XML_TRUE;- result = storeEntityValue(parser,- internalEncoding,- (char *)entity->textPtr,- (char *)(entity->textPtr- + entity->textLen));- entity->open = XML_FALSE;- if (result)- goto endEntityValue;- }- break;- }-#endif /* XML_DTD */- /* In the internal subset, PE references are not legal- within markup declarations, e.g entity values in this case. */- eventPtr = entityTextPtr;- result = XML_ERROR_PARAM_ENTITY_REF;- goto endEntityValue;- case XML_TOK_NONE:- result = XML_ERROR_NONE;- goto endEntityValue;- case XML_TOK_ENTITY_REF:- case XML_TOK_DATA_CHARS:- if (!poolAppend(pool, enc, entityTextPtr, next)) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- break;- case XML_TOK_TRAILING_CR:- next = entityTextPtr + enc->minBytesPerChar;- /* fall through */- case XML_TOK_DATA_NEWLINE:- if (pool->end == pool->ptr && !poolGrow(pool)) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- *(pool->ptr)++ = 0xA;- break;- case XML_TOK_CHAR_REF:- {- XML_Char buf[XML_ENCODE_MAX];- int i;- int n = XmlCharRefNumber(enc, entityTextPtr);- if (n < 0) {- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_BAD_CHAR_REF;- goto endEntityValue;- }- n = XmlEncode(n, (ICHAR *)buf);- if (!n) {- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_BAD_CHAR_REF;- goto endEntityValue;- }- for (i = 0; i < n; i++) {- if (pool->end == pool->ptr && !poolGrow(pool)) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- *(pool->ptr)++ = buf[i];- }- }- break;- case XML_TOK_PARTIAL:- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_INVALID_TOKEN;- goto endEntityValue;- case XML_TOK_INVALID:- if (enc == encoding)- eventPtr = next;- result = XML_ERROR_INVALID_TOKEN;- goto endEntityValue;- default:- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_UNEXPECTED_STATE;- goto endEntityValue;- }- entityTextPtr = next;- }-endEntityValue:-#ifdef XML_DTD- prologState.inEntityValue = oldInEntityValue;-#endif /* XML_DTD */- return result;-}--static void FASTCALL-normalizeLines(XML_Char *s)-{- XML_Char *p;- for (;; s++) {- if (*s == XML_T('\0'))- return;- if (*s == 0xD)- break;- }- p = s;- do {- if (*s == 0xD) {- *p++ = 0xA;- if (*++s == 0xA)- s++;- }- else- *p++ = *s++;- } while (*s);- *p = XML_T('\0');-}--static int-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end)-{- const XML_Char *target;- XML_Char *data;- const char *tem;- if (!processingInstructionHandler) {- if (defaultHandler)- reportDefault(parser, enc, start, end);- return 1;- }- start += enc->minBytesPerChar * 2;- tem = start + XmlNameLength(enc, start);- target = poolStoreString(&tempPool, enc, start, tem);- if (!target)- return 0;- poolFinish(&tempPool);- data = poolStoreString(&tempPool, enc,- XmlSkipS(enc, tem),- end - enc->minBytesPerChar*2);- if (!data)- return 0;- normalizeLines(data);- processingInstructionHandler(handlerArg, target, data);- poolClear(&tempPool);- return 1;-}--static int-reportComment(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end)-{- XML_Char *data;- if (!commentHandler) {- if (defaultHandler)- reportDefault(parser, enc, start, end);- return 1;- }- data = poolStoreString(&tempPool,- enc,- start + enc->minBytesPerChar * 4,- end - enc->minBytesPerChar * 3);- if (!data)- return 0;- normalizeLines(data);- commentHandler(handlerArg, data);- poolClear(&tempPool);- return 1;-}--static void-reportDefault(XML_Parser parser, const ENCODING *enc,- const char *s, const char *end)-{- if (MUST_CONVERT(enc, s)) {- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- do {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);- *eventEndPP = s;- defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));- *eventPP = s;- } while (s != end);- }- else- defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));-}---static int-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,- XML_Bool isId, const XML_Char *value, XML_Parser parser)-{- DEFAULT_ATTRIBUTE *att;- if (value || isId) {- /* The handling of default attributes gets messed up if we have- a default which duplicates a non-default. */- int i;- for (i = 0; i < type->nDefaultAtts; i++)- if (attId == type->defaultAtts[i].id)- return 1;- if (isId && !type->idAtt && !attId->xmlns)- type->idAtt = attId;- }- if (type->nDefaultAtts == type->allocDefaultAtts) {- if (type->allocDefaultAtts == 0) {- type->allocDefaultAtts = 8;- type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts- * sizeof(DEFAULT_ATTRIBUTE));- if (!type->defaultAtts)- return 0;- }- else {- DEFAULT_ATTRIBUTE *temp;- int count = type->allocDefaultAtts * 2;- temp = (DEFAULT_ATTRIBUTE *)- REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));- if (temp == NULL)- return 0;- type->allocDefaultAtts = count;- type->defaultAtts = temp;- }- }- att = type->defaultAtts + type->nDefaultAtts;- att->id = attId;- att->value = value;- att->isCdata = isCdata;- if (!isCdata)- attId->maybeTokenized = XML_TRUE;- type->nDefaultAtts += 1;- return 1;-}--static int-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)-{- DTD * const dtd = _dtd; /* save one level of indirection */- const XML_Char *name;- for (name = elementType->name; *name; name++) {- if (*name == XML_T(ASCII_COLON)) {- PREFIX *prefix;- const XML_Char *s;- for (s = elementType->name; s != name; s++) {- if (!poolAppendChar(&dtd->pool, *s))- return 0;- }- if (!poolAppendChar(&dtd->pool, XML_T('\0')))- return 0;- prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),- sizeof(PREFIX));- if (!prefix)- return 0;- if (prefix->name == poolStart(&dtd->pool))- poolFinish(&dtd->pool);- else- poolDiscard(&dtd->pool);- elementType->prefix = prefix;-- }- }- return 1;-}--static ATTRIBUTE_ID *-getAttributeId(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end)-{- DTD * const dtd = _dtd; /* save one level of indirection */- ATTRIBUTE_ID *id;- const XML_Char *name;- if (!poolAppendChar(&dtd->pool, XML_T('\0')))- return NULL;- name = poolStoreString(&dtd->pool, enc, start, end);- if (!name)- return NULL;- /* skip quotation mark - its storage will be re-used (like in name[-1]) */- ++name;- id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));- if (!id)- return NULL;- if (id->name != name)- poolDiscard(&dtd->pool);- else {- poolFinish(&dtd->pool);- if (!ns)- ;- else if (name[0] == XML_T(ASCII_x)- && name[1] == XML_T(ASCII_m)- && name[2] == XML_T(ASCII_l)- && name[3] == XML_T(ASCII_n)- && name[4] == XML_T(ASCII_s)- && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {- if (name[5] == XML_T('\0'))- id->prefix = &dtd->defaultPrefix;- else- id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));- id->xmlns = XML_TRUE;- }- else {- int i;- for (i = 0; name[i]; i++) {- /* attributes without prefix are *not* in the default namespace */- if (name[i] == XML_T(ASCII_COLON)) {- int j;- for (j = 0; j < i; j++) {- if (!poolAppendChar(&dtd->pool, name[j]))- return NULL;- }- if (!poolAppendChar(&dtd->pool, XML_T('\0')))- return NULL;- id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),- sizeof(PREFIX));- if (id->prefix->name == poolStart(&dtd->pool))- poolFinish(&dtd->pool);- else- poolDiscard(&dtd->pool);- break;- }- }- }- }- return id;-}--#define CONTEXT_SEP XML_T(ASCII_FF)--static const XML_Char *-getContext(XML_Parser parser)-{- DTD * const dtd = _dtd; /* save one level of indirection */- HASH_TABLE_ITER iter;- XML_Bool needSep = XML_FALSE;-- if (dtd->defaultPrefix.binding) {- int i;- int len;- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))- return NULL;- len = dtd->defaultPrefix.binding->uriLen;- if (namespaceSeparator)- len--;- for (i = 0; i < len; i++)- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))- return NULL;- needSep = XML_TRUE;- }-- hashTableIterInit(&iter, &(dtd->prefixes));- for (;;) {- int i;- int len;- const XML_Char *s;- PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);- if (!prefix)- break;- if (!prefix->binding)- continue;- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))- return NULL;- for (s = prefix->name; *s; s++)- if (!poolAppendChar(&tempPool, *s))- return NULL;- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))- return NULL;- len = prefix->binding->uriLen;- if (namespaceSeparator)- len--;- for (i = 0; i < len; i++)- if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))- return NULL;- needSep = XML_TRUE;- }--- hashTableIterInit(&iter, &(dtd->generalEntities));- for (;;) {- const XML_Char *s;- ENTITY *e = (ENTITY *)hashTableIterNext(&iter);- if (!e)- break;- if (!e->open)- continue;- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))- return NULL;- for (s = e->name; *s; s++)- if (!poolAppendChar(&tempPool, *s))- return 0;- needSep = XML_TRUE;- }-- if (!poolAppendChar(&tempPool, XML_T('\0')))- return NULL;- return tempPool.start;-}--static XML_Bool-setContext(XML_Parser parser, const XML_Char *context)-{- DTD * const dtd = _dtd; /* save one level of indirection */- const XML_Char *s = context;-- while (*context != XML_T('\0')) {- if (*s == CONTEXT_SEP || *s == XML_T('\0')) {- ENTITY *e;- if (!poolAppendChar(&tempPool, XML_T('\0')))- return XML_FALSE;- e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);- if (e)- e->open = XML_TRUE;- if (*s != XML_T('\0'))- s++;- context = s;- poolDiscard(&tempPool);- }- else if (*s == XML_T(ASCII_EQUALS)) {- PREFIX *prefix;- if (poolLength(&tempPool) == 0)- prefix = &dtd->defaultPrefix;- else {- if (!poolAppendChar(&tempPool, XML_T('\0')))- return XML_FALSE;- prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),- sizeof(PREFIX));- if (!prefix)- return XML_FALSE;- if (prefix->name == poolStart(&tempPool)) {- prefix->name = poolCopyString(&dtd->pool, prefix->name);- if (!prefix->name)- return XML_FALSE;- }- poolDiscard(&tempPool);- }- for (context = s + 1;- *context != CONTEXT_SEP && *context != XML_T('\0');- context++)- if (!poolAppendChar(&tempPool, *context))- return XML_FALSE;- if (!poolAppendChar(&tempPool, XML_T('\0')))- return XML_FALSE;- if (addBinding(parser, prefix, NULL, poolStart(&tempPool),- &inheritedBindings) != XML_ERROR_NONE)- return XML_FALSE;- poolDiscard(&tempPool);- if (*context != XML_T('\0'))- ++context;- s = context;- }- else {- if (!poolAppendChar(&tempPool, *s))- return XML_FALSE;- s++;- }- }- return XML_TRUE;-}--static void FASTCALL-normalizePublicId(XML_Char *publicId)-{- XML_Char *p = publicId;- XML_Char *s;- for (s = publicId; *s; s++) {- switch (*s) {- case 0x20:- case 0xD:- case 0xA:- if (p != publicId && p[-1] != 0x20)- *p++ = 0x20;- break;- default:- *p++ = *s;- }- }- if (p != publicId && p[-1] == 0x20)- --p;- *p = XML_T('\0');-}--static DTD *-dtdCreate(const XML_Memory_Handling_Suite *ms)-{- DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));- if (p == NULL)- return p;- poolInit(&(p->pool), ms);- poolInit(&(p->entityValuePool), ms);- hashTableInit(&(p->generalEntities), ms);- hashTableInit(&(p->elementTypes), ms);- hashTableInit(&(p->attributeIds), ms);- hashTableInit(&(p->prefixes), ms);-#ifdef XML_DTD- p->paramEntityRead = XML_FALSE;- hashTableInit(&(p->paramEntities), ms);-#endif /* XML_DTD */- p->defaultPrefix.name = NULL;- p->defaultPrefix.binding = NULL;-- p->in_eldecl = XML_FALSE;- p->scaffIndex = NULL;- p->scaffold = NULL;- p->scaffLevel = 0;- p->scaffSize = 0;- p->scaffCount = 0;- p->contentStringLen = 0;-- p->keepProcessing = XML_TRUE;- p->hasParamEntityRefs = XML_FALSE;- p->standalone = XML_FALSE;- return p;-}--static void-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)-{- HASH_TABLE_ITER iter;- hashTableIterInit(&iter, &(p->elementTypes));- for (;;) {- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);- if (!e)- break;- if (e->allocDefaultAtts != 0)- ms->free_fcn(e->defaultAtts);- }- hashTableClear(&(p->generalEntities));-#ifdef XML_DTD- p->paramEntityRead = XML_FALSE;- hashTableClear(&(p->paramEntities));-#endif /* XML_DTD */- hashTableClear(&(p->elementTypes));- hashTableClear(&(p->attributeIds));- hashTableClear(&(p->prefixes));- poolClear(&(p->pool));- poolClear(&(p->entityValuePool));- p->defaultPrefix.name = NULL;- p->defaultPrefix.binding = NULL;-- p->in_eldecl = XML_FALSE;-- ms->free_fcn(p->scaffIndex);- p->scaffIndex = NULL;- ms->free_fcn(p->scaffold);- p->scaffold = NULL;-- p->scaffLevel = 0;- p->scaffSize = 0;- p->scaffCount = 0;- p->contentStringLen = 0;-- p->keepProcessing = XML_TRUE;- p->hasParamEntityRefs = XML_FALSE;- p->standalone = XML_FALSE;-}--static void-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)-{- HASH_TABLE_ITER iter;- hashTableIterInit(&iter, &(p->elementTypes));- for (;;) {- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);- if (!e)- break;- if (e->allocDefaultAtts != 0)- ms->free_fcn(e->defaultAtts);- }- hashTableDestroy(&(p->generalEntities));-#ifdef XML_DTD- hashTableDestroy(&(p->paramEntities));-#endif /* XML_DTD */- hashTableDestroy(&(p->elementTypes));- hashTableDestroy(&(p->attributeIds));- hashTableDestroy(&(p->prefixes));- poolDestroy(&(p->pool));- poolDestroy(&(p->entityValuePool));- if (isDocEntity) {- ms->free_fcn(p->scaffIndex);- ms->free_fcn(p->scaffold);- }- ms->free_fcn(p);-}--/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.- The new DTD has already been initialized.-*/-static int-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)-{- HASH_TABLE_ITER iter;-- /* Copy the prefix table. */-- hashTableIterInit(&iter, &(oldDtd->prefixes));- for (;;) {- const XML_Char *name;- const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);- if (!oldP)- break;- name = poolCopyString(&(newDtd->pool), oldP->name);- if (!name)- return 0;- if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))- return 0;- }-- hashTableIterInit(&iter, &(oldDtd->attributeIds));-- /* Copy the attribute id table. */-- for (;;) {- ATTRIBUTE_ID *newA;- const XML_Char *name;- const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);-- if (!oldA)- break;- /* Remember to allocate the scratch byte before the name. */- if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))- return 0;- name = poolCopyString(&(newDtd->pool), oldA->name);- if (!name)- return 0;- ++name;- newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,- sizeof(ATTRIBUTE_ID));- if (!newA)- return 0;- newA->maybeTokenized = oldA->maybeTokenized;- if (oldA->prefix) {- newA->xmlns = oldA->xmlns;- if (oldA->prefix == &oldDtd->defaultPrefix)- newA->prefix = &newDtd->defaultPrefix;- else- newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),- oldA->prefix->name, 0);- }- }-- /* Copy the element type table. */-- hashTableIterInit(&iter, &(oldDtd->elementTypes));-- for (;;) {- int i;- ELEMENT_TYPE *newE;- const XML_Char *name;- const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);- if (!oldE)- break;- name = poolCopyString(&(newDtd->pool), oldE->name);- if (!name)- return 0;- newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,- sizeof(ELEMENT_TYPE));- if (!newE)- return 0;- if (oldE->nDefaultAtts) {- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)- ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));- if (!newE->defaultAtts) {- ms->free_fcn(newE);- return 0;- }- }- if (oldE->idAtt)- newE->idAtt = (ATTRIBUTE_ID *)- lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;- if (oldE->prefix)- newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),- oldE->prefix->name, 0);- for (i = 0; i < newE->nDefaultAtts; i++) {- newE->defaultAtts[i].id = (ATTRIBUTE_ID *)- lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);- newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;- if (oldE->defaultAtts[i].value) {- newE->defaultAtts[i].value- = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);- if (!newE->defaultAtts[i].value)- return 0;- }- else- newE->defaultAtts[i].value = NULL;- }- }-- /* Copy the entity tables. */- if (!copyEntityTable(&(newDtd->generalEntities),- &(newDtd->pool),- &(oldDtd->generalEntities)))- return 0;--#ifdef XML_DTD- if (!copyEntityTable(&(newDtd->paramEntities),- &(newDtd->pool),- &(oldDtd->paramEntities)))- return 0;- newDtd->paramEntityRead = oldDtd->paramEntityRead;-#endif /* XML_DTD */-- newDtd->keepProcessing = oldDtd->keepProcessing;- newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;- newDtd->standalone = oldDtd->standalone;-- /* Don't want deep copying for scaffolding */- newDtd->in_eldecl = oldDtd->in_eldecl;- newDtd->scaffold = oldDtd->scaffold;- newDtd->contentStringLen = oldDtd->contentStringLen;- newDtd->scaffSize = oldDtd->scaffSize;- newDtd->scaffLevel = oldDtd->scaffLevel;- newDtd->scaffIndex = oldDtd->scaffIndex;-- return 1;-} /* End dtdCopy */--static int-copyEntityTable(HASH_TABLE *newTable,- STRING_POOL *newPool,- const HASH_TABLE *oldTable)-{- HASH_TABLE_ITER iter;- const XML_Char *cachedOldBase = NULL;- const XML_Char *cachedNewBase = NULL;-- hashTableIterInit(&iter, oldTable);-- for (;;) {- ENTITY *newE;- const XML_Char *name;- const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);- if (!oldE)- break;- name = poolCopyString(newPool, oldE->name);- if (!name)- return 0;- newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));- if (!newE)- return 0;- if (oldE->systemId) {- const XML_Char *tem = poolCopyString(newPool, oldE->systemId);- if (!tem)- return 0;- newE->systemId = tem;- if (oldE->base) {- if (oldE->base == cachedOldBase)- newE->base = cachedNewBase;- else {- cachedOldBase = oldE->base;- tem = poolCopyString(newPool, cachedOldBase);- if (!tem)- return 0;- cachedNewBase = newE->base = tem;- }- }- if (oldE->publicId) {- tem = poolCopyString(newPool, oldE->publicId);- if (!tem)- return 0;- newE->publicId = tem;- }- }- else {- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,- oldE->textLen);- if (!tem)- return 0;- newE->textPtr = tem;- newE->textLen = oldE->textLen;- }- if (oldE->notation) {- const XML_Char *tem = poolCopyString(newPool, oldE->notation);- if (!tem)- return 0;- newE->notation = tem;- }- newE->is_param = oldE->is_param;- newE->is_internal = oldE->is_internal;- }- return 1;-}--#define INIT_POWER 6--static XML_Bool FASTCALL-keyeq(KEY s1, KEY s2)-{- for (; *s1 == *s2; s1++, s2++)- if (*s1 == 0)- return XML_TRUE;- return XML_FALSE;-}--static unsigned long FASTCALL-hash(KEY s)-{- unsigned long h = 0;- while (*s)- h = CHAR_HASH(h, *s++);- return h;-}--static NAMED *-lookup(HASH_TABLE *table, KEY name, size_t createSize)-{- size_t i;- if (table->size == 0) {- size_t tsize;- if (!createSize)- return NULL;- table->power = INIT_POWER;- /* table->size is a power of 2 */- table->size = (size_t)1 << INIT_POWER;- tsize = table->size * sizeof(NAMED *);- table->v = (NAMED **)table->mem->malloc_fcn(tsize);- if (!table->v) {- table->size = 0;- return NULL;- }- memset(table->v, 0, tsize);- i = hash(name) & ((unsigned long)table->size - 1);- }- else {- unsigned long h = hash(name);- unsigned long mask = (unsigned long)table->size - 1;- unsigned char step = 0;- i = h & mask;- while (table->v[i]) {- if (keyeq(name, table->v[i]->name))- return table->v[i];- if (!step)- step = PROBE_STEP(h, mask, table->power);- i < step ? (i += table->size - step) : (i -= step);- }- if (!createSize)- return NULL;-- /* check for overflow (table is half full) */- if (table->used >> (table->power - 1)) {- unsigned char newPower = table->power + 1;- size_t newSize = (size_t)1 << newPower;- unsigned long newMask = (unsigned long)newSize - 1;- size_t tsize = newSize * sizeof(NAMED *);- NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);- if (!newV)- return NULL;- memset(newV, 0, tsize);- for (i = 0; i < table->size; i++)- if (table->v[i]) {- unsigned long newHash = hash(table->v[i]->name);- size_t j = newHash & newMask;- step = 0;- while (newV[j]) {- if (!step)- step = PROBE_STEP(newHash, newMask, newPower);- j < step ? (j += newSize - step) : (j -= step);- }- newV[j] = table->v[i];- }- table->mem->free_fcn(table->v);- table->v = newV;- table->power = newPower;- table->size = newSize;- i = h & newMask;- step = 0;- while (table->v[i]) {- if (!step)- step = PROBE_STEP(h, newMask, newPower);- i < step ? (i += newSize - step) : (i -= step);- }- }- }- table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);- if (!table->v[i])- return NULL;- memset(table->v[i], 0, createSize);- table->v[i]->name = name;- (table->used)++;- return table->v[i];-}--static void FASTCALL-hashTableClear(HASH_TABLE *table)-{- size_t i;- for (i = 0; i < table->size; i++) {- table->mem->free_fcn(table->v[i]);- table->v[i] = NULL;- }- table->used = 0;-}--static void FASTCALL-hashTableDestroy(HASH_TABLE *table)-{- size_t i;- for (i = 0; i < table->size; i++)- table->mem->free_fcn(table->v[i]);- table->mem->free_fcn(table->v);-}--static void FASTCALL-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)-{- p->power = 0;- p->size = 0;- p->used = 0;- p->v = NULL;- p->mem = ms;-}--static void FASTCALL-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)-{- iter->p = table->v;- iter->end = iter->p + table->size;-}--static NAMED * FASTCALL-hashTableIterNext(HASH_TABLE_ITER *iter)-{- while (iter->p != iter->end) {- NAMED *tem = *(iter->p)++;- if (tem)- return tem;- }- return NULL;-}--static void FASTCALL-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)-{- pool->blocks = NULL;- pool->freeBlocks = NULL;- pool->start = NULL;- pool->ptr = NULL;- pool->end = NULL;- pool->mem = ms;-}--static void FASTCALL-poolClear(STRING_POOL *pool)-{- if (!pool->freeBlocks)- pool->freeBlocks = pool->blocks;- else {- BLOCK *p = pool->blocks;- while (p) {- BLOCK *tem = p->next;- p->next = pool->freeBlocks;- pool->freeBlocks = p;- p = tem;- }- }- pool->blocks = NULL;- pool->start = NULL;- pool->ptr = NULL;- pool->end = NULL;-}--static void FASTCALL-poolDestroy(STRING_POOL *pool)-{- BLOCK *p = pool->blocks;- while (p) {- BLOCK *tem = p->next;- pool->mem->free_fcn(p);- p = tem;- }- p = pool->freeBlocks;- while (p) {- BLOCK *tem = p->next;- pool->mem->free_fcn(p);- p = tem;- }-}--static XML_Char *-poolAppend(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end)-{- if (!pool->ptr && !poolGrow(pool))- return NULL;- for (;;) {- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);- if (ptr == end)- break;- if (!poolGrow(pool))- return NULL;- }- return pool->start;-}--static const XML_Char * FASTCALL-poolCopyString(STRING_POOL *pool, const XML_Char *s)-{- do {- if (!poolAppendChar(pool, *s))- return NULL;- } while (*s++);- s = pool->start;- poolFinish(pool);- return s;-}--static const XML_Char *-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)-{- if (!pool->ptr && !poolGrow(pool))- return NULL;- for (; n > 0; --n, s++) {- if (!poolAppendChar(pool, *s))- return NULL;- }- s = pool->start;- poolFinish(pool);- return s;-}--static const XML_Char * FASTCALL-poolAppendString(STRING_POOL *pool, const XML_Char *s)-{- while (*s) {- if (!poolAppendChar(pool, *s))- return NULL;- s++;- }- return pool->start;-}--static XML_Char *-poolStoreString(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end)-{- if (!poolAppend(pool, enc, ptr, end))- return NULL;- if (pool->ptr == pool->end && !poolGrow(pool))- return NULL;- *(pool->ptr)++ = 0;- return pool->start;-}--static XML_Bool FASTCALL-poolGrow(STRING_POOL *pool)-{- if (pool->freeBlocks) {- if (pool->start == 0) {- pool->blocks = pool->freeBlocks;- pool->freeBlocks = pool->freeBlocks->next;- pool->blocks->next = NULL;- pool->start = pool->blocks->s;- pool->end = pool->start + pool->blocks->size;- pool->ptr = pool->start;- return XML_TRUE;- }- if (pool->end - pool->start < pool->freeBlocks->size) {- BLOCK *tem = pool->freeBlocks->next;- pool->freeBlocks->next = pool->blocks;- pool->blocks = pool->freeBlocks;- pool->freeBlocks = tem;- memcpy(pool->blocks->s, pool->start,- (pool->end - pool->start) * sizeof(XML_Char));- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);- pool->start = pool->blocks->s;- pool->end = pool->start + pool->blocks->size;- return XML_TRUE;- }- }- if (pool->blocks && pool->start == pool->blocks->s) {- int blockSize = (int)(pool->end - pool->start)*2;- pool->blocks = (BLOCK *)- pool->mem->realloc_fcn(pool->blocks,- (offsetof(BLOCK, s)- + blockSize * sizeof(XML_Char)));- if (pool->blocks == NULL)- return XML_FALSE;- pool->blocks->size = blockSize;- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);- pool->start = pool->blocks->s;- pool->end = pool->start + blockSize;- }- else {- BLOCK *tem;- int blockSize = (int)(pool->end - pool->start);- if (blockSize < INIT_BLOCK_SIZE)- blockSize = INIT_BLOCK_SIZE;- else- blockSize *= 2;- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)- + blockSize * sizeof(XML_Char));- if (!tem)- return XML_FALSE;- tem->size = blockSize;- tem->next = pool->blocks;- pool->blocks = tem;- if (pool->ptr != pool->start)- memcpy(tem->s, pool->start,- (pool->ptr - pool->start) * sizeof(XML_Char));- pool->ptr = tem->s + (pool->ptr - pool->start);- pool->start = tem->s;- pool->end = tem->s + blockSize;- }- return XML_TRUE;-}--static int FASTCALL-nextScaffoldPart(XML_Parser parser)-{- DTD * const dtd = _dtd; /* save one level of indirection */- CONTENT_SCAFFOLD * me;- int next;-- if (!dtd->scaffIndex) {- dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));- if (!dtd->scaffIndex)- return -1;- dtd->scaffIndex[0] = 0;- }-- if (dtd->scaffCount >= dtd->scaffSize) {- CONTENT_SCAFFOLD *temp;- if (dtd->scaffold) {- temp = (CONTENT_SCAFFOLD *)- REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));- if (temp == NULL)- return -1;- dtd->scaffSize *= 2;- }- else {- temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS- * sizeof(CONTENT_SCAFFOLD));- if (temp == NULL)- return -1;- dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;- }- dtd->scaffold = temp;- }- next = dtd->scaffCount++;- me = &dtd->scaffold[next];- if (dtd->scaffLevel) {- CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];- if (parent->lastchild) {- dtd->scaffold[parent->lastchild].nextsib = next;- }- if (!parent->childcnt)- parent->firstchild = next;- parent->lastchild = next;- parent->childcnt++;- }- me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;- return next;-}--static void-build_node(XML_Parser parser,- int src_node,- XML_Content *dest,- XML_Content **contpos,- XML_Char **strpos)-{- DTD * const dtd = _dtd; /* save one level of indirection */- dest->type = dtd->scaffold[src_node].type;- dest->quant = dtd->scaffold[src_node].quant;- if (dest->type == XML_CTYPE_NAME) {- const XML_Char *src;- dest->name = *strpos;- src = dtd->scaffold[src_node].name;- for (;;) {- *(*strpos)++ = *src;- if (!*src)- break;- src++;- }- dest->numchildren = 0;- dest->children = NULL;- }- else {- unsigned int i;- int cn;- dest->numchildren = dtd->scaffold[src_node].childcnt;- dest->children = *contpos;- *contpos += dest->numchildren;- for (i = 0, cn = dtd->scaffold[src_node].firstchild;- i < dest->numchildren;- i++, cn = dtd->scaffold[cn].nextsib) {- build_node(parser, cn, &(dest->children[i]), contpos, strpos);- }- dest->name = NULL;- }-}--static XML_Content *-build_model (XML_Parser parser)-{- DTD * const dtd = _dtd; /* save one level of indirection */- XML_Content *ret;- XML_Content *cpos;- XML_Char * str;- int allocsize = (dtd->scaffCount * sizeof(XML_Content)- + (dtd->contentStringLen * sizeof(XML_Char)));-- ret = (XML_Content *)MALLOC(allocsize);- if (!ret)- return NULL;-- str = (XML_Char *) (&ret[dtd->scaffCount]);- cpos = &ret[1];-- build_node(parser, 0, ret, &cpos, &str);- return ret;-}--static ELEMENT_TYPE *-getElementType(XML_Parser parser,- const ENCODING *enc,- const char *ptr,- const char *end)-{- DTD * const dtd = _dtd; /* save one level of indirection */- const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);- ELEMENT_TYPE *ret;-- if (!name)- return NULL;- ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));++ 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)+*/++#define _GNU_SOURCE /* syscall prototype */++#include <stddef.h>+#include <string.h> /* memset(), memcpy() */+#include <assert.h>+#include <limits.h> /* UINT_MAX */+#include <stdio.h> /* fprintf */+#include <stdlib.h> /* getenv */++#ifdef _WIN32+#define getpid GetCurrentProcessId+#else+#include <sys/time.h> /* gettimeofday() */+#include <sys/types.h> /* getpid() */+#include <unistd.h> /* getpid() */+#endif++#define XML_BUILDING_EXPAT 1++#ifdef _WIN32+#include "winconfig.h"+#elif defined(HAVE_EXPAT_CONFIG_H)+#include <expat_config.h>+#endif /* ndef _WIN32 */++#include "ascii.h"+#include "expat.h"+#include "siphash.h"++#ifdef XML_UNICODE+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX+#define XmlConvert XmlUtf16Convert+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS+#define XmlEncode XmlUtf16Encode+/* Using pointer subtraction to convert to integer type. */+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))+typedef unsigned short ICHAR;+#else+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX+#define XmlConvert XmlUtf8Convert+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS+#define XmlEncode XmlUtf8Encode+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)+typedef char ICHAR;+#endif+++#ifndef XML_NS++#define XmlInitEncodingNS XmlInitEncoding+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding+#undef XmlGetInternalEncodingNS+#define XmlGetInternalEncodingNS XmlGetInternalEncoding+#define XmlParseXmlDeclNS XmlParseXmlDecl++#endif++#ifdef XML_UNICODE++#ifdef XML_UNICODE_WCHAR_T+#define XML_T(x) (const wchar_t)x+#define XML_L(x) L ## x+#else+#define XML_T(x) (const unsigned short)x+#define XML_L(x) x+#endif++#else++#define XML_T(x) x+#define XML_L(x) x++#endif++/* Round up n to be a multiple of sz, where sz is a power of 2. */+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))++/* Handle the case where memmove() doesn't exist. */+#ifndef HAVE_MEMMOVE+#ifdef HAVE_BCOPY+#define memmove(d,s,l) bcopy((s),(d),(l))+#else+#error memmove does not exist on this platform, nor is a substitute available+#endif /* HAVE_BCOPY */+#endif /* HAVE_MEMMOVE */++#include "internal.h"+#include "xmltok.h"+#include "xmlrole.h"++typedef const XML_Char *KEY;++typedef struct {+ KEY name;+} NAMED;++typedef struct {+ NAMED **v;+ unsigned char power;+ size_t size;+ size_t used;+ const XML_Memory_Handling_Suite *mem;+} HASH_TABLE;++static size_t+keylen(KEY s);++static void+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);++/* For probing (after a collision) we need a step size relative prime+ to the hash table size, which is a power of 2. We use double-hashing,+ since we can calculate a second hash value cheaply by taking those bits+ of the first hash value that were discarded (masked out) when the table+ index was calculated: index = hash & mask, where mask = table->size - 1.+ We limit the maximum step size to table->size / 4 (mask >> 2) and make+ it odd, since odd numbers are always relative prime to a power of 2.+*/+#define SECOND_HASH(hash, mask, power) \+ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))+#define PROBE_STEP(hash, mask, power) \+ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))++typedef struct {+ NAMED **p;+ NAMED **end;+} HASH_TABLE_ITER;++#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */+#define INIT_DATA_BUF_SIZE 1024+#define INIT_ATTS_SIZE 16+#define INIT_ATTS_VERSION 0xFFFFFFFF+#define INIT_BLOCK_SIZE 1024+#define INIT_BUFFER_SIZE 1024++#define EXPAND_SPARE 24++typedef struct binding {+ struct prefix *prefix;+ struct binding *nextTagBinding;+ struct binding *prevPrefixBinding;+ const struct attribute_id *attId;+ XML_Char *uri;+ int uriLen;+ int uriAlloc;+} BINDING;++typedef struct prefix {+ const XML_Char *name;+ BINDING *binding;+} PREFIX;++typedef struct {+ const XML_Char *str;+ const XML_Char *localPart;+ const XML_Char *prefix;+ int strLen;+ int uriLen;+ int prefixLen;+} TAG_NAME;++/* TAG represents an open element.+ The name of the element is stored in both the document and API+ encodings. The memory buffer 'buf' is a separately-allocated+ memory area which stores the name. During the XML_Parse()/+ XMLParseBuffer() when the element is open, the memory for the 'raw'+ version of the name (in the document encoding) is shared with the+ document buffer. If the element is open across calls to+ XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to+ contain the 'raw' name as well.++ A parser re-uses these structures, maintaining a list of allocated+ TAG objects in a free list.+*/+typedef struct tag {+ struct tag *parent; /* parent of this element */+ const char *rawName; /* tagName in the original encoding */+ int rawNameLength;+ TAG_NAME name; /* tagName in the API encoding */+ char *buf; /* buffer for name components */+ char *bufEnd; /* end of the buffer */+ BINDING *bindings;+} TAG;++typedef struct {+ const XML_Char *name;+ const XML_Char *textPtr;+ int textLen; /* length in XML_Chars */+ int processed; /* # of processed bytes - when suspended */+ const XML_Char *systemId;+ const XML_Char *base;+ const XML_Char *publicId;+ const XML_Char *notation;+ XML_Bool open;+ XML_Bool is_param;+ XML_Bool is_internal; /* true if declared in internal subset outside PE */+} ENTITY;++typedef struct {+ enum XML_Content_Type type;+ enum XML_Content_Quant quant;+ const XML_Char * name;+ int firstchild;+ int lastchild;+ int childcnt;+ int nextsib;+} CONTENT_SCAFFOLD;++#define INIT_SCAFFOLD_ELEMENTS 32++typedef struct block {+ struct block *next;+ int size;+ XML_Char s[1];+} BLOCK;++typedef struct {+ BLOCK *blocks;+ BLOCK *freeBlocks;+ const XML_Char *end;+ XML_Char *ptr;+ XML_Char *start;+ const XML_Memory_Handling_Suite *mem;+} STRING_POOL;++/* The XML_Char before the name is used to determine whether+ an attribute has been specified. */+typedef struct attribute_id {+ XML_Char *name;+ PREFIX *prefix;+ XML_Bool maybeTokenized;+ XML_Bool xmlns;+} ATTRIBUTE_ID;++typedef struct {+ const ATTRIBUTE_ID *id;+ XML_Bool isCdata;+ const XML_Char *value;+} DEFAULT_ATTRIBUTE;++typedef struct {+ unsigned long version;+ unsigned long hash;+ const XML_Char *uriName;+} NS_ATT;++typedef struct {+ const XML_Char *name;+ PREFIX *prefix;+ const ATTRIBUTE_ID *idAtt;+ int nDefaultAtts;+ int allocDefaultAtts;+ DEFAULT_ATTRIBUTE *defaultAtts;+} ELEMENT_TYPE;++typedef struct {+ HASH_TABLE generalEntities;+ HASH_TABLE elementTypes;+ HASH_TABLE attributeIds;+ HASH_TABLE prefixes;+ STRING_POOL pool;+ STRING_POOL entityValuePool;+ /* false once a parameter entity reference has been skipped */+ XML_Bool keepProcessing;+ /* true once an internal or external PE reference has been encountered;+ this includes the reference to an external subset */+ XML_Bool hasParamEntityRefs;+ XML_Bool standalone;+#ifdef XML_DTD+ /* indicates if external PE has been read */+ XML_Bool paramEntityRead;+ HASH_TABLE paramEntities;+#endif /* XML_DTD */+ PREFIX defaultPrefix;+ /* === scaffolding for building content model === */+ XML_Bool in_eldecl;+ CONTENT_SCAFFOLD *scaffold;+ unsigned contentStringLen;+ unsigned scaffSize;+ unsigned scaffCount;+ int scaffLevel;+ int *scaffIndex;+} DTD;++typedef struct open_internal_entity {+ const char *internalEventPtr;+ const char *internalEventEndPtr;+ struct open_internal_entity *next;+ ENTITY *entity;+ int startTagLevel;+ XML_Bool betweenDecl; /* WFC: PE Between Declarations */+} OPEN_INTERNAL_ENTITY;++typedef enum XML_Error PTRCALL Processor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr);++static Processor prologProcessor;+static Processor prologInitProcessor;+static Processor contentProcessor;+static Processor cdataSectionProcessor;+#ifdef XML_DTD+static Processor ignoreSectionProcessor;+static Processor externalParEntProcessor;+static Processor externalParEntInitProcessor;+static Processor entityValueProcessor;+static Processor entityValueInitProcessor;+#endif /* XML_DTD */+static Processor epilogProcessor;+static Processor errorProcessor;+static Processor externalEntityInitProcessor;+static Processor externalEntityInitProcessor2;+static Processor externalEntityInitProcessor3;+static Processor externalEntityContentProcessor;+static Processor internalEntityProcessor;++static enum XML_Error+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);+static enum XML_Error+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,+ const char *s, const char *next);+static enum XML_Error+initializeEncoding(XML_Parser parser);+static enum XML_Error+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,+ const char *end, int tok, const char *next, const char **nextPtr,+ XML_Bool haveMore);+static enum XML_Error+processInternalEntity(XML_Parser parser, ENTITY *entity,+ XML_Bool betweenDecl);+static enum XML_Error+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,+ const char *start, const char *end, const char **endPtr,+ XML_Bool haveMore);+static enum XML_Error+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,+ const char *end, const char **nextPtr, XML_Bool haveMore);+#ifdef XML_DTD+static enum XML_Error+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,+ const char *end, const char **nextPtr, XML_Bool haveMore);+#endif /* XML_DTD */++static void+freeBindings(XML_Parser parser, BINDING *bindings);+static enum XML_Error+storeAtts(XML_Parser parser, const ENCODING *, const char *s,+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr);+static enum XML_Error+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,+ const XML_Char *uri, BINDING **bindingsPtr);+static int+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,+ XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);+static enum XML_Error+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,+ const char *, const char *, STRING_POOL *);+static enum XML_Error+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,+ const char *, const char *, STRING_POOL *);+static ATTRIBUTE_ID *+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);+static int+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);+static enum XML_Error+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);+static int+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end);+static int+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);+static void+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);++static const XML_Char * getContext(XML_Parser parser);+static XML_Bool+setContext(XML_Parser parser, const XML_Char *context);++static void FASTCALL normalizePublicId(XML_Char *s);++static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);+/* do not call if parentParser != NULL */+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);+static void+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);+static int+dtdCopy(XML_Parser oldParser,+ DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);+static int+copyEntityTable(XML_Parser oldParser,+ HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);+static NAMED *+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);+static void FASTCALL+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);+static void FASTCALL hashTableClear(HASH_TABLE *);+static void FASTCALL hashTableDestroy(HASH_TABLE *);+static void FASTCALL+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);++static void FASTCALL+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);+static void FASTCALL poolClear(STRING_POOL *);+static void FASTCALL poolDestroy(STRING_POOL *);+static XML_Char *+poolAppend(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end);+static XML_Char *+poolStoreString(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end);+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);+static const XML_Char * FASTCALL+poolCopyString(STRING_POOL *pool, const XML_Char *s);+static const XML_Char *+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);+static const XML_Char * FASTCALL+poolAppendString(STRING_POOL *pool, const XML_Char *s);++static int FASTCALL nextScaffoldPart(XML_Parser parser);+static XML_Content * build_model(XML_Parser parser);+static ELEMENT_TYPE *+getElementType(XML_Parser parser, const ENCODING *enc,+ const char *ptr, const char *end);++static unsigned long generate_hash_secret_salt(XML_Parser parser);+static XML_Bool startParsing(XML_Parser parser);++static XML_Parser+parserCreate(const XML_Char *encodingName,+ const XML_Memory_Handling_Suite *memsuite,+ const XML_Char *nameSep,+ DTD *dtd);++static void+parserInit(XML_Parser parser, const XML_Char *encodingName);++#define poolStart(pool) ((pool)->start)+#define poolEnd(pool) ((pool)->ptr)+#define poolLength(pool) ((pool)->ptr - (pool)->start)+#define poolChop(pool) ((void)--(pool->ptr))+#define poolLastChar(pool) (((pool)->ptr)[-1])+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)+#define poolFinish(pool) ((pool)->start = (pool)->ptr)+#define poolAppendChar(pool, c) \+ (((pool)->ptr == (pool)->end && !poolGrow(pool)) \+ ? 0 \+ : ((*((pool)->ptr)++ = c), 1))++struct XML_ParserStruct {+ /* The first member must be userData so that the XML_GetUserData+ macro works. */+ void *m_userData;+ void *m_handlerArg;+ char *m_buffer;+ const XML_Memory_Handling_Suite m_mem;+ /* first character to be parsed */+ const char *m_bufferPtr;+ /* past last character to be parsed */+ char *m_bufferEnd;+ /* allocated end of buffer */+ const char *m_bufferLim;+ XML_Index m_parseEndByteIndex;+ const char *m_parseEndPtr;+ XML_Char *m_dataBuf;+ XML_Char *m_dataBufEnd;+ XML_StartElementHandler m_startElementHandler;+ XML_EndElementHandler m_endElementHandler;+ XML_CharacterDataHandler m_characterDataHandler;+ XML_ProcessingInstructionHandler m_processingInstructionHandler;+ XML_CommentHandler m_commentHandler;+ XML_StartCdataSectionHandler m_startCdataSectionHandler;+ XML_EndCdataSectionHandler m_endCdataSectionHandler;+ XML_DefaultHandler m_defaultHandler;+ XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;+ XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;+ XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;+ XML_NotationDeclHandler m_notationDeclHandler;+ XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;+ XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;+ XML_NotStandaloneHandler m_notStandaloneHandler;+ XML_ExternalEntityRefHandler m_externalEntityRefHandler;+ XML_Parser m_externalEntityRefHandlerArg;+ XML_SkippedEntityHandler m_skippedEntityHandler;+ XML_UnknownEncodingHandler m_unknownEncodingHandler;+ XML_ElementDeclHandler m_elementDeclHandler;+ XML_AttlistDeclHandler m_attlistDeclHandler;+ XML_EntityDeclHandler m_entityDeclHandler;+ XML_XmlDeclHandler m_xmlDeclHandler;+ const ENCODING *m_encoding;+ INIT_ENCODING m_initEncoding;+ const ENCODING *m_internalEncoding;+ const XML_Char *m_protocolEncodingName;+ XML_Bool m_ns;+ XML_Bool m_ns_triplets;+ void *m_unknownEncodingMem;+ void *m_unknownEncodingData;+ void *m_unknownEncodingHandlerData;+ void (XMLCALL *m_unknownEncodingRelease)(void *);+ PROLOG_STATE m_prologState;+ Processor *m_processor;+ enum XML_Error m_errorCode;+ const char *m_eventPtr;+ const char *m_eventEndPtr;+ const char *m_positionPtr;+ OPEN_INTERNAL_ENTITY *m_openInternalEntities;+ OPEN_INTERNAL_ENTITY *m_freeInternalEntities;+ XML_Bool m_defaultExpandInternalEntities;+ int m_tagLevel;+ ENTITY *m_declEntity;+ const XML_Char *m_doctypeName;+ const XML_Char *m_doctypeSysid;+ const XML_Char *m_doctypePubid;+ const XML_Char *m_declAttributeType;+ const XML_Char *m_declNotationName;+ const XML_Char *m_declNotationPublicId;+ ELEMENT_TYPE *m_declElementType;+ ATTRIBUTE_ID *m_declAttributeId;+ XML_Bool m_declAttributeIsCdata;+ XML_Bool m_declAttributeIsId;+ DTD *m_dtd;+ const XML_Char *m_curBase;+ TAG *m_tagStack;+ TAG *m_freeTagList;+ BINDING *m_inheritedBindings;+ BINDING *m_freeBindingList;+ int m_attsSize;+ int m_nSpecifiedAtts;+ int m_idAttIndex;+ ATTRIBUTE *m_atts;+ NS_ATT *m_nsAtts;+ unsigned long m_nsAttsVersion;+ unsigned char m_nsAttsPower;+#ifdef XML_ATTR_INFO+ XML_AttrInfo *m_attInfo;+#endif+ POSITION m_position;+ STRING_POOL m_tempPool;+ STRING_POOL m_temp2Pool;+ char *m_groupConnector;+ unsigned int m_groupSize;+ XML_Char m_namespaceSeparator;+ XML_Parser m_parentParser;+ XML_ParsingStatus m_parsingStatus;+#ifdef XML_DTD+ XML_Bool m_isParamEntity;+ XML_Bool m_useForeignDTD;+ enum XML_ParamEntityParsing m_paramEntityParsing;+#endif+ unsigned long m_hash_secret_salt;+};++#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))+#define FREE(p) (parser->m_mem.free_fcn((p)))++#define userData (parser->m_userData)+#define handlerArg (parser->m_handlerArg)+#define startElementHandler (parser->m_startElementHandler)+#define endElementHandler (parser->m_endElementHandler)+#define characterDataHandler (parser->m_characterDataHandler)+#define processingInstructionHandler \+ (parser->m_processingInstructionHandler)+#define commentHandler (parser->m_commentHandler)+#define startCdataSectionHandler \+ (parser->m_startCdataSectionHandler)+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)+#define defaultHandler (parser->m_defaultHandler)+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)+#define unparsedEntityDeclHandler \+ (parser->m_unparsedEntityDeclHandler)+#define notationDeclHandler (parser->m_notationDeclHandler)+#define startNamespaceDeclHandler \+ (parser->m_startNamespaceDeclHandler)+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)+#define notStandaloneHandler (parser->m_notStandaloneHandler)+#define externalEntityRefHandler \+ (parser->m_externalEntityRefHandler)+#define externalEntityRefHandlerArg \+ (parser->m_externalEntityRefHandlerArg)+#define internalEntityRefHandler \+ (parser->m_internalEntityRefHandler)+#define skippedEntityHandler (parser->m_skippedEntityHandler)+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)+#define elementDeclHandler (parser->m_elementDeclHandler)+#define attlistDeclHandler (parser->m_attlistDeclHandler)+#define entityDeclHandler (parser->m_entityDeclHandler)+#define xmlDeclHandler (parser->m_xmlDeclHandler)+#define encoding (parser->m_encoding)+#define initEncoding (parser->m_initEncoding)+#define internalEncoding (parser->m_internalEncoding)+#define unknownEncodingMem (parser->m_unknownEncodingMem)+#define unknownEncodingData (parser->m_unknownEncodingData)+#define unknownEncodingHandlerData \+ (parser->m_unknownEncodingHandlerData)+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)+#define protocolEncodingName (parser->m_protocolEncodingName)+#define ns (parser->m_ns)+#define ns_triplets (parser->m_ns_triplets)+#define prologState (parser->m_prologState)+#define processor (parser->m_processor)+#define errorCode (parser->m_errorCode)+#define eventPtr (parser->m_eventPtr)+#define eventEndPtr (parser->m_eventEndPtr)+#define positionPtr (parser->m_positionPtr)+#define position (parser->m_position)+#define openInternalEntities (parser->m_openInternalEntities)+#define freeInternalEntities (parser->m_freeInternalEntities)+#define defaultExpandInternalEntities \+ (parser->m_defaultExpandInternalEntities)+#define tagLevel (parser->m_tagLevel)+#define buffer (parser->m_buffer)+#define bufferPtr (parser->m_bufferPtr)+#define bufferEnd (parser->m_bufferEnd)+#define parseEndByteIndex (parser->m_parseEndByteIndex)+#define parseEndPtr (parser->m_parseEndPtr)+#define bufferLim (parser->m_bufferLim)+#define dataBuf (parser->m_dataBuf)+#define dataBufEnd (parser->m_dataBufEnd)+#define _dtd (parser->m_dtd)+#define curBase (parser->m_curBase)+#define declEntity (parser->m_declEntity)+#define doctypeName (parser->m_doctypeName)+#define doctypeSysid (parser->m_doctypeSysid)+#define doctypePubid (parser->m_doctypePubid)+#define declAttributeType (parser->m_declAttributeType)+#define declNotationName (parser->m_declNotationName)+#define declNotationPublicId (parser->m_declNotationPublicId)+#define declElementType (parser->m_declElementType)+#define declAttributeId (parser->m_declAttributeId)+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)+#define declAttributeIsId (parser->m_declAttributeIsId)+#define freeTagList (parser->m_freeTagList)+#define freeBindingList (parser->m_freeBindingList)+#define inheritedBindings (parser->m_inheritedBindings)+#define tagStack (parser->m_tagStack)+#define atts (parser->m_atts)+#define attsSize (parser->m_attsSize)+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)+#define idAttIndex (parser->m_idAttIndex)+#define nsAtts (parser->m_nsAtts)+#define nsAttsVersion (parser->m_nsAttsVersion)+#define nsAttsPower (parser->m_nsAttsPower)+#define attInfo (parser->m_attInfo)+#define tempPool (parser->m_tempPool)+#define temp2Pool (parser->m_temp2Pool)+#define groupConnector (parser->m_groupConnector)+#define groupSize (parser->m_groupSize)+#define namespaceSeparator (parser->m_namespaceSeparator)+#define parentParser (parser->m_parentParser)+#define ps_parsing (parser->m_parsingStatus.parsing)+#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)+#ifdef XML_DTD+#define isParamEntity (parser->m_isParamEntity)+#define useForeignDTD (parser->m_useForeignDTD)+#define paramEntityParsing (parser->m_paramEntityParsing)+#endif /* XML_DTD */+#define hash_secret_salt (parser->m_hash_secret_salt)++XML_Parser XMLCALL+XML_ParserCreate(const XML_Char *encodingName)+{+ return XML_ParserCreate_MM(encodingName, NULL, NULL);+}++XML_Parser XMLCALL+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)+{+ XML_Char tmp[2];+ *tmp = nsSep;+ return XML_ParserCreate_MM(encodingName, NULL, tmp);+}++static const XML_Char implicitContext[] = {+ ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,+ ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,+ ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,+ ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,+ ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,+ ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'+};+++#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)+# include <errno.h>++# if defined(HAVE_GETRANDOM)+# include <sys/random.h> /* getrandom */+# else+# include <unistd.h> /* syscall */+# include <sys/syscall.h> /* SYS_getrandom */+# endif++/* Obtain entropy on Linux 3.17+ */+static int+writeRandomBytes_getrandom(void * target, size_t count) {+ int success = 0; /* full count bytes written? */+ size_t bytesWrittenTotal = 0;+ const unsigned int getrandomFlags = 0;++ do {+ void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);+ const size_t bytesToWrite = count - bytesWrittenTotal;++ const int bytesWrittenMore =+#if defined(HAVE_GETRANDOM)+ getrandom(currentTarget, bytesToWrite, getrandomFlags);+#else+ syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);+#endif++ if (bytesWrittenMore > 0) {+ bytesWrittenTotal += bytesWrittenMore;+ if (bytesWrittenTotal >= count)+ success = 1;+ }+ } while (! success && (errno == EINTR || errno == EAGAIN));++ return success;+}++#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */+++#ifdef _WIN32++typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);++/* Obtain entropy on Windows XP / Windows Server 2003 and later.+ * Hint on RtlGenRandom and the following article from libsodioum.+ *+ * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI+ * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/+ */+static int+writeRandomBytes_RtlGenRandom(void * target, size_t count) {+ int success = 0; /* full count bytes written? */+ const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");++ if (advapi32) {+ const RTLGENRANDOM_FUNC RtlGenRandom+ = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");+ if (RtlGenRandom) {+ if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {+ success = 1;+ }+ }+ FreeLibrary(advapi32);+ }++ return success;+}++#endif /* _WIN32 */+++static unsigned long+gather_time_entropy(void)+{+#ifdef _WIN32+ FILETIME ft;+ GetSystemTimeAsFileTime(&ft); /* never fails */+ return ft.dwHighDateTime ^ ft.dwLowDateTime;+#else+ struct timeval tv;+ int gettimeofday_res;++ gettimeofday_res = gettimeofday(&tv, NULL);+ assert (gettimeofday_res == 0);++ /* Microseconds time is <20 bits entropy */+ return tv.tv_usec;+#endif+}++#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)+# include <bsd/stdlib.h>+#endif++static unsigned long+ENTROPY_DEBUG(const char * label, unsigned long entropy) {+ const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");+ if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {+ fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",+ label,+ (int)sizeof(entropy) * 2, entropy,+ (unsigned long)sizeof(entropy));+ }+ return entropy;+}++static unsigned long+generate_hash_secret_salt(XML_Parser parser)+{+ unsigned long entropy;+ (void)parser;+#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)+ (void)gather_time_entropy;+ arc4random_buf(&entropy, sizeof(entropy));+ return ENTROPY_DEBUG("arc4random_buf", entropy);+#else+ /* Try high quality providers first .. */+#ifdef _WIN32+ if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {+ return ENTROPY_DEBUG("RtlGenRandom", entropy);+ }+#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)+ if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {+ return ENTROPY_DEBUG("getrandom", entropy);+ }+#endif+ /* .. and self-made low quality for backup: */++ /* Process ID is 0 bits entropy if attacker has local access */+ entropy = gather_time_entropy() ^ getpid();++ /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */+ if (sizeof(unsigned long) == 4) {+ return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);+ } else {+ return ENTROPY_DEBUG("fallback(8)",+ entropy * (unsigned long)2305843009213693951);+ }+#endif+}++static unsigned long+get_hash_secret_salt(XML_Parser parser) {+ if (parser->m_parentParser != NULL)+ return get_hash_secret_salt(parser->m_parentParser);+ return parser->m_hash_secret_salt;+}++static XML_Bool /* only valid for root parser */+startParsing(XML_Parser parser)+{+ /* hash functions must be initialized before setContext() is called */+ if (hash_secret_salt == 0)+ hash_secret_salt = generate_hash_secret_salt(parser);+ if (ns) {+ /* implicit context only set for root parser, since child+ parsers (i.e. external entity parsers) will inherit it+ */+ return setContext(parser, implicitContext);+ }+ return XML_TRUE;+}++XML_Parser XMLCALL+XML_ParserCreate_MM(const XML_Char *encodingName,+ const XML_Memory_Handling_Suite *memsuite,+ const XML_Char *nameSep)+{+ return parserCreate(encodingName, memsuite, nameSep, NULL);+}++static XML_Parser+parserCreate(const XML_Char *encodingName,+ const XML_Memory_Handling_Suite *memsuite,+ const XML_Char *nameSep,+ DTD *dtd)+{+ XML_Parser parser;++ if (memsuite) {+ XML_Memory_Handling_Suite *mtemp;+ parser = (XML_Parser)+ memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));+ if (parser != NULL) {+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);+ mtemp->malloc_fcn = memsuite->malloc_fcn;+ mtemp->realloc_fcn = memsuite->realloc_fcn;+ mtemp->free_fcn = memsuite->free_fcn;+ }+ }+ else {+ XML_Memory_Handling_Suite *mtemp;+ parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));+ if (parser != NULL) {+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);+ mtemp->malloc_fcn = malloc;+ mtemp->realloc_fcn = realloc;+ mtemp->free_fcn = free;+ }+ }++ if (!parser)+ return parser;++ buffer = NULL;+ bufferLim = NULL;++ attsSize = INIT_ATTS_SIZE;+ atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));+ if (atts == NULL) {+ FREE(parser);+ return NULL;+ }+#ifdef XML_ATTR_INFO+ attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));+ if (attInfo == NULL) {+ FREE(atts);+ FREE(parser);+ return NULL;+ }+#endif+ dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));+ if (dataBuf == NULL) {+ FREE(atts);+#ifdef XML_ATTR_INFO+ FREE(attInfo);+#endif+ FREE(parser);+ return NULL;+ }+ dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;++ if (dtd)+ _dtd = dtd;+ else {+ _dtd = dtdCreate(&parser->m_mem);+ if (_dtd == NULL) {+ FREE(dataBuf);+ FREE(atts);+#ifdef XML_ATTR_INFO+ FREE(attInfo);+#endif+ FREE(parser);+ return NULL;+ }+ }++ freeBindingList = NULL;+ freeTagList = NULL;+ freeInternalEntities = NULL;++ groupSize = 0;+ groupConnector = NULL;++ unknownEncodingHandler = NULL;+ unknownEncodingHandlerData = NULL;++ namespaceSeparator = ASCII_EXCL;+ ns = XML_FALSE;+ ns_triplets = XML_FALSE;++ nsAtts = NULL;+ nsAttsVersion = 0;+ nsAttsPower = 0;++ poolInit(&tempPool, &(parser->m_mem));+ poolInit(&temp2Pool, &(parser->m_mem));+ parserInit(parser, encodingName);++ if (encodingName && !protocolEncodingName) {+ XML_ParserFree(parser);+ return NULL;+ }++ if (nameSep) {+ ns = XML_TRUE;+ internalEncoding = XmlGetInternalEncodingNS();+ namespaceSeparator = *nameSep;+ }+ else {+ internalEncoding = XmlGetInternalEncoding();+ }++ return parser;+}++static void+parserInit(XML_Parser parser, const XML_Char *encodingName)+{+ processor = prologInitProcessor;+ XmlPrologStateInit(&prologState);+ protocolEncodingName = (encodingName != NULL+ ? poolCopyString(&tempPool, encodingName)+ : NULL);+ curBase = NULL;+ XmlInitEncoding(&initEncoding, &encoding, 0);+ userData = NULL;+ handlerArg = NULL;+ startElementHandler = NULL;+ endElementHandler = NULL;+ characterDataHandler = NULL;+ processingInstructionHandler = NULL;+ commentHandler = NULL;+ startCdataSectionHandler = NULL;+ endCdataSectionHandler = NULL;+ defaultHandler = NULL;+ startDoctypeDeclHandler = NULL;+ endDoctypeDeclHandler = NULL;+ unparsedEntityDeclHandler = NULL;+ notationDeclHandler = NULL;+ startNamespaceDeclHandler = NULL;+ endNamespaceDeclHandler = NULL;+ notStandaloneHandler = NULL;+ externalEntityRefHandler = NULL;+ externalEntityRefHandlerArg = parser;+ skippedEntityHandler = NULL;+ elementDeclHandler = NULL;+ attlistDeclHandler = NULL;+ entityDeclHandler = NULL;+ xmlDeclHandler = NULL;+ bufferPtr = buffer;+ bufferEnd = buffer;+ parseEndByteIndex = 0;+ parseEndPtr = NULL;+ declElementType = NULL;+ declAttributeId = NULL;+ declEntity = NULL;+ doctypeName = NULL;+ doctypeSysid = NULL;+ doctypePubid = NULL;+ declAttributeType = NULL;+ declNotationName = NULL;+ declNotationPublicId = NULL;+ declAttributeIsCdata = XML_FALSE;+ declAttributeIsId = XML_FALSE;+ memset(&position, 0, sizeof(POSITION));+ errorCode = XML_ERROR_NONE;+ eventPtr = NULL;+ eventEndPtr = NULL;+ positionPtr = NULL;+ openInternalEntities = NULL;+ defaultExpandInternalEntities = XML_TRUE;+ tagLevel = 0;+ tagStack = NULL;+ inheritedBindings = NULL;+ nSpecifiedAtts = 0;+ unknownEncodingMem = NULL;+ unknownEncodingRelease = NULL;+ unknownEncodingData = NULL;+ parentParser = NULL;+ ps_parsing = XML_INITIALIZED;+#ifdef XML_DTD+ isParamEntity = XML_FALSE;+ useForeignDTD = XML_FALSE;+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;+#endif+ hash_secret_salt = 0;+}++/* moves list of bindings to freeBindingList */+static void FASTCALL+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)+{+ while (bindings) {+ BINDING *b = bindings;+ bindings = bindings->nextTagBinding;+ b->nextTagBinding = freeBindingList;+ freeBindingList = b;+ }+}++XML_Bool XMLCALL+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)+{+ TAG *tStk;+ OPEN_INTERNAL_ENTITY *openEntityList;++ if (parser == NULL)+ return XML_FALSE;++ if (parentParser)+ return XML_FALSE;+ /* move tagStack to freeTagList */+ tStk = tagStack;+ while (tStk) {+ TAG *tag = tStk;+ tStk = tStk->parent;+ tag->parent = freeTagList;+ moveToFreeBindingList(parser, tag->bindings);+ tag->bindings = NULL;+ freeTagList = tag;+ }+ /* move openInternalEntities to freeInternalEntities */+ openEntityList = openInternalEntities;+ while (openEntityList) {+ OPEN_INTERNAL_ENTITY *openEntity = openEntityList;+ openEntityList = openEntity->next;+ openEntity->next = freeInternalEntities;+ freeInternalEntities = openEntity;+ }+ moveToFreeBindingList(parser, inheritedBindings);+ FREE(unknownEncodingMem);+ if (unknownEncodingRelease)+ unknownEncodingRelease(unknownEncodingData);+ poolClear(&tempPool);+ poolClear(&temp2Pool);+ parserInit(parser, encodingName);+ dtdReset(_dtd, &parser->m_mem);+ return XML_TRUE;+}++enum XML_Status XMLCALL+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)+{+ if (parser == NULL)+ return XML_STATUS_ERROR;+ /* Block after XML_Parse()/XML_ParseBuffer() has been called.+ XXX There's no way for the caller to determine which of the+ XXX possible error cases caused the XML_STATUS_ERROR return.+ */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return XML_STATUS_ERROR;+ if (encodingName == NULL)+ protocolEncodingName = NULL;+ else {+ protocolEncodingName = poolCopyString(&tempPool, encodingName);+ if (!protocolEncodingName)+ return XML_STATUS_ERROR;+ }+ return XML_STATUS_OK;+}++XML_Parser XMLCALL+XML_ExternalEntityParserCreate(XML_Parser oldParser,+ const XML_Char *context,+ const XML_Char *encodingName)+{+ XML_Parser parser = oldParser;+ DTD *newDtd = NULL;+ DTD *oldDtd;+ XML_StartElementHandler oldStartElementHandler;+ XML_EndElementHandler oldEndElementHandler;+ XML_CharacterDataHandler oldCharacterDataHandler;+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler;+ XML_CommentHandler oldCommentHandler;+ XML_StartCdataSectionHandler oldStartCdataSectionHandler;+ XML_EndCdataSectionHandler oldEndCdataSectionHandler;+ XML_DefaultHandler oldDefaultHandler;+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;+ XML_NotationDeclHandler oldNotationDeclHandler;+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;+ XML_NotStandaloneHandler oldNotStandaloneHandler;+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler;+ XML_SkippedEntityHandler oldSkippedEntityHandler;+ XML_UnknownEncodingHandler oldUnknownEncodingHandler;+ XML_ElementDeclHandler oldElementDeclHandler;+ XML_AttlistDeclHandler oldAttlistDeclHandler;+ XML_EntityDeclHandler oldEntityDeclHandler;+ XML_XmlDeclHandler oldXmlDeclHandler;+ ELEMENT_TYPE * oldDeclElementType;++ void *oldUserData;+ void *oldHandlerArg;+ XML_Bool oldDefaultExpandInternalEntities;+ XML_Parser oldExternalEntityRefHandlerArg;+#ifdef XML_DTD+ enum XML_ParamEntityParsing oldParamEntityParsing;+ int oldInEntityValue;+#endif+ XML_Bool oldns_triplets;+ /* Note that the new parser shares the same hash secret as the old+ parser, so that dtdCopy and copyEntityTable can lookup values+ from hash tables associated with either parser without us having+ to worry which hash secrets each table has.+ */+ unsigned long oldhash_secret_salt;++ /* Validate the oldParser parameter before we pull everything out of it */+ if (oldParser == NULL)+ return NULL;++ /* Stash the original parser contents on the stack */+ oldDtd = _dtd;+ oldStartElementHandler = startElementHandler;+ oldEndElementHandler = endElementHandler;+ oldCharacterDataHandler = characterDataHandler;+ oldProcessingInstructionHandler = processingInstructionHandler;+ oldCommentHandler = commentHandler;+ oldStartCdataSectionHandler = startCdataSectionHandler;+ oldEndCdataSectionHandler = endCdataSectionHandler;+ oldDefaultHandler = defaultHandler;+ oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;+ oldNotationDeclHandler = notationDeclHandler;+ oldStartNamespaceDeclHandler = startNamespaceDeclHandler;+ oldEndNamespaceDeclHandler = endNamespaceDeclHandler;+ oldNotStandaloneHandler = notStandaloneHandler;+ oldExternalEntityRefHandler = externalEntityRefHandler;+ oldSkippedEntityHandler = skippedEntityHandler;+ oldUnknownEncodingHandler = unknownEncodingHandler;+ oldElementDeclHandler = elementDeclHandler;+ oldAttlistDeclHandler = attlistDeclHandler;+ oldEntityDeclHandler = entityDeclHandler;+ oldXmlDeclHandler = xmlDeclHandler;+ oldDeclElementType = declElementType;++ oldUserData = userData;+ oldHandlerArg = handlerArg;+ oldDefaultExpandInternalEntities = defaultExpandInternalEntities;+ oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;+#ifdef XML_DTD+ oldParamEntityParsing = paramEntityParsing;+ oldInEntityValue = prologState.inEntityValue;+#endif+ oldns_triplets = ns_triplets;+ /* Note that the new parser shares the same hash secret as the old+ parser, so that dtdCopy and copyEntityTable can lookup values+ from hash tables associated with either parser without us having+ to worry which hash secrets each table has.+ */+ oldhash_secret_salt = hash_secret_salt;++#ifdef XML_DTD+ if (!context)+ newDtd = oldDtd;+#endif /* XML_DTD */++ /* Note that the magical uses of the pre-processor to make field+ access look more like C++ require that `parser' be overwritten+ here. This makes this function more painful to follow than it+ would be otherwise.+ */+ if (ns) {+ XML_Char tmp[2];+ *tmp = namespaceSeparator;+ parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);+ }+ else {+ parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);+ }++ if (!parser)+ return NULL;++ startElementHandler = oldStartElementHandler;+ endElementHandler = oldEndElementHandler;+ characterDataHandler = oldCharacterDataHandler;+ processingInstructionHandler = oldProcessingInstructionHandler;+ commentHandler = oldCommentHandler;+ startCdataSectionHandler = oldStartCdataSectionHandler;+ endCdataSectionHandler = oldEndCdataSectionHandler;+ defaultHandler = oldDefaultHandler;+ unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;+ notationDeclHandler = oldNotationDeclHandler;+ startNamespaceDeclHandler = oldStartNamespaceDeclHandler;+ endNamespaceDeclHandler = oldEndNamespaceDeclHandler;+ notStandaloneHandler = oldNotStandaloneHandler;+ externalEntityRefHandler = oldExternalEntityRefHandler;+ skippedEntityHandler = oldSkippedEntityHandler;+ unknownEncodingHandler = oldUnknownEncodingHandler;+ elementDeclHandler = oldElementDeclHandler;+ attlistDeclHandler = oldAttlistDeclHandler;+ entityDeclHandler = oldEntityDeclHandler;+ xmlDeclHandler = oldXmlDeclHandler;+ declElementType = oldDeclElementType;+ userData = oldUserData;+ if (oldUserData == oldHandlerArg)+ handlerArg = userData;+ else+ handlerArg = parser;+ if (oldExternalEntityRefHandlerArg != oldParser)+ externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;+ defaultExpandInternalEntities = oldDefaultExpandInternalEntities;+ ns_triplets = oldns_triplets;+ hash_secret_salt = oldhash_secret_salt;+ parentParser = oldParser;+#ifdef XML_DTD+ paramEntityParsing = oldParamEntityParsing;+ prologState.inEntityValue = oldInEntityValue;+ if (context) {+#endif /* XML_DTD */+ if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)+ || !setContext(parser, context)) {+ XML_ParserFree(parser);+ return NULL;+ }+ processor = externalEntityInitProcessor;+#ifdef XML_DTD+ }+ else {+ /* The DTD instance referenced by _dtd is shared between the document's+ root parser and external PE parsers, therefore one does not need to+ call setContext. In addition, one also *must* not call setContext,+ because this would overwrite existing prefix->binding pointers in+ _dtd with ones that get destroyed with the external PE parser.+ This would leave those prefixes with dangling pointers.+ */+ isParamEntity = XML_TRUE;+ XmlPrologStateInitExternalEntity(&prologState);+ processor = externalParEntInitProcessor;+ }+#endif /* XML_DTD */+ return parser;+}++static void FASTCALL+destroyBindings(BINDING *bindings, XML_Parser parser)+{+ for (;;) {+ BINDING *b = bindings;+ if (!b)+ break;+ bindings = b->nextTagBinding;+ FREE(b->uri);+ FREE(b);+ }+}++void XMLCALL+XML_ParserFree(XML_Parser parser)+{+ TAG *tagList;+ OPEN_INTERNAL_ENTITY *entityList;+ if (parser == NULL)+ return;+ /* free tagStack and freeTagList */+ tagList = tagStack;+ for (;;) {+ TAG *p;+ if (tagList == NULL) {+ if (freeTagList == NULL)+ break;+ tagList = freeTagList;+ freeTagList = NULL;+ }+ p = tagList;+ tagList = tagList->parent;+ FREE(p->buf);+ destroyBindings(p->bindings, parser);+ FREE(p);+ }+ /* free openInternalEntities and freeInternalEntities */+ entityList = openInternalEntities;+ for (;;) {+ OPEN_INTERNAL_ENTITY *openEntity;+ if (entityList == NULL) {+ if (freeInternalEntities == NULL)+ break;+ entityList = freeInternalEntities;+ freeInternalEntities = NULL;+ }+ openEntity = entityList;+ entityList = entityList->next;+ FREE(openEntity);+ }++ destroyBindings(freeBindingList, parser);+ destroyBindings(inheritedBindings, parser);+ poolDestroy(&tempPool);+ poolDestroy(&temp2Pool);+#ifdef XML_DTD+ /* external parameter entity parsers share the DTD structure+ parser->m_dtd with the root parser, so we must not destroy it+ */+ if (!isParamEntity && _dtd)+#else+ if (_dtd)+#endif /* XML_DTD */+ dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);+ FREE((void *)atts);+#ifdef XML_ATTR_INFO+ FREE((void *)attInfo);+#endif+ FREE(groupConnector);+ FREE(buffer);+ FREE(dataBuf);+ FREE(nsAtts);+ FREE(unknownEncodingMem);+ if (unknownEncodingRelease)+ unknownEncodingRelease(unknownEncodingData);+ FREE(parser);+}++void XMLCALL+XML_UseParserAsHandlerArg(XML_Parser parser)+{+ if (parser != NULL)+ handlerArg = parser;+}++enum XML_Error XMLCALL+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)+{+ if (parser == NULL)+ return XML_ERROR_INVALID_ARGUMENT;+#ifdef XML_DTD+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;+ useForeignDTD = useDTD;+ return XML_ERROR_NONE;+#else+ return XML_ERROR_FEATURE_REQUIRES_XML_DTD;+#endif+}++void XMLCALL+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)+{+ if (parser == NULL)+ return;+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return;+ ns_triplets = do_nst ? XML_TRUE : XML_FALSE;+}++void XMLCALL+XML_SetUserData(XML_Parser parser, void *p)+{+ if (parser == NULL)+ return;+ if (handlerArg == userData)+ handlerArg = userData = p;+ else+ userData = p;+}++enum XML_Status XMLCALL+XML_SetBase(XML_Parser parser, const XML_Char *p)+{+ if (parser == NULL)+ return XML_STATUS_ERROR;+ if (p) {+ p = poolCopyString(&_dtd->pool, p);+ if (!p)+ return XML_STATUS_ERROR;+ curBase = p;+ }+ else+ curBase = NULL;+ return XML_STATUS_OK;+}++const XML_Char * XMLCALL+XML_GetBase(XML_Parser parser)+{+ if (parser == NULL)+ return NULL;+ return curBase;+}++int XMLCALL+XML_GetSpecifiedAttributeCount(XML_Parser parser)+{+ if (parser == NULL)+ return -1;+ return nSpecifiedAtts;+}++int XMLCALL+XML_GetIdAttributeIndex(XML_Parser parser)+{+ if (parser == NULL)+ return -1;+ return idAttIndex;+}++#ifdef XML_ATTR_INFO+const XML_AttrInfo * XMLCALL+XML_GetAttributeInfo(XML_Parser parser)+{+ if (parser == NULL)+ return NULL;+ return attInfo;+}+#endif++void XMLCALL+XML_SetElementHandler(XML_Parser parser,+ XML_StartElementHandler start,+ XML_EndElementHandler end)+{+ if (parser == NULL)+ return;+ startElementHandler = start;+ endElementHandler = end;+}++void XMLCALL+XML_SetStartElementHandler(XML_Parser parser,+ XML_StartElementHandler start) {+ if (parser != NULL)+ startElementHandler = start;+}++void XMLCALL+XML_SetEndElementHandler(XML_Parser parser,+ XML_EndElementHandler end) {+ if (parser != NULL)+ endElementHandler = end;+}++void XMLCALL+XML_SetCharacterDataHandler(XML_Parser parser,+ XML_CharacterDataHandler handler)+{+ if (parser != NULL)+ characterDataHandler = handler;+}++void XMLCALL+XML_SetProcessingInstructionHandler(XML_Parser parser,+ XML_ProcessingInstructionHandler handler)+{+ if (parser != NULL)+ processingInstructionHandler = handler;+}++void XMLCALL+XML_SetCommentHandler(XML_Parser parser,+ XML_CommentHandler handler)+{+ if (parser != NULL)+ commentHandler = handler;+}++void XMLCALL+XML_SetCdataSectionHandler(XML_Parser parser,+ XML_StartCdataSectionHandler start,+ XML_EndCdataSectionHandler end)+{+ if (parser == NULL)+ return;+ startCdataSectionHandler = start;+ endCdataSectionHandler = end;+}++void XMLCALL+XML_SetStartCdataSectionHandler(XML_Parser parser,+ XML_StartCdataSectionHandler start) {+ if (parser != NULL)+ startCdataSectionHandler = start;+}++void XMLCALL+XML_SetEndCdataSectionHandler(XML_Parser parser,+ XML_EndCdataSectionHandler end) {+ if (parser != NULL)+ endCdataSectionHandler = end;+}++void XMLCALL+XML_SetDefaultHandler(XML_Parser parser,+ XML_DefaultHandler handler)+{+ if (parser == NULL)+ return;+ defaultHandler = handler;+ defaultExpandInternalEntities = XML_FALSE;+}++void XMLCALL+XML_SetDefaultHandlerExpand(XML_Parser parser,+ XML_DefaultHandler handler)+{+ if (parser == NULL)+ return;+ defaultHandler = handler;+ defaultExpandInternalEntities = XML_TRUE;+}++void XMLCALL+XML_SetDoctypeDeclHandler(XML_Parser parser,+ XML_StartDoctypeDeclHandler start,+ XML_EndDoctypeDeclHandler end)+{+ if (parser == NULL)+ return;+ startDoctypeDeclHandler = start;+ endDoctypeDeclHandler = end;+}++void XMLCALL+XML_SetStartDoctypeDeclHandler(XML_Parser parser,+ XML_StartDoctypeDeclHandler start) {+ if (parser != NULL)+ startDoctypeDeclHandler = start;+}++void XMLCALL+XML_SetEndDoctypeDeclHandler(XML_Parser parser,+ XML_EndDoctypeDeclHandler end) {+ if (parser != NULL)+ endDoctypeDeclHandler = end;+}++void XMLCALL+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,+ XML_UnparsedEntityDeclHandler handler)+{+ if (parser != NULL)+ unparsedEntityDeclHandler = handler;+}++void XMLCALL+XML_SetNotationDeclHandler(XML_Parser parser,+ XML_NotationDeclHandler handler)+{+ if (parser != NULL)+ notationDeclHandler = handler;+}++void XMLCALL+XML_SetNamespaceDeclHandler(XML_Parser parser,+ XML_StartNamespaceDeclHandler start,+ XML_EndNamespaceDeclHandler end)+{+ if (parser == NULL)+ return;+ startNamespaceDeclHandler = start;+ endNamespaceDeclHandler = end;+}++void XMLCALL+XML_SetStartNamespaceDeclHandler(XML_Parser parser,+ XML_StartNamespaceDeclHandler start) {+ if (parser != NULL)+ startNamespaceDeclHandler = start;+}++void XMLCALL+XML_SetEndNamespaceDeclHandler(XML_Parser parser,+ XML_EndNamespaceDeclHandler end) {+ if (parser != NULL)+ endNamespaceDeclHandler = end;+}++void XMLCALL+XML_SetNotStandaloneHandler(XML_Parser parser,+ XML_NotStandaloneHandler handler)+{+ if (parser != NULL)+ notStandaloneHandler = handler;+}++void XMLCALL+XML_SetExternalEntityRefHandler(XML_Parser parser,+ XML_ExternalEntityRefHandler handler)+{+ if (parser != NULL)+ externalEntityRefHandler = handler;+}++void XMLCALL+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)+{+ if (parser == NULL)+ return;+ if (arg)+ externalEntityRefHandlerArg = (XML_Parser)arg;+ else+ externalEntityRefHandlerArg = parser;+}++void XMLCALL+XML_SetSkippedEntityHandler(XML_Parser parser,+ XML_SkippedEntityHandler handler)+{+ if (parser != NULL)+ skippedEntityHandler = handler;+}++void XMLCALL+XML_SetUnknownEncodingHandler(XML_Parser parser,+ XML_UnknownEncodingHandler handler,+ void *data)+{+ if (parser == NULL)+ return;+ unknownEncodingHandler = handler;+ unknownEncodingHandlerData = data;+}++void XMLCALL+XML_SetElementDeclHandler(XML_Parser parser,+ XML_ElementDeclHandler eldecl)+{+ if (parser != NULL)+ elementDeclHandler = eldecl;+}++void XMLCALL+XML_SetAttlistDeclHandler(XML_Parser parser,+ XML_AttlistDeclHandler attdecl)+{+ if (parser != NULL)+ attlistDeclHandler = attdecl;+}++void XMLCALL+XML_SetEntityDeclHandler(XML_Parser parser,+ XML_EntityDeclHandler handler)+{+ if (parser != NULL)+ entityDeclHandler = handler;+}++void XMLCALL+XML_SetXmlDeclHandler(XML_Parser parser,+ XML_XmlDeclHandler handler) {+ if (parser != NULL)+ xmlDeclHandler = handler;+}++int XMLCALL+XML_SetParamEntityParsing(XML_Parser parser,+ enum XML_ParamEntityParsing peParsing)+{+ if (parser == NULL)+ return 0;+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return 0;+#ifdef XML_DTD+ paramEntityParsing = peParsing;+ return 1;+#else+ return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;+#endif+}++int XMLCALL+XML_SetHashSalt(XML_Parser parser,+ unsigned long hash_salt)+{+ if (parser == NULL)+ return 0;+ if (parser->m_parentParser)+ return XML_SetHashSalt(parser->m_parentParser, hash_salt);+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return 0;+ hash_secret_salt = hash_salt;+ return 1;+}++enum XML_Status XMLCALL+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)+{+ if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {+ errorCode = XML_ERROR_INVALID_ARGUMENT;+ return XML_STATUS_ERROR;+ }+ switch (ps_parsing) {+ case XML_SUSPENDED:+ errorCode = XML_ERROR_SUSPENDED;+ return XML_STATUS_ERROR;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return XML_STATUS_ERROR;+ case XML_INITIALIZED:+ if (parentParser == NULL && !startParsing(parser)) {+ errorCode = XML_ERROR_NO_MEMORY;+ return XML_STATUS_ERROR;+ }+ default:+ ps_parsing = XML_PARSING;+ }++ if (len == 0) {+ ps_finalBuffer = (XML_Bool)isFinal;+ if (!isFinal)+ return XML_STATUS_OK;+ positionPtr = bufferPtr;+ parseEndPtr = bufferEnd;++ /* If data are left over from last buffer, and we now know that these+ data are the final chunk of input, then we have to check them again+ to detect errors based on that fact.+ */+ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);++ if (errorCode == XML_ERROR_NONE) {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);+ positionPtr = bufferPtr;+ return XML_STATUS_SUSPENDED;+ case XML_INITIALIZED:+ case XML_PARSING:+ ps_parsing = XML_FINISHED;+ /* fall through */+ default:+ return XML_STATUS_OK;+ }+ }+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+#ifndef XML_CONTEXT_BYTES+ else if (bufferPtr == bufferEnd) {+ const char *end;+ int nLeftOver;+ enum XML_Status result;+ /* Detect overflow (a+b > MAX <==> b > MAX-a) */+ if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {+ errorCode = XML_ERROR_NO_MEMORY;+ eventPtr = eventEndPtr = NULL;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ parseEndByteIndex += len;+ positionPtr = s;+ ps_finalBuffer = (XML_Bool)isFinal;++ errorCode = processor(parser, s, parseEndPtr = s + len, &end);++ if (errorCode != XML_ERROR_NONE) {+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ else {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ result = XML_STATUS_SUSPENDED;+ break;+ case XML_INITIALIZED:+ case XML_PARSING:+ if (isFinal) {+ ps_parsing = XML_FINISHED;+ return XML_STATUS_OK;+ }+ /* fall through */+ default:+ result = XML_STATUS_OK;+ }+ }++ XmlUpdatePosition(encoding, positionPtr, end, &position);+ nLeftOver = s + len - end;+ if (nLeftOver) {+ if (buffer == NULL || nLeftOver > bufferLim - buffer) {+ /* avoid _signed_ integer overflow */+ char *temp = NULL;+ const int bytesToAllocate = (int)((unsigned)len * 2U);+ if (bytesToAllocate > 0) {+ temp = (buffer == NULL+ ? (char *)MALLOC(bytesToAllocate)+ : (char *)REALLOC(buffer, bytesToAllocate));+ }+ if (temp == NULL) {+ errorCode = XML_ERROR_NO_MEMORY;+ eventPtr = eventEndPtr = NULL;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ buffer = temp;+ bufferLim = buffer + bytesToAllocate;+ }+ memcpy(buffer, end, nLeftOver);+ }+ bufferPtr = buffer;+ bufferEnd = buffer + nLeftOver;+ positionPtr = bufferPtr;+ parseEndPtr = bufferEnd;+ eventPtr = bufferPtr;+ eventEndPtr = bufferPtr;+ return result;+ }+#endif /* not defined XML_CONTEXT_BYTES */+ else {+ void *buff = XML_GetBuffer(parser, len);+ if (buff == NULL)+ return XML_STATUS_ERROR;+ else {+ memcpy(buff, s, len);+ return XML_ParseBuffer(parser, len, isFinal);+ }+ }+}++enum XML_Status XMLCALL+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)+{+ const char *start;+ enum XML_Status result = XML_STATUS_OK;++ if (parser == NULL)+ return XML_STATUS_ERROR;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ errorCode = XML_ERROR_SUSPENDED;+ return XML_STATUS_ERROR;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return XML_STATUS_ERROR;+ case XML_INITIALIZED:+ if (parentParser == NULL && !startParsing(parser)) {+ errorCode = XML_ERROR_NO_MEMORY;+ return XML_STATUS_ERROR;+ }+ default:+ ps_parsing = XML_PARSING;+ }++ start = bufferPtr;+ positionPtr = start;+ bufferEnd += len;+ parseEndPtr = bufferEnd;+ parseEndByteIndex += len;+ ps_finalBuffer = (XML_Bool)isFinal;++ errorCode = processor(parser, start, parseEndPtr, &bufferPtr);++ if (errorCode != XML_ERROR_NONE) {+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ else {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ result = XML_STATUS_SUSPENDED;+ break;+ case XML_INITIALIZED:+ case XML_PARSING:+ if (isFinal) {+ ps_parsing = XML_FINISHED;+ return result;+ }+ default: ; /* should not happen */+ }+ }++ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);+ positionPtr = bufferPtr;+ return result;+}++void * XMLCALL+XML_GetBuffer(XML_Parser parser, int len)+{+ if (parser == NULL)+ return NULL;+ if (len < 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+ switch (ps_parsing) {+ case XML_SUSPENDED:+ errorCode = XML_ERROR_SUSPENDED;+ return NULL;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return NULL;+ default: ;+ }++ if (len > bufferLim - bufferEnd) {+#ifdef XML_CONTEXT_BYTES+ int keep;+#endif /* defined XML_CONTEXT_BYTES */+ /* Do not invoke signed arithmetic overflow: */+ int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));+ if (neededSize < 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+#ifdef XML_CONTEXT_BYTES+ keep = (int)(bufferPtr - buffer);+ if (keep > XML_CONTEXT_BYTES)+ keep = XML_CONTEXT_BYTES;+ neededSize += keep;+#endif /* defined XML_CONTEXT_BYTES */+ if (neededSize <= bufferLim - buffer) {+#ifdef XML_CONTEXT_BYTES+ if (keep < bufferPtr - buffer) {+ int offset = (int)(bufferPtr - buffer) - keep;+ memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);+ bufferEnd -= offset;+ bufferPtr -= offset;+ }+#else+ memmove(buffer, bufferPtr, bufferEnd - bufferPtr);+ bufferEnd = buffer + (bufferEnd - bufferPtr);+ bufferPtr = buffer;+#endif /* not defined XML_CONTEXT_BYTES */+ }+ else {+ char *newBuf;+ int bufferSize = (int)(bufferLim - bufferPtr);+ if (bufferSize == 0)+ bufferSize = INIT_BUFFER_SIZE;+ do {+ /* Do not invoke signed arithmetic overflow: */+ bufferSize = (int) (2U * (unsigned) bufferSize);+ } while (bufferSize < neededSize && bufferSize > 0);+ if (bufferSize <= 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+ newBuf = (char *)MALLOC(bufferSize);+ if (newBuf == 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+ bufferLim = newBuf + bufferSize;+#ifdef XML_CONTEXT_BYTES+ if (bufferPtr) {+ int keep = (int)(bufferPtr - buffer);+ if (keep > XML_CONTEXT_BYTES)+ keep = XML_CONTEXT_BYTES;+ memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);+ FREE(buffer);+ buffer = newBuf;+ bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;+ bufferPtr = buffer + keep;+ }+ else {+ bufferEnd = newBuf + (bufferEnd - bufferPtr);+ bufferPtr = buffer = newBuf;+ }+#else+ if (bufferPtr) {+ memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);+ FREE(buffer);+ }+ bufferEnd = newBuf + (bufferEnd - bufferPtr);+ bufferPtr = buffer = newBuf;+#endif /* not defined XML_CONTEXT_BYTES */+ }+ eventPtr = eventEndPtr = NULL;+ positionPtr = NULL;+ }+ return bufferEnd;+}++enum XML_Status XMLCALL+XML_StopParser(XML_Parser parser, XML_Bool resumable)+{+ if (parser == NULL)+ return XML_STATUS_ERROR;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ if (resumable) {+ errorCode = XML_ERROR_SUSPENDED;+ return XML_STATUS_ERROR;+ }+ ps_parsing = XML_FINISHED;+ break;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return XML_STATUS_ERROR;+ default:+ if (resumable) {+#ifdef XML_DTD+ if (isParamEntity) {+ errorCode = XML_ERROR_SUSPEND_PE;+ return XML_STATUS_ERROR;+ }+#endif+ ps_parsing = XML_SUSPENDED;+ }+ else+ ps_parsing = XML_FINISHED;+ }+ return XML_STATUS_OK;+}++enum XML_Status XMLCALL+XML_ResumeParser(XML_Parser parser)+{+ enum XML_Status result = XML_STATUS_OK;++ if (parser == NULL)+ return XML_STATUS_ERROR;+ if (ps_parsing != XML_SUSPENDED) {+ errorCode = XML_ERROR_NOT_SUSPENDED;+ return XML_STATUS_ERROR;+ }+ ps_parsing = XML_PARSING;++ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);++ if (errorCode != XML_ERROR_NONE) {+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ else {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ result = XML_STATUS_SUSPENDED;+ break;+ case XML_INITIALIZED:+ case XML_PARSING:+ if (ps_finalBuffer) {+ ps_parsing = XML_FINISHED;+ return result;+ }+ default: ;+ }+ }++ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);+ positionPtr = bufferPtr;+ return result;+}++void XMLCALL+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)+{+ if (parser == NULL)+ return;+ assert(status != NULL);+ *status = parser->m_parsingStatus;+}++enum XML_Error XMLCALL+XML_GetErrorCode(XML_Parser parser)+{+ if (parser == NULL)+ return XML_ERROR_INVALID_ARGUMENT;+ return errorCode;+}++XML_Index XMLCALL+XML_GetCurrentByteIndex(XML_Parser parser)+{+ if (parser == NULL)+ return -1;+ if (eventPtr)+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));+ return -1;+}++int XMLCALL+XML_GetCurrentByteCount(XML_Parser parser)+{+ if (parser == NULL)+ return 0;+ if (eventEndPtr && eventPtr)+ return (int)(eventEndPtr - eventPtr);+ return 0;+}++const char * XMLCALL+XML_GetInputContext(XML_Parser parser, int *offset, int *size)+{+#ifdef XML_CONTEXT_BYTES+ if (parser == NULL)+ return NULL;+ if (eventPtr && buffer) {+ if (offset != NULL)+ *offset = (int)(eventPtr - buffer);+ if (size != NULL)+ *size = (int)(bufferEnd - buffer);+ return buffer;+ }+#else+ (void)parser;+ (void)offset;+ (void)size;+#endif /* defined XML_CONTEXT_BYTES */+ return (char *) 0;+}++XML_Size XMLCALL+XML_GetCurrentLineNumber(XML_Parser parser)+{+ if (parser == NULL)+ return 0;+ if (eventPtr && eventPtr >= positionPtr) {+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);+ positionPtr = eventPtr;+ }+ return position.lineNumber + 1;+}++XML_Size XMLCALL+XML_GetCurrentColumnNumber(XML_Parser parser)+{+ if (parser == NULL)+ return 0;+ if (eventPtr && eventPtr >= positionPtr) {+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);+ positionPtr = eventPtr;+ }+ return position.columnNumber;+}++void XMLCALL+XML_FreeContentModel(XML_Parser parser, XML_Content *model)+{+ if (parser != NULL)+ FREE(model);+}++void * XMLCALL+XML_MemMalloc(XML_Parser parser, size_t size)+{+ if (parser == NULL)+ return NULL;+ return MALLOC(size);+}++void * XMLCALL+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)+{+ if (parser == NULL)+ return NULL;+ return REALLOC(ptr, size);+}++void XMLCALL+XML_MemFree(XML_Parser parser, void *ptr)+{+ if (parser != NULL)+ FREE(ptr);+}++void XMLCALL+XML_DefaultCurrent(XML_Parser parser)+{+ if (parser == NULL)+ return;+ if (defaultHandler) {+ if (openInternalEntities)+ reportDefault(parser,+ internalEncoding,+ openInternalEntities->internalEventPtr,+ openInternalEntities->internalEventEndPtr);+ else+ reportDefault(parser, encoding, eventPtr, eventEndPtr);+ }+}++const XML_LChar * XMLCALL+XML_ErrorString(enum XML_Error code)+{+ static const XML_LChar* const message[] = {+ 0,+ XML_L("out of memory"),+ XML_L("syntax error"),+ XML_L("no element found"),+ XML_L("not well-formed (invalid token)"),+ XML_L("unclosed token"),+ XML_L("partial character"),+ XML_L("mismatched tag"),+ XML_L("duplicate attribute"),+ XML_L("junk after document element"),+ XML_L("illegal parameter entity reference"),+ XML_L("undefined entity"),+ XML_L("recursive entity reference"),+ XML_L("asynchronous entity"),+ XML_L("reference to invalid character number"),+ XML_L("reference to binary entity"),+ XML_L("reference to external entity in attribute"),+ XML_L("XML or text declaration not at start of entity"),+ XML_L("unknown encoding"),+ XML_L("encoding specified in XML declaration is incorrect"),+ XML_L("unclosed CDATA section"),+ XML_L("error in processing external entity reference"),+ XML_L("document is not standalone"),+ XML_L("unexpected parser state - please send a bug report"),+ XML_L("entity declared in parameter entity"),+ XML_L("requested feature requires XML_DTD support in Expat"),+ XML_L("cannot change setting once parsing has begun"),+ XML_L("unbound prefix"),+ XML_L("must not undeclare prefix"),+ XML_L("incomplete markup in parameter entity"),+ XML_L("XML declaration not well-formed"),+ XML_L("text declaration not well-formed"),+ XML_L("illegal character(s) in public id"),+ XML_L("parser suspended"),+ XML_L("parser not suspended"),+ XML_L("parsing aborted"),+ XML_L("parsing finished"),+ XML_L("cannot suspend in external parameter entity"),+ XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),+ XML_L("reserved prefix (xmlns) must not be declared or undeclared"),+ XML_L("prefix must not be bound to one of the reserved namespace names")+ };+ if (code > 0 && code < sizeof(message)/sizeof(message[0]))+ return message[code];+ return NULL;+}++const XML_LChar * XMLCALL+XML_ExpatVersion(void) {++ /* V1 is used to string-ize the version number. However, it would+ string-ize the actual version macro *names* unless we get them+ substituted before being passed to V1. CPP is defined to expand+ a macro, then rescan for more expansions. Thus, we use V2 to expand+ the version macros, then CPP will expand the resulting V1() macro+ with the correct numerals. */+ /* ### I'm assuming cpp is portable in this respect... */++#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)++ return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);++#undef V1+#undef V2+}++XML_Expat_Version XMLCALL+XML_ExpatVersionInfo(void)+{+ XML_Expat_Version version;++ version.major = XML_MAJOR_VERSION;+ version.minor = XML_MINOR_VERSION;+ version.micro = XML_MICRO_VERSION;++ return version;+}++const XML_Feature * XMLCALL+XML_GetFeatureList(void)+{+ static const XML_Feature features[] = {+ {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),+ sizeof(XML_Char)},+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),+ sizeof(XML_LChar)},+#ifdef XML_UNICODE+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},+#endif+#ifdef XML_UNICODE_WCHAR_T+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},+#endif+#ifdef XML_DTD+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},+#endif+#ifdef XML_CONTEXT_BYTES+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),+ XML_CONTEXT_BYTES},+#endif+#ifdef XML_MIN_SIZE+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},+#endif+#ifdef XML_NS+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},+#endif+#ifdef XML_LARGE_SIZE+ {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},+#endif+#ifdef XML_ATTR_INFO+ {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},+#endif+ {XML_FEATURE_END, NULL, 0}+ };++ return features;+}++/* Initially tag->rawName always points into the parse buffer;+ for those TAG instances opened while the current parse buffer was+ processed, and not yet closed, we need to store tag->rawName in a more+ permanent location, since the parse buffer is about to be discarded.+*/+static XML_Bool+storeRawNames(XML_Parser parser)+{+ TAG *tag = tagStack;+ while (tag) {+ int bufSize;+ int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);+ char *rawNameBuf = tag->buf + nameLen;+ /* Stop if already stored. Since tagStack is a stack, we can stop+ at the first entry that has already been copied; everything+ below it in the stack is already been accounted for in a+ previous call to this function.+ */+ if (tag->rawName == rawNameBuf)+ break;+ /* For re-use purposes we need to ensure that the+ size of tag->buf is a multiple of sizeof(XML_Char).+ */+ bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));+ if (bufSize > tag->bufEnd - tag->buf) {+ char *temp = (char *)REALLOC(tag->buf, bufSize);+ if (temp == NULL)+ return XML_FALSE;+ /* if tag->name.str points to tag->buf (only when namespace+ processing is off) then we have to update it+ */+ if (tag->name.str == (XML_Char *)tag->buf)+ tag->name.str = (XML_Char *)temp;+ /* if tag->name.localPart is set (when namespace processing is on)+ then update it as well, since it will always point into tag->buf+ */+ if (tag->name.localPart)+ tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -+ (XML_Char *)tag->buf);+ tag->buf = temp;+ tag->bufEnd = temp + bufSize;+ rawNameBuf = temp + nameLen;+ }+ memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);+ tag->rawName = rawNameBuf;+ tag = tag->parent;+ }+ return XML_TRUE;+}++static enum XML_Error PTRCALL+contentProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doContent(parser, 0, encoding, start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result == XML_ERROR_NONE) {+ if (!storeRawNames(parser))+ return XML_ERROR_NO_MEMORY;+ }+ return result;+}++static enum XML_Error PTRCALL+externalEntityInitProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = initializeEncoding(parser);+ if (result != XML_ERROR_NONE)+ return result;+ processor = externalEntityInitProcessor2;+ return externalEntityInitProcessor2(parser, start, end, endPtr);+}++static enum XML_Error PTRCALL+externalEntityInitProcessor2(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ const char *next = start; /* XmlContentTok doesn't always set the last arg */+ int tok = XmlContentTok(encoding, start, end, &next);+ switch (tok) {+ case XML_TOK_BOM:+ /* If we are at the end of the buffer, this would cause the next stage,+ i.e. externalEntityInitProcessor3, to pass control directly to+ doContent (by detecting XML_TOK_NONE) without processing any xml text+ declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.+ */+ if (next == end && !ps_finalBuffer) {+ *endPtr = next;+ return XML_ERROR_NONE;+ }+ start = next;+ break;+ case XML_TOK_PARTIAL:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ eventPtr = start;+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ eventPtr = start;+ return XML_ERROR_PARTIAL_CHAR;+ }+ processor = externalEntityInitProcessor3;+ return externalEntityInitProcessor3(parser, start, end, endPtr);+}++static enum XML_Error PTRCALL+externalEntityInitProcessor3(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ int tok;+ const char *next = start; /* XmlContentTok doesn't always set the last arg */+ eventPtr = start;+ tok = XmlContentTok(encoding, start, end, &next);+ eventEndPtr = next;++ switch (tok) {+ case XML_TOK_XML_DECL:+ {+ enum XML_Error result;+ result = processXmlDecl(parser, 1, start, next);+ if (result != XML_ERROR_NONE)+ return result;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *endPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default:+ start = next;+ }+ }+ break;+ case XML_TOK_PARTIAL:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ }+ processor = externalEntityContentProcessor;+ tagLevel = 1;+ return externalEntityContentProcessor(parser, start, end, endPtr);+}++static enum XML_Error PTRCALL+externalEntityContentProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doContent(parser, 1, encoding, start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result == XML_ERROR_NONE) {+ if (!storeRawNames(parser))+ return XML_ERROR_NO_MEMORY;+ }+ return result;+}++static enum XML_Error+doContent(XML_Parser parser,+ int startTagLevel,+ const ENCODING *enc,+ const char *s,+ const char *end,+ const char **nextPtr,+ XML_Bool haveMore)+{+ /* save one level of indirection */+ DTD * const dtd = _dtd;++ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ *eventPP = s;++ for (;;) {+ const char *next = s; /* XmlContentTok doesn't always set the last arg */+ int tok = XmlContentTok(enc, s, end, &next);+ *eventEndPP = next;+ switch (tok) {+ case XML_TOK_TRAILING_CR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ *eventEndPP = end;+ if (characterDataHandler) {+ XML_Char c = 0xA;+ characterDataHandler(handlerArg, &c, 1);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, end);+ /* We are at the end of the final buffer, should we check for+ XML_SUSPENDED, XML_FINISHED?+ */+ if (startTagLevel == 0)+ return XML_ERROR_NO_ELEMENTS;+ if (tagLevel != startTagLevel)+ return XML_ERROR_ASYNC_ENTITY;+ *nextPtr = end;+ return XML_ERROR_NONE;+ case XML_TOK_NONE:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ if (startTagLevel > 0) {+ if (tagLevel != startTagLevel)+ return XML_ERROR_ASYNC_ENTITY;+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_NO_ELEMENTS;+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_ENTITY_REF:+ {+ const XML_Char *name;+ ENTITY *entity;+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (ch) {+ if (characterDataHandler)+ characterDataHandler(handlerArg, &ch, 1);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ name = poolStoreString(&dtd->pool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);+ poolDiscard(&dtd->pool);+ /* First, determine if a check for an existing declaration is needed;+ if yes, check that the entity exists, and that it is internal,+ otherwise call the skipped entity or default handler.+ */+ if (!dtd->hasParamEntityRefs || dtd->standalone) {+ if (!entity)+ return XML_ERROR_UNDEFINED_ENTITY;+ else if (!entity->is_internal)+ return XML_ERROR_ENTITY_DECLARED_IN_PE;+ }+ else if (!entity) {+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, name, 0);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ if (entity->open)+ return XML_ERROR_RECURSIVE_ENTITY_REF;+ if (entity->notation)+ return XML_ERROR_BINARY_ENTITY_REF;+ if (entity->textPtr) {+ enum XML_Error result;+ if (!defaultExpandInternalEntities) {+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, entity->name, 0);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ result = processInternalEntity(parser, entity, XML_FALSE);+ if (result != XML_ERROR_NONE)+ return result;+ }+ else if (externalEntityRefHandler) {+ const XML_Char *context;+ entity->open = XML_TRUE;+ context = getContext(parser);+ entity->open = XML_FALSE;+ if (!context)+ return XML_ERROR_NO_MEMORY;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ context,+ entity->base,+ entity->systemId,+ entity->publicId))+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ poolDiscard(&tempPool);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ case XML_TOK_START_TAG_NO_ATTS:+ /* fall through */+ case XML_TOK_START_TAG_WITH_ATTS:+ {+ TAG *tag;+ enum XML_Error result;+ XML_Char *toPtr;+ if (freeTagList) {+ tag = freeTagList;+ freeTagList = freeTagList->parent;+ }+ else {+ tag = (TAG *)MALLOC(sizeof(TAG));+ if (!tag)+ return XML_ERROR_NO_MEMORY;+ tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);+ if (!tag->buf) {+ FREE(tag);+ return XML_ERROR_NO_MEMORY;+ }+ tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;+ }+ tag->bindings = NULL;+ tag->parent = tagStack;+ tagStack = tag;+ tag->name.localPart = NULL;+ tag->name.prefix = NULL;+ tag->rawName = s + enc->minBytesPerChar;+ tag->rawNameLength = XmlNameLength(enc, tag->rawName);+ ++tagLevel;+ {+ const char *rawNameEnd = tag->rawName + tag->rawNameLength;+ const char *fromPtr = tag->rawName;+ toPtr = (XML_Char *)tag->buf;+ for (;;) {+ int bufSize;+ int convLen;+ const enum XML_Convert_Result convert_res = XmlConvert(enc,+ &fromPtr, rawNameEnd,+ (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);+ convLen = (int)(toPtr - (XML_Char *)tag->buf);+ if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {+ tag->name.strLen = convLen;+ break;+ }+ bufSize = (int)(tag->bufEnd - tag->buf) << 1;+ {+ char *temp = (char *)REALLOC(tag->buf, bufSize);+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ tag->buf = temp;+ tag->bufEnd = temp + bufSize;+ toPtr = (XML_Char *)temp + convLen;+ }+ }+ }+ tag->name.str = (XML_Char *)tag->buf;+ *toPtr = XML_T('\0');+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));+ if (result)+ return result;+ if (startElementHandler)+ startElementHandler(handlerArg, tag->name.str,+ (const XML_Char **)atts);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ poolClear(&tempPool);+ break;+ }+ case XML_TOK_EMPTY_ELEMENT_NO_ATTS:+ /* fall through */+ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:+ {+ const char *rawName = s + enc->minBytesPerChar;+ enum XML_Error result;+ BINDING *bindings = NULL;+ XML_Bool noElmHandlers = XML_TRUE;+ TAG_NAME name;+ name.str = poolStoreString(&tempPool, enc, rawName,+ rawName + XmlNameLength(enc, rawName));+ if (!name.str)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ result = storeAtts(parser, enc, s, &name, &bindings);+ if (result != XML_ERROR_NONE) {+ freeBindings(parser, bindings);+ return result;+ }+ poolFinish(&tempPool);+ if (startElementHandler) {+ startElementHandler(handlerArg, name.str, (const XML_Char **)atts);+ noElmHandlers = XML_FALSE;+ }+ if (endElementHandler) {+ if (startElementHandler)+ *eventPP = *eventEndPP;+ endElementHandler(handlerArg, name.str);+ noElmHandlers = XML_FALSE;+ }+ if (noElmHandlers && defaultHandler)+ reportDefault(parser, enc, s, next);+ poolClear(&tempPool);+ freeBindings(parser, bindings);+ }+ if (tagLevel == 0)+ return epilogProcessor(parser, next, end, nextPtr);+ break;+ case XML_TOK_END_TAG:+ if (tagLevel == startTagLevel)+ return XML_ERROR_ASYNC_ENTITY;+ else {+ int len;+ const char *rawName;+ TAG *tag = tagStack;+ tagStack = tag->parent;+ tag->parent = freeTagList;+ freeTagList = tag;+ rawName = s + enc->minBytesPerChar*2;+ len = XmlNameLength(enc, rawName);+ if (len != tag->rawNameLength+ || memcmp(tag->rawName, rawName, len) != 0) {+ *eventPP = rawName;+ return XML_ERROR_TAG_MISMATCH;+ }+ --tagLevel;+ if (endElementHandler) {+ const XML_Char *localPart;+ const XML_Char *prefix;+ XML_Char *uri;+ localPart = tag->name.localPart;+ if (ns && localPart) {+ /* localPart and prefix may have been overwritten in+ tag->name.str, since this points to the binding->uri+ buffer which gets re-used; so we have to add them again+ */+ uri = (XML_Char *)tag->name.str + tag->name.uriLen;+ /* don't need to check for space - already done in storeAtts() */+ while (*localPart) *uri++ = *localPart++;+ prefix = (XML_Char *)tag->name.prefix;+ if (ns_triplets && prefix) {+ *uri++ = namespaceSeparator;+ while (*prefix) *uri++ = *prefix++;+ }+ *uri = XML_T('\0');+ }+ endElementHandler(handlerArg, tag->name.str);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ while (tag->bindings) {+ BINDING *b = tag->bindings;+ if (endNamespaceDeclHandler)+ endNamespaceDeclHandler(handlerArg, b->prefix->name);+ tag->bindings = tag->bindings->nextTagBinding;+ b->nextTagBinding = freeBindingList;+ freeBindingList = b;+ b->prefix->binding = b->prevPrefixBinding;+ }+ if (tagLevel == 0)+ return epilogProcessor(parser, next, end, nextPtr);+ }+ break;+ case XML_TOK_CHAR_REF:+ {+ int n = XmlCharRefNumber(enc, s);+ if (n < 0)+ return XML_ERROR_BAD_CHAR_REF;+ if (characterDataHandler) {+ XML_Char buf[XML_ENCODE_MAX];+ characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ }+ break;+ case XML_TOK_XML_DECL:+ return XML_ERROR_MISPLACED_XML_PI;+ case XML_TOK_DATA_NEWLINE:+ if (characterDataHandler) {+ XML_Char c = 0xA;+ characterDataHandler(handlerArg, &c, 1);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ case XML_TOK_CDATA_SECT_OPEN:+ {+ enum XML_Error result;+ if (startCdataSectionHandler)+ startCdataSectionHandler(handlerArg);+#if 0+ /* Suppose you doing a transformation on a document that involves+ changing only the character data. You set up a defaultHandler+ and a characterDataHandler. The defaultHandler simply copies+ characters through. The characterDataHandler does the+ transformation and writes the characters out escaping them as+ necessary. This case will fail to work if we leave out the+ following two lines (because & and < inside CDATA sections will+ be incorrectly escaped).++ However, now we have a start/endCdataSectionHandler, so it seems+ easier to let the user deal with this.+ */+ else if (characterDataHandler)+ characterDataHandler(handlerArg, dataBuf, 0);+#endif+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);+ if (result != XML_ERROR_NONE)+ return result;+ else if (!next) {+ processor = cdataSectionProcessor;+ return result;+ }+ }+ break;+ case XML_TOK_TRAILING_RSQB:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ if (characterDataHandler) {+ if (MUST_CONVERT(enc, s)) {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);+ characterDataHandler(handlerArg, dataBuf,+ (int)(dataPtr - (ICHAR *)dataBuf));+ }+ else+ characterDataHandler(handlerArg,+ (XML_Char *)s,+ (int)((XML_Char *)end - (XML_Char *)s));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, end);+ /* We are at the end of the final buffer, should we check for+ XML_SUSPENDED, XML_FINISHED?+ */+ if (startTagLevel == 0) {+ *eventPP = end;+ return XML_ERROR_NO_ELEMENTS;+ }+ if (tagLevel != startTagLevel) {+ *eventPP = end;+ return XML_ERROR_ASYNC_ENTITY;+ }+ *nextPtr = end;+ return XML_ERROR_NONE;+ case XML_TOK_DATA_CHARS:+ {+ XML_CharacterDataHandler charDataHandler = characterDataHandler;+ if (charDataHandler) {+ if (MUST_CONVERT(enc, s)) {+ for (;;) {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);+ *eventEndPP = s;+ charDataHandler(handlerArg, dataBuf,+ (int)(dataPtr - (ICHAR *)dataBuf));+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))+ break;+ *eventPP = s;+ }+ }+ else+ charDataHandler(handlerArg,+ (XML_Char *)s,+ (int)((XML_Char *)next - (XML_Char *)s));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ }+ break;+ case XML_TOK_PI:+ if (!reportProcessingInstruction(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_COMMENT:+ if (!reportComment(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ default:+ if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ *eventPP = s = next;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default: ;+ }+ }+ /* not reached */+}++/* This function does not call free() on the allocated memory, merely+ * moving it to the parser's freeBindingList where it can be freed or+ * reused as appropriate.+ */+static void+freeBindings(XML_Parser parser, BINDING *bindings)+{+ while (bindings) {+ BINDING *b = bindings;++ /* startNamespaceDeclHandler will have been called for this+ * binding in addBindings(), so call the end handler now.+ */+ if (endNamespaceDeclHandler)+ endNamespaceDeclHandler(handlerArg, b->prefix->name);++ bindings = bindings->nextTagBinding;+ b->nextTagBinding = freeBindingList;+ freeBindingList = b;+ b->prefix->binding = b->prevPrefixBinding;+ }+}++/* Precondition: all arguments must be non-NULL;+ Purpose:+ - normalize attributes+ - check attributes for well-formedness+ - generate namespace aware attribute names (URI, prefix)+ - build list of attributes for startElementHandler+ - default attributes+ - process namespace declarations (check and report them)+ - generate namespace aware element name (URI, prefix)+*/+static enum XML_Error+storeAtts(XML_Parser parser, const ENCODING *enc,+ const char *attStr, TAG_NAME *tagNamePtr,+ BINDING **bindingsPtr)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ ELEMENT_TYPE *elementType;+ int nDefaultAtts;+ const XML_Char **appAtts; /* the attribute list for the application */+ int attIndex = 0;+ int prefixLen;+ int i;+ int n;+ XML_Char *uri;+ int nPrefixes = 0;+ BINDING *binding;+ const XML_Char *localPart;++ /* lookup the element type name */+ elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);+ if (!elementType) {+ const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,+ sizeof(ELEMENT_TYPE));+ if (!elementType)+ return XML_ERROR_NO_MEMORY;+ if (ns && !setElementTypePrefix(parser, elementType))+ return XML_ERROR_NO_MEMORY;+ }+ nDefaultAtts = elementType->nDefaultAtts;++ /* get the attributes from the tokenizer */+ n = XmlGetAttributes(enc, attStr, attsSize, atts);+ if (n + nDefaultAtts > attsSize) {+ int oldAttsSize = attsSize;+ ATTRIBUTE *temp;+#ifdef XML_ATTR_INFO+ XML_AttrInfo *temp2;+#endif+ attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;+ temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ atts = temp;+#ifdef XML_ATTR_INFO+ temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));+ if (temp2 == NULL)+ return XML_ERROR_NO_MEMORY;+ attInfo = temp2;+#endif+ if (n > oldAttsSize)+ XmlGetAttributes(enc, attStr, n, atts);+ }++ appAtts = (const XML_Char **)atts;+ for (i = 0; i < n; i++) {+ ATTRIBUTE *currAtt = &atts[i];+#ifdef XML_ATTR_INFO+ XML_AttrInfo *currAttInfo = &attInfo[i];+#endif+ /* add the name and value to the attribute list */+ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,+ currAtt->name+ + XmlNameLength(enc, currAtt->name));+ if (!attId)+ return XML_ERROR_NO_MEMORY;+#ifdef XML_ATTR_INFO+ currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);+ currAttInfo->nameEnd = currAttInfo->nameStart ++ XmlNameLength(enc, currAtt->name);+ currAttInfo->valueStart = parseEndByteIndex -+ (parseEndPtr - currAtt->valuePtr);+ currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);+#endif+ /* Detect duplicate attributes by their QNames. This does not work when+ namespace processing is turned on and different prefixes for the same+ namespace are used. For this case we have a check further down.+ */+ if ((attId->name)[-1]) {+ if (enc == encoding)+ eventPtr = atts[i].name;+ return XML_ERROR_DUPLICATE_ATTRIBUTE;+ }+ (attId->name)[-1] = 1;+ appAtts[attIndex++] = attId->name;+ if (!atts[i].normalized) {+ enum XML_Error result;+ XML_Bool isCdata = XML_TRUE;++ /* figure out whether declared as other than CDATA */+ if (attId->maybeTokenized) {+ int j;+ for (j = 0; j < nDefaultAtts; j++) {+ if (attId == elementType->defaultAtts[j].id) {+ isCdata = elementType->defaultAtts[j].isCdata;+ break;+ }+ }+ }++ /* normalize the attribute value */+ result = storeAttributeValue(parser, enc, isCdata,+ atts[i].valuePtr, atts[i].valueEnd,+ &tempPool);+ if (result)+ return result;+ appAtts[attIndex] = poolStart(&tempPool);+ poolFinish(&tempPool);+ }+ else {+ /* the value did not need normalizing */+ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,+ atts[i].valueEnd);+ if (appAtts[attIndex] == 0)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ }+ /* handle prefixed attribute names */+ if (attId->prefix) {+ if (attId->xmlns) {+ /* deal with namespace declarations here */+ enum XML_Error result = addBinding(parser, attId->prefix, attId,+ appAtts[attIndex], bindingsPtr);+ if (result)+ return result;+ --attIndex;+ }+ else {+ /* deal with other prefixed names later */+ attIndex++;+ nPrefixes++;+ (attId->name)[-1] = 2;+ }+ }+ else+ attIndex++;+ }++ /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */+ nSpecifiedAtts = attIndex;+ if (elementType->idAtt && (elementType->idAtt->name)[-1]) {+ for (i = 0; i < attIndex; i += 2)+ if (appAtts[i] == elementType->idAtt->name) {+ idAttIndex = i;+ break;+ }+ }+ else+ idAttIndex = -1;++ /* do attribute defaulting */+ for (i = 0; i < nDefaultAtts; i++) {+ const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;+ if (!(da->id->name)[-1] && da->value) {+ if (da->id->prefix) {+ if (da->id->xmlns) {+ enum XML_Error result = addBinding(parser, da->id->prefix, da->id,+ da->value, bindingsPtr);+ if (result)+ return result;+ }+ else {+ (da->id->name)[-1] = 2;+ nPrefixes++;+ appAtts[attIndex++] = da->id->name;+ appAtts[attIndex++] = da->value;+ }+ }+ else {+ (da->id->name)[-1] = 1;+ appAtts[attIndex++] = da->id->name;+ appAtts[attIndex++] = da->value;+ }+ }+ }+ appAtts[attIndex] = 0;++ /* expand prefixed attribute names, check for duplicates,+ and clear flags that say whether attributes were specified */+ i = 0;+ if (nPrefixes) {+ int j; /* hash table index */+ unsigned long version = nsAttsVersion;+ int nsAttsSize = (int)1 << nsAttsPower;+ /* size of hash table must be at least 2 * (# of prefixed attributes) */+ if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */+ NS_ATT *temp;+ /* hash table size must also be a power of 2 and >= 8 */+ while (nPrefixes >> nsAttsPower++);+ if (nsAttsPower < 3)+ nsAttsPower = 3;+ nsAttsSize = (int)1 << nsAttsPower;+ temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));+ if (!temp)+ return XML_ERROR_NO_MEMORY;+ nsAtts = temp;+ version = 0; /* force re-initialization of nsAtts hash table */+ }+ /* using a version flag saves us from initializing nsAtts every time */+ if (!version) { /* initialize version flags when version wraps around */+ version = INIT_ATTS_VERSION;+ for (j = nsAttsSize; j != 0; )+ nsAtts[--j].version = version;+ }+ nsAttsVersion = --version;++ /* expand prefixed names and check for duplicates */+ for (; i < attIndex; i += 2) {+ const XML_Char *s = appAtts[i];+ if (s[-1] == 2) { /* prefixed */+ ATTRIBUTE_ID *id;+ const BINDING *b;+ unsigned long uriHash;+ struct siphash sip_state;+ struct sipkey sip_key;++ copy_salt_to_sipkey(parser, &sip_key);+ sip24_init(&sip_state, &sip_key);++ ((XML_Char *)s)[-1] = 0; /* clear flag */+ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);+ if (!id || !id->prefix)+ return XML_ERROR_NO_MEMORY;+ b = id->prefix->binding;+ if (!b)+ return XML_ERROR_UNBOUND_PREFIX;++ for (j = 0; j < b->uriLen; j++) {+ const XML_Char c = b->uri[j];+ if (!poolAppendChar(&tempPool, c))+ return XML_ERROR_NO_MEMORY;+ }++ sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));++ while (*s++ != XML_T(ASCII_COLON))+ ;++ sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));++ do { /* copies null terminator */+ if (!poolAppendChar(&tempPool, *s))+ return XML_ERROR_NO_MEMORY;+ } while (*s++);++ uriHash = (unsigned long)sip24_final(&sip_state);++ { /* Check hash table for duplicate of expanded name (uriName).+ Derived from code in lookup(parser, HASH_TABLE *table, ...).+ */+ unsigned char step = 0;+ unsigned long mask = nsAttsSize - 1;+ j = uriHash & mask; /* index into hash table */+ while (nsAtts[j].version == version) {+ /* for speed we compare stored hash values first */+ if (uriHash == nsAtts[j].hash) {+ const XML_Char *s1 = poolStart(&tempPool);+ const XML_Char *s2 = nsAtts[j].uriName;+ /* s1 is null terminated, but not s2 */+ for (; *s1 == *s2 && *s1 != 0; s1++, s2++);+ if (*s1 == 0)+ return XML_ERROR_DUPLICATE_ATTRIBUTE;+ }+ if (!step)+ step = PROBE_STEP(uriHash, mask, nsAttsPower);+ j < step ? (j += nsAttsSize - step) : (j -= step);+ }+ }++ if (ns_triplets) { /* append namespace separator and prefix */+ tempPool.ptr[-1] = namespaceSeparator;+ s = b->prefix->name;+ do {+ if (!poolAppendChar(&tempPool, *s))+ return XML_ERROR_NO_MEMORY;+ } while (*s++);+ }++ /* store expanded name in attribute list */+ s = poolStart(&tempPool);+ poolFinish(&tempPool);+ appAtts[i] = s;++ /* fill empty slot with new version, uriName and hash value */+ nsAtts[j].version = version;+ nsAtts[j].hash = uriHash;+ nsAtts[j].uriName = s;++ if (!--nPrefixes) {+ i += 2;+ break;+ }+ }+ else /* not prefixed */+ ((XML_Char *)s)[-1] = 0; /* clear flag */+ }+ }+ /* clear flags for the remaining attributes */+ for (; i < attIndex; i += 2)+ ((XML_Char *)(appAtts[i]))[-1] = 0;+ for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)+ binding->attId->name[-1] = 0;++ if (!ns)+ return XML_ERROR_NONE;++ /* expand the element type name */+ if (elementType->prefix) {+ binding = elementType->prefix->binding;+ if (!binding)+ return XML_ERROR_UNBOUND_PREFIX;+ localPart = tagNamePtr->str;+ while (*localPart++ != XML_T(ASCII_COLON))+ ;+ }+ else if (dtd->defaultPrefix.binding) {+ binding = dtd->defaultPrefix.binding;+ localPart = tagNamePtr->str;+ }+ else+ return XML_ERROR_NONE;+ prefixLen = 0;+ if (ns_triplets && binding->prefix->name) {+ for (; binding->prefix->name[prefixLen++];)+ ; /* prefixLen includes null terminator */+ }+ tagNamePtr->localPart = localPart;+ tagNamePtr->uriLen = binding->uriLen;+ tagNamePtr->prefix = binding->prefix->name;+ tagNamePtr->prefixLen = prefixLen;+ for (i = 0; localPart[i++];)+ ; /* i includes null terminator */+ n = i + binding->uriLen + prefixLen;+ if (n > binding->uriAlloc) {+ TAG *p;+ uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));+ if (!uri)+ return XML_ERROR_NO_MEMORY;+ binding->uriAlloc = n + EXPAND_SPARE;+ memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));+ for (p = tagStack; p; p = p->parent)+ if (p->name.str == binding->uri)+ p->name.str = uri;+ FREE(binding->uri);+ binding->uri = uri;+ }+ /* if namespaceSeparator != '\0' then uri includes it already */+ uri = binding->uri + binding->uriLen;+ memcpy(uri, localPart, i * sizeof(XML_Char));+ /* we always have a namespace separator between localPart and prefix */+ if (prefixLen) {+ uri += i - 1;+ *uri = namespaceSeparator; /* replace null terminator */+ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));+ }+ tagNamePtr->str = binding->uri;+ return XML_ERROR_NONE;+}++/* addBinding() overwrites the value of prefix->binding without checking.+ Therefore one must keep track of the old value outside of addBinding().+*/+static enum XML_Error+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,+ const XML_Char *uri, BINDING **bindingsPtr)+{+ static const XML_Char xmlNamespace[] = {+ ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,+ ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,+ ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,+ ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,+ ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,+ ASCII_e, '\0'+ };+ static const int xmlLen =+ (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;+ static const XML_Char xmlnsNamespace[] = {+ ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,+ ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,+ ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,+ ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,+ ASCII_SLASH, '\0'+ };+ static const int xmlnsLen =+ (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;++ XML_Bool mustBeXML = XML_FALSE;+ XML_Bool isXML = XML_TRUE;+ XML_Bool isXMLNS = XML_TRUE;++ BINDING *b;+ int len;++ /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */+ if (*uri == XML_T('\0') && prefix->name)+ return XML_ERROR_UNDECLARING_PREFIX;++ if (prefix->name+ && prefix->name[0] == XML_T(ASCII_x)+ && prefix->name[1] == XML_T(ASCII_m)+ && prefix->name[2] == XML_T(ASCII_l)) {++ /* Not allowed to bind xmlns */+ if (prefix->name[3] == XML_T(ASCII_n)+ && prefix->name[4] == XML_T(ASCII_s)+ && prefix->name[5] == XML_T('\0'))+ return XML_ERROR_RESERVED_PREFIX_XMLNS;++ if (prefix->name[3] == XML_T('\0'))+ mustBeXML = XML_TRUE;+ }++ for (len = 0; uri[len]; len++) {+ if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))+ isXML = XML_FALSE;++ if (!mustBeXML && isXMLNS+ && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))+ isXMLNS = XML_FALSE;+ }+ isXML = isXML && len == xmlLen;+ isXMLNS = isXMLNS && len == xmlnsLen;++ if (mustBeXML != isXML)+ return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML+ : XML_ERROR_RESERVED_NAMESPACE_URI;++ if (isXMLNS)+ return XML_ERROR_RESERVED_NAMESPACE_URI;++ if (namespaceSeparator)+ len++;+ if (freeBindingList) {+ b = freeBindingList;+ if (len > b->uriAlloc) {+ XML_Char *temp = (XML_Char *)REALLOC(b->uri,+ sizeof(XML_Char) * (len + EXPAND_SPARE));+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ b->uri = temp;+ b->uriAlloc = len + EXPAND_SPARE;+ }+ freeBindingList = b->nextTagBinding;+ }+ else {+ b = (BINDING *)MALLOC(sizeof(BINDING));+ if (!b)+ return XML_ERROR_NO_MEMORY;+ b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));+ if (!b->uri) {+ FREE(b);+ return XML_ERROR_NO_MEMORY;+ }+ b->uriAlloc = len + EXPAND_SPARE;+ }+ b->uriLen = len;+ memcpy(b->uri, uri, len * sizeof(XML_Char));+ if (namespaceSeparator)+ b->uri[len - 1] = namespaceSeparator;+ b->prefix = prefix;+ b->attId = attId;+ b->prevPrefixBinding = prefix->binding;+ /* NULL binding when default namespace undeclared */+ if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)+ prefix->binding = NULL;+ else+ prefix->binding = b;+ b->nextTagBinding = *bindingsPtr;+ *bindingsPtr = b;+ /* if attId == NULL then we are not starting a namespace scope */+ if (attId && startNamespaceDeclHandler)+ startNamespaceDeclHandler(handlerArg, prefix->name,+ prefix->binding ? uri : 0);+ return XML_ERROR_NONE;+}++/* The idea here is to avoid using stack for each CDATA section when+ the whole file is parsed with one call.+*/+static enum XML_Error PTRCALL+cdataSectionProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doCdataSection(parser, encoding, &start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result != XML_ERROR_NONE)+ return result;+ if (start) {+ if (parentParser) { /* we are parsing an external entity */+ processor = externalEntityContentProcessor;+ return externalEntityContentProcessor(parser, start, end, endPtr);+ }+ else {+ processor = contentProcessor;+ return contentProcessor(parser, start, end, endPtr);+ }+ }+ return result;+}++/* startPtr gets set to non-null if the section is closed, and to null if+ the section is not yet closed.+*/+static enum XML_Error+doCdataSection(XML_Parser parser,+ const ENCODING *enc,+ const char **startPtr,+ const char *end,+ const char **nextPtr,+ XML_Bool haveMore)+{+ const char *s = *startPtr;+ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ *eventPP = s;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ *eventPP = s;+ *startPtr = NULL;++ for (;;) {+ const char *next;+ int tok = XmlCdataSectionTok(enc, s, end, &next);+ *eventEndPP = next;+ switch (tok) {+ case XML_TOK_CDATA_SECT_CLOSE:+ if (endCdataSectionHandler)+ endCdataSectionHandler(handlerArg);+#if 0+ /* see comment under XML_TOK_CDATA_SECT_OPEN */+ else if (characterDataHandler)+ characterDataHandler(handlerArg, dataBuf, 0);+#endif+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ *startPtr = next;+ *nextPtr = next;+ if (ps_parsing == XML_FINISHED)+ return XML_ERROR_ABORTED;+ else+ return XML_ERROR_NONE;+ case XML_TOK_DATA_NEWLINE:+ if (characterDataHandler) {+ XML_Char c = 0xA;+ characterDataHandler(handlerArg, &c, 1);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ case XML_TOK_DATA_CHARS:+ {+ XML_CharacterDataHandler charDataHandler = characterDataHandler;+ if (charDataHandler) {+ if (MUST_CONVERT(enc, s)) {+ for (;;) {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);+ *eventEndPP = next;+ charDataHandler(handlerArg, dataBuf,+ (int)(dataPtr - (ICHAR *)dataBuf));+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))+ break;+ *eventPP = s;+ }+ }+ else+ charDataHandler(handlerArg,+ (XML_Char *)s,+ (int)((XML_Char *)next - (XML_Char *)s));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ }+ break;+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_PARTIAL:+ case XML_TOK_NONE:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_CDATA_SECTION;+ default:+ *eventPP = next;+ return XML_ERROR_UNEXPECTED_STATE;+ }++ *eventPP = s = next;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default: ;+ }+ }+ /* not reached */+}++#ifdef XML_DTD++/* The idea here is to avoid using stack for each IGNORE section when+ the whole file is parsed with one call.+*/+static enum XML_Error PTRCALL+ignoreSectionProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result != XML_ERROR_NONE)+ return result;+ if (start) {+ processor = prologProcessor;+ return prologProcessor(parser, start, end, endPtr);+ }+ return result;+}++/* startPtr gets set to non-null is the section is closed, and to null+ if the section is not yet closed.+*/+static enum XML_Error+doIgnoreSection(XML_Parser parser,+ const ENCODING *enc,+ const char **startPtr,+ const char *end,+ const char **nextPtr,+ XML_Bool haveMore)+{+ const char *next;+ int tok;+ const char *s = *startPtr;+ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ *eventPP = s;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ *eventPP = s;+ *startPtr = NULL;+ tok = XmlIgnoreSectionTok(enc, s, end, &next);+ *eventEndPP = next;+ switch (tok) {+ case XML_TOK_IGNORE_SECT:+ if (defaultHandler)+ reportDefault(parser, enc, s, next);+ *startPtr = next;+ *nextPtr = next;+ if (ps_parsing == XML_FINISHED)+ return XML_ERROR_ABORTED;+ else+ return XML_ERROR_NONE;+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_PARTIAL:+ case XML_TOK_NONE:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */+ default:+ *eventPP = next;+ return XML_ERROR_UNEXPECTED_STATE;+ }+ /* not reached */+}++#endif /* XML_DTD */++static enum XML_Error+initializeEncoding(XML_Parser parser)+{+ const char *s;+#ifdef XML_UNICODE+ char encodingBuf[128];+ if (!protocolEncodingName)+ s = NULL;+ else {+ int i;+ for (i = 0; protocolEncodingName[i]; i++) {+ if (i == sizeof(encodingBuf) - 1+ || (protocolEncodingName[i] & ~0x7f) != 0) {+ encodingBuf[0] = '\0';+ break;+ }+ encodingBuf[i] = (char)protocolEncodingName[i];+ }+ encodingBuf[i] = '\0';+ s = encodingBuf;+ }+#else+ s = protocolEncodingName;+#endif+ if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))+ return XML_ERROR_NONE;+ return handleUnknownEncoding(parser, protocolEncodingName);+}++static enum XML_Error+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,+ const char *s, const char *next)+{+ const char *encodingName = NULL;+ const XML_Char *storedEncName = NULL;+ const ENCODING *newEncoding = NULL;+ const char *version = NULL;+ const char *versionend;+ const XML_Char *storedversion = NULL;+ int standalone = -1;+ if (!(ns+ ? XmlParseXmlDeclNS+ : XmlParseXmlDecl)(isGeneralTextEntity,+ encoding,+ s,+ next,+ &eventPtr,+ &version,+ &versionend,+ &encodingName,+ &newEncoding,+ &standalone)) {+ if (isGeneralTextEntity)+ return XML_ERROR_TEXT_DECL;+ else+ return XML_ERROR_XML_DECL;+ }+ if (!isGeneralTextEntity && standalone == 1) {+ _dtd->standalone = XML_TRUE;+#ifdef XML_DTD+ if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;+#endif /* XML_DTD */+ }+ if (xmlDeclHandler) {+ if (encodingName != NULL) {+ storedEncName = poolStoreString(&temp2Pool,+ encoding,+ encodingName,+ encodingName+ + XmlNameLength(encoding, encodingName));+ if (!storedEncName)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&temp2Pool);+ }+ if (version) {+ storedversion = poolStoreString(&temp2Pool,+ encoding,+ version,+ versionend - encoding->minBytesPerChar);+ if (!storedversion)+ return XML_ERROR_NO_MEMORY;+ }+ xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);+ }+ else if (defaultHandler)+ reportDefault(parser, encoding, s, next);+ if (protocolEncodingName == NULL) {+ if (newEncoding) {+ if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {+ eventPtr = encodingName;+ return XML_ERROR_INCORRECT_ENCODING;+ }+ encoding = newEncoding;+ }+ else if (encodingName) {+ enum XML_Error result;+ if (!storedEncName) {+ storedEncName = poolStoreString(+ &temp2Pool, encoding, encodingName,+ encodingName + XmlNameLength(encoding, encodingName));+ if (!storedEncName)+ return XML_ERROR_NO_MEMORY;+ }+ result = handleUnknownEncoding(parser, storedEncName);+ poolClear(&temp2Pool);+ if (result == XML_ERROR_UNKNOWN_ENCODING)+ eventPtr = encodingName;+ return result;+ }+ }++ if (storedEncName || storedversion)+ poolClear(&temp2Pool);++ return XML_ERROR_NONE;+}++static enum XML_Error+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)+{+ if (unknownEncodingHandler) {+ XML_Encoding info;+ int i;+ for (i = 0; i < 256; i++)+ info.map[i] = -1;+ info.convert = NULL;+ info.data = NULL;+ info.release = NULL;+ if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,+ &info)) {+ ENCODING *enc;+ unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());+ if (!unknownEncodingMem) {+ if (info.release)+ info.release(info.data);+ return XML_ERROR_NO_MEMORY;+ }+ enc = (ns+ ? XmlInitUnknownEncodingNS+ : XmlInitUnknownEncoding)(unknownEncodingMem,+ info.map,+ info.convert,+ info.data);+ if (enc) {+ unknownEncodingData = info.data;+ unknownEncodingRelease = info.release;+ encoding = enc;+ return XML_ERROR_NONE;+ }+ }+ if (info.release != NULL)+ info.release(info.data);+ }+ return XML_ERROR_UNKNOWN_ENCODING;+}++static enum XML_Error PTRCALL+prologInitProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ enum XML_Error result = initializeEncoding(parser);+ if (result != XML_ERROR_NONE)+ return result;+ processor = prologProcessor;+ return prologProcessor(parser, s, end, nextPtr);+}++#ifdef XML_DTD++static enum XML_Error PTRCALL+externalParEntInitProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ enum XML_Error result = initializeEncoding(parser);+ if (result != XML_ERROR_NONE)+ return result;++ /* we know now that XML_Parse(Buffer) has been called,+ so we consider the external parameter entity read */+ _dtd->paramEntityRead = XML_TRUE;++ if (prologState.inEntityValue) {+ processor = entityValueInitProcessor;+ return entityValueInitProcessor(parser, s, end, nextPtr);+ }+ else {+ processor = externalParEntProcessor;+ return externalParEntProcessor(parser, s, end, nextPtr);+ }+}++static enum XML_Error PTRCALL+entityValueInitProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ int tok;+ const char *start = s;+ const char *next = start;+ eventPtr = start;++ for (;;) {+ tok = XmlPrologTok(encoding, start, end, &next);+ eventEndPtr = next;+ if (tok <= 0) {+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_NONE: /* start == end */+ default:+ break;+ }+ /* found end of entity value - can store it now */+ return storeEntityValue(parser, encoding, s, end);+ }+ else if (tok == XML_TOK_XML_DECL) {+ enum XML_Error result;+ result = processXmlDecl(parser, 0, start, next);+ if (result != XML_ERROR_NONE)+ return result;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default:+ *nextPtr = next;+ }+ /* stop scanning for text declaration - we found one */+ processor = entityValueProcessor;+ return entityValueProcessor(parser, next, end, nextPtr);+ }+ /* If we are at the end of the buffer, this would cause XmlPrologTok to+ return XML_TOK_NONE on the next call, which would then cause the+ function to exit with *nextPtr set to s - that is what we want for other+ tokens, but not for the BOM - we would rather like to skip it;+ then, when this routine is entered the next time, XmlPrologTok will+ return XML_TOK_INVALID, since the BOM is still in the buffer+ */+ else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {+ *nextPtr = next;+ return XML_ERROR_NONE;+ }+ /* If we get this token, we have the start of what might be a+ normal tag, but not a declaration (i.e. it doesn't begin with+ "<!"). In a DTD context, that isn't legal.+ */+ else if (tok == XML_TOK_INSTANCE_START) {+ *nextPtr = next;+ return XML_ERROR_SYNTAX;+ }+ start = next;+ eventPtr = start;+ }+}++static enum XML_Error PTRCALL+externalParEntProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ const char *next = s;+ int tok;++ tok = XmlPrologTok(encoding, s, end, &next);+ if (tok <= 0) {+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_NONE: /* start == end */+ default:+ break;+ }+ }+ /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.+ However, when parsing an external subset, doProlog will not accept a BOM+ as valid, and report a syntax error, so we have to skip the BOM+ */+ else if (tok == XML_TOK_BOM) {+ s = next;+ tok = XmlPrologTok(encoding, s, end, &next);+ }++ processor = prologProcessor;+ return doProlog(parser, encoding, s, end, tok, next,+ nextPtr, (XML_Bool)!ps_finalBuffer);+}++static enum XML_Error PTRCALL+entityValueProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ const char *start = s;+ const char *next = s;+ const ENCODING *enc = encoding;+ int tok;++ for (;;) {+ tok = XmlPrologTok(enc, start, end, &next);+ if (tok <= 0) {+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_NONE: /* start == end */+ default:+ break;+ }+ /* found end of entity value - can store it now */+ return storeEntityValue(parser, enc, s, end);+ }+ start = next;+ }+}++#endif /* XML_DTD */++static enum XML_Error PTRCALL+prologProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ const char *next = s;+ int tok = XmlPrologTok(encoding, s, end, &next);+ return doProlog(parser, encoding, s, end, tok, next,+ nextPtr, (XML_Bool)!ps_finalBuffer);+}++static enum XML_Error+doProlog(XML_Parser parser,+ const ENCODING *enc,+ const char *s,+ const char *end,+ int tok,+ const char *next,+ const char **nextPtr,+ XML_Bool haveMore)+{+#ifdef XML_DTD+ static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };+#endif /* XML_DTD */+ static const XML_Char atypeCDATA[] =+ { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };+ static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };+ static const XML_Char atypeIDREF[] =+ { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };+ static const XML_Char atypeIDREFS[] =+ { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };+ static const XML_Char atypeENTITY[] =+ { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };+ static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,+ ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };+ static const XML_Char atypeNMTOKEN[] = {+ ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };+ static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,+ ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };+ static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,+ ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };+ static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };+ static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };++ /* save one level of indirection */+ DTD * const dtd = _dtd;++ const char **eventPP;+ const char **eventEndPP;+ enum XML_Content_Quant quant;++ if (enc == encoding) {+ eventPP = &eventPtr;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }++ for (;;) {+ int role;+ XML_Bool handleDefault = XML_TRUE;+ *eventPP = s;+ *eventEndPP = next;+ if (tok <= 0) {+ if (haveMore && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case -XML_TOK_PROLOG_S:+ tok = -tok;+ break;+ case XML_TOK_NONE:+#ifdef XML_DTD+ /* for internal PE NOT referenced between declarations */+ if (enc != encoding && !openInternalEntities->betweenDecl) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ /* WFC: PE Between Declarations - must check that PE contains+ complete markup, not only for external PEs, but also for+ internal PEs if the reference occurs between declarations.+ */+ if (isParamEntity || enc != encoding) {+ if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)+ == XML_ROLE_ERROR)+ return XML_ERROR_INCOMPLETE_PE;+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+#endif /* XML_DTD */+ return XML_ERROR_NO_ELEMENTS;+ default:+ tok = -tok;+ next = end;+ break;+ }+ }+ role = XmlTokenRole(&prologState, tok, s, next, enc);+ switch (role) {+ case XML_ROLE_XML_DECL:+ {+ enum XML_Error result = processXmlDecl(parser, 0, s, next);+ if (result != XML_ERROR_NONE)+ return result;+ enc = encoding;+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_DOCTYPE_NAME:+ if (startDoctypeDeclHandler) {+ doctypeName = poolStoreString(&tempPool, enc, s, next);+ if (!doctypeName)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ doctypePubid = NULL;+ handleDefault = XML_FALSE;+ }+ doctypeSysid = NULL; /* always initialize to NULL */+ break;+ case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:+ if (startDoctypeDeclHandler) {+ startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,+ doctypePubid, 1);+ doctypeName = NULL;+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ break;+#ifdef XML_DTD+ case XML_ROLE_TEXT_DECL:+ {+ enum XML_Error result = processXmlDecl(parser, 1, s, next);+ if (result != XML_ERROR_NONE)+ return result;+ enc = encoding;+ handleDefault = XML_FALSE;+ }+ break;+#endif /* XML_DTD */+ case XML_ROLE_DOCTYPE_PUBLIC_ID:+#ifdef XML_DTD+ useForeignDTD = XML_FALSE;+ declEntity = (ENTITY *)lookup(parser,+ &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+#endif /* XML_DTD */+ dtd->hasParamEntityRefs = XML_TRUE;+ if (startDoctypeDeclHandler) {+ XML_Char *pubId;+ if (!XmlIsPublicId(enc, s, next, eventPP))+ return XML_ERROR_PUBLICID;+ pubId = poolStoreString(&tempPool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!pubId)+ return XML_ERROR_NO_MEMORY;+ normalizePublicId(pubId);+ poolFinish(&tempPool);+ doctypePubid = pubId;+ handleDefault = XML_FALSE;+ goto alreadyChecked;+ }+ /* fall through */+ case XML_ROLE_ENTITY_PUBLIC_ID:+ if (!XmlIsPublicId(enc, s, next, eventPP))+ return XML_ERROR_PUBLICID;+ alreadyChecked:+ if (dtd->keepProcessing && declEntity) {+ XML_Char *tem = poolStoreString(&dtd->pool,+ enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!tem)+ return XML_ERROR_NO_MEMORY;+ normalizePublicId(tem);+ declEntity->publicId = tem;+ poolFinish(&dtd->pool);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_DOCTYPE_CLOSE:+ if (doctypeName) {+ startDoctypeDeclHandler(handlerArg, doctypeName,+ doctypeSysid, doctypePubid, 0);+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ /* doctypeSysid will be non-NULL in the case of a previous+ XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler+ was not set, indicating an external subset+ */+#ifdef XML_DTD+ if (doctypeSysid || useForeignDTD) {+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;+ dtd->hasParamEntityRefs = XML_TRUE;+ if (paramEntityParsing && externalEntityRefHandler) {+ ENTITY *entity = (ENTITY *)lookup(parser,+ &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!entity)+ return XML_ERROR_NO_MEMORY;+ if (useForeignDTD)+ entity->base = curBase;+ dtd->paramEntityRead = XML_FALSE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId))+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ if (dtd->paramEntityRead) {+ if (!dtd->standalone &&+ notStandaloneHandler &&+ !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+ }+ /* if we didn't read the foreign DTD then this means that there+ is no external subset and we must reset dtd->hasParamEntityRefs+ */+ else if (!doctypeSysid)+ dtd->hasParamEntityRefs = hadParamEntityRefs;+ /* end of DTD - no need to update dtd->keepProcessing */+ }+ useForeignDTD = XML_FALSE;+ }+#endif /* XML_DTD */+ if (endDoctypeDeclHandler) {+ endDoctypeDeclHandler(handlerArg);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_INSTANCE_START:+#ifdef XML_DTD+ /* if there is no DOCTYPE declaration then now is the+ last chance to read the foreign DTD+ */+ if (useForeignDTD) {+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;+ dtd->hasParamEntityRefs = XML_TRUE;+ if (paramEntityParsing && externalEntityRefHandler) {+ ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!entity)+ return XML_ERROR_NO_MEMORY;+ entity->base = curBase;+ dtd->paramEntityRead = XML_FALSE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId))+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ if (dtd->paramEntityRead) {+ if (!dtd->standalone &&+ notStandaloneHandler &&+ !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+ }+ /* if we didn't read the foreign DTD then this means that there+ is no external subset and we must reset dtd->hasParamEntityRefs+ */+ else+ dtd->hasParamEntityRefs = hadParamEntityRefs;+ /* end of DTD - no need to update dtd->keepProcessing */+ }+ }+#endif /* XML_DTD */+ processor = contentProcessor;+ return contentProcessor(parser, s, end, nextPtr);+ case XML_ROLE_ATTLIST_ELEMENT_NAME:+ declElementType = getElementType(parser, enc, s, next);+ if (!declElementType)+ return XML_ERROR_NO_MEMORY;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_NAME:+ declAttributeId = getAttributeId(parser, enc, s, next);+ if (!declAttributeId)+ return XML_ERROR_NO_MEMORY;+ declAttributeIsCdata = XML_FALSE;+ declAttributeType = NULL;+ declAttributeIsId = XML_FALSE;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_CDATA:+ declAttributeIsCdata = XML_TRUE;+ declAttributeType = atypeCDATA;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_ID:+ declAttributeIsId = XML_TRUE;+ declAttributeType = atypeID;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_IDREF:+ declAttributeType = atypeIDREF;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:+ declAttributeType = atypeIDREFS;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:+ declAttributeType = atypeENTITY;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:+ declAttributeType = atypeENTITIES;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:+ declAttributeType = atypeNMTOKEN;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:+ declAttributeType = atypeNMTOKENS;+ checkAttListDeclHandler:+ if (dtd->keepProcessing && attlistDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ATTRIBUTE_ENUM_VALUE:+ case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:+ if (dtd->keepProcessing && attlistDeclHandler) {+ const XML_Char *prefix;+ if (declAttributeType) {+ prefix = enumValueSep;+ }+ else {+ prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE+ ? notationPrefix+ : enumValueStart);+ }+ if (!poolAppendString(&tempPool, prefix))+ return XML_ERROR_NO_MEMORY;+ if (!poolAppend(&tempPool, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ declAttributeType = tempPool.start;+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:+ case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:+ if (dtd->keepProcessing) {+ if (!defineAttribute(declElementType, declAttributeId,+ declAttributeIsCdata, declAttributeIsId,+ 0, parser))+ return XML_ERROR_NO_MEMORY;+ if (attlistDeclHandler && declAttributeType) {+ if (*declAttributeType == XML_T(ASCII_LPAREN)+ || (*declAttributeType == XML_T(ASCII_N)+ && declAttributeType[1] == XML_T(ASCII_O))) {+ /* Enumerated or Notation type */+ if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))+ || !poolAppendChar(&tempPool, XML_T('\0')))+ return XML_ERROR_NO_MEMORY;+ declAttributeType = tempPool.start;+ poolFinish(&tempPool);+ }+ *eventEndPP = s;+ attlistDeclHandler(handlerArg, declElementType->name,+ declAttributeId->name, declAttributeType,+ 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ }+ break;+ case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:+ case XML_ROLE_FIXED_ATTRIBUTE_VALUE:+ if (dtd->keepProcessing) {+ const XML_Char *attVal;+ enum XML_Error result =+ storeAttributeValue(parser, enc, declAttributeIsCdata,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar,+ &dtd->pool);+ if (result)+ return result;+ attVal = poolStart(&dtd->pool);+ poolFinish(&dtd->pool);+ /* ID attributes aren't allowed to have a default */+ if (!defineAttribute(declElementType, declAttributeId,+ declAttributeIsCdata, XML_FALSE, attVal, parser))+ return XML_ERROR_NO_MEMORY;+ if (attlistDeclHandler && declAttributeType) {+ if (*declAttributeType == XML_T(ASCII_LPAREN)+ || (*declAttributeType == XML_T(ASCII_N)+ && declAttributeType[1] == XML_T(ASCII_O))) {+ /* Enumerated or Notation type */+ if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))+ || !poolAppendChar(&tempPool, XML_T('\0')))+ return XML_ERROR_NO_MEMORY;+ declAttributeType = tempPool.start;+ poolFinish(&tempPool);+ }+ *eventEndPP = s;+ attlistDeclHandler(handlerArg, declElementType->name,+ declAttributeId->name, declAttributeType,+ attVal,+ role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ }+ break;+ case XML_ROLE_ENTITY_VALUE:+ if (dtd->keepProcessing) {+ enum XML_Error result = storeEntityValue(parser, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (declEntity) {+ declEntity->textPtr = poolStart(&dtd->entityValuePool);+ declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));+ poolFinish(&dtd->entityValuePool);+ if (entityDeclHandler) {+ *eventEndPP = s;+ entityDeclHandler(handlerArg,+ declEntity->name,+ declEntity->is_param,+ declEntity->textPtr,+ declEntity->textLen,+ curBase, 0, 0, 0);+ handleDefault = XML_FALSE;+ }+ }+ else+ poolDiscard(&dtd->entityValuePool);+ if (result != XML_ERROR_NONE)+ return result;+ }+ break;+ case XML_ROLE_DOCTYPE_SYSTEM_ID:+#ifdef XML_DTD+ useForeignDTD = XML_FALSE;+#endif /* XML_DTD */+ dtd->hasParamEntityRefs = XML_TRUE;+ if (startDoctypeDeclHandler) {+ doctypeSysid = poolStoreString(&tempPool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (doctypeSysid == NULL)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ handleDefault = XML_FALSE;+ }+#ifdef XML_DTD+ else+ /* use externalSubsetName to make doctypeSysid non-NULL+ for the case where no startDoctypeDeclHandler is set */+ doctypeSysid = externalSubsetName;+#endif /* XML_DTD */+ if (!dtd->standalone+#ifdef XML_DTD+ && !paramEntityParsing+#endif /* XML_DTD */+ && notStandaloneHandler+ && !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+#ifndef XML_DTD+ break;+#else /* XML_DTD */+ if (!declEntity) {+ declEntity = (ENTITY *)lookup(parser,+ &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+ declEntity->publicId = NULL;+ }+ /* fall through */+#endif /* XML_DTD */+ case XML_ROLE_ENTITY_SYSTEM_ID:+ if (dtd->keepProcessing && declEntity) {+ declEntity->systemId = poolStoreString(&dtd->pool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!declEntity->systemId)+ return XML_ERROR_NO_MEMORY;+ declEntity->base = curBase;+ poolFinish(&dtd->pool);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_ENTITY_COMPLETE:+ if (dtd->keepProcessing && declEntity && entityDeclHandler) {+ *eventEndPP = s;+ entityDeclHandler(handlerArg,+ declEntity->name,+ declEntity->is_param,+ 0,0,+ declEntity->base,+ declEntity->systemId,+ declEntity->publicId,+ 0);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_ENTITY_NOTATION_NAME:+ if (dtd->keepProcessing && declEntity) {+ declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);+ if (!declEntity->notation)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&dtd->pool);+ if (unparsedEntityDeclHandler) {+ *eventEndPP = s;+ unparsedEntityDeclHandler(handlerArg,+ declEntity->name,+ declEntity->base,+ declEntity->systemId,+ declEntity->publicId,+ declEntity->notation);+ handleDefault = XML_FALSE;+ }+ else if (entityDeclHandler) {+ *eventEndPP = s;+ entityDeclHandler(handlerArg,+ declEntity->name,+ 0,0,0,+ declEntity->base,+ declEntity->systemId,+ declEntity->publicId,+ declEntity->notation);+ handleDefault = XML_FALSE;+ }+ }+ break;+ case XML_ROLE_GENERAL_ENTITY_NAME:+ {+ if (XmlPredefinedEntityName(enc, s, next)) {+ declEntity = NULL;+ break;+ }+ if (dtd->keepProcessing) {+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,+ sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+ if (declEntity->name != name) {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+ else {+ poolFinish(&dtd->pool);+ declEntity->publicId = NULL;+ declEntity->is_param = XML_FALSE;+ /* if we have a parent parser or are reading an internal parameter+ entity, then the entity declaration is not considered "internal"+ */+ declEntity->is_internal = !(parentParser || openInternalEntities);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ }+ else {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+ }+ break;+ case XML_ROLE_PARAM_ENTITY_NAME:+#ifdef XML_DTD+ if (dtd->keepProcessing) {+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,+ name, sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+ if (declEntity->name != name) {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+ else {+ poolFinish(&dtd->pool);+ declEntity->publicId = NULL;+ declEntity->is_param = XML_TRUE;+ /* if we have a parent parser or are reading an internal parameter+ entity, then the entity declaration is not considered "internal"+ */+ declEntity->is_internal = !(parentParser || openInternalEntities);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ }+ else {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+#else /* not XML_DTD */+ declEntity = NULL;+#endif /* XML_DTD */+ break;+ case XML_ROLE_NOTATION_NAME:+ declNotationPublicId = NULL;+ declNotationName = NULL;+ if (notationDeclHandler) {+ declNotationName = poolStoreString(&tempPool, enc, s, next);+ if (!declNotationName)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_NOTATION_PUBLIC_ID:+ if (!XmlIsPublicId(enc, s, next, eventPP))+ return XML_ERROR_PUBLICID;+ if (declNotationName) { /* means notationDeclHandler != NULL */+ XML_Char *tem = poolStoreString(&tempPool,+ enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!tem)+ return XML_ERROR_NO_MEMORY;+ normalizePublicId(tem);+ declNotationPublicId = tem;+ poolFinish(&tempPool);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_NOTATION_SYSTEM_ID:+ if (declNotationName && notationDeclHandler) {+ const XML_Char *systemId+ = poolStoreString(&tempPool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!systemId)+ return XML_ERROR_NO_MEMORY;+ *eventEndPP = s;+ notationDeclHandler(handlerArg,+ declNotationName,+ curBase,+ systemId,+ declNotationPublicId);+ handleDefault = XML_FALSE;+ }+ poolClear(&tempPool);+ break;+ case XML_ROLE_NOTATION_NO_SYSTEM_ID:+ if (declNotationPublicId && notationDeclHandler) {+ *eventEndPP = s;+ notationDeclHandler(handlerArg,+ declNotationName,+ curBase,+ 0,+ declNotationPublicId);+ handleDefault = XML_FALSE;+ }+ poolClear(&tempPool);+ break;+ case XML_ROLE_ERROR:+ switch (tok) {+ case XML_TOK_PARAM_ENTITY_REF:+ /* PE references in internal subset are+ not allowed within declarations. */+ return XML_ERROR_PARAM_ENTITY_REF;+ case XML_TOK_XML_DECL:+ return XML_ERROR_MISPLACED_XML_PI;+ default:+ return XML_ERROR_SYNTAX;+ }+#ifdef XML_DTD+ case XML_ROLE_IGNORE_SECT:+ {+ enum XML_Error result;+ if (defaultHandler)+ reportDefault(parser, enc, s, next);+ handleDefault = XML_FALSE;+ result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);+ if (result != XML_ERROR_NONE)+ return result;+ else if (!next) {+ processor = ignoreSectionProcessor;+ return result;+ }+ }+ break;+#endif /* XML_DTD */+ case XML_ROLE_GROUP_OPEN:+ if (prologState.level >= groupSize) {+ if (groupSize) {+ char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ groupConnector = temp;+ if (dtd->scaffIndex) {+ int *temp = (int *)REALLOC(dtd->scaffIndex,+ groupSize * sizeof(int));+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffIndex = temp;+ }+ }+ else {+ groupConnector = (char *)MALLOC(groupSize = 32);+ if (!groupConnector)+ return XML_ERROR_NO_MEMORY;+ }+ }+ groupConnector[prologState.level] = 0;+ if (dtd->in_eldecl) {+ int myindex = nextScaffoldPart(parser);+ if (myindex < 0)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffIndex[dtd->scaffLevel] = myindex;+ dtd->scaffLevel++;+ dtd->scaffold[myindex].type = XML_CTYPE_SEQ;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_GROUP_SEQUENCE:+ if (groupConnector[prologState.level] == ASCII_PIPE)+ return XML_ERROR_SYNTAX;+ groupConnector[prologState.level] = ASCII_COMMA;+ if (dtd->in_eldecl && elementDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_GROUP_CHOICE:+ if (groupConnector[prologState.level] == ASCII_COMMA)+ return XML_ERROR_SYNTAX;+ if (dtd->in_eldecl+ && !groupConnector[prologState.level]+ && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type+ != XML_CTYPE_MIXED)+ ) {+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type+ = XML_CTYPE_CHOICE;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ groupConnector[prologState.level] = ASCII_PIPE;+ break;+ case XML_ROLE_PARAM_ENTITY_REF:+#ifdef XML_DTD+ case XML_ROLE_INNER_PARAM_ENTITY_REF:+ dtd->hasParamEntityRefs = XML_TRUE;+ if (!paramEntityParsing)+ dtd->keepProcessing = dtd->standalone;+ else {+ const XML_Char *name;+ ENTITY *entity;+ name = poolStoreString(&dtd->pool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);+ poolDiscard(&dtd->pool);+ /* first, determine if a check for an existing declaration is needed;+ if yes, check that the entity exists, and that it is internal,+ otherwise call the skipped entity handler+ */+ if (prologState.documentEntity &&+ (dtd->standalone+ ? !openInternalEntities+ : !dtd->hasParamEntityRefs)) {+ if (!entity)+ return XML_ERROR_UNDEFINED_ENTITY;+ else if (!entity->is_internal)+ return XML_ERROR_ENTITY_DECLARED_IN_PE;+ }+ else if (!entity) {+ dtd->keepProcessing = dtd->standalone;+ /* cannot report skipped entities in declarations */+ if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {+ skippedEntityHandler(handlerArg, name, 1);+ handleDefault = XML_FALSE;+ }+ break;+ }+ if (entity->open)+ return XML_ERROR_RECURSIVE_ENTITY_REF;+ if (entity->textPtr) {+ enum XML_Error result;+ XML_Bool betweenDecl =+ (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);+ result = processInternalEntity(parser, entity, betweenDecl);+ if (result != XML_ERROR_NONE)+ return result;+ handleDefault = XML_FALSE;+ break;+ }+ if (externalEntityRefHandler) {+ dtd->paramEntityRead = XML_FALSE;+ entity->open = XML_TRUE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId)) {+ entity->open = XML_FALSE;+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ }+ entity->open = XML_FALSE;+ handleDefault = XML_FALSE;+ if (!dtd->paramEntityRead) {+ dtd->keepProcessing = dtd->standalone;+ break;+ }+ }+ else {+ dtd->keepProcessing = dtd->standalone;+ break;+ }+ }+#endif /* XML_DTD */+ if (!dtd->standalone &&+ notStandaloneHandler &&+ !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+ break;++ /* Element declaration stuff */++ case XML_ROLE_ELEMENT_NAME:+ if (elementDeclHandler) {+ declElementType = getElementType(parser, enc, s, next);+ if (!declElementType)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffLevel = 0;+ dtd->scaffCount = 0;+ dtd->in_eldecl = XML_TRUE;+ handleDefault = XML_FALSE;+ }+ break;++ case XML_ROLE_CONTENT_ANY:+ case XML_ROLE_CONTENT_EMPTY:+ if (dtd->in_eldecl) {+ if (elementDeclHandler) {+ XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));+ if (!content)+ return XML_ERROR_NO_MEMORY;+ content->quant = XML_CQUANT_NONE;+ content->name = NULL;+ content->numchildren = 0;+ content->children = NULL;+ content->type = ((role == XML_ROLE_CONTENT_ANY) ?+ XML_CTYPE_ANY :+ XML_CTYPE_EMPTY);+ *eventEndPP = s;+ elementDeclHandler(handlerArg, declElementType->name, content);+ handleDefault = XML_FALSE;+ }+ dtd->in_eldecl = XML_FALSE;+ }+ break;++ case XML_ROLE_CONTENT_PCDATA:+ if (dtd->in_eldecl) {+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type+ = XML_CTYPE_MIXED;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;++ case XML_ROLE_CONTENT_ELEMENT:+ quant = XML_CQUANT_NONE;+ goto elementContent;+ case XML_ROLE_CONTENT_ELEMENT_OPT:+ quant = XML_CQUANT_OPT;+ goto elementContent;+ case XML_ROLE_CONTENT_ELEMENT_REP:+ quant = XML_CQUANT_REP;+ goto elementContent;+ case XML_ROLE_CONTENT_ELEMENT_PLUS:+ quant = XML_CQUANT_PLUS;+ elementContent:+ if (dtd->in_eldecl) {+ ELEMENT_TYPE *el;+ const XML_Char *name;+ int nameLen;+ const char *nxt = (quant == XML_CQUANT_NONE+ ? next+ : next - enc->minBytesPerChar);+ int myindex = nextScaffoldPart(parser);+ if (myindex < 0)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffold[myindex].type = XML_CTYPE_NAME;+ dtd->scaffold[myindex].quant = quant;+ el = getElementType(parser, enc, s, nxt);+ if (!el)+ return XML_ERROR_NO_MEMORY;+ name = el->name;+ dtd->scaffold[myindex].name = name;+ nameLen = 0;+ for (; name[nameLen++]; );+ dtd->contentStringLen += nameLen;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;++ case XML_ROLE_GROUP_CLOSE:+ quant = XML_CQUANT_NONE;+ goto closeGroup;+ case XML_ROLE_GROUP_CLOSE_OPT:+ quant = XML_CQUANT_OPT;+ goto closeGroup;+ case XML_ROLE_GROUP_CLOSE_REP:+ quant = XML_CQUANT_REP;+ goto closeGroup;+ case XML_ROLE_GROUP_CLOSE_PLUS:+ quant = XML_CQUANT_PLUS;+ closeGroup:+ if (dtd->in_eldecl) {+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ dtd->scaffLevel--;+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;+ if (dtd->scaffLevel == 0) {+ if (!handleDefault) {+ XML_Content *model = build_model(parser);+ if (!model)+ return XML_ERROR_NO_MEMORY;+ *eventEndPP = s;+ elementDeclHandler(handlerArg, declElementType->name, model);+ }+ dtd->in_eldecl = XML_FALSE;+ dtd->contentStringLen = 0;+ }+ }+ break;+ /* End element declaration stuff */++ case XML_ROLE_PI:+ if (!reportProcessingInstruction(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_COMMENT:+ if (!reportComment(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_NONE:+ switch (tok) {+ case XML_TOK_BOM:+ handleDefault = XML_FALSE;+ break;+ }+ break;+ case XML_ROLE_DOCTYPE_NONE:+ if (startDoctypeDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ENTITY_NONE:+ if (dtd->keepProcessing && entityDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_NOTATION_NONE:+ if (notationDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ATTLIST_NONE:+ if (dtd->keepProcessing && attlistDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ELEMENT_NONE:+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ break;+ } /* end of big switch */++ if (handleDefault && defaultHandler)+ reportDefault(parser, enc, s, next);++ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default:+ s = next;+ tok = XmlPrologTok(enc, s, end, &next);+ }+ }+ /* not reached */+}++static enum XML_Error PTRCALL+epilogProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ processor = epilogProcessor;+ eventPtr = s;+ for (;;) {+ const char *next = NULL;+ int tok = XmlPrologTok(encoding, s, end, &next);+ eventEndPtr = next;+ switch (tok) {+ /* report partial linebreak - it might be the last token */+ case -XML_TOK_PROLOG_S:+ if (defaultHandler) {+ reportDefault(parser, encoding, s, next);+ if (ps_parsing == XML_FINISHED)+ return XML_ERROR_ABORTED;+ }+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_TOK_NONE:+ *nextPtr = s;+ return XML_ERROR_NONE;+ case XML_TOK_PROLOG_S:+ if (defaultHandler)+ reportDefault(parser, encoding, s, next);+ break;+ case XML_TOK_PI:+ if (!reportProcessingInstruction(parser, encoding, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_COMMENT:+ if (!reportComment(parser, encoding, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_INVALID:+ eventPtr = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ if (!ps_finalBuffer) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (!ps_finalBuffer) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ default:+ return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;+ }+ eventPtr = s = next;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default: ;+ }+ }+}++static enum XML_Error+processInternalEntity(XML_Parser parser, ENTITY *entity,+ XML_Bool betweenDecl)+{+ const char *textStart, *textEnd;+ const char *next;+ enum XML_Error result;+ OPEN_INTERNAL_ENTITY *openEntity;++ if (freeInternalEntities) {+ openEntity = freeInternalEntities;+ freeInternalEntities = openEntity->next;+ }+ else {+ openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));+ if (!openEntity)+ return XML_ERROR_NO_MEMORY;+ }+ entity->open = XML_TRUE;+ entity->processed = 0;+ openEntity->next = openInternalEntities;+ openInternalEntities = openEntity;+ openEntity->entity = entity;+ openEntity->startTagLevel = tagLevel;+ openEntity->betweenDecl = betweenDecl;+ openEntity->internalEventPtr = NULL;+ openEntity->internalEventEndPtr = NULL;+ textStart = (char *)entity->textPtr;+ textEnd = (char *)(entity->textPtr + entity->textLen);+ /* Set a safe default value in case 'next' does not get set */+ next = textStart;++#ifdef XML_DTD+ if (entity->is_param) {+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,+ next, &next, XML_FALSE);+ }+ else+#endif /* XML_DTD */+ result = doContent(parser, tagLevel, internalEncoding, textStart,+ textEnd, &next, XML_FALSE);++ if (result == XML_ERROR_NONE) {+ if (textEnd != next && ps_parsing == XML_SUSPENDED) {+ entity->processed = (int)(next - textStart);+ processor = internalEntityProcessor;+ }+ else {+ entity->open = XML_FALSE;+ openInternalEntities = openEntity->next;+ /* put openEntity back in list of free instances */+ openEntity->next = freeInternalEntities;+ freeInternalEntities = openEntity;+ }+ }+ return result;+}++static enum XML_Error PTRCALL+internalEntityProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ ENTITY *entity;+ const char *textStart, *textEnd;+ const char *next;+ enum XML_Error result;+ OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;+ if (!openEntity)+ return XML_ERROR_UNEXPECTED_STATE;++ entity = openEntity->entity;+ textStart = ((char *)entity->textPtr) + entity->processed;+ textEnd = (char *)(entity->textPtr + entity->textLen);+ /* Set a safe default value in case 'next' does not get set */+ next = textStart;++#ifdef XML_DTD+ if (entity->is_param) {+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,+ next, &next, XML_FALSE);+ }+ else+#endif /* XML_DTD */+ result = doContent(parser, openEntity->startTagLevel, internalEncoding,+ textStart, textEnd, &next, XML_FALSE);++ if (result != XML_ERROR_NONE)+ return result;+ else if (textEnd != next && ps_parsing == XML_SUSPENDED) {+ entity->processed = (int)(next - (char *)entity->textPtr);+ return result;+ }+ else {+ entity->open = XML_FALSE;+ openInternalEntities = openEntity->next;+ /* put openEntity back in list of free instances */+ openEntity->next = freeInternalEntities;+ freeInternalEntities = openEntity;+ }++#ifdef XML_DTD+ if (entity->is_param) {+ int tok;+ processor = prologProcessor;+ tok = XmlPrologTok(encoding, s, end, &next);+ return doProlog(parser, encoding, s, end, tok, next, nextPtr,+ (XML_Bool)!ps_finalBuffer);+ }+ else+#endif /* XML_DTD */+ {+ processor = contentProcessor;+ /* see externalEntityContentProcessor vs contentProcessor */+ return doContent(parser, parentParser ? 1 : 0, encoding, s, end,+ nextPtr, (XML_Bool)!ps_finalBuffer);+ }+}++static enum XML_Error PTRCALL+errorProcessor(XML_Parser parser,+ const char *UNUSED_P(s),+ const char *UNUSED_P(end),+ const char **UNUSED_P(nextPtr))+{+ return errorCode;+}++static enum XML_Error+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,+ const char *ptr, const char *end,+ STRING_POOL *pool)+{+ enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,+ end, pool);+ if (result)+ return result;+ if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)+ poolChop(pool);+ if (!poolAppendChar(pool, XML_T('\0')))+ return XML_ERROR_NO_MEMORY;+ return XML_ERROR_NONE;+}++static enum XML_Error+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,+ const char *ptr, const char *end,+ STRING_POOL *pool)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ for (;;) {+ const char *next;+ int tok = XmlAttributeValueTok(enc, ptr, end, &next);+ switch (tok) {+ case XML_TOK_NONE:+ return XML_ERROR_NONE;+ case XML_TOK_INVALID:+ if (enc == encoding)+ eventPtr = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_CHAR_REF:+ {+ XML_Char buf[XML_ENCODE_MAX];+ int i;+ int n = XmlCharRefNumber(enc, ptr);+ if (n < 0) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_BAD_CHAR_REF;+ }+ if (!isCdata+ && n == 0x20 /* space */+ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))+ break;+ n = XmlEncode(n, (ICHAR *)buf);+ if (!n) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_BAD_CHAR_REF;+ }+ for (i = 0; i < n; i++) {+ if (!poolAppendChar(pool, buf[i]))+ return XML_ERROR_NO_MEMORY;+ }+ }+ break;+ case XML_TOK_DATA_CHARS:+ if (!poolAppend(pool, enc, ptr, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_TRAILING_CR:+ next = ptr + enc->minBytesPerChar;+ /* fall through */+ case XML_TOK_ATTRIBUTE_VALUE_S:+ case XML_TOK_DATA_NEWLINE:+ if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))+ break;+ if (!poolAppendChar(pool, 0x20))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_ENTITY_REF:+ {+ const XML_Char *name;+ ENTITY *entity;+ char checkEntityDecl;+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,+ ptr + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (ch) {+ if (!poolAppendChar(pool, ch))+ return XML_ERROR_NO_MEMORY;+ break;+ }+ name = poolStoreString(&temp2Pool, enc,+ ptr + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);+ poolDiscard(&temp2Pool);+ /* First, determine if a check for an existing declaration is needed;+ if yes, check that the entity exists, and that it is internal.+ */+ if (pool == &dtd->pool) /* are we called from prolog? */+ checkEntityDecl =+#ifdef XML_DTD+ prologState.documentEntity &&+#endif /* XML_DTD */+ (dtd->standalone+ ? !openInternalEntities+ : !dtd->hasParamEntityRefs);+ else /* if (pool == &tempPool): we are called from content */+ checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;+ if (checkEntityDecl) {+ if (!entity)+ return XML_ERROR_UNDEFINED_ENTITY;+ else if (!entity->is_internal)+ return XML_ERROR_ENTITY_DECLARED_IN_PE;+ }+ else if (!entity) {+ /* Cannot report skipped entity here - see comments on+ skippedEntityHandler.+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, name, 0);+ */+ /* Cannot call the default handler because this would be+ out of sync with the call to the startElementHandler.+ if ((pool == &tempPool) && defaultHandler)+ reportDefault(parser, enc, ptr, next);+ */+ break;+ }+ if (entity->open) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_RECURSIVE_ENTITY_REF;+ }+ if (entity->notation) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_BINARY_ENTITY_REF;+ }+ if (!entity->textPtr) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;+ }+ else {+ enum XML_Error result;+ const XML_Char *textEnd = entity->textPtr + entity->textLen;+ entity->open = XML_TRUE;+ result = appendAttributeValue(parser, internalEncoding, isCdata,+ (char *)entity->textPtr,+ (char *)textEnd, pool);+ entity->open = XML_FALSE;+ if (result)+ return result;+ }+ }+ break;+ default:+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_UNEXPECTED_STATE;+ }+ ptr = next;+ }+ /* not reached */+}++static enum XML_Error+storeEntityValue(XML_Parser parser,+ const ENCODING *enc,+ const char *entityTextPtr,+ const char *entityTextEnd)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ STRING_POOL *pool = &(dtd->entityValuePool);+ enum XML_Error result = XML_ERROR_NONE;+#ifdef XML_DTD+ int oldInEntityValue = prologState.inEntityValue;+ prologState.inEntityValue = 1;+#endif /* XML_DTD */+ /* never return Null for the value argument in EntityDeclHandler,+ since this would indicate an external entity; therefore we+ have to make sure that entityValuePool.start is not null */+ if (!pool->blocks) {+ if (!poolGrow(pool))+ return XML_ERROR_NO_MEMORY;+ }++ for (;;) {+ const char *next;+ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);+ switch (tok) {+ case XML_TOK_PARAM_ENTITY_REF:+#ifdef XML_DTD+ if (isParamEntity || enc != encoding) {+ const XML_Char *name;+ ENTITY *entity;+ name = poolStoreString(&tempPool, enc,+ entityTextPtr + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);+ poolDiscard(&tempPool);+ if (!entity) {+ /* not a well-formedness error - see XML 1.0: WFC Entity Declared */+ /* cannot report skipped entity here - see comments on+ skippedEntityHandler+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, name, 0);+ */+ dtd->keepProcessing = dtd->standalone;+ goto endEntityValue;+ }+ if (entity->open) {+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_RECURSIVE_ENTITY_REF;+ goto endEntityValue;+ }+ if (entity->systemId) {+ if (externalEntityRefHandler) {+ dtd->paramEntityRead = XML_FALSE;+ entity->open = XML_TRUE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId)) {+ entity->open = XML_FALSE;+ result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ goto endEntityValue;+ }+ entity->open = XML_FALSE;+ if (!dtd->paramEntityRead)+ dtd->keepProcessing = dtd->standalone;+ }+ else+ dtd->keepProcessing = dtd->standalone;+ }+ else {+ entity->open = XML_TRUE;+ result = storeEntityValue(parser,+ internalEncoding,+ (char *)entity->textPtr,+ (char *)(entity->textPtr+ + entity->textLen));+ entity->open = XML_FALSE;+ if (result)+ goto endEntityValue;+ }+ break;+ }+#endif /* XML_DTD */+ /* In the internal subset, PE references are not legal+ within markup declarations, e.g entity values in this case. */+ eventPtr = entityTextPtr;+ result = XML_ERROR_PARAM_ENTITY_REF;+ goto endEntityValue;+ case XML_TOK_NONE:+ result = XML_ERROR_NONE;+ goto endEntityValue;+ case XML_TOK_ENTITY_REF:+ case XML_TOK_DATA_CHARS:+ if (!poolAppend(pool, enc, entityTextPtr, next)) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ break;+ case XML_TOK_TRAILING_CR:+ next = entityTextPtr + enc->minBytesPerChar;+ /* fall through */+ case XML_TOK_DATA_NEWLINE:+ if (pool->end == pool->ptr && !poolGrow(pool)) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ *(pool->ptr)++ = 0xA;+ break;+ case XML_TOK_CHAR_REF:+ {+ XML_Char buf[XML_ENCODE_MAX];+ int i;+ int n = XmlCharRefNumber(enc, entityTextPtr);+ if (n < 0) {+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_BAD_CHAR_REF;+ goto endEntityValue;+ }+ n = XmlEncode(n, (ICHAR *)buf);+ if (!n) {+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_BAD_CHAR_REF;+ goto endEntityValue;+ }+ for (i = 0; i < n; i++) {+ if (pool->end == pool->ptr && !poolGrow(pool)) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ *(pool->ptr)++ = buf[i];+ }+ }+ break;+ case XML_TOK_PARTIAL:+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_INVALID_TOKEN;+ goto endEntityValue;+ case XML_TOK_INVALID:+ if (enc == encoding)+ eventPtr = next;+ result = XML_ERROR_INVALID_TOKEN;+ goto endEntityValue;+ default:+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_UNEXPECTED_STATE;+ goto endEntityValue;+ }+ entityTextPtr = next;+ }+endEntityValue:+#ifdef XML_DTD+ prologState.inEntityValue = oldInEntityValue;+#endif /* XML_DTD */+ return result;+}++static void FASTCALL+normalizeLines(XML_Char *s)+{+ XML_Char *p;+ for (;; s++) {+ if (*s == XML_T('\0'))+ return;+ if (*s == 0xD)+ break;+ }+ p = s;+ do {+ if (*s == 0xD) {+ *p++ = 0xA;+ if (*++s == 0xA)+ s++;+ }+ else+ *p++ = *s++;+ } while (*s);+ *p = XML_T('\0');+}++static int+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end)+{+ const XML_Char *target;+ XML_Char *data;+ const char *tem;+ if (!processingInstructionHandler) {+ if (defaultHandler)+ reportDefault(parser, enc, start, end);+ return 1;+ }+ start += enc->minBytesPerChar * 2;+ tem = start + XmlNameLength(enc, start);+ target = poolStoreString(&tempPool, enc, start, tem);+ if (!target)+ return 0;+ poolFinish(&tempPool);+ data = poolStoreString(&tempPool, enc,+ XmlSkipS(enc, tem),+ end - enc->minBytesPerChar*2);+ if (!data)+ return 0;+ normalizeLines(data);+ processingInstructionHandler(handlerArg, target, data);+ poolClear(&tempPool);+ return 1;+}++static int+reportComment(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end)+{+ XML_Char *data;+ if (!commentHandler) {+ if (defaultHandler)+ reportDefault(parser, enc, start, end);+ return 1;+ }+ data = poolStoreString(&tempPool,+ enc,+ start + enc->minBytesPerChar * 4,+ end - enc->minBytesPerChar * 3);+ if (!data)+ return 0;+ normalizeLines(data);+ commentHandler(handlerArg, data);+ poolClear(&tempPool);+ return 1;+}++static void+reportDefault(XML_Parser parser, const ENCODING *enc,+ const char *s, const char *end)+{+ if (MUST_CONVERT(enc, s)) {+ enum XML_Convert_Result convert_res;+ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ do {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);+ *eventEndPP = s;+ defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));+ *eventPP = s;+ } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));+ }+ else+ defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));+}+++static int+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,+ XML_Bool isId, const XML_Char *value, XML_Parser parser)+{+ DEFAULT_ATTRIBUTE *att;+ if (value || isId) {+ /* The handling of default attributes gets messed up if we have+ a default which duplicates a non-default. */+ int i;+ for (i = 0; i < type->nDefaultAtts; i++)+ if (attId == type->defaultAtts[i].id)+ return 1;+ if (isId && !type->idAtt && !attId->xmlns)+ type->idAtt = attId;+ }+ if (type->nDefaultAtts == type->allocDefaultAtts) {+ if (type->allocDefaultAtts == 0) {+ type->allocDefaultAtts = 8;+ type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts+ * sizeof(DEFAULT_ATTRIBUTE));+ if (!type->defaultAtts)+ return 0;+ }+ else {+ DEFAULT_ATTRIBUTE *temp;+ int count = type->allocDefaultAtts * 2;+ temp = (DEFAULT_ATTRIBUTE *)+ REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));+ if (temp == NULL)+ return 0;+ type->allocDefaultAtts = count;+ type->defaultAtts = temp;+ }+ }+ att = type->defaultAtts + type->nDefaultAtts;+ att->id = attId;+ att->value = value;+ att->isCdata = isCdata;+ if (!isCdata)+ attId->maybeTokenized = XML_TRUE;+ type->nDefaultAtts += 1;+ return 1;+}++static int+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ const XML_Char *name;+ for (name = elementType->name; *name; name++) {+ if (*name == XML_T(ASCII_COLON)) {+ PREFIX *prefix;+ const XML_Char *s;+ for (s = elementType->name; s != name; s++) {+ if (!poolAppendChar(&dtd->pool, *s))+ return 0;+ }+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))+ return 0;+ prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),+ sizeof(PREFIX));+ if (!prefix)+ return 0;+ if (prefix->name == poolStart(&dtd->pool))+ poolFinish(&dtd->pool);+ else+ poolDiscard(&dtd->pool);+ elementType->prefix = prefix;++ }+ }+ return 1;+}++static ATTRIBUTE_ID *+getAttributeId(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ ATTRIBUTE_ID *id;+ const XML_Char *name;+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))+ return NULL;+ name = poolStoreString(&dtd->pool, enc, start, end);+ if (!name)+ return NULL;+ /* skip quotation mark - its storage will be re-used (like in name[-1]) */+ ++name;+ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));+ if (!id)+ return NULL;+ if (id->name != name)+ poolDiscard(&dtd->pool);+ else {+ poolFinish(&dtd->pool);+ if (!ns)+ ;+ else if (name[0] == XML_T(ASCII_x)+ && name[1] == XML_T(ASCII_m)+ && name[2] == XML_T(ASCII_l)+ && name[3] == XML_T(ASCII_n)+ && name[4] == XML_T(ASCII_s)+ && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {+ if (name[5] == XML_T('\0'))+ id->prefix = &dtd->defaultPrefix;+ else+ id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));+ id->xmlns = XML_TRUE;+ }+ else {+ int i;+ for (i = 0; name[i]; i++) {+ /* attributes without prefix are *not* in the default namespace */+ if (name[i] == XML_T(ASCII_COLON)) {+ int j;+ for (j = 0; j < i; j++) {+ if (!poolAppendChar(&dtd->pool, name[j]))+ return NULL;+ }+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))+ return NULL;+ id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),+ sizeof(PREFIX));+ if (!id->prefix)+ return NULL;+ if (id->prefix->name == poolStart(&dtd->pool))+ poolFinish(&dtd->pool);+ else+ poolDiscard(&dtd->pool);+ break;+ }+ }+ }+ }+ return id;+}++#define CONTEXT_SEP XML_T(ASCII_FF)++static const XML_Char *+getContext(XML_Parser parser)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ HASH_TABLE_ITER iter;+ XML_Bool needSep = XML_FALSE;++ if (dtd->defaultPrefix.binding) {+ int i;+ int len;+ if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))+ return NULL;+ len = dtd->defaultPrefix.binding->uriLen;+ if (namespaceSeparator)+ len--;+ for (i = 0; i < len; i++)+ if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))+ return NULL;+ needSep = XML_TRUE;+ }++ hashTableIterInit(&iter, &(dtd->prefixes));+ for (;;) {+ int i;+ int len;+ const XML_Char *s;+ PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);+ if (!prefix)+ break;+ if (!prefix->binding)+ continue;+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))+ return NULL;+ for (s = prefix->name; *s; s++)+ if (!poolAppendChar(&tempPool, *s))+ return NULL;+ if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))+ return NULL;+ len = prefix->binding->uriLen;+ if (namespaceSeparator)+ len--;+ for (i = 0; i < len; i++)+ if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))+ return NULL;+ needSep = XML_TRUE;+ }+++ hashTableIterInit(&iter, &(dtd->generalEntities));+ for (;;) {+ const XML_Char *s;+ ENTITY *e = (ENTITY *)hashTableIterNext(&iter);+ if (!e)+ break;+ if (!e->open)+ continue;+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))+ return NULL;+ for (s = e->name; *s; s++)+ if (!poolAppendChar(&tempPool, *s))+ return 0;+ needSep = XML_TRUE;+ }++ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return NULL;+ return tempPool.start;+}++static XML_Bool+setContext(XML_Parser parser, const XML_Char *context)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ const XML_Char *s = context;++ while (*context != XML_T('\0')) {+ if (*s == CONTEXT_SEP || *s == XML_T('\0')) {+ ENTITY *e;+ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return XML_FALSE;+ e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);+ if (e)+ e->open = XML_TRUE;+ if (*s != XML_T('\0'))+ s++;+ context = s;+ poolDiscard(&tempPool);+ }+ else if (*s == XML_T(ASCII_EQUALS)) {+ PREFIX *prefix;+ if (poolLength(&tempPool) == 0)+ prefix = &dtd->defaultPrefix;+ else {+ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return XML_FALSE;+ prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),+ sizeof(PREFIX));+ if (!prefix)+ return XML_FALSE;+ if (prefix->name == poolStart(&tempPool)) {+ prefix->name = poolCopyString(&dtd->pool, prefix->name);+ if (!prefix->name)+ return XML_FALSE;+ }+ poolDiscard(&tempPool);+ }+ for (context = s + 1;+ *context != CONTEXT_SEP && *context != XML_T('\0');+ context++)+ if (!poolAppendChar(&tempPool, *context))+ return XML_FALSE;+ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return XML_FALSE;+ if (addBinding(parser, prefix, NULL, poolStart(&tempPool),+ &inheritedBindings) != XML_ERROR_NONE)+ return XML_FALSE;+ poolDiscard(&tempPool);+ if (*context != XML_T('\0'))+ ++context;+ s = context;+ }+ else {+ if (!poolAppendChar(&tempPool, *s))+ return XML_FALSE;+ s++;+ }+ }+ return XML_TRUE;+}++static void FASTCALL+normalizePublicId(XML_Char *publicId)+{+ XML_Char *p = publicId;+ XML_Char *s;+ for (s = publicId; *s; s++) {+ switch (*s) {+ case 0x20:+ case 0xD:+ case 0xA:+ if (p != publicId && p[-1] != 0x20)+ *p++ = 0x20;+ break;+ default:+ *p++ = *s;+ }+ }+ if (p != publicId && p[-1] == 0x20)+ --p;+ *p = XML_T('\0');+}++static DTD *+dtdCreate(const XML_Memory_Handling_Suite *ms)+{+ DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));+ if (p == NULL)+ return p;+ poolInit(&(p->pool), ms);+ poolInit(&(p->entityValuePool), ms);+ hashTableInit(&(p->generalEntities), ms);+ hashTableInit(&(p->elementTypes), ms);+ hashTableInit(&(p->attributeIds), ms);+ hashTableInit(&(p->prefixes), ms);+#ifdef XML_DTD+ p->paramEntityRead = XML_FALSE;+ hashTableInit(&(p->paramEntities), ms);+#endif /* XML_DTD */+ p->defaultPrefix.name = NULL;+ p->defaultPrefix.binding = NULL;++ p->in_eldecl = XML_FALSE;+ p->scaffIndex = NULL;+ p->scaffold = NULL;+ p->scaffLevel = 0;+ p->scaffSize = 0;+ p->scaffCount = 0;+ p->contentStringLen = 0;++ p->keepProcessing = XML_TRUE;+ p->hasParamEntityRefs = XML_FALSE;+ p->standalone = XML_FALSE;+ return p;+}++static void+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)+{+ HASH_TABLE_ITER iter;+ hashTableIterInit(&iter, &(p->elementTypes));+ for (;;) {+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);+ if (!e)+ break;+ if (e->allocDefaultAtts != 0)+ ms->free_fcn(e->defaultAtts);+ }+ hashTableClear(&(p->generalEntities));+#ifdef XML_DTD+ p->paramEntityRead = XML_FALSE;+ hashTableClear(&(p->paramEntities));+#endif /* XML_DTD */+ hashTableClear(&(p->elementTypes));+ hashTableClear(&(p->attributeIds));+ hashTableClear(&(p->prefixes));+ poolClear(&(p->pool));+ poolClear(&(p->entityValuePool));+ p->defaultPrefix.name = NULL;+ p->defaultPrefix.binding = NULL;++ p->in_eldecl = XML_FALSE;++ ms->free_fcn(p->scaffIndex);+ p->scaffIndex = NULL;+ ms->free_fcn(p->scaffold);+ p->scaffold = NULL;++ p->scaffLevel = 0;+ p->scaffSize = 0;+ p->scaffCount = 0;+ p->contentStringLen = 0;++ p->keepProcessing = XML_TRUE;+ p->hasParamEntityRefs = XML_FALSE;+ p->standalone = XML_FALSE;+}++static void+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)+{+ HASH_TABLE_ITER iter;+ hashTableIterInit(&iter, &(p->elementTypes));+ for (;;) {+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);+ if (!e)+ break;+ if (e->allocDefaultAtts != 0)+ ms->free_fcn(e->defaultAtts);+ }+ hashTableDestroy(&(p->generalEntities));+#ifdef XML_DTD+ hashTableDestroy(&(p->paramEntities));+#endif /* XML_DTD */+ hashTableDestroy(&(p->elementTypes));+ hashTableDestroy(&(p->attributeIds));+ hashTableDestroy(&(p->prefixes));+ poolDestroy(&(p->pool));+ poolDestroy(&(p->entityValuePool));+ if (isDocEntity) {+ ms->free_fcn(p->scaffIndex);+ ms->free_fcn(p->scaffold);+ }+ ms->free_fcn(p);+}++/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.+ The new DTD has already been initialized.+*/+static int+dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)+{+ HASH_TABLE_ITER iter;++ /* Copy the prefix table. */++ hashTableIterInit(&iter, &(oldDtd->prefixes));+ for (;;) {+ const XML_Char *name;+ const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);+ if (!oldP)+ break;+ name = poolCopyString(&(newDtd->pool), oldP->name);+ if (!name)+ return 0;+ if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))+ return 0;+ }++ hashTableIterInit(&iter, &(oldDtd->attributeIds));++ /* Copy the attribute id table. */++ for (;;) {+ ATTRIBUTE_ID *newA;+ const XML_Char *name;+ const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);++ if (!oldA)+ break;+ /* Remember to allocate the scratch byte before the name. */+ if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))+ return 0;+ name = poolCopyString(&(newDtd->pool), oldA->name);+ if (!name)+ return 0;+ ++name;+ newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,+ sizeof(ATTRIBUTE_ID));+ if (!newA)+ return 0;+ newA->maybeTokenized = oldA->maybeTokenized;+ if (oldA->prefix) {+ newA->xmlns = oldA->xmlns;+ if (oldA->prefix == &oldDtd->defaultPrefix)+ newA->prefix = &newDtd->defaultPrefix;+ else+ newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),+ oldA->prefix->name, 0);+ }+ }++ /* Copy the element type table. */++ hashTableIterInit(&iter, &(oldDtd->elementTypes));++ for (;;) {+ int i;+ ELEMENT_TYPE *newE;+ const XML_Char *name;+ const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);+ if (!oldE)+ break;+ name = poolCopyString(&(newDtd->pool), oldE->name);+ if (!name)+ return 0;+ newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,+ sizeof(ELEMENT_TYPE));+ if (!newE)+ return 0;+ if (oldE->nDefaultAtts) {+ newE->defaultAtts = (DEFAULT_ATTRIBUTE *)+ ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));+ if (!newE->defaultAtts) {+ return 0;+ }+ }+ if (oldE->idAtt)+ newE->idAtt = (ATTRIBUTE_ID *)+ lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);+ newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;+ if (oldE->prefix)+ newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),+ oldE->prefix->name, 0);+ for (i = 0; i < newE->nDefaultAtts; i++) {+ newE->defaultAtts[i].id = (ATTRIBUTE_ID *)+ lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);+ newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;+ if (oldE->defaultAtts[i].value) {+ newE->defaultAtts[i].value+ = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);+ if (!newE->defaultAtts[i].value)+ return 0;+ }+ else+ newE->defaultAtts[i].value = NULL;+ }+ }++ /* Copy the entity tables. */+ if (!copyEntityTable(oldParser,+ &(newDtd->generalEntities),+ &(newDtd->pool),+ &(oldDtd->generalEntities)))+ return 0;++#ifdef XML_DTD+ if (!copyEntityTable(oldParser,+ &(newDtd->paramEntities),+ &(newDtd->pool),+ &(oldDtd->paramEntities)))+ return 0;+ newDtd->paramEntityRead = oldDtd->paramEntityRead;+#endif /* XML_DTD */++ newDtd->keepProcessing = oldDtd->keepProcessing;+ newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;+ newDtd->standalone = oldDtd->standalone;++ /* Don't want deep copying for scaffolding */+ newDtd->in_eldecl = oldDtd->in_eldecl;+ newDtd->scaffold = oldDtd->scaffold;+ newDtd->contentStringLen = oldDtd->contentStringLen;+ newDtd->scaffSize = oldDtd->scaffSize;+ newDtd->scaffLevel = oldDtd->scaffLevel;+ newDtd->scaffIndex = oldDtd->scaffIndex;++ return 1;+} /* End dtdCopy */++static int+copyEntityTable(XML_Parser oldParser,+ HASH_TABLE *newTable,+ STRING_POOL *newPool,+ const HASH_TABLE *oldTable)+{+ HASH_TABLE_ITER iter;+ const XML_Char *cachedOldBase = NULL;+ const XML_Char *cachedNewBase = NULL;++ hashTableIterInit(&iter, oldTable);++ for (;;) {+ ENTITY *newE;+ const XML_Char *name;+ const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);+ if (!oldE)+ break;+ name = poolCopyString(newPool, oldE->name);+ if (!name)+ return 0;+ newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));+ if (!newE)+ return 0;+ if (oldE->systemId) {+ const XML_Char *tem = poolCopyString(newPool, oldE->systemId);+ if (!tem)+ return 0;+ newE->systemId = tem;+ if (oldE->base) {+ if (oldE->base == cachedOldBase)+ newE->base = cachedNewBase;+ else {+ cachedOldBase = oldE->base;+ tem = poolCopyString(newPool, cachedOldBase);+ if (!tem)+ return 0;+ cachedNewBase = newE->base = tem;+ }+ }+ if (oldE->publicId) {+ tem = poolCopyString(newPool, oldE->publicId);+ if (!tem)+ return 0;+ newE->publicId = tem;+ }+ }+ else {+ const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,+ oldE->textLen);+ if (!tem)+ return 0;+ newE->textPtr = tem;+ newE->textLen = oldE->textLen;+ }+ if (oldE->notation) {+ const XML_Char *tem = poolCopyString(newPool, oldE->notation);+ if (!tem)+ return 0;+ newE->notation = tem;+ }+ newE->is_param = oldE->is_param;+ newE->is_internal = oldE->is_internal;+ }+ return 1;+}++#define INIT_POWER 6++static XML_Bool FASTCALL+keyeq(KEY s1, KEY s2)+{+ for (; *s1 == *s2; s1++, s2++)+ if (*s1 == 0)+ return XML_TRUE;+ return XML_FALSE;+}++static size_t+keylen(KEY s)+{+ size_t len = 0;+ for (; *s; s++, len++);+ return len;+}++static void+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)+{+ key->k[0] = 0;+ key->k[1] = get_hash_secret_salt(parser);+}++static unsigned long FASTCALL+hash(XML_Parser parser, KEY s)+{+ struct siphash state;+ struct sipkey key;+ (void)sip_tobin;+ (void)sip24_valid;+ copy_salt_to_sipkey(parser, &key);+ sip24_init(&state, &key);+ sip24_update(&state, s, keylen(s) * sizeof(XML_Char));+ return (unsigned long)sip24_final(&state);+}++static NAMED *+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)+{+ size_t i;+ if (table->size == 0) {+ size_t tsize;+ if (!createSize)+ return NULL;+ table->power = INIT_POWER;+ /* table->size is a power of 2 */+ table->size = (size_t)1 << INIT_POWER;+ tsize = table->size * sizeof(NAMED *);+ table->v = (NAMED **)table->mem->malloc_fcn(tsize);+ if (!table->v) {+ table->size = 0;+ return NULL;+ }+ memset(table->v, 0, tsize);+ i = hash(parser, name) & ((unsigned long)table->size - 1);+ }+ else {+ unsigned long h = hash(parser, name);+ unsigned long mask = (unsigned long)table->size - 1;+ unsigned char step = 0;+ i = h & mask;+ while (table->v[i]) {+ if (keyeq(name, table->v[i]->name))+ return table->v[i];+ if (!step)+ step = PROBE_STEP(h, mask, table->power);+ i < step ? (i += table->size - step) : (i -= step);+ }+ if (!createSize)+ return NULL;++ /* check for overflow (table is half full) */+ if (table->used >> (table->power - 1)) {+ unsigned char newPower = table->power + 1;+ size_t newSize = (size_t)1 << newPower;+ unsigned long newMask = (unsigned long)newSize - 1;+ size_t tsize = newSize * sizeof(NAMED *);+ NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);+ if (!newV)+ return NULL;+ memset(newV, 0, tsize);+ for (i = 0; i < table->size; i++)+ if (table->v[i]) {+ unsigned long newHash = hash(parser, table->v[i]->name);+ size_t j = newHash & newMask;+ step = 0;+ while (newV[j]) {+ if (!step)+ step = PROBE_STEP(newHash, newMask, newPower);+ j < step ? (j += newSize - step) : (j -= step);+ }+ newV[j] = table->v[i];+ }+ table->mem->free_fcn(table->v);+ table->v = newV;+ table->power = newPower;+ table->size = newSize;+ i = h & newMask;+ step = 0;+ while (table->v[i]) {+ if (!step)+ step = PROBE_STEP(h, newMask, newPower);+ i < step ? (i += newSize - step) : (i -= step);+ }+ }+ }+ table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);+ if (!table->v[i])+ return NULL;+ memset(table->v[i], 0, createSize);+ table->v[i]->name = name;+ (table->used)++;+ return table->v[i];+}++static void FASTCALL+hashTableClear(HASH_TABLE *table)+{+ size_t i;+ for (i = 0; i < table->size; i++) {+ table->mem->free_fcn(table->v[i]);+ table->v[i] = NULL;+ }+ table->used = 0;+}++static void FASTCALL+hashTableDestroy(HASH_TABLE *table)+{+ size_t i;+ for (i = 0; i < table->size; i++)+ table->mem->free_fcn(table->v[i]);+ table->mem->free_fcn(table->v);+}++static void FASTCALL+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)+{+ p->power = 0;+ p->size = 0;+ p->used = 0;+ p->v = NULL;+ p->mem = ms;+}++static void FASTCALL+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)+{+ iter->p = table->v;+ iter->end = iter->p + table->size;+}++static NAMED * FASTCALL+hashTableIterNext(HASH_TABLE_ITER *iter)+{+ while (iter->p != iter->end) {+ NAMED *tem = *(iter->p)++;+ if (tem)+ return tem;+ }+ return NULL;+}++static void FASTCALL+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)+{+ pool->blocks = NULL;+ pool->freeBlocks = NULL;+ pool->start = NULL;+ pool->ptr = NULL;+ pool->end = NULL;+ pool->mem = ms;+}++static void FASTCALL+poolClear(STRING_POOL *pool)+{+ if (!pool->freeBlocks)+ pool->freeBlocks = pool->blocks;+ else {+ BLOCK *p = pool->blocks;+ while (p) {+ BLOCK *tem = p->next;+ p->next = pool->freeBlocks;+ pool->freeBlocks = p;+ p = tem;+ }+ }+ pool->blocks = NULL;+ pool->start = NULL;+ pool->ptr = NULL;+ pool->end = NULL;+}++static void FASTCALL+poolDestroy(STRING_POOL *pool)+{+ BLOCK *p = pool->blocks;+ while (p) {+ BLOCK *tem = p->next;+ pool->mem->free_fcn(p);+ p = tem;+ }+ p = pool->freeBlocks;+ while (p) {+ BLOCK *tem = p->next;+ pool->mem->free_fcn(p);+ p = tem;+ }+}++static XML_Char *+poolAppend(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end)+{+ if (!pool->ptr && !poolGrow(pool))+ return NULL;+ for (;;) {+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))+ break;+ if (!poolGrow(pool))+ return NULL;+ }+ return pool->start;+}++static const XML_Char * FASTCALL+poolCopyString(STRING_POOL *pool, const XML_Char *s)+{+ do {+ if (!poolAppendChar(pool, *s))+ return NULL;+ } while (*s++);+ s = pool->start;+ poolFinish(pool);+ return s;+}++static const XML_Char *+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)+{+ if (!pool->ptr && !poolGrow(pool))+ return NULL;+ for (; n > 0; --n, s++) {+ if (!poolAppendChar(pool, *s))+ return NULL;+ }+ s = pool->start;+ poolFinish(pool);+ return s;+}++static const XML_Char * FASTCALL+poolAppendString(STRING_POOL *pool, const XML_Char *s)+{+ while (*s) {+ if (!poolAppendChar(pool, *s))+ return NULL;+ s++;+ }+ return pool->start;+}++static XML_Char *+poolStoreString(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end)+{+ if (!poolAppend(pool, enc, ptr, end))+ return NULL;+ if (pool->ptr == pool->end && !poolGrow(pool))+ return NULL;+ *(pool->ptr)++ = 0;+ return pool->start;+}++static size_t+poolBytesToAllocateFor(int blockSize)+{+ /* Unprotected math would be:+ ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);+ **+ ** Detect overflow, avoiding _signed_ overflow undefined behavior+ ** For a + b * c we check b * c in isolation first, so that addition of a+ ** on top has no chance of making us accept a small non-negative number+ */+ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */++ if (blockSize <= 0)+ return 0;++ if (blockSize > (int)(INT_MAX / stretch))+ return 0;++ {+ const int stretchedBlockSize = blockSize * (int)stretch;+ const int bytesToAllocate = (int)(+ offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);+ if (bytesToAllocate < 0)+ return 0;++ return (size_t)bytesToAllocate;+ }+}++static XML_Bool FASTCALL+poolGrow(STRING_POOL *pool)+{+ if (pool->freeBlocks) {+ if (pool->start == 0) {+ pool->blocks = pool->freeBlocks;+ pool->freeBlocks = pool->freeBlocks->next;+ pool->blocks->next = NULL;+ pool->start = pool->blocks->s;+ pool->end = pool->start + pool->blocks->size;+ pool->ptr = pool->start;+ return XML_TRUE;+ }+ if (pool->end - pool->start < pool->freeBlocks->size) {+ BLOCK *tem = pool->freeBlocks->next;+ pool->freeBlocks->next = pool->blocks;+ pool->blocks = pool->freeBlocks;+ pool->freeBlocks = tem;+ memcpy(pool->blocks->s, pool->start,+ (pool->end - pool->start) * sizeof(XML_Char));+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);+ pool->start = pool->blocks->s;+ pool->end = pool->start + pool->blocks->size;+ return XML_TRUE;+ }+ }+ if (pool->blocks && pool->start == pool->blocks->s) {+ BLOCK *temp;+ int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);+ size_t bytesToAllocate;++ if (blockSize < 0)+ return XML_FALSE;++ bytesToAllocate = poolBytesToAllocateFor(blockSize);+ if (bytesToAllocate == 0)+ return XML_FALSE;++ temp = (BLOCK *)+ pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);+ if (temp == NULL)+ return XML_FALSE;+ pool->blocks = temp;+ pool->blocks->size = blockSize;+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);+ pool->start = pool->blocks->s;+ pool->end = pool->start + blockSize;+ }+ else {+ BLOCK *tem;+ int blockSize = (int)(pool->end - pool->start);+ size_t bytesToAllocate;++ if (blockSize < 0)+ return XML_FALSE;++ if (blockSize < INIT_BLOCK_SIZE)+ blockSize = INIT_BLOCK_SIZE;+ else {+ /* Detect overflow, avoiding _signed_ overflow undefined behavior */+ if ((int)((unsigned)blockSize * 2U) < 0) {+ return XML_FALSE;+ }+ blockSize *= 2;+ }++ bytesToAllocate = poolBytesToAllocateFor(blockSize);+ if (bytesToAllocate == 0)+ return XML_FALSE;++ tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);+ if (!tem)+ return XML_FALSE;+ tem->size = blockSize;+ tem->next = pool->blocks;+ pool->blocks = tem;+ if (pool->ptr != pool->start)+ memcpy(tem->s, pool->start,+ (pool->ptr - pool->start) * sizeof(XML_Char));+ pool->ptr = tem->s + (pool->ptr - pool->start);+ pool->start = tem->s;+ pool->end = tem->s + blockSize;+ }+ return XML_TRUE;+}++static int FASTCALL+nextScaffoldPart(XML_Parser parser)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ CONTENT_SCAFFOLD * me;+ int next;++ if (!dtd->scaffIndex) {+ dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));+ if (!dtd->scaffIndex)+ return -1;+ dtd->scaffIndex[0] = 0;+ }++ if (dtd->scaffCount >= dtd->scaffSize) {+ CONTENT_SCAFFOLD *temp;+ if (dtd->scaffold) {+ temp = (CONTENT_SCAFFOLD *)+ REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));+ if (temp == NULL)+ return -1;+ dtd->scaffSize *= 2;+ }+ else {+ temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS+ * sizeof(CONTENT_SCAFFOLD));+ if (temp == NULL)+ return -1;+ dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;+ }+ dtd->scaffold = temp;+ }+ next = dtd->scaffCount++;+ me = &dtd->scaffold[next];+ if (dtd->scaffLevel) {+ CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];+ if (parent->lastchild) {+ dtd->scaffold[parent->lastchild].nextsib = next;+ }+ if (!parent->childcnt)+ parent->firstchild = next;+ parent->lastchild = next;+ parent->childcnt++;+ }+ me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;+ return next;+}++static void+build_node(XML_Parser parser,+ int src_node,+ XML_Content *dest,+ XML_Content **contpos,+ XML_Char **strpos)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ dest->type = dtd->scaffold[src_node].type;+ dest->quant = dtd->scaffold[src_node].quant;+ if (dest->type == XML_CTYPE_NAME) {+ const XML_Char *src;+ dest->name = *strpos;+ src = dtd->scaffold[src_node].name;+ for (;;) {+ *(*strpos)++ = *src;+ if (!*src)+ break;+ src++;+ }+ dest->numchildren = 0;+ dest->children = NULL;+ }+ else {+ unsigned int i;+ int cn;+ dest->numchildren = dtd->scaffold[src_node].childcnt;+ dest->children = *contpos;+ *contpos += dest->numchildren;+ for (i = 0, cn = dtd->scaffold[src_node].firstchild;+ i < dest->numchildren;+ i++, cn = dtd->scaffold[cn].nextsib) {+ build_node(parser, cn, &(dest->children[i]), contpos, strpos);+ }+ dest->name = NULL;+ }+}++static XML_Content *+build_model (XML_Parser parser)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ XML_Content *ret;+ XML_Content *cpos;+ XML_Char * str;+ int allocsize = (dtd->scaffCount * sizeof(XML_Content)+ + (dtd->contentStringLen * sizeof(XML_Char)));++ ret = (XML_Content *)MALLOC(allocsize);+ if (!ret)+ return NULL;++ str = (XML_Char *) (&ret[dtd->scaffCount]);+ cpos = &ret[1];++ build_node(parser, 0, ret, &cpos, &str);+ return ret;+}++static ELEMENT_TYPE *+getElementType(XML_Parser parser,+ const ENCODING *enc,+ const char *ptr,+ const char *end)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);+ ELEMENT_TYPE *ret;++ if (!name)+ return NULL;+ ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); if (!ret) return NULL; if (ret->name != name)
cbits/xmlrole.c view
@@ -4,19 +4,13 @@ #include <stddef.h> -#ifdef COMPILED_FROM_DSP+#ifdef _WIN32 #include "winconfig.h"-#elif defined(MACOS_CLASSIC)-#include "macconfig.h"-#elif defined(__amigaos4__)-#include "amigaconfig.h"-#elif defined(__WATCOMC__)-#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include <expat_config.h> #endif-#endif /* ndef COMPILED_FROM_DSP */+#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h"@@ -195,9 +189,9 @@ static int PTRCALL prolog2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -216,9 +210,9 @@ static int PTRCALL doctype0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -264,9 +258,9 @@ static int PTRCALL doctype2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -281,9 +275,9 @@ static int PTRCALL doctype3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -298,9 +292,9 @@ static int PTRCALL doctype4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -318,9 +312,9 @@ static int PTRCALL doctype5(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -437,9 +431,9 @@ static int PTRCALL entity0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -457,9 +451,9 @@ static int PTRCALL entity1(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -502,9 +496,9 @@ static int PTRCALL entity3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -519,9 +513,9 @@ static int PTRCALL entity4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -559,9 +553,9 @@ static int PTRCALL entity6(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -605,9 +599,9 @@ static int PTRCALL entity8(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -622,9 +616,9 @@ static int PTRCALL entity9(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -639,9 +633,9 @@ static int PTRCALL entity10(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -656,9 +650,9 @@ static int PTRCALL notation0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -697,9 +691,9 @@ static int PTRCALL notation2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -714,9 +708,9 @@ static int PTRCALL notation3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -732,9 +726,9 @@ static int PTRCALL notation4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -753,9 +747,9 @@ static int PTRCALL attlist0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -771,9 +765,9 @@ static int PTRCALL attlist1(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -833,9 +827,9 @@ static int PTRCALL attlist3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -852,9 +846,9 @@ static int PTRCALL attlist4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -872,9 +866,9 @@ static int PTRCALL attlist5(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -889,9 +883,9 @@ static int PTRCALL attlist6(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -906,9 +900,9 @@ static int PTRCALL attlist7(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -967,9 +961,9 @@ static int PTRCALL attlist9(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -984,9 +978,9 @@ static int PTRCALL element0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1072,9 +1066,9 @@ static int PTRCALL element3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1097,9 +1091,9 @@ static int PTRCALL element4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1115,9 +1109,9 @@ static int PTRCALL element5(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1136,9 +1130,9 @@ static int PTRCALL element6(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1166,9 +1160,9 @@ static int PTRCALL element7(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1240,9 +1234,9 @@ static int PTRCALL condSect1(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1258,9 +1252,9 @@ static int PTRCALL condSect2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1277,9 +1271,9 @@ static int PTRCALL declClose(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1292,11 +1286,11 @@ } static int PTRCALL-error(PROLOG_STATE *state,- int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+error(PROLOG_STATE *UNUSED_P(state),+ int UNUSED_P(tok),+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { return XML_ROLE_NONE; }
cbits/xmltok.c view
@@ -4,19 +4,13 @@ #include <stddef.h> -#ifdef COMPILED_FROM_DSP+#ifdef _WIN32 #include "winconfig.h"-#elif defined(MACOS_CLASSIC)-#include "macconfig.h"-#elif defined(__amigaos4__)-#include "amigaconfig.h"-#elif defined(__WATCOMC__)-#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include <expat_config.h> #endif-#endif /* ndef COMPILED_FROM_DSP */+#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h"@@ -46,7 +40,7 @@ #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) #define UCS2_GET_NAMING(pages, hi, lo) \- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))+ (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@@ -56,7 +50,7 @@ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) \ + ((((byte)[1]) >> 5) & 1)] \- & (1 << (((byte)[1]) & 0x1F)))+ & (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@@ -69,7 +63,7 @@ << 3) \ + ((((byte)[1]) & 3) << 1) \ + ((((byte)[2]) >> 5) & 1)] \- & (1 << (((byte)[2]) & 0x1F)))+ & (1u << (((byte)[2]) & 0x1F))) #define UTF8_GET_NAMING(pages, p, n) \ ((n) == 2 \@@ -122,19 +116,19 @@ ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) static int PTRFASTCALL-isNever(const ENCODING *enc, const char *p)+isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p)) { return 0; } static int PTRFASTCALL-utf8_isName2(const ENCODING *enc, const char *p)+utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int PTRFASTCALL-utf8_isName3(const ENCODING *enc, const char *p)+utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); }@@ -142,13 +136,13 @@ #define utf8_isName4 isNever static int PTRFASTCALL-utf8_isNmstrt2(const ENCODING *enc, const char *p)+utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int PTRFASTCALL-utf8_isNmstrt3(const ENCODING *enc, const char *p)+utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); }@@ -156,19 +150,19 @@ #define utf8_isNmstrt4 isNever static int PTRFASTCALL-utf8_isInvalid2(const ENCODING *enc, const char *p)+utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID2((const unsigned char *)p); } static int PTRFASTCALL-utf8_isInvalid3(const ENCODING *enc, const char *p)+utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID3((const unsigned char *)p); } static int PTRFASTCALL-utf8_isInvalid4(const ENCODING *enc, const char *p)+utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID4((const unsigned char *)p); }@@ -222,6 +216,17 @@ 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"@@ -318,39 +323,89 @@ UTF8_cval4 = 0xf0 }; -static void PTRCALL-utf8_toUtf8(const ENCODING *enc,+void+align_limit_to_full_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 *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { char *to; const char *from;- if (fromLim - *fromP > toLim - *toP) {- /* Avoid copying partial characters. */- for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)- if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)- break;- }- for (to = *toP, from = *fromP; from != fromLim; from++, to++)+ const char *fromLimInitial = fromLim;++ /* Avoid copying partial characters. */+ align_limit_to_full_utf8_characters(*fromP, &fromLim);++ for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++) *to = *from; *fromP = from; *toP = to;++ if (fromLim < fromLimInitial)+ return XML_CONVERT_INPUT_INCOMPLETE;+ else if ((to == toLim) && (from < fromLim))+ return XML_CONVERT_OUTPUT_EXHAUSTED;+ else+ return XML_CONVERT_COMPLETED; } -static void PTRCALL+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) {+ 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;@@ -358,8 +413,14 @@ case BT_LEAD4: { unsigned long n;- if (to + 1 == toLim)+ 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;@@ -374,9 +435,12 @@ break; } }+ if (from < fromLim)+ res = XML_CONVERT_OUTPUT_EXHAUSTED; after: *fromP = from; *toP = to;+ return res; } #ifdef XML_NS@@ -425,38 +489,43 @@ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; -static void PTRCALL-latin1_toUtf8(const ENCODING *enc,+static enum XML_Convert_Result PTRCALL+latin1_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { for (;;) { unsigned char c; if (*fromP == fromLim)- break;+ return XML_CONVERT_COMPLETED; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = (char)((c >> 6) | UTF8_cval2); *(*toP)++ = (char)((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; } } } -static void PTRCALL-latin1_toUtf16(const ENCODING *enc,+static enum XML_Convert_Result PTRCALL+latin1_toUtf16(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) {- while (*fromP != fromLim && *toP != toLim)+ 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@@ -467,7 +536,7 @@ #include "asciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; #endif@@ -480,16 +549,21 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; -static void PTRCALL-ascii_toUtf8(const ENCODING *enc,+static enum XML_Convert_Result PTRCALL+ascii_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) {- while (*fromP != fromLim && *toP != toLim)+ 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@@ -500,7 +574,7 @@ #include "asciitab.h" /* BT_NONXML == 0 */ },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; #endif@@ -513,7 +587,7 @@ #undef BT_COLON /* BT_NONXML == 0 */ },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; static int PTRFASTCALL@@ -536,13 +610,14 @@ } #define DEFINE_UTF16_TO_UTF8(E) \-static void PTRCALL \-E ## toUtf8(const ENCODING *enc, \+static enum XML_Convert_Result PTRCALL \+E ## toUtf8(const ENCODING *UNUSED_P(enc), \ const char **fromP, const char *fromLim, \ char **toP, const char *toLim) \ { \- const char *from; \- for (from = *fromP; from != fromLim; from += 2) { \+ const char *from = *fromP; \+ 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); \@@ -552,7 +627,7 @@ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = lo; \ break; \@@ -562,7 +637,7 @@ case 0x4: case 0x5: case 0x6: case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \@@ -570,7 +645,7 @@ default: \ if (toLim - *toP < 3) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \@@ -580,8 +655,12 @@ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \- return; \+ 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)++ = ((plane >> 2) | UTF8_cval4); \ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \@@ -596,20 +675,32 @@ } \ } \ *fromP = from; \+ if (from < fromLim) \+ return XML_CONVERT_INPUT_INCOMPLETE; \+ else \+ return XML_CONVERT_COMPLETED; \ } #define DEFINE_UTF16_TO_UTF16(E) \-static void PTRCALL \-E ## toUtf16(const ENCODING *enc, \+static enum XML_Convert_Result PTRCALL \+E ## toUtf16(const ENCODING *UNUSED_P(enc), \ const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) \ { \+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \+ 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) \+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ fromLim -= 2; \- for (; *fromP != fromLim && *toP != toLim; *fromP += 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) \@@ -726,7 +817,7 @@ #include "asciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif@@ -745,7 +836,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #if BYTEORDER != 4321@@ -758,7 +849,7 @@ #include "iasciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif@@ -771,7 +862,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif@@ -867,7 +958,7 @@ #include "asciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif@@ -886,7 +977,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #if BYTEORDER != 1234@@ -899,7 +990,7 @@ #include "iasciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif@@ -912,7 +1003,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif@@ -938,7 +1029,7 @@ } static void PTRCALL-initUpdatePosition(const ENCODING *enc, const char *ptr,+initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, POSITION *pos) { normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);@@ -1288,7 +1379,7 @@ return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } -static void PTRCALL+static enum XML_Convert_Result PTRCALL unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim)@@ -1299,21 +1390,21 @@ const char *utf8; int n; if (*fromP == fromLim)- break;+ 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)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; utf8 = buf; *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else { if (n > toLim - *toP)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; } do {@@ -1322,13 +1413,13 @@ } } -static void PTRCALL+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) {+ while (*fromP < fromLim && *toP < toLim) { unsigned short c = uenc->utf16[(unsigned char)**fromP]; if (c == 0) { c = (unsigned short)@@ -1340,12 +1431,17 @@ (*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, + CONVERTER convert, void *userData) { int i;@@ -1503,7 +1599,7 @@ { const ENCODING **encPtr; - if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; encPtr = enc->encPtr; if (ptr + 1 == end) {@@ -1639,7 +1735,7 @@ ENCODING * XmlInitUnknownEncodingNS(void *mem, int *table,- CONVERTER convert, + CONVERTER convert, void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
cbits/xmltok.h view
@@ -130,6 +130,12 @@ const char *, const char **); +enum XML_Convert_Result {+ XML_CONVERT_COMPLETED = 0,+ XML_CONVERT_INPUT_INCOMPLETE = 1,+ XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */+};+ struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES];@@ -158,12 +164,12 @@ const char *ptr, const char *end, const char **badPtr);- void (PTRCALL *utf8Convert)(const ENCODING *enc,+ enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim);- void (PTRCALL *utf16Convert)(const ENCODING *enc,+ enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP,
cbits/xmltok_impl.c view
@@ -87,27 +87,45 @@ #define PREFIX(ident) ident #endif ++#define HAS_CHARS(enc, ptr, end, count) \+ (end - ptr >= count * MINBPC(enc))++#define HAS_CHAR(enc, ptr, end) \+ HAS_CHARS(enc, ptr, end, 1)++#define REQUIRE_CHARS(enc, ptr, end, count) \+ { \+ if (! HAS_CHARS(enc, ptr, end, count)) { \+ return XML_TOK_PARTIAL; \+ } \+ }++#define REQUIRE_CHAR(enc, ptr, end) \+ REQUIRE_CHARS(enc, ptr, end, 1)++ /* ptr points to character following "<!-" */ static int PTRCALL PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr != end) {+ if (HAS_CHAR(enc, ptr, end)) { if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { *nextTokPtr = ptr; return XML_TOK_INVALID; } ptr += MINBPC(enc);- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_MINUS:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID;@@ -131,8 +149,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);@@ -147,11 +164,10 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { case BT_PERCNT:- if (ptr + MINBPC(enc) == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHARS(enc, ptr, end, 2); /* don't allow <!ENTITY% foo "whatever"> */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:@@ -175,7 +191,7 @@ } static int PTRCALL-PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,+PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, int *tokPtr) { int upper = 0;@@ -225,15 +241,14 @@ { int tok; const char *target = ptr;- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF:@@ -242,13 +257,12 @@ return XML_TOK_INVALID; } ptr += MINBPC(enc);- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_QUEST: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr + MINBPC(enc); return tok;@@ -266,8 +280,7 @@ return XML_TOK_INVALID; } ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr + MINBPC(enc); return tok;@@ -282,15 +295,14 @@ } static int PTRCALL-PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,+PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, const char **nextTokPtr) { static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB }; int i; /* CDATA[ */- if (end - ptr < 6 * MINBPC(enc))- return XML_TOK_PARTIAL;+ REQUIRE_CHARS(enc, ptr, end, 6); for (i = 0; i < 6; i++, ptr += MINBPC(enc)) { if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) { *nextTokPtr = ptr;@@ -305,7 +317,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr;@@ -319,13 +331,11 @@ switch (BYTE_TYPE(enc, ptr)) { case BT_RSQB: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break;@@ -334,8 +344,7 @@ return XML_TOK_CDATA_SECT_CLOSE; case BT_CR: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr;@@ -348,7 +357,7 @@ ptr += MINBPC(enc); break; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \@@ -383,19 +392,18 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF:- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: break;@@ -432,7 +440,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr != end) {+ if (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX:@@ -441,7 +449,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX:@@ -464,7 +472,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr != end) {+ if (HAS_CHAR(enc, ptr, end)) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); switch (BYTE_TYPE(enc, ptr)) {@@ -474,7 +482,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: break;@@ -496,8 +504,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM:@@ -506,7 +513,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI:@@ -529,7 +536,7 @@ #ifdef XML_NS int hadColon = 0; #endif- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS@@ -540,8 +547,7 @@ } hadColon = 1; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default:@@ -555,8 +561,7 @@ int t; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); if (t == BT_EQUALS) break;@@ -579,8 +584,7 @@ #endif for (;;) { ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); open = BYTE_TYPE(enc, ptr); if (open == BT_QUOT || open == BT_APOS) break;@@ -598,8 +602,7 @@ /* in attribute value */ for (;;) { int t;- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); if (t == open) break;@@ -624,8 +627,7 @@ } } ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR:@@ -642,8 +644,7 @@ /* ptr points to closing quote */ for (;;) { ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF:@@ -655,8 +656,7 @@ case BT_SOL: sol: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID;@@ -688,13 +688,12 @@ #ifdef XML_NS int hadColon; #endif- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);@@ -716,7 +715,7 @@ hadColon = 0; #endif /* we have a start-tag */- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS@@ -727,8 +726,7 @@ } hadColon = 1; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default:@@ -740,7 +738,7 @@ case BT_S: case BT_CR: case BT_LF: { ptr += MINBPC(enc);- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_GT:@@ -765,8 +763,7 @@ case BT_SOL: sol: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID;@@ -785,7 +782,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr;@@ -803,7 +800,7 @@ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_CR: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc);@@ -814,12 +811,12 @@ return XML_TOK_DATA_NEWLINE; case BT_RSQB: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc);@@ -832,7 +829,7 @@ ptr += MINBPC(enc); break; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \@@ -845,12 +842,12 @@ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_RSQB:- if (ptr + MINBPC(enc) != end) {+ if (HAS_CHARS(enc, ptr, end, 2)) { if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { ptr += MINBPC(enc); break; }- if (ptr + 2*MINBPC(enc) != end) {+ if (HAS_CHARS(enc, ptr, end, 3)) { if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { ptr += MINBPC(enc); break;@@ -884,8 +881,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return -XML_TOK_PERCENT;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:@@ -895,7 +891,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI:@@ -913,15 +909,14 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S:@@ -941,7 +936,7 @@ const char *ptr, const char *end, const char **nextTokPtr) {- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); switch (t) { INVALID_CASES(ptr, nextTokPtr)@@ -950,7 +945,7 @@ ptr += MINBPC(enc); if (t != open) break;- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) {@@ -973,7 +968,7 @@ const char **nextTokPtr) { int tok;- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr;@@ -992,8 +987,7 @@ case BT_LT: { ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_EXCL: return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);@@ -1021,7 +1015,7 @@ case BT_S: case BT_LF: for (;;) { ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF:@@ -1048,11 +1042,10 @@ return XML_TOK_OPEN_BRACKET; case BT_RSQB: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {- if (ptr + MINBPC(enc) == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHARS(enc, ptr, end, 2); if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { *nextTokPtr = ptr + 2*MINBPC(enc); return XML_TOK_COND_SECT_CLOSE;@@ -1065,7 +1058,7 @@ return XML_TOK_OPEN_PAREN; case BT_RPAR: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST:@@ -1141,7 +1134,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_GT: case BT_RPAR: case BT_COMMA:@@ -1154,8 +1147,7 @@ ptr += MINBPC(enc); switch (tok) { case XML_TOK_NAME:- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)@@ -1204,10 +1196,12 @@ const char *end, const char **nextTokPtr) { const char *start;- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE;+ else if (! HAS_CHAR(enc, ptr, end))+ return XML_TOK_PARTIAL; start = ptr;- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break;@@ -1232,7 +1226,7 @@ case BT_CR: if (ptr == start) { ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc);@@ -1262,10 +1256,12 @@ const char *end, const char **nextTokPtr) { const char *start;- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE;+ else if (! HAS_CHAR(enc, ptr, end))+ return XML_TOK_PARTIAL; start = ptr;- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break;@@ -1294,7 +1290,7 @@ case BT_CR: if (ptr == start) { ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc);@@ -1326,15 +1322,15 @@ end = ptr + n; } }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_LT:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { ++level; ptr += MINBPC(enc);@@ -1342,11 +1338,11 @@ } break; case BT_RSQB:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr += MINBPC(enc); if (level == 0) {@@ -1373,7 +1369,7 @@ { ptr += MINBPC(enc); end -= MINBPC(enc);- for (; ptr != end; ptr += MINBPC(enc)) {+ for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX:@@ -1521,7 +1517,7 @@ } static int PTRFASTCALL-PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)+PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) { int result = 0; /* skip &# */@@ -1565,7 +1561,7 @@ } static int PTRCALL-PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,+PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end) { switch ((end - ptr)/MINBPC(enc)) {@@ -1683,11 +1679,11 @@ } static int PTRCALL-PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,+PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, const char *end1, const char *ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {- if (ptr1 == end1)+ if (end1 - ptr1 < MINBPC(enc)) return 0; if (!CHAR_MATCHES(enc, ptr1, *ptr2)) return 0;@@ -1744,7 +1740,7 @@ const char *end, POSITION *pos) {- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \@@ -1760,7 +1756,7 @@ case BT_CR: pos->lineNumber++; ptr += MINBPC(enc);- if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)+ if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); pos->columnNumber = (XML_Size)-1; break;
hexpat.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: >= 1.6 Name: hexpat-Version: 0.19.10+Version: 0.20.13 Synopsis: XML parser/formatter based on expat Description: This package provides a general purpose Haskell XML library using Expat to@@ -23,24 +23,21 @@ If you want to do interactive I\/O, an obvious option is to use lazy parsing with one of the lazy I\/O functions such as hGetContents. However, this can be problematic in some applications because it doesn't handle I\/O errors properly- and can give no guarantee of timely resource cleanup. In these cases, chunked- I\/O is a better approach: Take a look at the /hexpat-enumerator/ package.+ and can give no guarantee of timely resource cleanup. Because of the generalized+ list, Hexpat is designed to allow for chunked I/O, but as of this writing I haven't+ done a nice integration with enumerator and friends. . /IO/ is filed under /Internal/ because it's low-level and most users won't want it. The other /Internal/ modules are re-exported by /Annotated/, /Tree/ and /Extended/, so you won't need to import them directly. .+ If you have trouble building on Windows, you can try the bundle flag. This will+ make it build from the source of libexpat bundled inside the hexpat package:+ cabal install -f bundle hexpat+ . Credits to Iavor Diatchki and the @xml@ (XML.Light) package for /Proc/ and /Cursor/. Thanks to the many contributors. .- BOUND VS. UNBOUND THREADS: GHC (at least versions 6.12.X) will spawn threads- if you call a safe FFI callback from an unbound thread. This can get out of- control in a busy application. To avoid this, from version 0.19.1 we now delegate- processing to a single worker thread if the calling thread is not bound.- This essentially means that hexpat currently won't exploit multicores very well.- It also means that hexpat may be more efficient on threads spawned with forkOS- (to give you a bound thread) rather than forkIO.- . ChangeLog: 0.15 changes intended to fix a (rare) \"error: a C finalizer called back into Haskell.\" that seemed only to happen only on ghc6.12.X; 0.15.1 Fix broken Annotated parse; 0.16 switch from mtl to transformers; 0.17 fix mapNodeContainer & rename some things.;@@ -52,7 +49,16 @@ which broke entity parsing; 0.19.4 bump version constraint for text; 0.19.5 bump text to < 0.12 and fix text-0.10.0.1 breakage; 0.19.6 dependency breakage with List; 0.19.7 ghc-7.2.1 compatibility; 0.19.8 fix space leak on lazy parse under ghc-7.2.1;- 0.19.9 fix formatting of > character + improve performance; 0.9.10 ghc-7.4.x compatibility.+ 0.19.9 fix formatting of > character + improve performance; 0.19.10 ghc-7.4.x compatibility;+ 0.20.1 fix an unfortunate crash when used in parallel processing and greatly improve+ performance; 0.20.2 make parseSaxG lazier; 0.20.3 minor build issues; 0.20.4 remove+ dependency on extensible-exceptions; 0.20.5 bump text upper bound; 0.20.6 bump text again+ to include 1.1.x.x; 0.20.7 bump text again for 1.2.x.x; 0.20.8 bump utf8-string dep;+ 0.20.9 bump deepseq dep/ghc-7.10 compatibility.; 0.20.10 increase dependency upper bounds;+ 0.20.11 update to libexpat-2.2.1 which includes several security fixes;+ 0.20.12 use the system libexpat by default, but provide a bundle flag to allow a bundled+ copy of expat to be used, which might make life easier on Windows: cabal install -f bundle+ hexpat; 0.20.13 Fix some mistakes made in 0.20.12 cabal file. Category: XML License: BSD3 License-File: LICENSE@@ -65,7 +71,7 @@ Kevin Jardine, Jacob Stanley, Simon Hengel-Maintainer: http://blacksapphire.com/antispam/+Maintainer: Stephen Blackheath <hexpat2.stephen@blacksapphire.com> Copyright: (c) 2009 Doug Beardsley <mightybyte@gmail.com>, (c) 2009-2012 Stephen Blackheath <http://blacksapphire.com/antispam/>,@@ -95,48 +101,58 @@ test/hexpat-leak/Parse.hs, test/hexpat-leak/run.sh, test/hexpat-leak/build.sh- cbits/amigaconfig.h,- cbits/asciitab.h,- cbits/expat.h,- cbits/internal.h,- cbits/macconfig.h,- cbits/utf8tab.h,- cbits/xmlrole.h,- cbits/xmltok_impl.h,- cbits/ascii.h,- cbits/expat_external.h,- cbits/iasciitab.h,- cbits/latin1tab.h,- cbits/nametab.h,+ test/readRoads.hs,+ test/ROADS.xml, cbits/winconfig.h, cbits/xmltok.h+ cbits/winconfig.h+ cbits/xmltok_ns.c+ cbits/internal.h+ cbits/utf8tab.h+ cbits/siphash.h+ cbits/latin1tab.h+ cbits/xmltok.h+ cbits/expat.h+ cbits/xmltok.c+ cbits/iasciitab.h+ cbits/asciitab.h+ cbits/README+ cbits/xmlparse.c+ cbits/xmltok_impl.h+ cbits/xmltok_impl.c+ cbits/xmlrole.c+ cbits/xmlrole.h+ cbits/expat_external.h+ cbits/ascii.h+ cbits/nametab.h+ Build-Type: Simple Stability: beta source-repository head- type: darcs- location: http://code.haskell.org/hexpat/+ type: git+ location: https://github.com/the-real-blackh/hexpat +Flag bundle {+ Description: Use bundled libexpat+ Default: False+}+ Library Build-Depends: base >= 3 && < 5, bytestring, transformers,- text >= 0.5 && < 0.12,- utf8-string == 0.3.*,- deepseq >= 1.1.0.0 && < 1.4.0.0,+ text >= 0.5.0.0 && < 1.3.0.0,+ utf8-string >= 0.3 && < 1.1,+ deepseq >= 1.1.0.0 && < 1.5.0.0, containers,- extensible-exceptions == 0.1.*,- List >= 0.4.2 && < 0.5+ List >= 0.4.2 && < 0.7 Exposed-Modules: Text.XML.Expat.Annotated, Text.XML.Expat.Cursor, Text.XML.Expat.Extended, Text.XML.Expat.Format,- Text.XML.Expat.IO,- Text.XML.Expat.Namespaced,- Text.XML.Expat.NodeClass, Text.XML.Expat.Proc,- Text.XML.Expat.Qualified, Text.XML.Expat.SAX, Text.XML.Expat.Tree, Text.XML.Expat.Internal.DocumentClass,@@ -146,12 +162,19 @@ Text.XML.Expat.Internal.Qualified ghc-options: -Wall -fno-warn-name-shadowing - include-dirs: cbits- c-sources:- cbits/xmlparse.c,- cbits/xmlrole.c,- cbits/xmltok.c,- cbits/xmltok_impl.c,- cbits/xmltok_ns.c- cc-options: -DHAVE_MEMMOVE -DXML_NS -DXML_DTD-+ if flag(bundle) {+ include-dirs: cbits+ c-sources:+ cbits/xmlparse.c,+ cbits/xmlrole.c,+ cbits/xmltok.c,+ cbits/xmltok_impl.c,+ cbits/xmltok_ns.c,+ Text/XML/Expat/Internal/Glue.c+ cc-options: -DHAVE_MEMMOVE -DXML_NS -DXML_DTD+ }+ else {+ c-sources:+ Text/XML/Expat/Internal/Glue.c+ extra-libraries: expat+ }
+ test/ROADS.xml view
@@ -0,0 +1,1008 @@+<?xml version="1.0" encoding="UTF-8"?>+<shapes>+ <shape shapeType="polyLine" id="0" ADD_L_DIR="-1" ADD_L_MAX="17" ADD_L_MIN="3" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="26" ADD_R_MIN="6" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="WAIMEA LANE" ID="64" ISLAND="North Island" NAME="WAIMEA LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64414" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Remuera" TOWN="Auckland" TURNRESLNK="ak66" URBANRURAL="U" ID1="1">+ <vertices>+ <vertex X="174.800917" Y="-36.874316"/>+ <vertex X="174.800705" Y="-36.874296"/>+ <vertex X="174.798671" Y="-36.874107"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="1" ADD_L_DIR="1" ADD_L_MAX="25" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="DENARIUS LANE" ID="65" ISLAND="North Island" NAME="DENARIUS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64413" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glendene" TOWN="Waitakere" TURNRESLNK="ak67" URBANRURAL="U" ID1="2">+ <vertices>+ <vertex X="174.657551" Y="-36.889236"/>+ <vertex X="174.656120" Y="-36.888354"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="2" ADD_L_DIR="1" ADD_L_MAX="46" ADD_L_MIN="1" ADD_L_TYPE="M" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="BOARDMAN LANE" ID="66" ISLAND="North Island" NAME="BOARDMAN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64412" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak92" URBANRURAL="U" ID1="3">+ <vertices>+ <vertex X="174.757249" Y="-36.857860"/>+ <vertex X="174.757058" Y="-36.857463"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="3" ADD_L_DIR="1" ADD_L_MAX="20" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="13" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="GARDEN LANE" ID="35" ISLAND="North Island" NAME="GARDEN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64411" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Northcross" TOWN="North Shore" TURNRESLNK="ak35" URBANRURAL="U" ID1="4">+ <vertices>+ <vertex X="174.735888" Y="-36.707362"/>+ <vertex X="174.736360" Y="-36.707260"/>+ <vertex X="174.736581" Y="-36.707229"/>+ <vertex X="174.737098" Y="-36.707092"/>+ <vertex X="174.737294" Y="-36.706989"/>+ <vertex X="174.737303" Y="-36.706958"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="4" ADD_L_DIR="1" ADD_L_MAX="10" ADD_L_MIN="2" ADD_L_TYPE="M" ADD_R_DIR="1" ADD_R_MAX="3" ADD_R_MIN="3" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="EMILY LANE" ID="36" ISLAND="North Island" NAME="EMILY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64409" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Cuthill" TOWN="North Shore" TURNRESLNK="ak36" URBANRURAL="U" ID1="5">+ <vertices>+ <vertex X="174.704080" Y="-36.764450"/>+ <vertex X="174.703525" Y="-36.764050"/>+ <vertex X="174.703360" Y="-36.763845"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="5" ADD_L_DIR="1" ADD_L_MAX="22" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="15" ADD_R_MIN="5" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="DENE COURT LANE" ID="37" ISLAND="North Island" NAME="DENE COURT LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64408" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Cuthill" TOWN="North Shore" TURNRESLNK="ak37" URBANRURAL="U" ID1="6">+ <vertices>+ <vertex X="174.706178" Y="-36.762460"/>+ <vertex X="174.707042" Y="-36.763011"/>+ <vertex X="174.707911" Y="-36.763718"/>+ <vertex X="174.708126" Y="-36.764282"/>+ <vertex X="174.708057" Y="-36.764526"/>+ <vertex X="174.707982" Y="-36.764789"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="6" ADD_L_DIR="1" ADD_L_MAX="22" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="23" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="REDFERN LANE" ID="38" ISLAND="North Island" NAME="REDFERN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64407" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glenfield" TOWN="North Shore" TURNRESLNK="ak38" URBANRURAL="U" ID1="7">+ <vertices>+ <vertex X="174.708554" Y="-36.786916"/>+ <vertex X="174.709059" Y="-36.786575"/>+ <vertex X="174.709234" Y="-36.786400"/>+ <vertex X="174.709373" Y="-36.786128"/>+ <vertex X="174.709438" Y="-36.785949"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="7" ADD_L_DIR="-1" ADD_L_MAX="15" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="14" ADD_R_MIN="4" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="GLADFIELD LANE" ID="39" ISLAND="North Island" NAME="GLADFIELD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64405" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak39" URBANRURAL="U" ID1="8">+ <vertices>+ <vertex X="174.649093" Y="-36.835993"/>+ <vertex X="174.648993" Y="-36.836069"/>+ <vertex X="174.648946" Y="-36.836104"/>+ <vertex X="174.648276" Y="-36.836606"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="8" ADD_L_DIR="-1" ADD_L_MAX="9" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="10" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="GLENFORD LANE" ID="40" ISLAND="North Island" NAME="GLENFORD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64404" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak40" URBANRURAL="U" ID1="9">+ <vertices>+ <vertex X="174.646092" Y="-36.834602"/>+ <vertex X="174.645978" Y="-36.834622"/>+ <vertex X="174.645450" Y="-36.834975"/>+ <vertex X="174.645188" Y="-36.835258"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="9" ADD_L_DIR="-1" ADD_L_MAX="5" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="6" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="BRAEBANK LANE" ID="41" ISLAND="North Island" NAME="BRAEBANK LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64403" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu South" TOWN="Waitakere" TURNRESLNK="ak41" URBANRURAL="U" ID1="10">+ <vertices>+ <vertex X="174.654567" Y="-36.860195"/>+ <vertex X="174.654041" Y="-36.861186"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="10" ADD_L_DIR="-1" ADD_L_MAX="8" ADD_L_MIN="4" ADD_L_TYPE="E" ADD_R_DIR="-1" ADD_R_MAX="7" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="SUNRISE LANE" ID="42" ISLAND="North Island" NAME="SUNRISE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64402" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu South" TOWN="Waitakere" TURNRESLNK="ak42" URBANRURAL="U" ID1="11">+ <vertices>+ <vertex X="174.651493" Y="-36.861550"/>+ <vertex X="174.650956" Y="-36.862099"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="11" ADD_L_DIR="-1" ADD_L_MAX="11" ADD_L_MIN="3" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="10" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="GANE LANE" ID="43" ISLAND="North Island" NAME="GANE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64399" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak45" URBANRURAL="U" ID1="12">+ <vertices>+ <vertex X="174.648910" Y="-36.846895"/>+ <vertex X="174.648532" Y="-36.847487"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="12" ADD_L_DIR="-1" ADD_L_MAX="7" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="6" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="GLENVIL LANE" ID="44" ISLAND="North Island" NAME="GLENVIL LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64398" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak46" URBANRURAL="U" ID1="13">+ <vertices>+ <vertex X="174.648767" Y="-36.849879"/>+ <vertex X="174.648673" Y="-36.849839"/>+ <vertex X="174.648157" Y="-36.849209"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="13" ADD_L_DIR="-1" ADD_L_MAX="11" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="16" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="SPRINGBANK LANE" ID="45" ISLAND="North Island" NAME="SPRINGBANK LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64397" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak47" URBANRURAL="U" ID1="14">+ <vertices>+ <vertex X="174.644889" Y="-36.843879"/>+ <vertex X="174.646215" Y="-36.843489"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="14" ADD_L_DIR="-1" ADD_L_MAX="11" ADD_L_MIN="3" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="14" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="SHAMROCK LANE" ID="46" ISLAND="North Island" NAME="SHAMROCK LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64396" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak48" URBANRURAL="U" ID1="15">+ <vertices>+ <vertex X="174.649589" Y="-36.838069"/>+ <vertex X="174.649551" Y="-36.838033"/>+ <vertex X="174.648642" Y="-36.837629"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="15" ADD_L_DIR="-1" ADD_L_MAX="9" ADD_L_MIN="3" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="10" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="BEAUFIELD LANE" ID="47" ISLAND="North Island" NAME="BEAUFIELD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64395" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak49" URBANRURAL="U" ID1="16">+ <vertices>+ <vertex X="174.647448" Y="-36.837864"/>+ <vertex X="174.648140" Y="-36.838223"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="16" ADD_L_DIR="1" ADD_L_MAX="22" ADD_L_MIN="4" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="25" ADD_R_MIN="3" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="ELISA LANE" ID="48" ISLAND="North Island" NAME="ELISA LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64394" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Ranui" TOWN="Waitakere" TURNRESLNK="ak50" URBANRURAL="U" ID1="17">+ <vertices>+ <vertex X="174.602145" Y="-36.861159"/>+ <vertex X="174.602659" Y="-36.861093"/>+ <vertex X="174.603003" Y="-36.861153"/>+ <vertex X="174.603023" Y="-36.861149"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="17" ADD_L_DIR="-1" ADD_L_MAX="23" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="6" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="CONSTABLE LANE" ID="49" ISLAND="North Island" NAME="CONSTABLE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64393" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="West Harbour" TOWN="Waitakere" TURNRESLNK="ak51" URBANRURAL="U" ID1="18">+ <vertices>+ <vertex X="174.642384" Y="-36.818826"/>+ <vertex X="174.642240" Y="-36.818688"/>+ <vertex X="174.642098" Y="-36.818540"/>+ <vertex X="174.642057" Y="-36.818473"/>+ <vertex X="174.642042" Y="-36.818390"/>+ <vertex X="174.642085" Y="-36.818272"/>+ <vertex X="174.642163" Y="-36.818113"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="18" ADD_L_DIR="-1" ADD_L_MAX="9" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="8" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="STAFSON LANE" ID="50" ISLAND="North Island" NAME="STAFSON LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64392" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Te Atatu Peninsula" TOWN="Waitakere" TURNRESLNK="ak52" URBANRURAL="U" ID1="19">+ <vertices>+ <vertex X="174.645498" Y="-36.829736"/>+ <vertex X="174.645394" Y="-36.829932"/>+ <vertex X="174.644814" Y="-36.830599"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="19" ADD_L_DIR="-1" ADD_L_MAX="3" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="2" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SPROSTON AVENUE" ID="83" ISLAND="North Island" NAME="SPROSTON AVE" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64391" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Ellerslie" TOWN="Auckland" TURNRESLNK="ak109" URBANRURAL="U" ID1="20">+ <vertices>+ <vertex X="174.804846" Y="-36.893312"/>+ <vertex X="174.805949" Y="-36.893695"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="20" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SHELLY BEACH ROAD" ID="84" ISLAND="North Island" NAME="SHELLY BEACH RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64388" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Saint Marys Bay" TOWN="Auckland" TURNRESLNK="ak110" URBANRURAL="U" ID1="21">+ <vertices>+ <vertex X="174.742966" Y="-36.835312"/>+ <vertex X="174.742938" Y="-36.835373"/>+ <vertex X="174.742907" Y="-36.835428"/>+ <vertex X="174.742885" Y="-36.835464"/>+ <vertex X="174.742868" Y="-36.835504"/>+ <vertex X="174.742830" Y="-36.835629"/>+ <vertex X="174.742809" Y="-36.835687"/>+ <vertex X="174.742779" Y="-36.835746"/>+ <vertex X="174.742666" Y="-36.835944"/>+ <vertex X="174.742452" Y="-36.836289"/>+ <vertex X="174.742391" Y="-36.836391"/>+ <vertex X="174.742328" Y="-36.836503"/>+ <vertex X="174.742293" Y="-36.836577"/>+ <vertex X="174.742261" Y="-36.836648"/>+ <vertex X="174.742233" Y="-36.836717"/>+ <vertex X="174.742211" Y="-36.836777"/>+ <vertex X="174.742183" Y="-36.836868"/>+ <vertex X="174.742153" Y="-36.836985"/>+ <vertex X="174.742136" Y="-36.837071"/>+ <vertex X="174.742106" Y="-36.837292"/>+ <vertex X="174.742080" Y="-36.837419"/>+ <vertex X="174.742054" Y="-36.837504"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="21" ADD_L_DIR="1" ADD_L_MAX="20" ADD_L_MIN="8" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="30" ADD_R_MIN="30" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="WHITAKER PLACE" ID="85" ISLAND="North Island" NAME="WHITAKER PL" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64386" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak111" URBANRURAL="U" ID1="22">+ <vertices>+ <vertex X="174.766871" Y="-36.856923"/>+ <vertex X="174.766970" Y="-36.856946"/>+ <vertex X="174.767088" Y="-36.856905"/>+ <vertex X="174.767243" Y="-36.856747"/>+ <vertex X="174.767260" Y="-36.856668"/>+ <vertex X="174.766999" Y="-36.856464"/>+ <vertex X="174.767445" Y="-36.856063"/>+ <vertex X="174.767785" Y="-36.855951"/>+ <vertex X="174.768032" Y="-36.855830"/>+ <vertex X="174.768469" Y="-36.855183"/>+ <vertex X="174.768525" Y="-36.854709"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="22" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="DOMAIN DRIVE" ID="86" ISLAND="North Island" NAME="DOMAIN DR" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64385" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak112" URBANRURAL="U" ID1="23">+ <vertices>+ <vertex X="174.774820" Y="-36.858931"/>+ <vertex X="174.774130" Y="-36.858981"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="23" ADD_L_DIR="-1" ADD_L_MAX="14" ADD_L_MIN="7" ADD_L_TYPE="M" ADD_R_DIR="1" ADD_R_MAX="6" ADD_R_MIN="1" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="DAVERN LANE" ID="90" ISLAND="North Island" NAME="DAVERN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64383" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="New Lynn" TOWN="Waitakere" TURNRESLNK="ak71" URBANRURAL="U" ID1="24">+ <vertices>+ <vertex X="174.673713" Y="-36.920832"/>+ <vertex X="174.672945" Y="-36.920079"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="24" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="CLUB LANE" ID="1" ISLAND="North Island" NAME="CLUB LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64382" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Takapuna Beach" TOWN="North Shore" TURNRESLNK="ak91" URBANRURAL="U" ID1="25">+ <vertices>+ <vertex X="174.773774" Y="-36.790392"/>+ <vertex X="174.773267" Y="-36.789750"/>+ <vertex X="174.773144" Y="-36.789551"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="25" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="CENOTAPH ROAD" ID="2" ISLAND="North Island" NAME="CENOTAPH RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64380" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak1" URBANRURAL="U" ID1="26">+ <vertices>+ <vertex X="174.776349" Y="-36.859527"/>+ <vertex X="174.777016" Y="-36.859524"/>+ <vertex X="174.777847" Y="-36.859529"/>+ <vertex X="174.778229" Y="-36.859538"/>+ <vertex X="174.778380" Y="-36.859585"/>+ <vertex X="174.778588" Y="-36.859740"/>+ <vertex X="174.778668" Y="-36.859853"/>+ <vertex X="174.778713" Y="-36.859979"/>+ <vertex X="174.778710" Y="-36.860295"/>+ <vertex X="174.778704" Y="-36.860951"/>+ <vertex X="174.778656" Y="-36.861033"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="26" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MUSEUM CIRCUIT" ID="3" ISLAND="North Island" NAME="MUSEUM CIRCUIT" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64379" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak2" URBANRURAL="U" ID1="27">+ <vertices>+ <vertex X="174.777198" Y="-36.860080"/>+ <vertex X="174.776455" Y="-36.860071"/>+ <vertex X="174.776317" Y="-36.860009"/>+ <vertex X="174.776212" Y="-36.859899"/>+ <vertex X="174.776200" Y="-36.859756"/>+ <vertex X="174.776239" Y="-36.859658"/>+ <vertex X="174.776291" Y="-36.859564"/>+ <vertex X="174.776349" Y="-36.859527"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="27" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="KIOSK ROAD" ID="5" ISLAND="North Island" NAME="KIOSK RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64378" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak4" URBANRURAL="U" ID1="28">+ <vertices>+ <vertex X="174.774677" Y="-36.859587"/>+ <vertex X="174.774392" Y="-36.859701"/>+ <vertex X="174.774214" Y="-36.859776"/>+ <vertex X="174.773644" Y="-36.860015"/>+ <vertex X="174.773341" Y="-36.860152"/>+ <vertex X="174.773183" Y="-36.860250"/>+ <vertex X="174.773065" Y="-36.860346"/>+ <vertex X="174.772994" Y="-36.860449"/>+ <vertex X="174.772941" Y="-36.860568"/>+ <vertex X="174.772880" Y="-36.860701"/>+ <vertex X="174.772806" Y="-36.860780"/>+ <vertex X="174.772722" Y="-36.860833"/>+ <vertex X="174.772635" Y="-36.860870"/>+ <vertex X="174.772509" Y="-36.860898"/>+ <vertex X="174.771892" Y="-36.860896"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="28" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="THE CRESCENT" ID="6" ISLAND="North Island" NAME="THE CRESCENT" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64376" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak5" URBANRURAL="U" ID1="29">+ <vertices>+ <vertex X="174.775859" Y="-36.859622"/>+ <vertex X="174.775569" Y="-36.859700"/>+ <vertex X="174.775344" Y="-36.859728"/>+ <vertex X="174.775129" Y="-36.859719"/>+ <vertex X="174.774952" Y="-36.859688"/>+ <vertex X="174.774677" Y="-36.859587"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="29" ADD_L_DIR="1" ADD_L_MAX="2" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="13" ADD_R_MIN="3" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MERCURY LANE" ID="7" ISLAND="North Island" NAME="MERCURY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="3" RD_SEG_LNK="63668" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Newton" TOWN="Auckland" TURNRESLNK="ak6" URBANRURAL="U" ID1="30">+ <vertices>+ <vertex X="174.759046" Y="-36.857703"/>+ <vertex X="174.759010" Y="-36.858434"/>+ <vertex X="174.759055" Y="-36.858534"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="30" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="2" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="FREYBERG PLACE" ID="13" ISLAND="North Island" NAME="FREYBERG PL" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63666" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak12" URBANRURAL="U" ID1="31">+ <vertices>+ <vertex X="174.766620" Y="-36.847670"/>+ <vertex X="174.767098" Y="-36.847748"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="31" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SAINT JAMES STREET" ID="14" ISLAND="North Island" NAME="ST JAMES ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63662" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak13" URBANRURAL="U" ID1="32">+ <vertices>+ <vertex X="174.757675" Y="-36.856022"/>+ <vertex X="174.757645" Y="-36.855944"/>+ <vertex X="174.757642" Y="-36.855650"/>+ <vertex X="174.757668" Y="-36.855191"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="32" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="DOMAIN DRIVE" ID="15" ISLAND="North Island" NAME="DOMAIN DR" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="64385" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak14" URBANRURAL="U" ID1="33">+ <vertices>+ <vertex X="174.771892" Y="-36.860896"/>+ <vertex X="174.771686" Y="-36.860869"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="33" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="DOMAIN DRIVE" ID="16" ISLAND="North Island" NAME="DOMAIN DR" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64385" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak15" URBANRURAL="U" ID1="34">+ <vertices>+ <vertex X="174.770486" Y="-36.862104"/>+ <vertex X="174.771000" Y="-36.861930"/>+ <vertex X="174.771237" Y="-36.861723"/>+ <vertex X="174.771503" Y="-36.861320"/>+ <vertex X="174.771660" Y="-36.860995"/>+ <vertex X="174.771686" Y="-36.860869"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="34" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="DOMAIN DRIVE" ID="17" ISLAND="North Island" NAME="DOMAIN DR" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="64385" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Grafton" TOWN="Auckland" TURNRESLNK="ak16" URBANRURAL="U" ID1="35">+ <vertices>+ <vertex X="174.771686" Y="-36.860869"/>+ <vertex X="174.771735" Y="-36.860556"/>+ <vertex X="174.771747" Y="-36.860486"/>+ <vertex X="174.771949" Y="-36.860006"/>+ <vertex X="174.771972" Y="-36.859972"/>+ <vertex X="174.772085" Y="-36.859815"/>+ <vertex X="174.772274" Y="-36.859625"/>+ <vertex X="174.772397" Y="-36.859522"/>+ <vertex X="174.772529" Y="-36.859425"/>+ <vertex X="174.772670" Y="-36.859344"/>+ <vertex X="174.773031" Y="-36.859209"/>+ <vertex X="174.773325" Y="-36.859123"/>+ <vertex X="174.773592" Y="-36.859043"/>+ <vertex X="174.773705" Y="-36.859018"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="35" ADD_L_DIR="1" ADD_L_MAX="76" ADD_L_MIN="70" ADD_L_TYPE="E" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SALE STREET" ID="19" ISLAND="North Island" NAME="SALE ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63657" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Freemans Bay" TOWN="Auckland" TURNRESLNK="ak18" URBANRURAL="U" ID1="36">+ <vertices>+ <vertex X="174.755025" Y="-36.849591"/>+ <vertex X="174.754814" Y="-36.849627"/>+ <vertex X="174.754580" Y="-36.849690"/>+ <vertex X="174.754515" Y="-36.849738"/>+ <vertex X="174.754489" Y="-36.849789"/>+ <vertex X="174.754489" Y="-36.849846"/>+ <vertex X="174.754505" Y="-36.849907"/>+ <vertex X="174.754562" Y="-36.849995"/>+ <vertex X="174.754712" Y="-36.850189"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="36" ADD_L_DIR="-1" ADD_L_MAX="47" ADD_L_MIN="31" ADD_L_TYPE="O" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SALE STREET" ID="20" ISLAND="North Island" NAME="SALE ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63657" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Freemans Bay" TOWN="Auckland" TURNRESLNK="ak19" URBANRURAL="U" ID1="37">+ <vertices>+ <vertex X="174.753766" Y="-36.849635"/>+ <vertex X="174.753836" Y="-36.849684"/>+ <vertex X="174.753920" Y="-36.849716"/>+ <vertex X="174.753985" Y="-36.849723"/>+ <vertex X="174.755015" Y="-36.849549"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="37" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="22" ADD_R_MIN="22" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="DUNLOP LANE" ID="21" ISLAND="North Island" NAME="DUNLOP LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63651" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Panmure" TOWN="Auckland" TURNRESLNK="ak20" URBANRURAL="U" ID1="38">+ <vertices>+ <vertex X="174.851563" Y="-36.898649"/>+ <vertex X="174.851600" Y="-36.898659"/>+ <vertex X="174.854052" Y="-36.899122"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="38" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="KORMA LANE" ID="22" ISLAND="North Island" NAME="KORMA LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63650" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Panmure" TOWN="Auckland" TURNRESLNK="ak21" URBANRURAL="U" ID1="39">+ <vertices>+ <vertex X="174.853639" Y="-36.899839"/>+ <vertex X="174.853685" Y="-36.899839"/>+ <vertex X="174.853737" Y="-36.899847"/>+ <vertex X="174.854524" Y="-36.900038"/>+ <vertex X="174.854544" Y="-36.900065"/>+ <vertex X="174.854302" Y="-36.900260"/>+ <vertex X="174.854560" Y="-36.900441"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="39" ADD_L_DIR="-1" ADD_L_MAX="15" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Manukau City" FULL_NAME="FULTON CRESCENT" ID="23" ISLAND="North Island" NAME="FULTON CRES" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63649" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Otara" TOWN="Manukau" TURNRESLNK="ak22" URBANRURAL="U" ID1="40">+ <vertices>+ <vertex X="174.873543" Y="-36.962569"/>+ <vertex X="174.873564" Y="-36.962848"/>+ <vertex X="174.873522" Y="-36.962913"/>+ <vertex X="174.873430" Y="-36.962932"/>+ <vertex X="174.872717" Y="-36.962731"/>+ <vertex X="174.872602" Y="-36.962681"/>+ <vertex X="174.872539" Y="-36.962627"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="40" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="BOLLARD AVENUE" ID="24" ISLAND="North Island" NAME="BOLLARD AVE" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="0" OWNERSHIP="0" RC="6" RD_SEG_LNK="63647" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="2" SUBURB="One Tree Hill" TOWN="Auckland" TURNRESLNK="ak23" URBANRURAL="U" ID1="41">+ <vertices>+ <vertex X="174.787861" Y="-36.902871"/>+ <vertex X="174.788213" Y="-36.903178"/>+ <vertex X="174.788414" Y="-36.903353"/>+ <vertex X="174.788708" Y="-36.903665"/>+ <vertex X="174.788835" Y="-36.903807"/>+ <vertex X="174.788923" Y="-36.903984"/>+ <vertex X="174.788965" Y="-36.904094"/>+ <vertex X="174.788972" Y="-36.904131"/>+ <vertex X="174.789040" Y="-36.904486"/>+ <vertex X="174.789094" Y="-36.904569"/>+ <vertex X="174.789159" Y="-36.904644"/>+ <vertex X="174.789621" Y="-36.904889"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="41" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="BOLLARD AVENUE" ID="25" ISLAND="North Island" NAME="BOLLARD AVE" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="6" RD_SEG_LNK="63647" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="One Tree Hill" TOWN="Auckland" TURNRESLNK="ak24" URBANRURAL="U" ID1="42">+ <vertices>+ <vertex X="174.786526" Y="-36.902359"/>+ <vertex X="174.786637" Y="-36.902407"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="42" ADD_L_DIR="1" ADD_L_MAX="34" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="41" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="HONEYSUCKLE LANE" ID="26" ISLAND="North Island" NAME="HONEYSUCKLE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63646" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Mairangi Bay" TOWN="North Shore" TURNRESLNK="ak25" URBANRURAL="U" ID1="43">+ <vertices>+ <vertex X="174.741128" Y="-36.736259"/>+ <vertex X="174.741358" Y="-36.736481"/>+ <vertex X="174.741422" Y="-36.736503"/>+ <vertex X="174.741459" Y="-36.736506"/>+ <vertex X="174.742485" Y="-36.736318"/>+ <vertex X="174.742653" Y="-36.736325"/>+ <vertex X="174.744429" Y="-36.736584"/>+ <vertex X="174.744678" Y="-36.736644"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="43" ADD_L_DIR="1" ADD_L_MAX="47" ADD_L_MIN="1" ADD_L_TYPE="M" ADD_R_DIR="1" ADD_R_MAX="42" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="PALLISER LANE" ID="27" ISLAND="North Island" NAME="PALLISER LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63643" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Browns Bay" TOWN="North Shore" TURNRESLNK="ak26" URBANRURAL="U" ID1="44">+ <vertices>+ <vertex X="174.728908" Y="-36.723964"/>+ <vertex X="174.728860" Y="-36.724225"/>+ <vertex X="174.728827" Y="-36.724343"/>+ <vertex X="174.728794" Y="-36.724425"/>+ <vertex X="174.728743" Y="-36.724477"/>+ <vertex X="174.728285" Y="-36.724653"/>+ <vertex X="174.727985" Y="-36.724765"/>+ <vertex X="174.727794" Y="-36.724862"/>+ <vertex X="174.727023" Y="-36.725360"/>+ <vertex X="174.726975" Y="-36.725391"/>+ <vertex X="174.726550" Y="-36.725542"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="44" ADD_L_DIR="1" ADD_L_MAX="43" ADD_L_MIN="33" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="44" ADD_R_MIN="36" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="BERENICE LANE" ID="67" ISLAND="North Island" NAME="BERENICE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63642" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Coatesville" TOWN="" TURNRESLNK="ak93" URBANRURAL="R" ID1="45">+ <vertices>+ <vertex X="174.609999" Y="-36.735115"/>+ <vertex X="174.610605" Y="-36.734742"/>+ <vertex X="174.613196" Y="-36.734630"/>+ <vertex X="174.613911" Y="-36.734341"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="45" ADD_L_DIR="1" ADD_L_MAX="22" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="27" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="MARTIN JUGUM LANE" ID="68" ISLAND="North Island" NAME="MARTIN JUGUM LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63641" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Ranui" TOWN="Waitakere" TURNRESLNK="ak94" URBANRURAL="U" ID1="46">+ <vertices>+ <vertex X="174.607807" Y="-36.866540"/>+ <vertex X="174.607892" Y="-36.866638"/>+ <vertex X="174.608251" Y="-36.866944"/>+ <vertex X="174.608487" Y="-36.867111"/>+ <vertex X="174.608763" Y="-36.867248"/>+ <vertex X="174.609359" Y="-36.867418"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="46" ADD_L_DIR="1" ADD_L_MAX="10" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="19" ADD_R_MIN="3" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="SUMMERFIELD LANE" ID="69" ISLAND="North Island" NAME="SUMMERFIELD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63640" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Albany" TOWN="North Shore" TURNRESLNK="ak95" URBANRURAL="U" ID1="47">+ <vertices>+ <vertex X="174.691313" Y="-36.734866"/>+ <vertex X="174.690747" Y="-36.734736"/>+ <vertex X="174.689931" Y="-36.734486"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="47" ADD_L_DIR="1" ADD_L_MAX="45" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="48" ADD_R_MIN="4" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="DYSART LANE" ID="70" ISLAND="North Island" NAME="DYSART LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63638" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Kumeu" TOWN="" TURNRESLNK="ak96" URBANRURAL="R" ID1="48">+ <vertices>+ <vertex X="174.540356" Y="-36.798417"/>+ <vertex X="174.542820" Y="-36.794720"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="48" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="69" ADD_R_MIN="69" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="CHERRY BLOSSOM LANE" ID="71" ISLAND="North Island" NAME="CHERRY BLOSSOM LN" NAMED_AREA="" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63637" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Te Pua" TOWN="" TURNRESLNK="ak97" URBANRURAL="R" ID1="49">+ <vertices>+ <vertex X="174.408949" Y="-36.683874"/>+ <vertex X="174.408647" Y="-36.684589"/>+ <vertex X="174.408495" Y="-36.684653"/>+ <vertex X="174.408054" Y="-36.684705"/>+ <vertex X="174.407883" Y="-36.684785"/>+ <vertex X="174.407781" Y="-36.684957"/>+ <vertex X="174.407799" Y="-36.685343"/>+ <vertex X="174.409682" Y="-36.689106"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="49" ADD_L_DIR="1" ADD_L_MAX="51" ADD_L_MIN="23" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="61" ADD_R_MIN="34" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="PIONEER LANE" ID="72" ISLAND="North Island" NAME="PIONEER LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63636" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Taupaki" TOWN="" TURNRESLNK="ak98" URBANRURAL="R" ID1="50">+ <vertices>+ <vertex X="174.521642" Y="-36.811908"/>+ <vertex X="174.520775" Y="-36.812576"/>+ <vertex X="174.519719" Y="-36.812978"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="50" ADD_L_DIR="1" ADD_L_MAX="81" ADD_L_MIN="45" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="82" ADD_R_MIN="50" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="ROSS LANE" ID="73" ISLAND="North Island" NAME="ROSS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63634" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Huapai" TOWN="" TURNRESLNK="ak99" URBANRURAL="R" ID1="51">+ <vertices>+ <vertex X="174.513874" Y="-36.792036"/>+ <vertex X="174.509156" Y="-36.793528"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="51" ADD_L_DIR="1" ADD_L_MAX="25" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="41" ADD_R_MIN="2" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="SARAH TODD LANE" ID="74" ISLAND="North Island" NAME="SARAH TODD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63632" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Waimauku" TOWN="" TURNRESLNK="ak100" URBANRURAL="R" ID1="52">+ <vertices>+ <vertex X="174.491722" Y="-36.769882"/>+ <vertex X="174.492339" Y="-36.770018"/>+ <vertex X="174.492473" Y="-36.770058"/>+ <vertex X="174.492585" Y="-36.770108"/>+ <vertex X="174.492673" Y="-36.770145"/>+ <vertex X="174.492751" Y="-36.770176"/>+ <vertex X="174.492872" Y="-36.770220"/>+ <vertex X="174.492974" Y="-36.770252"/>+ <vertex X="174.493106" Y="-36.770287"/>+ <vertex X="174.493237" Y="-36.770311"/>+ <vertex X="174.493256" Y="-36.770314"/>+ <vertex X="174.493276" Y="-36.770317"/>+ <vertex X="174.493376" Y="-36.770323"/>+ <vertex X="174.493492" Y="-36.770329"/>+ <vertex X="174.493583" Y="-36.770329"/>+ <vertex X="174.493612" Y="-36.770329"/>+ <vertex X="174.493742" Y="-36.770330"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="52" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="44" ADD_R_MIN="6" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="POYNTER LANE" ID="75" ISLAND="North Island" NAME="POYNTER LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63631" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Pine Valley" TOWN="" TURNRESLNK="ak101" URBANRURAL="R" ID1="53">+ <vertices>+ <vertex X="174.626114" Y="-36.630809"/>+ <vertex X="174.625650" Y="-36.630147"/>+ <vertex X="174.624725" Y="-36.628828"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="53" ADD_L_DIR="1" ADD_L_MAX="40" ADD_L_MIN="14" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="22" ADD_R_MIN="22" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="PETERS LANE" ID="76" ISLAND="North Island" NAME="PETERS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63630" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Taupaki" TOWN="" TURNRESLNK="ak102" URBANRURAL="R" ID1="54">+ <vertices>+ <vertex X="174.536625" Y="-36.824937"/>+ <vertex X="174.536109" Y="-36.823184"/>+ <vertex X="174.534002" Y="-36.822798"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="54" ADD_L_DIR="1" ADD_L_MAX="10" ADD_L_MIN="1" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="15" ADD_R_MIN="11" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SIMMONDS LANE" ID="77" ISLAND="North Island" NAME="SIMMONDS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63628" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Mount Wellington" TOWN="Auckland" TURNRESLNK="ak103" URBANRURAL="U" ID1="55">+ <vertices>+ <vertex X="174.837888" Y="-36.905740"/>+ <vertex X="174.837440" Y="-36.905565"/>+ <vertex X="174.837366" Y="-36.905529"/>+ <vertex X="174.837323" Y="-36.905485"/>+ <vertex X="174.837285" Y="-36.905432"/>+ <vertex X="174.837190" Y="-36.905230"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="55" ADD_L_DIR="1" ADD_L_MAX="19" ADD_L_MIN="8" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="7" ADD_R_MIN="1" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MARINE LANE" ID="78" ISLAND="North Island" NAME="MARINE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63627" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Panmure" TOWN="Auckland" TURNRESLNK="ak104" URBANRURAL="U" ID1="56">+ <vertices>+ <vertex X="174.851022" Y="-36.908243"/>+ <vertex X="174.851100" Y="-36.908210"/>+ <vertex X="174.851197" Y="-36.908185"/>+ <vertex X="174.851424" Y="-36.908187"/>+ <vertex X="174.851546" Y="-36.908196"/>+ <vertex X="174.851632" Y="-36.908223"/>+ <vertex X="174.851696" Y="-36.908275"/>+ <vertex X="174.851731" Y="-36.908333"/>+ <vertex X="174.851739" Y="-36.908399"/>+ <vertex X="174.851736" Y="-36.908488"/>+ <vertex X="174.851734" Y="-36.908601"/>+ <vertex X="174.851747" Y="-36.908698"/>+ <vertex X="174.851787" Y="-36.908818"/>+ <vertex X="174.851886" Y="-36.909043"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="56" ADD_L_DIR="1" ADD_L_MAX="8" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="-1" ADD_R_MAX="12" ADD_R_MIN="10" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="CONVAMORE LANE" ID="79" ISLAND="North Island" NAME="CONVAMORE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="0" OWNERSHIP="1" RC="6" RD_SEG_LNK="63626" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Mount Wellington" TOWN="Auckland" TURNRESLNK="ak105" URBANRURAL="U" ID1="57">+ <vertices>+ <vertex X="174.850544" Y="-36.909363"/>+ <vertex X="174.850607" Y="-36.908479"/>+ <vertex X="174.850588" Y="-36.908421"/>+ <vertex X="174.850526" Y="-36.908385"/>+ <vertex X="174.850149" Y="-36.908363"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="57" ADD_L_DIR="-1" ADD_L_MAX="53" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="24" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="CONVOY LANE" ID="80" ISLAND="North Island" NAME="CONVOY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63625" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Otahuhu" TOWN="Auckland" TURNRESLNK="ak106" URBANRURAL="U" ID1="58">+ <vertices>+ <vertex X="174.854789" Y="-36.932748"/>+ <vertex X="174.854754" Y="-36.933246"/>+ <vertex X="174.854574" Y="-36.935832"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="58" ADD_L_DIR="-1" ADD_L_MAX="6" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="-1" ADD_R_MAX="11" ADD_R_MIN="1" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MELODY LANE" ID="81" ISLAND="North Island" NAME="MELODY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63624" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Otahuhu" TOWN="Auckland" TURNRESLNK="ak107" URBANRURAL="U" ID1="59">+ <vertices>+ <vertex X="174.853044" Y="-36.945118"/>+ <vertex X="174.853225" Y="-36.945157"/>+ <vertex X="174.853855" Y="-36.945035"/>+ <vertex X="174.853956" Y="-36.944992"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="59" ADD_L_DIR="1" ADD_L_MAX="4" ADD_L_MIN="1" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="8" ADD_R_MIN="5" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="DEBORAH HATTON LANE" ID="82" ISLAND="North Island" NAME="DEBORAH HATTON LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="0" OWNERSHIP="1" RC="6" RD_SEG_LNK="63616" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Otahuhu" TOWN="Auckland" TURNRESLNK="ak108" URBANRURAL="U" ID1="60">+ <vertices>+ <vertex X="174.849189" Y="-36.930396"/>+ <vertex X="174.849748" Y="-36.930387"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="60" ADD_L_DIR="-1" ADD_L_MAX="71" ADD_L_MIN="69" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="78" ADD_R_MIN="70" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="WOLVERTON STREET" ID="124" ISLAND="North Island" NAME="WOLVERTON ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="2" RD_SEG_LNK="63615" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Avondale" TOWN="Auckland" TURNRESLNK="ak254" URBANRURAL="U" ID1="61">+ <vertices>+ <vertex X="174.695523" Y="-36.909057"/>+ <vertex X="174.696334" Y="-36.908654"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="61" ADD_L_DIR="1" ADD_L_MAX="13" ADD_L_MIN="1" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="33" ADD_R_MIN="17" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="COTSWOLD LANE" ID="51" ISLAND="North Island" NAME="COTSWOLD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63614" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Mount Wellington" TOWN="Auckland" TURNRESLNK="ak53" URBANRURAL="U" ID1="62">+ <vertices>+ <vertex X="174.823371" Y="-36.911283"/>+ <vertex X="174.823512" Y="-36.911226"/>+ <vertex X="174.824201" Y="-36.911003"/>+ <vertex X="174.824304" Y="-36.910974"/>+ <vertex X="174.824402" Y="-36.910955"/>+ <vertex X="174.824497" Y="-36.910945"/>+ <vertex X="174.824604" Y="-36.910939"/>+ <vertex X="174.824727" Y="-36.910939"/>+ <vertex X="174.824982" Y="-36.910949"/>+ <vertex X="174.825108" Y="-36.910949"/>+ <vertex X="174.825223" Y="-36.910943"/>+ <vertex X="174.825305" Y="-36.910933"/>+ <vertex X="174.825411" Y="-36.910905"/>+ <vertex X="174.825519" Y="-36.910858"/>+ <vertex X="174.825621" Y="-36.910806"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="62" ADD_L_DIR="1" ADD_L_MAX="14" ADD_L_MIN="4" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="13" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="LEASIDE LANE" ID="52" ISLAND="North Island" NAME="LEASIDE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63613" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glen Innes" TOWN="Auckland" TURNRESLNK="ak54" URBANRURAL="U" ID1="63">+ <vertices>+ <vertex X="174.866100" Y="-36.874944"/>+ <vertex X="174.864949" Y="-36.874544"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="63" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="-1" ADD_R_MAX="4" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="HORNES LANE" ID="53" ISLAND="North Island" NAME="HORNES LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63612" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Onehunga" TOWN="Auckland" TURNRESLNK="ak55" URBANRURAL="U" ID1="64">+ <vertices>+ <vertex X="174.776373" Y="-36.922343"/>+ <vertex X="174.776316" Y="-36.922307"/>+ <vertex X="174.775964" Y="-36.922240"/>+ <vertex X="174.775859" Y="-36.922257"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="64" ADD_L_DIR="1" ADD_L_MAX="1" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="LOWER MUNICIPAL PLACE" ID="54" ISLAND="North Island" NAME="LOWER MUNICIPAL PL" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63611" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Onehunga" TOWN="Auckland" TURNRESLNK="ak56" URBANRURAL="U" ID1="65">+ <vertices>+ <vertex X="174.783876" Y="-36.923053"/>+ <vertex X="174.784036" Y="-36.924250"/>+ <vertex X="174.784055" Y="-36.924297"/>+ <vertex X="174.784084" Y="-36.924341"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="65" ADD_L_DIR="-1" ADD_L_MAX="11" ADD_L_MIN="3" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="10" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="TYNOR PLACE" ID="55" ISLAND="North Island" NAME="TYNOR PL" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63610" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Hillsborough" TOWN="Auckland" TURNRESLNK="ak57" URBANRURAL="U" ID1="66">+ <vertices>+ <vertex X="174.760577" Y="-36.923815"/>+ <vertex X="174.760323" Y="-36.923977"/>+ <vertex X="174.759957" Y="-36.924341"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="66" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="UPPER MUNICIPAL PLACE" ID="56" ISLAND="North Island" NAME="UPPER MUNICIPAL PL" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63609" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Onehunga" TOWN="Auckland" TURNRESLNK="ak58" URBANRURAL="U" ID1="67">+ <vertices>+ <vertex X="174.784562" Y="-36.922991"/>+ <vertex X="174.784745" Y="-36.924290"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="67" ADD_L_DIR="1" ADD_L_MAX="18" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="11" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="GEORGE LAURENSON LANE" ID="57" ISLAND="North Island" NAME="GEORGE LAURENSON LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63608" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Waikowhai" TOWN="Auckland" TURNRESLNK="ak59" URBANRURAL="U" ID1="68">+ <vertices>+ <vertex X="174.732340" Y="-36.932485"/>+ <vertex X="174.732194" Y="-36.932424"/>+ <vertex X="174.732039" Y="-36.932357"/>+ <vertex X="174.731943" Y="-36.932310"/>+ <vertex X="174.731750" Y="-36.932199"/>+ <vertex X="174.731692" Y="-36.932171"/>+ <vertex X="174.731617" Y="-36.932139"/>+ <vertex X="174.731547" Y="-36.932113"/>+ <vertex X="174.731478" Y="-36.932081"/>+ <vertex X="174.731427" Y="-36.932047"/>+ <vertex X="174.731401" Y="-36.932005"/>+ <vertex X="174.731383" Y="-36.931948"/>+ <vertex X="174.731360" Y="-36.931834"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="68" ADD_L_DIR="-1" ADD_L_MAX="41" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="43" ADD_R_MIN="2" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="DANUBE LANE" ID="58" ISLAND="North Island" NAME="DANUBE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63607" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glen Eden" TOWN="Waitakere" TURNRESLNK="ak60" URBANRURAL="U" ID1="69">+ <vertices>+ <vertex X="174.631432" Y="-36.918479"/>+ <vertex X="174.631385" Y="-36.918487"/>+ <vertex X="174.630877" Y="-36.918290"/>+ <vertex X="174.629824" Y="-36.917887"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="69" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="BAKERS LANE" ID="59" ISLAND="North Island" NAME="BAKERS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63606" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Whenuapai" TOWN="" TURNRESLNK="ak61" URBANRURAL="R" ID1="70">+ <vertices>+ <vertex X="174.602054" Y="-36.822786"/>+ <vertex X="174.604625" Y="-36.820273"/>+ <vertex X="174.604716" Y="-36.820154"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="70" ADD_L_DIR="1" ADD_L_MAX="8" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="11" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="RUBENS LANE" ID="60" ISLAND="North Island" NAME="RUBENS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63605" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="West Harbour" TOWN="Waitakere" TURNRESLNK="ak62" URBANRURAL="U" ID1="71">+ <vertices>+ <vertex X="174.635083" Y="-36.821030"/>+ <vertex X="174.634745" Y="-36.820963"/>+ <vertex X="174.634522" Y="-36.821011"/>+ <vertex X="174.634200" Y="-36.821064"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="71" ADD_L_DIR="1" ADD_L_MAX="4" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="3" ADD_R_MIN="3" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Waitakere City" FULL_NAME="SWAN LANE" ID="61" ISLAND="North Island" NAME="SWAN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63604" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Henderson" TOWN="Waitakere" TURNRESLNK="ak63" URBANRURAL="U" ID1="72">+ <vertices>+ <vertex X="174.637982" Y="-36.870826"/>+ <vertex X="174.637337" Y="-36.871554"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="72" ADD_L_DIR="-1" ADD_L_MAX="9" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="8" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="BASIN VIEW LANE" ID="62" ISLAND="North Island" NAME="BASIN VIEW LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63602" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Panmure" TOWN="Auckland" TURNRESLNK="ak64" URBANRURAL="U" ID1="73">+ <vertices>+ <vertex X="174.854626" Y="-36.900384"/>+ <vertex X="174.855122" Y="-36.899952"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="73" ADD_L_DIR="-1" ADD_L_MAX="15" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="16" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="GLENTIES LANE" ID="63" ISLAND="North Island" NAME="GLENTIES LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63601" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Ellerslie" TOWN="Auckland" TURNRESLNK="ak65" URBANRURAL="U" ID1="74">+ <vertices>+ <vertex X="174.823038" Y="-36.889889"/>+ <vertex X="174.823083" Y="-36.889757"/>+ <vertex X="174.823292" Y="-36.889157"/>+ <vertex X="174.823300" Y="-36.889114"/>+ <vertex X="174.823301" Y="-36.889071"/>+ <vertex X="174.823295" Y="-36.889021"/>+ <vertex X="174.823238" Y="-36.888703"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="74" ADD_L_DIR="1" ADD_L_MAX="24" ADD_L_MIN="24" ADD_L_TYPE="E" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MERCURY LANE" ID="8" ISLAND="North Island" NAME="MERCURY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="3" RD_SEG_LNK="63668" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Newton" TOWN="Auckland" TURNRESLNK="ak7" URBANRURAL="U" ID1="75">+ <vertices>+ <vertex X="174.759225" Y="-36.858848"/>+ <vertex X="174.759338" Y="-36.859103"/>+ <vertex X="174.759415" Y="-36.859210"/>+ <vertex X="174.759542" Y="-36.859290"/>+ <vertex X="174.759672" Y="-36.859371"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="75" ADD_L_DIR="1" ADD_L_MAX="1" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="12" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SAINT MARTINS LANE" ID="9" ISLAND="North Island" NAME="ST MARTINS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63600" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak8" URBANRURAL="U" ID1="76">+ <vertices>+ <vertex X="174.764743" Y="-36.857990"/>+ <vertex X="174.765292" Y="-36.857534"/>+ <vertex X="174.764862" Y="-36.857203"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="76" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MARKET LANE" ID="10" ISLAND="North Island" NAME="MARKET LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63599" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak9" URBANRURAL="U" ID1="77">+ <vertices>+ <vertex X="174.762109" Y="-36.844683"/>+ <vertex X="174.762082" Y="-36.844587"/>+ <vertex X="174.762074" Y="-36.844527"/>+ <vertex X="174.762076" Y="-36.844486"/>+ <vertex X="174.762089" Y="-36.844443"/>+ <vertex X="174.762166" Y="-36.844249"/>+ <vertex X="174.762278" Y="-36.843958"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="77" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MARKET LANE" ID="11" ISLAND="North Island" NAME="MARKET LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63599" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak10" URBANRURAL="U" ID1="78">+ <vertices>+ <vertex X="174.762278" Y="-36.843958"/>+ <vertex X="174.762447" Y="-36.843521"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="78" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="BRADNOR LANE" ID="12" ISLAND="North Island" NAME="BRADNOR LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63598" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Auckland City Centre" TOWN="Auckland" TURNRESLNK="ak11" URBANRURAL="U" ID1="79">+ <vertices>+ <vertex X="174.761602" Y="-36.845360"/>+ <vertex X="174.761611" Y="-36.845392"/>+ <vertex X="174.761629" Y="-36.845423"/>+ <vertex X="174.761650" Y="-36.845446"/>+ <vertex X="174.761692" Y="-36.845467"/>+ <vertex X="174.762667" Y="-36.845767"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="79" ADD_L_DIR="1" ADD_L_MAX="14" ADD_L_MIN="4" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="15" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="SAINT THOMAS MORE LANE" ID="163" ISLAND="North Island" NAME="ST THOMAS MORE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63597" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glenfield" TOWN="North Shore" TURNRESLNK="ak146" URBANRURAL="U" ID1="80">+ <vertices>+ <vertex X="174.721762" Y="-36.770566"/>+ <vertex X="174.722295" Y="-36.770628"/>+ <vertex X="174.722843" Y="-36.771146"/>+ <vertex X="174.722944" Y="-36.771241"/>+ <vertex X="174.723064" Y="-36.771246"/>+ <vertex X="174.723102" Y="-36.771201"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="80" ADD_L_DIR="1" ADD_L_MAX="28" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="11" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="TYBURN LANE" ID="164" ISLAND="North Island" NAME="TYBURN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63596" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Unsworth Heights" TOWN="North Shore" TURNRESLNK="ak147" URBANRURAL="U" ID1="81">+ <vertices>+ <vertex X="174.713292" Y="-36.759233"/>+ <vertex X="174.713272" Y="-36.759544"/>+ <vertex X="174.712937" Y="-36.759900"/>+ <vertex X="174.712843" Y="-36.759922"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="81" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="ROSEBERRY LANE" ID="165" ISLAND="North Island" NAME="ROSEBERRY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63594" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Birkenhead" TOWN="North Shore" TURNRESLNK="ak148" URBANRURAL="U" ID1="82">+ <vertices>+ <vertex X="174.714800" Y="-36.809357"/>+ <vertex X="174.715762" Y="-36.809337"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="82" ADD_L_DIR="1" ADD_L_MAX="14" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="11" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="PELICAN LANE" ID="166" ISLAND="North Island" NAME="PELICAN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63593" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="The Palms" TOWN="North Shore" TURNRESLNK="ak149" URBANRURAL="U" ID1="83">+ <vertices>+ <vertex X="174.716272" Y="-36.760730"/>+ <vertex X="174.716504" Y="-36.760433"/>+ <vertex X="174.716575" Y="-36.760095"/>+ <vertex X="174.716642" Y="-36.760028"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="83" ADD_L_DIR="1" ADD_L_MAX="89" ADD_L_MIN="21" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="86" ADD_R_MIN="6" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="CROFT LANE" ID="167" ISLAND="North Island" NAME="CROFT LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63592" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Coatesville" TOWN="" TURNRESLNK="ak150" URBANRURAL="R" ID1="84">+ <vertices>+ <vertex X="174.608952" Y="-36.730269"/>+ <vertex X="174.608998" Y="-36.728435"/>+ <vertex X="174.611995" Y="-36.727512"/>+ <vertex X="174.614542" Y="-36.727276"/>+ <vertex X="174.616560" Y="-36.726837"/>+ <vertex X="174.616910" Y="-36.726860"/>+ <vertex X="174.617176" Y="-36.726997"/>+ <vertex X="174.617228" Y="-36.727194"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="84" ADD_L_DIR="-1" ADD_L_MAX="7" ADD_L_MIN="5" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="4" ADD_R_MIN="1" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="LOGAN LANE" ID="168" ISLAND="North Island" NAME="LOGAN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="HIBISCUS COAST" NAMED_ARE2="WHANGAPARAOA PENINSULA" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63591" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Stanmore Bay" TOWN="Whangaparaoa" TURNRESLNK="ak151" URBANRURAL="U" ID1="85">+ <vertices>+ <vertex X="174.721974" Y="-36.620861"/>+ <vertex X="174.722470" Y="-36.620454"/>+ <vertex X="174.722548" Y="-36.620444"/>+ <vertex X="174.722624" Y="-36.620466"/>+ <vertex X="174.722668" Y="-36.620511"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="85" ADD_L_DIR="-1" ADD_L_MAX="18" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="-1" ADD_R_MAX="37" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="BAKEHOUSE LANE" ID="169" ISLAND="North Island" NAME="BAKEHOUSE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="HIBISCUS COAST" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63589" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Orewa" TOWN="Orewa" TURNRESLNK="ak152" URBANRURAL="U" ID1="86">+ <vertices>+ <vertex X="174.695998" Y="-36.587363"/>+ <vertex X="174.695576" Y="-36.586401"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="86" ADD_L_DIR="1" ADD_L_MAX="81" ADD_L_MIN="31" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="88" ADD_R_MIN="44" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="BURNS LANE" ID="170" ISLAND="North Island" NAME="BURNS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="0" OWNERSHIP="1" RC="6" RD_SEG_LNK="63588" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Kumeu" TOWN="" TURNRESLNK="ak153" URBANRURAL="R" ID1="87">+ <vertices>+ <vertex X="174.556592" Y="-36.765629"/>+ <vertex X="174.556029" Y="-36.765517"/>+ <vertex X="174.555933" Y="-36.765481"/>+ <vertex X="174.555869" Y="-36.765424"/>+ <vertex X="174.551561" Y="-36.761151"/>+ <vertex X="174.551470" Y="-36.761049"/>+ <vertex X="174.551412" Y="-36.760920"/>+ <vertex X="174.551402" Y="-36.760817"/>+ <vertex X="174.551403" Y="-36.760670"/>+ <vertex X="174.551464" Y="-36.760087"/>+ <vertex X="174.551439" Y="-36.759710"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="87" ADD_L_DIR="1" ADD_L_MAX="60" ADD_L_MIN="15" ADD_L_TYPE="M" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Rodney" FULL_NAME="GOLDFLATS LANE" ID="171" ISLAND="North Island" NAME="GOLDFLATS LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63587" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Coatesville" TOWN="" TURNRESLNK="ak154" URBANRURAL="R" ID1="88">+ <vertices>+ <vertex X="174.623641" Y="-36.733450"/>+ <vertex X="174.625973" Y="-36.736026"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="88" ADD_L_DIR="1" ADD_L_MAX="14" ADD_L_MIN="2" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="9" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="FALSTONE LANE" ID="172" ISLAND="North Island" NAME="FALSTONE LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63586" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Browns Bay" TOWN="North Shore" TURNRESLNK="ak155" URBANRURAL="U" ID1="89">+ <vertices>+ <vertex X="174.726189" Y="-36.721564"/>+ <vertex X="174.725102" Y="-36.721261"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="89" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="53" ADD_R_MIN="53" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="PENCARROW AVENUE" ID="132" ISLAND="North Island" NAME="PENCARROW AVE" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63585" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Epsom" TOWN="Auckland" TURNRESLNK="ak115" URBANRURAL="U" ID1="90">+ <vertices>+ <vertex X="174.766126" Y="-36.889163"/>+ <vertex X="174.766231" Y="-36.889204"/>+ <vertex X="174.766327" Y="-36.889264"/>+ <vertex X="174.766614" Y="-36.889485"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="90" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="17" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SELBY SQUARE" ID="133" ISLAND="North Island" NAME="SELBY SQ" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63583" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Saint Marys Bay" TOWN="Auckland" TURNRESLNK="ak116" URBANRURAL="U" ID1="91">+ <vertices>+ <vertex X="174.743485" Y="-36.845338"/>+ <vertex X="174.743746" Y="-36.845500"/>+ <vertex X="174.743776" Y="-36.845513"/>+ <vertex X="174.743803" Y="-36.845518"/>+ <vertex X="174.743826" Y="-36.845516"/>+ <vertex X="174.743846" Y="-36.845512"/>+ <vertex X="174.743862" Y="-36.845501"/>+ <vertex X="174.743880" Y="-36.845484"/>+ <vertex X="174.744105" Y="-36.845225"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="91" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="UNION STREET" ID="134" ISLAND="North Island" NAME="UNION ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63565" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Freemans Bay" TOWN="Auckland" TURNRESLNK="ak117" URBANRURAL="U" ID1="92">+ <vertices>+ <vertex X="174.754498" Y="-36.850543"/>+ <vertex X="174.754557" Y="-36.850419"/>+ <vertex X="174.754610" Y="-36.850378"/>+ <vertex X="174.754695" Y="-36.850346"/>+ <vertex X="174.754819" Y="-36.850324"/>+ <vertex X="174.754952" Y="-36.850328"/>+ <vertex X="174.755257" Y="-36.850394"/>+ <vertex X="174.755372" Y="-36.850419"/>+ <vertex X="174.755711" Y="-36.850433"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="92" ADD_L_DIR="1" ADD_L_MAX="10" ADD_L_MIN="6" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="9" ADD_R_MIN="1" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="YARBOROUGH STREET" ID="136" ISLAND="North Island" NAME="YARBOROUGH ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63562" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Saint Marys Bay" TOWN="Auckland" TURNRESLNK="ak119" URBANRURAL="U" ID1="93">+ <vertices>+ <vertex X="174.745114" Y="-36.845546"/>+ <vertex X="174.744105" Y="-36.845225"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="93" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="SULTAN LANE" ID="87" ISLAND="North Island" NAME="SULTAN LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63561" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Ellerslie" TOWN="Auckland" TURNRESLNK="ak68" URBANRURAL="U" ID1="94">+ <vertices>+ <vertex X="174.807469" Y="-36.898926"/>+ <vertex X="174.807974" Y="-36.898539"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="94" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="-1" ADD_R_MAX="250" ADD_R_MIN="240" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="TANIWHA STREET" ID="88" ISLAND="North Island" NAME="TANIWHA ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63555" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glen Innes" TOWN="Auckland" TURNRESLNK="ak69" URBANRURAL="U" ID1="95">+ <vertices>+ <vertex X="174.854332" Y="-36.878091"/>+ <vertex X="174.854497" Y="-36.878020"/>+ <vertex X="174.854715" Y="-36.877982"/>+ <vertex X="174.854783" Y="-36.877963"/>+ <vertex X="174.854823" Y="-36.877941"/>+ <vertex X="174.854855" Y="-36.877909"/>+ <vertex X="174.854876" Y="-36.877874"/>+ <vertex X="174.854887" Y="-36.877834"/>+ <vertex X="174.854889" Y="-36.877777"/>+ <vertex X="174.854877" Y="-36.877733"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="95" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="STRATTON LANE" ID="89" ISLAND="North Island" NAME="STRATTON LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63554" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glen Innes" TOWN="Auckland" TURNRESLNK="ak70" URBANRURAL="U" ID1="96">+ <vertices>+ <vertex X="174.855619" Y="-36.879355"/>+ <vertex X="174.855667" Y="-36.879556"/>+ <vertex X="174.855826" Y="-36.879538"/>+ <vertex X="174.856320" Y="-36.879634"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="96" ADD_L_DIR="1" ADD_L_MAX="13" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="1" ADD_R_MAX="12" ADD_R_MIN="2" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="TOSCA LANE" ID="143" ISLAND="North Island" NAME="TOSCA LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63553" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Point England" TOWN="Auckland" TURNRESLNK="ak126" URBANRURAL="U" ID1="97">+ <vertices>+ <vertex X="174.860267" Y="-36.879043"/>+ <vertex X="174.860411" Y="-36.879063"/>+ <vertex X="174.861071" Y="-36.879128"/>+ <vertex X="174.861522" Y="-36.879087"/>+ <vertex X="174.861436" Y="-36.878624"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="97" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="655" ADD_R_MIN="649" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MANUKAU ROAD" ID="110" ISLAND="North Island" NAME="MANUKAU RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="2" RD_SEG_LNK="63549" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Royal Oak" TOWN="Auckland" TURNRESLNK="ak239" URBANRURAL="U" ID1="98">+ <vertices>+ <vertex X="174.774915" Y="-36.906935"/>+ <vertex X="174.775106" Y="-36.907725"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="98" ADD_L_DIR="1" ADD_L_MAX="104" ADD_L_MIN="96" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="119" ADD_R_MIN="115" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="NEWTON ROAD" ID="111" ISLAND="North Island" NAME="NEWTON RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="2" RD_SEG_LNK="63548" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Newton" TOWN="Auckland" TURNRESLNK="ak240" URBANRURAL="U" ID1="99">+ <vertices>+ <vertex X="174.757389" Y="-36.862992"/>+ <vertex X="174.757958" Y="-36.863119"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="99" ADD_L_DIR="-1" ADD_L_MAX="579" ADD_L_MIN="573" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="522" ADD_R_MIN="504" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="HILLSBOROUGH ROAD" ID="112" ISLAND="North Island" NAME="HILLSBOROUGH RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="1" RD_SEG_LNK="63535" REGION="Auckland" ROUTE="Urban Route 15" SH_NO="" SPEED="50" SR="0" SUBURB="Lynfield" TOWN="Auckland" TURNRESLNK="ak241" URBANRURAL="U" ID1="100">+ <vertices>+ <vertex X="174.724347" Y="-36.925631"/>+ <vertex X="174.724459" Y="-36.925724"/>+ <vertex X="174.724634" Y="-36.925874"/>+ <vertex X="174.724825" Y="-36.926035"/>+ <vertex X="174.725776" Y="-36.926815"/>+ <vertex X="174.725870" Y="-36.926887"/>+ <vertex X="174.725942" Y="-36.926940"/>+ <vertex X="174.726110" Y="-36.927055"/>+ <vertex X="174.726393" Y="-36.927246"/>+ <vertex X="174.726496" Y="-36.927315"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="100" ADD_L_DIR="-1" ADD_L_MAX="7" ADD_L_MIN="1" ADD_L_TYPE="O" ADD_R_DIR="-1" ADD_R_MAX="12" ADD_R_MIN="2" ADD_R_TYPE="E" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="TRISTRAM AVENUE" ID="113" ISLAND="North Island" NAME="TRISTRAM AVE" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="1" RD_SEG_LNK="63534" REGION="Auckland" ROUTE="Urban Route 21" SH_NO="" SPEED="50" SR="0" SUBURB="Forrest Hill" TOWN="North Shore" TURNRESLNK="ak243" URBANRURAL="U" ID1="101">+ <vertices>+ <vertex X="174.747826" Y="-36.770445"/>+ <vertex X="174.749219" Y="-36.770040"/>+ <vertex X="174.749250" Y="-36.770034"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="101" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="1" ADD_R_MAX="659" ADD_R_MIN="657" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="MANUKAU ROAD" ID="114" ISLAND="North Island" NAME="MANUKAU RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="2" RD_SEG_LNK="63549" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Royal Oak" TOWN="Auckland" TURNRESLNK="ak244" URBANRURAL="U" ID1="102">+ <vertices>+ <vertex X="174.775106" Y="-36.907725"/>+ <vertex X="174.775199" Y="-36.908106"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="102" ADD_L_DIR="1" ADD_L_MAX="118" ADD_L_MIN="108" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="127" ADD_R_MIN="121" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Auckland City" FULL_NAME="NEWTON ROAD" ID="115" ISLAND="North Island" NAME="NEWTON RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="2" RD_SEG_LNK="63548" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Newton" TOWN="Auckland" TURNRESLNK="ak245" URBANRURAL="U" ID1="103">+ <vertices>+ <vertex X="174.757958" Y="-36.863119"/>+ <vertex X="174.758606" Y="-36.863259"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="103" ADD_L_DIR="-1" ADD_L_MAX="8" ADD_L_MIN="1" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="11" ADD_R_MIN="9" ADD_R_TYPE="O" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="CHERRY LANE" ID="33" ISLAND="North Island" NAME="CHERRY LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="0" OWNERSHIP="1" RC="6" RD_SEG_LNK="63533" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Glenfield" TOWN="North Shore" TURNRESLNK="ak33" URBANRURAL="U" ID1="104">+ <vertices>+ <vertex X="174.745740" Y="-36.780780"/>+ <vertex X="174.744841" Y="-36.779979"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="104" ADD_L_DIR="1" ADD_L_MAX="14" ADD_L_MIN="5" ADD_L_TYPE="M" ADD_R_DIR="-1" ADD_R_MAX="4" ADD_R_MIN="1" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="North Shore City" FULL_NAME="ELDERWOOD LANE" ID="34" ISLAND="North Island" NAME="ELDERWOOD LN" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="4" RD_SEG_LNK="63526" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Belmont" TOWN="North Shore" TURNRESLNK="ak34" URBANRURAL="U" ID1="105">+ <vertices>+ <vertex X="174.785128" Y="-36.803494"/>+ <vertex X="174.784406" Y="-36.803101"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="105" ADD_L_DIR="0" ADD_L_MAX="0" ADD_L_MIN="0" ADD_L_TYPE="" ADD_R_DIR="0" ADD_R_MAX="0" ADD_R_MIN="0" ADD_R_TYPE="" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Manukau City" FULL_NAME="WATFORD STREET" ID="229" ISLAND="North Island" NAME="WATFORD ST" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="5" RD_SEG_LNK="63522" REGION="Auckland" ROUTE="" SH_NO="" SPEED="50" SR="0" SUBURB="Otara" TOWN="Manukau" TURNRESLNK="ak210" URBANRURAL="U" ID1="106">+ <vertices>+ <vertex X="174.872745" Y="-36.960379"/>+ <vertex X="174.872738" Y="-36.960413"/>+ <vertex X="174.872731" Y="-36.960486"/>+ <vertex X="174.872746" Y="-36.960670"/>+ </vertices>+ </shape>+ <shape shapeType="polyLine" id="106" ADD_L_DIR="1" ADD_L_MAX="484" ADD_L_MIN="140" ADD_L_TYPE="E" ADD_R_DIR="1" ADD_R_MAX="411" ADD_R_MIN="75" ADD_R_TYPE="M" ALTERNATE_="" BRIDGE_NAM="" DISTRICT="Papakura" FULL_NAME="HUNUA ROAD" ID="230" ISLAND="North Island" NAME="HUNUA RD" NAMED_AREA="GREATER AUCKLAND" NAMED_ARE1="" NAMED_ARE2="" OPEN_TO_PU="1" OWNERSHIP="0" RC="3" RD_SEG_LNK="63521" REGION="Auckland" ROUTE="" SH_NO="" SPEED="100" SR="0" SUBURB="Red Hill" TOWN="Papakura" TURNRESLNK="ak211" URBANRURAL="R" ID1="107">+ <vertices>+ <vertex X="174.975798" Y="-37.075472"/>+ <vertex X="174.976585" Y="-37.075457"/>+ <vertex X="174.976789" Y="-37.075536"/>+ <vertex X="174.976827" Y="-37.075551"/>+ <vertex X="174.977052" Y="-37.075638"/>+ <vertex X="174.977470" Y="-37.075721"/>+ <vertex X="174.978963" Y="-37.075603"/>+ <vertex X="174.980279" Y="-37.075201"/>+ <vertex X="174.980735" Y="-37.075021"/>+ <vertex X="174.981142" Y="-37.074698"/>+ <vertex X="174.981180" Y="-37.074427"/>+ <vertex X="174.980887" Y="-37.073648"/>+ <vertex X="174.980700" Y="-37.073390"/>+ <vertex X="174.980648" Y="-37.073139"/>+ <vertex X="174.980690" Y="-37.073039"/>+ <vertex X="174.980847" Y="-37.073000"/>+ <vertex X="174.981197" Y="-37.073075"/>+ <vertex X="174.981701" Y="-37.072985"/>+ <vertex X="174.981914" Y="-37.072972"/>+ <vertex X="174.982619" Y="-37.072418"/>+ <vertex X="174.982929" Y="-37.072250"/>+ <vertex X="174.983356" Y="-37.072233"/>+ <vertex X="174.983724" Y="-37.072524"/>+ <vertex X="174.983981" Y="-37.072844"/>+ <vertex X="174.984317" Y="-37.073586"/>+ <vertex X="174.984488" Y="-37.073673"/>+ <vertex X="174.985129" Y="-37.073679"/>+ <vertex X="174.985819" Y="-37.073811"/>+ <vertex X="174.987735" Y="-37.074740"/>+ <vertex X="174.987897" Y="-37.074872"/>+ <vertex X="174.988529" Y="-37.075753"/>+ <vertex X="174.989204" Y="-37.076525"/>+ <vertex X="174.989827" Y="-37.076685"/>+ <vertex X="174.990158" Y="-37.076850"/>+ <vertex X="174.990654" Y="-37.077283"/>+ <vertex X="174.990747" Y="-37.077398"/>+ <vertex X="174.990887" Y="-37.077558"/>+ <vertex X="174.991457" Y="-37.077836"/>+ <vertex X="174.991798" Y="-37.077938"/>+ <vertex X="174.992227" Y="-37.078022"/>+ </vertices>+ </shape>+</shapes>
test/hexpat-tests.cabal view
@@ -9,16 +9,16 @@ build-depends: HUnit < 1.3,- QuickCheck == 2.4.*,+ QuickCheck >= 2.7.0.0, base >= 3 && < 5, bytestring, containers, transformers, deepseq >= 1.1.0.0,- parallel >= 3.1.0.0 && < 3.3.0.0,- test-framework > 0.3.0,- test-framework-hunit == 0.2.*,- test-framework-quickcheck2 == 0.2.*,+ parallel >= 3.1.0.0,+ test-framework,+ test-framework-hunit,+ test-framework-quickcheck2, text >= 0.5, utf8-string >= 0.3.3, List >= 0.4.2,
+ test/readRoads.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE OverloadedStrings #-}+import Text.XML.Expat.Tree+import Control.Monad+import Data.Text (Text)+import qualified Data.Text as T+import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as L+import Data.Maybe+++-- Reads the contents of ROADS.xml from stdin+main :: IO ()+main = do+ bs <- L.getContents+ let Element _ _ chs = parseThrowing defaultParseOptions bs :: UNode Text+ forM_ chs $ \ch -> do+ case ch of+ elt@(Element "shape" _ _) -> do+ putStrLn $ T.unpack $ fromMaybe "" $ getAttribute elt "FULL_NAME"+ _ -> return ()
test/suite/Text/XML/Expat/Cursor/Tests.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BangPatterns, FlexibleContexts, OverloadedStrings #-} module Text.XML.Expat.Cursor.Tests (tests) where @@ -159,6 +158,7 @@ return (n', ch1, chN) + p :: (TNode, TNode, TNode) -> Bool p (node, ch1, chN) = p1 && p2 where cursor = fromTree node
test/suite/Text/XML/Expat/ParallelTest.hs view
@@ -17,6 +17,7 @@ import qualified Data.ByteString.Lazy.Char8 as L import Test.QuickCheck import Test.QuickCheck.Gen+import Test.QuickCheck.Random import Test.HUnit hiding (Node) import System.IO import System.Random@@ -47,19 +48,16 @@ testParallel fork = do resultMVs <- replicateM nthreads $ do resultMV <- newEmptyMVar- fork $ do- g <- newStdGen- flip evalStateT g $ do- replicateM_ nloops $ do- (g, g2) <- gets split- put g- let treeIn = normalizeText $ unGen (arbitrary :: Gen TNode) g 0- xml = breakUp $ format' treeIn- treeOut = normalizeText $ parseThrowing defaultParseOptions xml- lift $ assertEqual "tree match" treeIn treeOut- `catch` \exc -> do- putStrLn $ "failing XML: "++concat (map B.unpack $ L.toChunks xml)- throwIO (exc :: SomeException)+ do+ replicateM_ nloops $ do+ g <- newQCGen+ let treeIn = normalizeText $ unGen (arbitrary :: Gen TNode) g 30+ xml = breakUp $ format' treeIn+ treeOut = normalizeText $ parseThrowing defaultParseOptions xml+ assertEqual "tree match" treeIn treeOut+ `catch` \exc -> do+ putStrLn $ "failing XML: "++concat (map B.unpack $ L.toChunks xml)+ throwIO (exc :: SomeException) putMVar resultMV Nothing `catch` \exc -> do putMVar resultMV $ Just (exc :: SomeException)
test/suite/Text/XML/Expat/ParseFormat.hs view
@@ -173,7 +173,7 @@ sbDoc = normalizeText $ fromElement (getRoot $ pfDoc pf) assertEqual "parse match" sbDoc (root :: Tree.UNode Text) let sb = fromMaybe (pfXML pf) (impl `lookup` pfOutXML pf)- bs = formatTree' root+ bs = format' root assertEqual "format match" sb bs ] Annotated -> [@@ -185,7 +185,7 @@ sbDoc = normalizeText $ fromElement (getRoot $ pfDoc pf) assertEqual "parse match" sbDoc (root :: Annotated.UNode () Text) let sb = fromMaybe (pfXML pf) (impl `lookup` pfOutXML pf)- bs = formatTree' root+ bs = format' root assertEqual "format match" sb bs ] Extended -> [
test/suite/Text/XML/Expat/UnitTests.hs view
@@ -2,12 +2,14 @@ import Text.XML.Expat.Tree hiding (parse) import qualified Text.XML.Expat.Tree as Tree-import Text.XML.Expat.IO hiding (parse)-import qualified Text.XML.Expat.IO as IO+import Text.XML.Expat.SAX (SAXEvent(..))+import qualified Text.XML.Expat.SAX as SAX import Text.XML.Expat.Cursor import Text.XML.Expat.Format-import Text.XML.Expat.Qualified+import Text.XML.Expat.Extended (LDocument)+import qualified Text.XML.Expat.Extended as Extended import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as C import qualified Data.ByteString.Lazy.Char8 as LC import qualified Data.ByteString.Lazy as L import qualified Data.Text as T@@ -16,8 +18,10 @@ import Data.ByteString.Internal (c2w, w2c) import Data.Char import Data.Maybe+import Data.Monoid import Data.IORef import Control.Applicative+import Control.Arrow (first) import Control.Exception as E import Control.Monad import Control.DeepSeq@@ -98,30 +102,6 @@ assertEqual "error1" (Left $ XMLParseError "not well-formed (invalid token)" (XMLParseLocation 1 0 0 0)) eDoc -test_parse :: IO ()-test_parse = do- ref <- newIORef []- let lazy = L.fromChunks [- toByteString "<open><tes",- toByteString "t1>Hello</test",- toByteString "1><hello></he",- toByteString "llo></open>"]- parser <- newParser Nothing- setStartElementHandler parser $ \_ cname cattrs -> do- name <- peekCString cname- ref <- modifyIORef ref $ \l -> ("start "++name):l- return True- setEndElementHandler parser $ \_ cname -> do- name <- peekCString cname- ref <- modifyIORef ref $ \l -> ("end "++name):l- return True- IO.parse parser lazy- l <- reverse <$> readIORef ref- assertEqual "parse"- ["start open","start test1","end test1","start hello","end hello","end open"]- l-- test_entities1 = do assertEqual "parse error" merr Nothing assertEqual "entity substitution" (Text "foo") c@@ -240,6 +220,68 @@ data ParseFormatTest = ParseFormatTest { } +test_xmlDecl1 :: IO ()+test_xmlDecl1 = do+ assertEqual "plain" [XMLDeclaration "1.0" Nothing Nothing,StartElement "hello" [],EndElement "hello"]+ (SAX.parse defaultParseOptions (LC.pack "<?xml version=\"1.0\"?><hello/>") :: [SAXEvent String String])+ assertEqual "withEnc" [XMLDeclaration "1.0" (Just "UTF-8") Nothing,StartElement "hello" [],EndElement "hello"]+ (SAX.parse defaultParseOptions (LC.pack "<?xml version=\"1.0\" encoding=\"UTF-8\"?><hello/>") :: [SAXEvent String String])+ assertEqual "SA0" [XMLDeclaration "1.0" Nothing (Just False),StartElement "hello" [],EndElement "hello"]+ (SAX.parse defaultParseOptions (LC.pack "<?xml version=\"1.0\" standalone=\"no\"?><hello/>") :: [SAXEvent String String])+ assertEqual "SA1" [XMLDeclaration "1.0" Nothing (Just True),StartElement "hello" [],EndElement "hello"]+ (SAX.parse defaultParseOptions (LC.pack "<?xml version=\"1.0\" standalone=\"yes\"?><hello/>") :: [SAXEvent String String])+ assertEqual "SA0enc" [XMLDeclaration "1.0" (Just "UTF-8") (Just False),StartElement "hello" [],EndElement "hello"]+ (SAX.parse defaultParseOptions (LC.pack "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><hello/>") :: [SAXEvent String String])+ assertEqual "SA1enc" [XMLDeclaration "1.0" (Just "UTF-8") (Just True),StartElement "hello" [],EndElement "hello"]+ (SAX.parse defaultParseOptions (LC.pack "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><hello/>") :: [SAXEvent String String])++normalizeSAXText :: Monoid t => [SAXEvent s t] -> [SAXEvent s t]+normalizeSAXText (CharacterData a:CharacterData b:xs) = normalizeSAXText (CharacterData (a `mappend` b):xs)+normalizeSAXText (x:xs) = x:normalizeSAXText xs+normalizeSAXText [] = []++test_various :: IO ()+test_various =+ assertEqual "var1" [+ StartElement "test" [],+ StartElement "sample" [("id","5")],+ CharacterData "This \"text with quotations\" should be escaped.",+ EndElement "sample",+ StartElement "mytest" [],+ CharacterData "//",+ StartCData,+ CharacterData "This \"text with quotations\" should not be escaped.//",+ EndCData,+ EndElement "mytest",+ ProcessingInstruction "php" "somecode(); ",+ Comment " this is a comment ",+ EndElement "test"+ ]+ (normalizeSAXText $ SAX.parse defaultParseOptions (LC.pack variousText) :: [SAXEvent String String])++variousText =+ "<test>"+++ "<sample id=\"5\">This \"text with quotations\" should be escaped.</sample>"+++ "<mytest>"+++ "//<![CDATA["+++ "This \"text with quotations\" should not be escaped."+++ "//]]>"+++ "</mytest>"+++ "<?php somecode(); ?>"+++ "<!-- this is a comment -->"+++ "</test>"++quotationOut =+ "<test><sample id=\"5\">This "text with quotations" should be escaped.</sample>"+++ "<mytest>//<![CDATA[This \"text with quotations\" should not be escaped.//]]>"+++ "</mytest><?php somecode(); ?><!-- this is a comment --></test>"++test_quotation =+ assertEqual "quotation"+ (quotationOut, Nothing)+ $ first (C.unpack . mconcat . LC.toChunks . formatDocument)+ $ (Extended.parse defaultParseOptions (LC.pack variousText) :: (LDocument String String, Maybe XMLParseError))+ tests = hUnitTestToTests $ TestList [ t' ("String",@@ -276,12 +318,14 @@ TestLabel "error2" $ TestCase $ test_error2, TestLabel "error3" $ TestCase $ test_error3, TestLabel "error4" $ TestCase $ test_error4,- TestLabel "parse" $ TestCase $ test_parse, TestLabel "entities1" $ TestCase $ test_entities1, TestLabel "entities2" $ TestCase $ test_entities2, TestLabel "textContent" $ TestCase $ test_textContent, TestLabel "indent" $ TestCase $ test_indent,- TestLabel "setAttribute" $ TestCase $ test_setAttribute+ TestLabel "setAttribute" $ TestCase $ test_setAttribute,+ TestLabel "xmlDecl1" $ TestCase $ test_xmlDecl1,+ TestLabel "various" $ TestCase $ test_various,+ TestLabel "quotation" $ TestCase $ test_quotation ] where