packages feed

libxml-enumerator (empty) → 0.1

raw patch · 4 files changed

+156/−0 lines, 4 filesdep +basedep +bytestringdep +enumeratorsetup-changed

Dependencies added: base, bytestring, enumerator, libxml-sax, text, transformers, xml-types

Files

+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Text/XML/LibXML/Enumerator.hs view
@@ -0,0 +1,103 @@+-----------------------------------------------------------------------------+-- |+-- Module: Text.XML.LibXML.Enumerator+-- Copyright: 2010 John Millikin+-- License: MIT+--+-- Maintainer: jmillikin@gmail.com+-- Portability: portable+--+-----------------------------------------------------------------------------+module Text.XML.LibXML.Enumerator+	( Event (..)+	, parseBytes+	, parseText+	) where+import qualified Data.ByteString as B+import qualified Data.Enumerator as E+import Data.Enumerator ((>>==))+import qualified Data.Text as T+import qualified Data.XML.Types as X+import qualified Text.XML.LibXML.SAX as SAX++import Control.Monad.Trans.Class (lift)+import Control.Monad.ST (ST, unsafeSTToIO)+import qualified Data.STRef as ST+import System.IO.Unsafe (unsafePerformIO)++data Event+	= EventBeginDocument+	| EventEndDocument+	| EventBeginElement X.Name [X.Attribute]+	| EventEndElement X.Name+	| EventCharacters T.Text+	| EventComment T.Text+	| EventInstruction X.Instruction+	deriving (Show, Eq)++newParser :: Maybe T.Text -> ST s (SAX.Parser (ST s), ST.STRef s [Event], ST.STRef s (Maybe T.Text))+newParser name = do+	errRef <- ST.newSTRef Nothing+	p <- SAX.newParserST (\msg -> ST.writeSTRef errRef (Just msg)) name+	eventRef <- ST.newSTRef []+	+	let addEvent e = ST.modifySTRef eventRef (e:) >> return True+	let setCallback cb st = SAX.setCallback p cb st+	+	setCallback SAX.parsedBeginDocument (addEvent EventBeginDocument)+	setCallback SAX.parsedEndDocument (addEvent EventEndDocument)+	setCallback SAX.parsedBeginElement ((addEvent .) . EventBeginElement)+	setCallback SAX.parsedEndElement (addEvent . EventEndElement)+	setCallback SAX.parsedCharacters (addEvent . EventCharacters)+	setCallback SAX.parsedComment (addEvent . EventComment)+	setCallback SAX.parsedInstruction (addEvent . EventInstruction)+	+	return (p, eventRef, errRef)++unsafePerformST_M :: Monad m => ST s a -> m a+unsafePerformST_M st = unsafePerformIO (unsafeSTToIO (fmap return st))++parseBytes :: Monad m => Maybe T.Text -> E.Enumeratee T.Text B.ByteString Event m b+parseBytes = parseSomething SAX.parseBytes++parseText :: Monad m => Maybe T.Text -> E.Enumeratee T.Text T.Text Event m b+parseText = parseSomething SAX.parseText++parseSomething :: Monad m+               => (SAX.Parser (ST s) -> a -> ST s ())+               -> Maybe T.Text+               -> E.Enumeratee T.Text a Event m b+parseSomething something name s = E.Iteratee $ do+	(p, eventRef, errRef) <- unsafePerformST_M $ newParser name+	+	let withEvents st = unsafePerformST_M $ do+		ST.writeSTRef eventRef []+		ST.writeSTRef errRef Nothing+		st+		events <- ST.readSTRef eventRef+		err <- ST.readSTRef errRef+		return (reverse events, err)+	+	let parseChunk bytes = withEvents (something p bytes)+	let complete = withEvents (SAX.parseComplete p)+	E.runIteratee $ eneeParser parseChunk complete s++eneeParser :: Monad m+           => (a -> m ([Event], Maybe T.Text))+           -> m ([Event], Maybe T.Text)+           -> E.Enumeratee T.Text a Event m b+eneeParser parseChunk parseComplete = E.checkDone (E.continue . step) where+	step k E.EOF = checkEvents k parseComplete (\k' -> E.yield (E.Continue k') E.EOF)+	step k (E.Chunks xs) = parseLoop k xs+	+	parseLoop k [] = E.continue (step k)+	parseLoop k (x:xs) = checkEvents k (parseChunk x) (\k' -> parseLoop k' xs)+	+	checkEvents k getEvents next = do+		(events, maybeErr) <- lift getEvents+		let checkError k' = case maybeErr of+			Nothing -> next k'+			Just err -> E.throwError err+		if null events+			then checkError k+			else k (E.Chunks events) >>== E.checkDone checkError
+ libxml-enumerator.cabal view
@@ -0,0 +1,29 @@+name: libxml-enumerator+version: 0.1+synopsis: Enumerator-based API for libXML's SAX interface+license: MIT+license-file: license.txt+author: John Millikin <jmillikin@gmail.com>+maintainer: jmillikin@gmail.com+copyright: Copyright (c) John Millikin 2010+build-type: Simple+cabal-version: >=1.6+category: Enumerator, Text, XML, Parsing+stability: experimental+bug-reports: mailto:jmillikin@gmail.com+tested-with: GHC==6.12.1++library+  ghc-options: -Wall -fno-warn-unused-do-bind++  build-depends:+      base >= 4 && < 5+    , bytestring >= 0.9 && < 0.10+    , text >= 0.7 && < 0.8+    , enumerator >= 0.1 && < 0.4+    , transformers >= 0.2 && < 0.3+    , libxml-sax >= 0.6 && < 0.7+    , xml-types >= 0.1 && < 0.2++  exposed-modules:+    Text.XML.LibXML.Enumerator
+ license.txt view
@@ -0,0 +1,22 @@+Copyright (c) 2010 John Millikin++Permission is hereby granted, free of charge, to any person+obtaining a copy of this software and associated documentation+files (the "Software"), to deal in the Software without+restriction, including without limitation the rights to use,+copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the+Software is furnished to do so, subject to the following+conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+OTHER DEALINGS IN THE SOFTWARE.