@@ -35,19 +35,13 @@ import Foreign.ForeignPtr
35import Foreign.Marshal.Alloc
35import Foreign.Marshal.Alloc
36import Data.Data
36import Data.Data
38−#if MIN_VERSION_transformers(0,2,0)
38+import Control.Monad.IO.Class
39−import "transformers" Control.Monad.IO.Class
39+import Control.Monad.Trans.Class (lift)
41−import "transformers" Control.Monad.Trans
44import Control.Exception (throwIO, Exception)
41import Control.Exception (throwIO, Exception)
45−import Data.Iteratee
42+import Data.Enumerator
46−import qualified Data.Iteratee.Base.StreamChunk as SC
47import Control.Applicative
43import Control.Applicative
48−import Control.Monad.CatchIO (MonadCatchIO, finally)
44+import "MonadCatchIO-transformers" Control.Monad.CatchIO (MonadCatchIO, finally)
50−import qualified Data.ListLike as LL
52data Event =
46data Event =
53 EventStreamStart
47 EventStreamStart
@@ -457,16 +451,13 @@ newtype ToEventRawException = ToEventRawException CInt
457 deriving (Show, Typeable)
451 deriving (Show, Typeable)
458instance Exception ToEventRawException
452instance Exception ToEventRawException
460−decode :: SC.StreamChunk c Event
461− => MonadCatchIO m
454+decode :: MonadCatchIO m => B.ByteString -> Enumerator Event m a
463− -> EnumeratorGM c Event m a
464decode bs i = do
455decode bs i = do
465 fp <- liftIO $ mallocForeignPtrBytes parserSize
456 fp <- liftIO $ mallocForeignPtrBytes parserSize
466 res <- liftIO $ withForeignPtr fp c_yaml_parser_initialize
457 res <- liftIO $ withForeignPtr fp c_yaml_parser_initialize
467− flip finally (liftIO $ withForeignPtr fp c_yaml_parser_delete) $
458+ a <-
468 if (res == 0)
459 if (res == 0)
469− then return $ throwErr $ Err "Yaml out of memory"
460+ then throwError $ YamlException "Yaml out of memory"
470 else do -- NOTE: can't replace the following with unsafeUseAsCString
461 else do -- NOTE: can't replace the following with unsafeUseAsCString
471 -- since it must run in a MonadIO
462 -- since it must run in a MonadIO
472 let (fptr, offset, len) = B.toForeignPtr bs
463 let (fptr, offset, len) = B.toForeignPtr bs
@@ -476,47 +467,47 @@ decode bs i = do
476 liftIO $ withForeignPtr fp $ \p ->
467 liftIO $ withForeignPtr fp $ \p ->
477 c_yaml_parser_set_input_string p ptr' len'
468 c_yaml_parser_set_input_string p ptr' len'
478 runParser fp i
469 runParser fp i
470+ liftIO $ withForeignPtr fp c_yaml_parser_delete -- FIXME finally
480−decodeFile :: SC.StreamChunk c Event
473+-- FIXME decodeFile :: MonadCatchIO m => FilePath -> Enumerator Event m a
481− => MonadCatchIO m
474+decodeFile :: FilePath -> Enumerator Event IO a
483− -> EnumeratorGM c Event m a
484decodeFile file i = do
475decodeFile file i = do
485 fp <- liftIO $ mallocForeignPtrBytes parserSize
476 fp <- liftIO $ mallocForeignPtrBytes parserSize
486 res <- liftIO $ withForeignPtr fp c_yaml_parser_initialize
477 res <- liftIO $ withForeignPtr fp c_yaml_parser_initialize
487− flip finally (liftIO $ withForeignPtr fp c_yaml_parser_delete) $
478+ a <-
488− if (res == 0)
479+ if res == 0
489− then return $ throwErr $ Err "Yaml out of memory"
480+ then throwError $ YamlException "Yaml out of memory"
491 file' <- liftIO
482 file' <- liftIO
492 $ withCString file $ \file' -> withCString "r" $ \r' ->
483 $ withCString file $ \file' -> withCString "r" $ \r' ->
493 c_fopen file' r'
484 c_fopen file' r'
494 if (file' == nullPtr)
485 if (file' == nullPtr)
495− then return $ throwErr $ Err
486+ then throwError $ YamlException
496 $ "Yaml file not found: " ++ file
487 $ "Yaml file not found: " ++ file
498 liftIO $ withForeignPtr fp $ \p ->
489 liftIO $ withForeignPtr fp $ \p ->
499 c_yaml_parser_set_input_file p file'
490 c_yaml_parser_set_input_file p file'
500− finally (runParser fp i) $ liftIO $ do
491+ a <- runParser fp i
501− c_fclose file'
493+ liftIO $ c_fclose file'
502− withForeignPtr fp c_yaml_parser_delete
494+ liftIO $ withForeignPtr fp c_yaml_parser_delete
504−runParser :: SC.StreamChunk c Event
496+ liftIO $ withForeignPtr fp c_yaml_parser_delete -- FIXME finally
505− => MonadCatchIO m
499+runParser :: MonadCatchIO m
506 => ForeignPtr ParserStruct
500 => ForeignPtr ParserStruct
507− -> IterateeG c Event m a
508− -> m (IterateeG c Event m a)
501+ -> Enumerator Event m a
509−runParser fp iter = do
502+runParser fp (Continue k) = do
510 e <- liftIO $ withForeignPtr fp parserParseOne'
503 e <- liftIO $ withForeignPtr fp parserParseOne'
511 case e of
504 case e of
512− Left err -> return $ throwErr $ Err $ show err
505+ Left err -> throwError $ YamlException err
513− Right Nothing -> return iter
506+ Right Nothing -> continue k
514 Right (Just ev) -> do
507 Right (Just ev) -> do
515− igv <- runIter iter $ Chunk $ SC.fromList [ev]
508+ step' <- lift $ runIteratee $ k $ Chunks [ev]
517− Done a _ -> return $ return a
518− Cont iter' Nothing -> runParser fp iter'
509+ runParser fp step'
519− Cont _ (Just err) -> return $ throwErr err
510+runParser _ step = returnI step
521parserParseOne' :: Parser
512parserParseOne' :: Parser
522 -> IO (Either String (Maybe Event))
513 -> IO (Either String (Maybe Event))
@@ -539,19 +530,18 @@ parserParseOne' parser = allocaBytes eventSize $ \er -> do
540 else liftIO $ Right <$> getEvent er
531 else liftIO $ Right <$> getEvent er
542−encode :: SC.StreamChunk c Event
544− => IterateeG c Event m B.ByteString
533+encode :: MonadIO m => Iteratee Event m B.ByteString
545−encode = joinIM $ liftIO $ do
534+encode = do
546− fp <- mallocForeignPtrBytes emitterSize
535+ fp <- liftIO $ mallocForeignPtrBytes emitterSize
547− res <- withForeignPtr fp c_yaml_emitter_initialize
536+ res <- liftIO $ withForeignPtr fp c_yaml_emitter_initialize
537+ when (res == 0) $ throwError
548− when (res == 0) $ fail "c_yaml_emitter_initialize failed"
538+ $ YamlException "c_yaml_emitter_initialize failed"
549− buf <- mallocForeignPtrBytes bufferSize
539+ buf <- liftIO $ mallocForeignPtrBytes bufferSize
550− withForeignPtr buf c_buffer_init
540+ liftIO $ withForeignPtr buf c_buffer_init
551− withForeignPtr fp $
541+ liftIO $ withForeignPtr fp $
552 \emitter -> withForeignPtr buf $
542 \emitter -> withForeignPtr buf $
553 \b -> c_my_emitter_set_output emitter b
543 \b -> c_my_emitter_set_output emitter b
554− return $ runEmitter (go buf) fp
544+ runEmitter (go buf) fp
556 go buf = withForeignPtr buf $ \b -> do
546 go buf = withForeignPtr buf $ \b -> do
557 ptr' <- c_get_buffer_buff b
547 ptr' <- c_get_buffer_buff b
@@ -559,34 +549,37 @@ encode = joinIM $ liftIO $ do
559 fptr <- newForeignPtr_ $ castPtr ptr'
549 fptr <- newForeignPtr_ $ castPtr ptr'
560 return $ B.fromForeignPtr fptr 0 $ fromIntegral len
550 return $ B.fromForeignPtr fptr 0 $ fromIntegral len
563−encodeFile :: SC.StreamChunk c Event
564− => MonadIO m
552+encodeFile :: MonadIO m
565 => FilePath
553 => FilePath
566− -> IterateeG c Event m ()
554+ -> Iteratee Event m ()
567−encodeFile filePath = joinIM $ liftIO $ do
555+encodeFile filePath = do
568− fp <- mallocForeignPtrBytes emitterSize
556+ fp <- liftIO $ mallocForeignPtrBytes emitterSize
569− res <- withForeignPtr fp c_yaml_emitter_initialize
557+ res <- liftIO $ withForeignPtr fp c_yaml_emitter_initialize
558+ when (res == 0) $ throwError
570− when (res == 0) $ fail "c_yaml_emitter_initialize failed"
559+ $ YamlException "c_yaml_emitter_initialize failed"
571− file <- withCString filePath $
560+ file <- liftIO $ withCString filePath $
572 \filePath' -> withCString "w" $
561 \filePath' -> withCString "w" $
573 \w' -> c_fopen filePath' w'
562 \w' -> c_fopen filePath' w'
563+ when (file == nullPtr) $ throwError
574− when (file == nullPtr) $ fail $ "could not open file for write: " ++ filePath
564+ $ YamlException $ "could not open file for write: " ++ filePath
575− withForeignPtr fp $ flip c_yaml_emitter_set_output_file file
565+ liftIO $ withForeignPtr fp $ flip c_yaml_emitter_set_output_file file
576− return $ runEmitter (c_fclose file) fp
566+ runEmitter (c_fclose file) fp
578−runEmitter :: SC.StreamChunk c Event
579− => MonadIO m
568+runEmitter :: MonadIO m
581 -> ForeignPtr EmitterStruct
570 -> ForeignPtr EmitterStruct
582− -> IterateeG c Event m a
571+ -> Iteratee Event m a
583−runEmitter close fp = IterateeG go
572+runEmitter close fp = continue go
585− go (EOF x) = do
574+ go EOF = do
586 liftIO $ withForeignPtr fp c_yaml_emitter_delete
575 liftIO $ withForeignPtr fp c_yaml_emitter_delete
587 a <- liftIO close
576 a <- liftIO close
588− return $ Done a $ EOF x
577+ yield a EOF
589− go (Chunk c) = do
578+ go (Chunks c) = do
590 liftIO $ withForeignPtr fp $ \emitter ->
579 liftIO $ withForeignPtr fp $ \emitter ->
591− LL.mapM_ (\e -> toEventRaw e $ c_yaml_emitter_emit emitter) c
580+ mapM_ (\e -> toEventRaw e $ c_yaml_emitter_emit emitter) c
592− return $ Cont (runEmitter close fp) Nothing
581+ continue go
583+data YamlException = YamlException String
584+ deriving (Show, Typeable)
585+instance Exception YamlException