{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}-- | 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'.moduleText.XML.Expat.Internal.IO(-- ** Parser SetupParser,newParser,-- ** Parsingparse,parse',withParser,ParserPtr,Parser_struct,parseChunk,Encoding(..),XMLParseError(..),getParseLocation,XMLParseLocation(..),-- ** Parser CallbacksXMLDeclarationHandler,StartElementHandler,EndElementHandler,CharacterDataHandler,ExternalEntityRefHandler,SkippedEntityHandler,StartCDataHandler,EndCDataHandler,CommentHandler,ProcessingInstructionHandler,setXMLDeclarationHandler,setStartElementHandler,setEndElementHandler,setCharacterDataHandler,setStartCDataHandler,setEndCDataHandler,setProcessingInstructionHandler,setCommentHandler,setExternalEntityRefHandler,setSkippedEntityHandler,setUseForeignDTD,-- ** Lower-level interfaceparseExternalEntityReference,ExpatHandlers,-- ** HelpersencodingToString)whereimportControl.ConcurrentimportControl.Exception(bracket)importControl.DeepSeqimportControl.MonadimportqualifiedData.ByteStringasBSimportqualifiedData.ByteString.LazyasBSLimportData.IORefimportForeignimportForeign.C-- |Opaque parser type.dataParser_structtypeParserPtr=PtrParser_structdataParser=Parser{_parserObj::ForeignPtrParser_struct,_xmlDeclarationHandler::IORefCXMLDeclarationHandler,_startElementHandler::IORefCStartElementHandler,_endElementHandler::IORefCEndElementHandler,_cdataHandler::IORefCCharacterDataHandler,_externalEntityRefHandler::IORef(MaybeCExternalEntityRefHandler),_skippedEntityHandler::IORef(MaybeCSkippedEntityHandler),_startCDataHandler::IORefCStartCDataHandler,_endCDataHandler::IORefCEndCDataHandler,_processingInstructionHandler::IORefCProcessingInstructionHandler,_commentHandler::IORefCCommentHandler}instanceShowParserwhereshowsPrec_(Parserfp__________)=showsPrec0fp-- |Encoding types available for the document encoding.dataEncoding=ASCII|UTF8|UTF16|ISO88591encodingToString::Encoding->StringencodingToStringASCII="US-ASCII"encodingToStringUTF8="UTF-8"encodingToStringUTF16="UTF-16"encodingToStringISO88591="ISO-8859-1"withOptEncoding::MaybeEncoding->(CString->IOa)->IOawithOptEncodingNothingf=fnullPtrwithOptEncoding(Justenc)f=withCString(encodingToStringenc)fparserCreate::MaybeEncoding->IO(ParserPtr)parserCreatea1=withOptEncodinga1$\a1'->dopp<-parserCreate'_a1'xmlSetUserDatappppreturnpp-- | Create a 'Parser'.newParser::MaybeEncoding->IOParsernewParserenc=doptr<-parserCreateencfptr<-newForeignPtrparserFreeptrnullXMLDeclH<-newIORefnullCXMLDeclarationHandlernullStartH<-newIORefnullCStartElementHandlernullEndH<-newIORefnullCEndElementHandlernullCharH<-newIORefnullCCharacterDataHandlerextH<-newIORefNothingskipH<-newIORefNothingnullSCDataH<-newIORefnullCStartCDataHandlernullECDataH<-newIORefnullCEndCDataHandlernullPIH<-newIORefnullCProcessingInstructionHandlernullCommentH<-newIORefnullCCommentHandlerreturn$ParserfptrnullXMLDeclHnullStartHnullEndHnullCharHextHskipHnullSCDataHnullECDataHnullPIHnullCommentHsetUseForeignDTD::Parser->Bool->IO()setUseForeignDTDpb=withParserp$\p'->xmlUseForeignDTDp'b'whereb'=ifbthen1else0-- ByteString.useAsCStringLen is almost what we need, but C2HS wants a CInt-- instead of an Int.withBStringLen::BS.ByteString->((CString,CInt)->IOa)->IOawithBStringLenbsf=doBS.useAsCStringLenbs$\(str,len)->f(str,fromIntegrallen)unStatus::CInt->BoolunStatus0=FalseunStatus_=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(MaybeXMLParseError)parseparserbs=withParserparser$\pp->doletdoParseChunks[]=doParseChunkppBS.emptyTruedoParseChunks(c:cs)=dook<-doParseChunkppcFalseifokthendoParseChunkscselsereturnFalseok<-doParseChunks(BSL.toChunksbs)ifokthenreturnNothingelseJust`fmap`getErrorpp-- |@parse data@ feeds /strict/ ByteString data into a 'Parser'. It returns-- Nothing on success, or Just the parse error.parse'::Parser->BS.ByteString->IO(MaybeXMLParseError)parse'parserbs=withParserparser$\pp->dook<-doParseChunkppbsTrueifokthenreturnNothingelseJust`fmap`getErrorppparseExternalEntityReference::Parser->CString-- ^ context->MaybeEncoding-- ^ encoding->CStringLen-- ^ text->IOBoolparseExternalEntityReferenceparsercontextencoding(text,sz)=withParserparser$\pp->doextp<-withOptEncodingencoding$xmlExternalEntityParserCreateppcontexte<-doParseChunk'_extptext(fromIntegralsz)1parserFree'extpreturn$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(MaybeXMLParseError)parseChunkppxmlfinal=dook<-doParseChunkppxmlfinalifokthenreturnNothingelseJust`fmap`getErrorppgetError::ParserPtr->IOXMLParseErrorgetErrorpp=docode<-xmlGetErrorCodeppcerr<-xmlErrorStringcodeerr<-peekCStringcerrloc<-getParseLocationppreturn$XMLParseErrorerrlocdataExpatHandlers=ExpatHandlers(FunPtrCXMLDeclarationHandler)(FunPtrCStartElementHandler)(FunPtrCEndElementHandler)(FunPtrCCharacterDataHandler)(Maybe(FunPtrCExternalEntityRefHandler))(Maybe(FunPtrCSkippedEntityHandler))(FunPtrCStartCDataHandler)(FunPtrCEndCDataHandler)(FunPtrCProcessingInstructionHandler)(FunPtrCCommentHandler)-- | Most of the low-level functions take a ParserPtr so are required to be-- called inside @withParser@.withParser::Parser->(ParserPtr->IOa)-- ^ Computation where parseChunk and other low-level functions may be used->IOawithParserparser@(Parserfp__________)code=withForeignPtrfp$\pp->dobracket(unsafeSetHandlersparserpp)unsafeReleaseHandlers(\_->codepp)whereunsafeSetHandlers::Parser->ParserPtr->IOExpatHandlersunsafeSetHandlers(Parser_xmlDeclRefstartRefendRefcharRefextRefskipRefstartCDataRefendCDataRefprocessingInstructionRefcommentRef)pp=docXMLDeclH<-mkCXMLDeclarationHandler=<<readIORefxmlDeclRefcStartH<-mkCStartElementHandler=<<readIORefstartRefcEndH<-mkCEndElementHandler=<<readIORefendRefcCharH<-mkCCharacterDataHandler=<<readIORefcharRefmExtH<-readIORefextRef>>=maybe(returnNothing)(\h->liftMJust$mkCExternalEntityRefHandlerh)mSkipH<-readIORefskipRef>>=maybe(returnNothing)(\h->liftMJust$mkCSkippedEntityHandlerh)cStartCDataH<-mkCStartCDataHandler=<<readIORefstartCDataRefcEndCDataH<-mkCEndCDataHandler=<<readIORefendCDataRefcProcessingInstructionH<-mkCProcessingInstructionHandler=<<readIORefprocessingInstructionRefcCommentH<-mkCCommentHandler=<<readIORefcommentRefxmlSetxmldeclhandlerppcXMLDeclHxmlSetstartelementhandlerppcStartHxmlSetendelementhandlerppcEndHxmlSetcharacterdatahandlerppcCharHxmlSetstartcdatahandlerppcStartCDataHxmlSetendcdatahandlerppcEndCDataHxmlSetprocessinginstructionhandlerppcProcessingInstructionHxmlSetcommenthandlerppcCommentHmaybe(return())(xmlSetExternalEntityRefHandlerpp)mExtHmaybe(return())(xmlSetSkippedEntityHandlerpp)mSkipHreturn$ExpatHandlerscXMLDeclHcStartHcEndHcCharHmExtHmSkipHcStartCDataHcEndCDataHcProcessingInstructionHcCommentHunsafeReleaseHandlers::ExpatHandlers->IO()unsafeReleaseHandlers(ExpatHandlerscXMLDeclHcStartHcEndHcCharHmcExtHmcSkipHcStartCDataHcEndCDataHcProcessingInstructionHcCommentH)=dofreeHaskellFunPtrcXMLDeclHfreeHaskellFunPtrcStartHfreeHaskellFunPtrcEndHfreeHaskellFunPtrcCharHmaybe(return())freeHaskellFunPtrmcExtHmaybe(return())freeHaskellFunPtrmcSkipHfreeHaskellFunPtrcStartCDataHfreeHaskellFunPtrcEndCDataHfreeHaskellFunPtrcProcessingInstructionHfreeHaskellFunPtrcCommentH-- |Obtain C value from Haskell 'Bool'.--cFromBool::Numa=>Bool->acFromBool=fromBooldoParseChunk::ParserPtr->BS.ByteString->Bool->IO(Bool)doParseChunk=ensureBoundThread$\a1a2a3->withBStringLena2$\(a2'1,a2'2)->let{a3'=cFromBoola3}indoParseChunk'_a1a2'1a2'2a3'>>=\res->let{res'=unStatusres}inreturn(res')dataWorkerIface=WorkerIface(MVar(ParserPtr,BS.ByteString,Bool))(MVarBool)workerIfaceRef::IORef(MaybeWorkerIface){-# NOINLINE workerIfaceRef #-}workerIfaceRef=unsafePerformIO$newIORefNothing-- 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->IOBool)->ParserPtr->BS.ByteString->Bool->IOBoolensureBoundThreaddoitpbslast=dobound<-isCurrentThreadBoundifrtsSupportsBoundThreads&&notboundthendelegateelsedoitpbslastwheredelegate=domIface<-readIORefworkerIfaceRefcasemIfaceofJustiface->pipeToifaceNothing->doinV<-newEmptyMVaroutV<-newEmptyMVarletiface=WorkerIfaceinVoutVjustSetItGlobally<-atomicModifyIORefworkerIfaceRef$\mIface->casemIfaceofJust_->(mIface,False)Nothing->(Justiface,True)ifjustSetItGloballythendo_<-forkOS$workerifacepipeToifaceelse-- 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.delegatepipeTo(WorkerIfaceinVoutV)=putMVarinV(p,bs,last)>>takeMVaroutVworker(WorkerIfaceinVoutV)=forever$putMVaroutV=<<uncurry3doit=<<takeMVarinVwhereuncurry3f(a,b,c)=fabc-- | Parse error, consisting of message text and error locationdataXMLParseError=XMLParseErrorStringXMLParseLocationderiving(Eq,Show)instanceNFDataXMLParseErrorwherernf(XMLParseErrormsgloc)=rnf(msg,loc)-- | Specifies a location of an event within the input textdataXMLParseLocation=XMLParseLocation{xmlLineNumber::Int64,-- ^ Line number of the eventxmlColumnNumber::Int64,-- ^ Column number of the eventxmlByteIndex::Int64,-- ^ Byte index of event from start of documentxmlByteCount::Int64-- ^ The number of bytes in the event}deriving(Eq,Show)instanceNFDataXMLParseLocationwherernf(XMLParseLocationlincolindcou)=rnf(lin,col,ind,cou)getParseLocation::ParserPtr->IOXMLParseLocationgetParseLocationpp=doline<-xmlGetCurrentLineNumberppcol<-xmlGetCurrentColumnNumberppindex<-xmlGetCurrentByteIndexppcount<-xmlGetCurrentByteCountppreturn$XMLParseLocation{xmlLineNumber=fromIntegralline,xmlColumnNumber=fromIntegralcol,xmlByteIndex=fromIntegralindex,xmlByteCount=fromIntegralcount}-- | 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.typeXMLDeclarationHandler=ParserPtr->CString->CString->CInt->IOBool-- | 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.typeStartElementHandler=ParserPtr->CString->[(CString,CString)]->IOBool-- | 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.typeEndElementHandler=ParserPtr->CString->IOBool-- | 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.typeCharacterDataHandler=ParserPtr->CStringLen->IOBool-- | The type of the \"start cdata\" callback. Return True to continue-- parsing as normal, or False to terminate the parse.typeStartCDataHandler=ParserPtr->IOBool-- | The type of the \"end cdata\" callback. Return True to continue-- parsing as normal, or False to terminate the parse.typeEndCDataHandler=ParserPtr->IOBool-- | 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.typeProcessingInstructionHandler=ParserPtr->CString->CString->IOBool-- | 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.typeCommentHandler=ParserPtr->CString->IOBool-- | The type of the \"external entity reference\" callback. See the expat-- documentation.typeExternalEntityRefHandler=Parser->CString-- context->CString-- base->CString-- systemID->CString-- publicID->IOBool-- | 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.typeSkippedEntityHandler=ParserPtr->CString-- entityName->Int-- is a parameter entity?->IOBooltypeCXMLDeclarationHandler=ParserPtr->CString->CString->CInt->IO()nullCXMLDeclarationHandler::CXMLDeclarationHandlernullCXMLDeclarationHandler____=return()foreignimportccallsafe"wrapper"mkCXMLDeclarationHandler::CXMLDeclarationHandler->IO(FunPtrCXMLDeclarationHandler)wrapXMLDeclarationHandler::Parser->XMLDeclarationHandler->CXMLDeclarationHandlerwrapXMLDeclarationHandlerparserhandler=hwherehppverencsd|ver/=nullPtr=dostillRunning<-handlerppverencsdunlessstillRunning$stoppparser{- 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()setXMLDeclarationHandlerparser@(Parser_xmlDeclRef_________)handler=writeIORefxmlDeclRef$wrapXMLDeclarationHandlerparserhandlertypeCStartElementHandler=ParserPtr->CString->PtrCString->IO()nullCStartElementHandler::CStartElementHandlernullCStartElementHandler___=return()foreignimportccallsafe"wrapper"mkCStartElementHandler::CStartElementHandler->IO(FunPtrCStartElementHandler)wrapStartElementHandler::Parser->StartElementHandler->CStartElementHandlerwrapStartElementHandlerparserhandler=hwherehppcnamecattrs=docattrlist<-peekArray0nullPtrcattrsstillRunning<-handlerppcname(pairwisecattrlist)unlessstillRunning$stoppparser-- | Attach a StartElementHandler to a Parser.setStartElementHandler::Parser->StartElementHandler->IO()setStartElementHandlerparser@(Parser__startRef________)handler=writeIORefstartRef$wrapStartElementHandlerparserhandlertypeCEndElementHandler=ParserPtr->CString->IO()nullCEndElementHandler::CEndElementHandlernullCEndElementHandler__=return()foreignimportccallsafe"wrapper"mkCEndElementHandler::CEndElementHandler->IO(FunPtrCEndElementHandler)wrapEndElementHandler::Parser->EndElementHandler->CEndElementHandlerwrapEndElementHandlerparserhandler=hwherehppcname=dostillRunning<-handlerppcnameunlessstillRunning$stoppparser-- | Attach an EndElementHandler to a Parser.setEndElementHandler::Parser->EndElementHandler->IO()setEndElementHandlerparser@(Parser___endRef_______)handler=writeIORefendRef$wrapEndElementHandlerparserhandlertypeCCharacterDataHandler=ParserPtr->CString->CInt->IO()nullCCharacterDataHandler::CCharacterDataHandlernullCCharacterDataHandler___=return()foreignimportccallsafe"wrapper"mkCCharacterDataHandler::CCharacterDataHandler->IO(FunPtrCCharacterDataHandler)wrapCharacterDataHandler::Parser->CharacterDataHandler->CCharacterDataHandlerwrapCharacterDataHandlerparserhandler=hwherehppcdatalen=dostillRunning<-handlerpp(cdata,fromIntegrallen)unlessstillRunning$stoppparser-- | Attach an CharacterDataHandler to a Parser.setCharacterDataHandler::Parser->CharacterDataHandler->IO()setCharacterDataHandlerparser@(Parser____charRef______)handler=writeIORefcharRef$wrapCharacterDataHandlerparserhandlertypeCStartCDataHandler=ParserPtr->IO()nullCStartCDataHandler::CStartCDataHandlernullCStartCDataHandler_=return()foreignimportccallsafe"wrapper"mkCStartCDataHandler::CStartCDataHandler->IO(FunPtrCStartCDataHandler)wrapStartCDataHandler::Parser->StartCDataHandler->CStartCDataHandlerwrapStartCDataHandlerparserhandler=hwherehpp=dostillRunning<-handlerppunlessstillRunning$stoppparser-- | Attach a StartCDataHandler to a Parser.setStartCDataHandler::Parser->StartCDataHandler->IO()setStartCDataHandlerparser@(Parser_______startCData___)handler=writeIORefstartCData$wrapStartCDataHandlerparserhandlertypeCEndCDataHandler=ParserPtr->IO()nullCEndCDataHandler::CEndCDataHandlernullCEndCDataHandler_=return()foreignimportccallsafe"wrapper"mkCEndCDataHandler::CEndCDataHandler->IO(FunPtrCEndCDataHandler)wrapEndCDataHandler::Parser->EndCDataHandler->CEndCDataHandlerwrapEndCDataHandlerparserhandler=hwherehpp=dostillRunning<-handlerppunlessstillRunning$stoppparser-- | Attach a EndCDataHandler to a Parser.setEndCDataHandler::Parser->EndCDataHandler->IO()setEndCDataHandlerparser@(Parser________endCData__)handler=writeIORefendCData$wrapEndCDataHandlerparserhandlertypeCProcessingInstructionHandler=ParserPtr->CString->CString->IO()nullCProcessingInstructionHandler::CProcessingInstructionHandlernullCProcessingInstructionHandler___=return()foreignimportccallsafe"wrapper"mkCProcessingInstructionHandler::CProcessingInstructionHandler->IO(FunPtrCProcessingInstructionHandler)wrapProcessingInstructionHandler::Parser->ProcessingInstructionHandler->CProcessingInstructionHandlerwrapProcessingInstructionHandlerparserhandler=hwherehppctargetcdata=dostillRunning<-handlerppctargetcdataunlessstillRunning$stoppparser-- | Attach a ProcessingInstructionHandler to a Parser.setProcessingInstructionHandler::Parser->ProcessingInstructionHandler->IO()setProcessingInstructionHandlerparser@(Parser_________piRef_)handler=writeIORefpiRef$wrapProcessingInstructionHandlerparserhandlertypeCCommentHandler=ParserPtr->CString->IO()nullCCommentHandler::CCommentHandlernullCCommentHandler__=return()foreignimportccallsafe"wrapper"mkCCommentHandler::CCommentHandler->IO(FunPtrCCommentHandler)wrapCommentHandler::Parser->CommentHandler->CCommentHandlerwrapCommentHandlerparserhandler=hwherehppcdata=dostillRunning<-handlerppcdataunlessstillRunning$stoppparser-- | Attach a CommentHandler to a Parser.setCommentHandler::Parser->CommentHandler->IO()setCommentHandlerparser@(Parser__________commentRef)handler=writeIORefcommentRef$wrapCommentHandlerparserhandlerpairwise::[a]->[(a,a)]pairwise(x1:x2:xs)=(x1,x2):pairwisexspairwise_=[]stopp::Parser->IO()stoppparser=withParserparser$\p->xmlStopParserp0-------------------------------------------------------------------------------- C importsforeignimportccallunsafe"XML_ParserCreate"parserCreate'_::PtrCChar->IOParserPtrforeignimportccallunsafe"XML_SetUserData"xmlSetUserData::ParserPtr->ParserPtr->IO()foreignimportccallunsafe"XML_SetXmlDeclHandler"xmlSetxmldeclhandler::ParserPtr->FunPtrCXMLDeclarationHandler->IO()foreignimportccallunsafe"XML_SetStartElementHandler"xmlSetstartelementhandler::ParserPtr->((FunPtr(ParserPtr->((PtrCChar)->((Ptr(PtrCChar))->(IO()))))->(IO())))foreignimportccallunsafe"XML_SetEndElementHandler"xmlSetendelementhandler::ParserPtr->((FunPtr(ParserPtr->((PtrCChar)->(IO())))->(IO())))foreignimportccallunsafe"XML_SetCharacterDataHandler"xmlSetcharacterdatahandler::ParserPtr->((FunPtr(ParserPtr->((PtrCChar)->(CInt->(IO()))))->(IO())))foreignimportccallunsafe"XML_SetStartCdataSectionHandler"xmlSetstartcdatahandler::ParserPtr->FunPtrCStartCDataHandler->IO()foreignimportccallunsafe"XML_SetEndCdataSectionHandler"xmlSetendcdatahandler::ParserPtr->FunPtrCStartCDataHandler->IO()foreignimportccallunsafe"XML_SetCommentHandler"xmlSetcommenthandler::ParserPtr->((FunPtr(ParserPtr->((PtrCChar)->(IO())))->(IO())))foreignimportccallunsafe"XML_SetProcessingInstructionHandler"xmlSetprocessinginstructionhandler::ParserPtr->((FunPtr(ParserPtr->((PtrCChar)->((PtrCChar)->(IO()))))->(IO())))foreignimportccallsafe"XML_Parse"doParseChunk'_::ParserPtr->((PtrCChar)->(CInt->(CInt->(IOCInt))))foreignimportccallunsafe"XML_UseForeignDTD"xmlUseForeignDTD::ParserPtr-- ^ parser->CChar-- ^ use foreign DTD? (external entity ref-- handler will be called with publicID &-- systemID set to null->IO()foreignimportccall"&XML_ParserFree"parserFree::FunPtr(ParserPtr->IO())foreignimportccall"XML_ParserFree"parserFree'::ParserPtr->IO()typeCExternalEntityRefHandler=ParserPtr-- parser->PtrCChar-- context->PtrCChar-- base->PtrCChar-- systemID->PtrCChar-- publicID->IO()foreignimportccallunsafe"wrapper"mkCExternalEntityRefHandler::CExternalEntityRefHandler->IO(FunPtrCExternalEntityRefHandler)foreignimportccallunsafe"XML_SetExternalEntityRefHandler"xmlSetExternalEntityRefHandler::ParserPtr->FunPtrCExternalEntityRefHandler->IO()foreignimportccallunsafe"XML_SetSkippedEntityHandler"xmlSetSkippedEntityHandler::ParserPtr->FunPtrCSkippedEntityHandler->IO()foreignimportccallunsafe"XML_ExternalEntityParserCreate"xmlExternalEntityParserCreate::ParserPtr->CString-- ^ context->CString-- ^ encoding->IOParserPtrtypeCSkippedEntityHandler=ParserPtr-- user data pointer->CString-- entity name->CInt-- is a parameter entity?->IO()foreignimportccallsafe"wrapper"mkCSkippedEntityHandler::CSkippedEntityHandler->IO(FunPtrCSkippedEntityHandler)wrapExternalEntityRefHandler::Parser->ExternalEntityRefHandler->CExternalEntityRefHandlerwrapExternalEntityRefHandlerparserhandler=hwhereh_contextbasesystemIDpublicID=dostillRunning<-handlerparsercontextbasesystemIDpublicIDunlessstillRunning$stoppparserwrapSkippedEntityHandler::Parser->SkippedEntityHandler->CSkippedEntityHandlerwrapSkippedEntityHandlerparserhandler=hwherehppentityNamei=dostillRunning<-handlerppentityName(fromIntegrali)unlessstillRunning$stoppparsersetExternalEntityRefHandler::Parser->ExternalEntityRefHandler->IO()setExternalEntityRefHandlerparserh=writeIORefref$Just$wrapExternalEntityRefHandlerparserhwhereref=_externalEntityRefHandlerparsersetSkippedEntityHandler::Parser->SkippedEntityHandler->IO()setSkippedEntityHandlerparserh=writeIORefref$Just$wrapSkippedEntityHandlerparserhwhereref=_skippedEntityHandlerparser-- Note on word sizes:---- on expat 2.0:-- XML_GetCurrentLineNumber returns XML_Size-- XML_GetCurrentColumnNumber returns XML_Size-- XML_GetCurrentByteIndex returns XML_Index-- These are defined in expat_external.h---- debian-i386 says XML_Size and XML_Index are 4 bytes.-- ubuntu-amd64 says XML_Size and XML_Index are 8 bytes.-- These two systems do NOT define XML_LARGE_SIZE, which would force these types-- to be 64-bit.---- If we guess the word size too small, it shouldn't matter: We will just discard-- the most significant part. If we get the word size too large, we will get-- garbage (very bad).---- So - what I will do is use CLong and CULong, which correspond to what expat-- is using when XML_LARGE_SIZE is disabled, and give the correct sizes on the-- two machines mentioned above. At the absolute worst the word size will be too-- short.foreignimportccallunsafe"expat.h XML_GetErrorCode"xmlGetErrorCode::ParserPtr->IOCIntforeignimportccallunsafe"expat.h XML_GetCurrentLineNumber"xmlGetCurrentLineNumber::ParserPtr->IOCULongforeignimportccallunsafe"expat.h XML_GetCurrentColumnNumber"xmlGetCurrentColumnNumber::ParserPtr->IOCULongforeignimportccallunsafe"expat.h XML_GetCurrentByteIndex"xmlGetCurrentByteIndex::ParserPtr->IOCLongforeignimportccallunsafe"expat.h XML_GetCurrentByteCount"xmlGetCurrentByteCount::ParserPtr->IOCIntforeignimportccallunsafe"expat.h XML_ErrorString"xmlErrorString::CInt->IOCStringforeignimportccallunsafe"expat.h XML_StopParser"xmlStopParser::ParserPtr->CInt->IO()