 -- |@parseChunk data False@ feeds /strict/ ByteString data into a
 -- 'Parser'.  The end of the data is indicated by passing @True@ for the
 -- final parameter.  @parse@ returns @False@ on a parse error.
-{#fun XML_Parse as parseChunk
+parseChunk :: Parser
+              -> BS.ByteString
+              -> Bool
+              -> IO Bool
+parseChunk parser@(Parser fp startRef endRef charRef) xml final = do
+    bracket
+        (do
+            cStartH <- mkCStartElementHandler =<< readIORef startRef
+            cEndH   <- mkCEndElementHandler =<< readIORef endRef
+            cCharH  <- mkCCharacterDataHandler =<< readIORef charRef
+            withParser parser $ \p -> do
+                {#call unsafe XML_SetStartElementHandler as ^#}  p cStartH
+                {#call unsafe XML_SetEndElementHandler as ^#}    p cEndH
+                {#call unsafe XML_SetCharacterDataHandler as ^#} p cCharH
+            return (cStartH, cEndH, cCharH))
+        (\(cStartH, cEndH, cCharH) -> do
+            freeHaskellFunPtr cStartH
+            freeHaskellFunPtr cEndH
+            freeHaskellFunPtr cCharH)
+        (\_ -> doParseChunk parser xml final)
+
+{#fun XML_Parse as doParseChunk
     {withParser* `Parser', withBStringLen* `BS.ByteString' &, `Bool'}
     -> `Bool' unStatus#}
 

  encodingToString
) where

import C2HS
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL

#include <expat.h>



-- |Opaque parser type.
type ParserPtr = Ptr ()
data Parser = Parser
    (ForeignPtr ())
    (IORef CStartElementHandler) 
    (IORef CEndElementHandler) 
    (IORef CCharacterDataHandler) 

withParser :: Parser -> (ParserPtr -> IO a) -> IO a
withParser (Parser fp _ _ _) = withForeignPtr fp

-- |Encoding types available for the document encoding.
data Encoding = ASCII | UTF8 | UTF16 | ISO88591
