packages feed

yajl-enumerator 0.2.0.4 → 0.3

raw patch · 2 files changed

+61/−62 lines, 2 files

Files

Text/JSON/YAJL/Enumerator.hs view
@@ -13,9 +13,7 @@ 	 	-- * Parsing 	, parseBytesIO-	, parseTextIO 	, parseBytesST-	, parseTextST 	 	-- * Generating 	, Y.GeneratorConfig (..)@@ -51,21 +49,37 @@ 	| EventBeginObject 	| EventAttributeName T.Text 	| EventEndObject-	deriving (Show)+	deriving (Show, Eq)  -- Parser {{{  parseBytesIO :: MonadIO m => E.Enumeratee B.ByteString Event m b-parseBytesIO = parseIO Y.parseBytes--parseTextIO :: MonadIO m => E.Enumeratee T.Text Event m b-parseTextIO = parseIO Y.parseText+parseBytesIO s = do+	(p, eventRef) <- liftIO newParserIO+	+	let withEvents io = liftIO $ do+		IO.writeIORef eventRef []+		status <- io+		events <- IO.readIORef eventRef+		return (reverse events, status)+	+	let parseChunk bytes = withEvents (Y.parseBytes p bytes)+	let complete = withEvents (Y.parseComplete p)+	eneeParser (liftIO (Y.getBytesConsumed p)) parseChunk complete s  parseBytesST :: E.Enumeratee B.ByteString Event (ST s) b-parseBytesST = parseST Y.parseBytes--parseTextST :: E.Enumeratee T.Text Event (ST s) b-parseTextST = parseST Y.parseText+parseBytesST s = do+	(p, eventRef) <- lift newParserST+	+	let withEvents st = do+		ST.writeSTRef eventRef []+		status <- st+		events <- ST.readSTRef eventRef+		return (reverse events, status)+	+	let parseChunk bytes = withEvents (Y.parseBytes p bytes)+	let complete = withEvents (Y.parseComplete p)+	eneeParser (Y.getBytesConsumed p) parseChunk complete s  newParserIO :: IO (Y.Parser IO, IO.IORef [Event]) newParserIO = do@@ -97,64 +111,45 @@ 	set Y.parsedAttributeText (addEvent . EventAttributeName) 	set Y.parsedText (addEvent . EventText) -parseIO :: MonadIO m-        => (Y.Parser IO -> a -> IO Y.ParseStatus)-        -> E.Enumeratee a Event m b-parseIO parseFn s = do-	(p, eventRef) <- liftIO newParserIO-	-	let withEvents io = liftIO $ do-		IO.writeIORef eventRef []-		status <- io-		events <- IO.readIORef eventRef-		return (reverse events, status)-	-	let parseChunk bytes = withEvents (parseFn p bytes)-	let complete = withEvents (Y.parseComplete p)-	eneeParser parseChunk complete s--parseST :: (Y.Parser (ST s) -> a -> ST s Y.ParseStatus)-        -> E.Enumeratee a Event (ST s) b-parseST parseFn s = do-	(p, eventRef) <- lift newParserST-	-	let withEvents st = do-		ST.writeSTRef eventRef []-		status <- st-		events <- ST.readSTRef eventRef-		return (reverse events, status)-	-	let parseChunk bytes = withEvents (parseFn p bytes)-	let complete = withEvents (Y.parseComplete p)-	eneeParser parseChunk complete s- eneeParser :: Monad m-           => (a -> m ([Event], Y.ParseStatus))+           => m Integer+           -> (B.ByteString -> m ([Event], Y.ParseStatus))            -> m ([Event], Y.ParseStatus)-           -> E.Enumeratee a Event m b-eneeParser parseChunk parseComplete = E.checkDone (E.continue . step) where+           -> E.Enumeratee B.ByteString Event m b+eneeParser getBytesConsumed parseChunk parseComplete = E.checkDone (E.continue . step) where 	step k (E.Chunks xs) = parseLoop k xs-	step k E.EOF = checkEvents k E.EOF parseComplete-		(\k' -> E.yield (E.Continue k') E.EOF)-		(\_ -> throwError (T.pack "Unexpected EOF"))+	step k E.EOF = do+		(events, status) <- lift parseComplete+		checkStatus status events E.EOF k+			(\_ -> throwError "yajl-enumerator: Unexpected EOF while parsing") 	 	parseLoop k [] = E.continue (step k)-	parseLoop k (x:xs) = checkEvents k (E.Chunks xs) (parseChunk x)-		(\k' -> E.yield (E.Continue k') (E.Chunks xs))-		(\k' -> parseLoop k' xs)+	parseLoop k (x:xs) = do+		(events, status) <- lift (parseChunk x)+		extra <- getExtra x xs status+		checkStatus status events extra k+			(\k' -> parseLoop k' xs) 	-	checkEvents k extra getEvents onFinished onContinue = do-		(events, status) <- lift getEvents-		let checkError k' = case status of-			Y.ParseError err -> throwError err-			Y.ParseFinished -> onFinished k'+	getExtra x xs Y.ParseFinished = do+		consumed <- lift getBytesConsumed+		let extraX = B.drop (fromInteger consumed) x+		return . E.Chunks $ if null extraX+			then xs+			else extraX:xs+	getExtra _ _ _ = return (E.Chunks [])+	+	checkStatus status events extra k onContinue = iter where+		checkError k' = case status of+			Y.ParseError err -> throwError (T.unpack err)+			Y.ParseFinished -> E.yield (E.Continue k') extra 			Y.ParseContinue -> onContinue k'-			Y.ParseCancelled -> throwError (T.pack "Parse cancelled")-		if null events+			Y.ParseCancelled -> throwError "Parse cancelled"+		+		iter = if null events 			then checkError k 			else k (E.Chunks events) >>== E.checkDoneEx extra checkError 	-	throwError = E.throwError . Exc.ErrorCall . T.unpack+	throwError = E.throwError . Exc.ErrorCall  -- }}} @@ -227,11 +222,15 @@ eneeGenerator genEvent takeBuf = E.checkDone (E.continue . step) where 	step k (E.Chunks []) = E.continue (step k) 	step k (E.Chunks xs) = parseLoop k xs-	step k E.EOF = E.yield (E.Continue k) E.EOF+	step k E.EOF = do+		maybeError <- lift (genEvent EventNull)+		case maybeError of+			Just Y.GenerationComplete -> E.yield (E.Continue k) E.EOF+			_ -> E.throwError (Exc.ErrorCall "yajl-enumerator: Unexpected EOF while generating") 	 	parseLoop k [] = checkBuf k [] (E.continue . step) 	parseLoop k (x:xs) = do-		maybeError <- lift $ genEvent x+		maybeError <- lift (genEvent x) 		case maybeError of 			Just Y.GenerationComplete -> checkBuf k xs 				(\k' -> E.yield (E.Continue k') (E.Chunks (x:xs)))
yajl-enumerator.cabal view
@@ -1,5 +1,5 @@ name: yajl-enumerator-version: 0.2.0.4+version: 0.3 synopsis: Enumerator-based interface to YAJL, an event-based JSON implementation license: GPL-3 license-file: license.txt