packages feed

iteratee 0.3.5 → 0.3.6

raw patch · 8 files changed

+148/−10 lines, 8 filesdep −haskell98dep ~test-frameworkPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: haskell98

Dependency ranges changed: test-framework

API changes (from Hackage documentation)

- Data.Iteratee.Base: instance (Eq (c el)) => Eq (StreamG c el)
- Data.Iteratee.Base: instance (Functor c) => Functor (StreamG c)
- Data.Iteratee.Base: instance (Monad m) => Monad (IterateeG s el m)
- Data.Iteratee.Base: instance (MonadIO m) => MonadIO (IterateeG s el m)
- Data.Iteratee.Base: instance (Monoid (c el)) => Monoid (StreamG c el)
- Data.Iteratee.Base: instance (Show (c el)) => Show (StreamG c el)
+ Data.Iteratee.Base: convStateStream :: MonadIO m => (t -> s el -> IterateeG s el m (Maybe (t, s el, s' el'))) -> t -> s el -> EnumeratorN s el s' el' m b
+ Data.Iteratee.Base: instance Eq (c el) => Eq (StreamG c el)
+ Data.Iteratee.Base: instance Functor c => Functor (StreamG c)
+ Data.Iteratee.Base: instance Monad m => Monad (IterateeG s el m)
+ Data.Iteratee.Base: instance MonadIO m => MonadIO (IterateeG s el m)
+ Data.Iteratee.Base: instance Monoid (c el) => Monoid (StreamG c el)
+ Data.Iteratee.Base: instance Show (c el) => Show (StreamG c el)
+ Data.Iteratee.Base: last :: (StreamChunk s el, Monad m) => IterateeG s el m el
+ Data.Iteratee.Base: mapM_ :: (ListLike (s el) el, MonadIO m) => (el -> m ()) -> IterateeG s el m ()
+ Data.Iteratee.IO.Fd: enumFdFollow :: ReadableChunk s el => Fd -> EnumeratorGM s el IO a
+ Data.Iteratee.IO.Fd: fileDriverFollowFd :: ReadableChunk s el => IterateeG s el IO a -> (a -> IterateeG s el IO b) -> FilePath -> IO b
+ Data.Iteratee.IO.Interact: ioIter :: (StreamChunk s el, MonadIO m) => (a -> IO (Either b (IterateeG s el m a))) -> a -> IterateeG s el m b
- Data.Iteratee.Base: convStream :: (Monad m) => IterateeG s el m (Maybe (s' el')) -> EnumeratorN s el s' el' m a
+ Data.Iteratee.Base: convStream :: Monad m => IterateeG s el m (Maybe (s' el')) -> EnumeratorN s el s' el' m a
- Data.Iteratee.Base: enumEof :: (Monad m) => EnumeratorGM s el m a
+ Data.Iteratee.Base: enumEof :: Monad m => EnumeratorGM s el m a
- Data.Iteratee.Base: identity :: (Monad m) => IterateeG s el m ()
+ Data.Iteratee.Base: identity :: Monad m => IterateeG s el m ()
- Data.Iteratee.Base: joinIM :: (Monad m) => m (IterateeG s el m a) -> IterateeG s el m a
+ Data.Iteratee.Base: joinIM :: Monad m => m (IterateeG s el m a) -> IterateeG s el m a
- Data.Iteratee.Base: seek :: (Monad m) => FileOffset -> IterateeG s el m ()
+ Data.Iteratee.Base: seek :: Monad m => FileOffset -> IterateeG s el m ()
- Data.Iteratee.Base: skipToEof :: (Monad m) => IterateeG s el m ()
+ Data.Iteratee.Base: skipToEof :: Monad m => IterateeG s el m ()
- Data.Iteratee.Base: throwErr :: (Monad m) => ErrMsg -> IterateeG s el m a
+ Data.Iteratee.Base: throwErr :: Monad m => ErrMsg -> IterateeG s el m a
- Data.Iteratee.Base.LooseMap: looseMap :: (LooseMap c el el') => (el -> el') -> c el -> c el'
+ Data.Iteratee.Base.LooseMap: looseMap :: LooseMap c el el' => (el -> el') -> c el -> c el'
- Data.Iteratee.Base.StreamChunk: class (ListLike (c el) el) => StreamChunk c el
+ Data.Iteratee.Base.StreamChunk: class ListLike (c el) el => StreamChunk c el
- Data.Iteratee.Base.StreamChunk: cons :: (StreamChunk c el) => el -> c el -> c el
+ Data.Iteratee.Base.StreamChunk: cons :: StreamChunk c el => el -> c el -> c el
- Data.Iteratee.Base.StreamChunk: dropWhile :: (StreamChunk c el) => (el -> Bool) -> c el -> c el
+ Data.Iteratee.Base.StreamChunk: dropWhile :: StreamChunk c el => (el -> Bool) -> c el -> c el
- Data.Iteratee.Base.StreamChunk: findIndex :: (StreamChunk c el) => (el -> Bool) -> c el -> Maybe Int
+ Data.Iteratee.Base.StreamChunk: findIndex :: StreamChunk c el => (el -> Bool) -> c el -> Maybe Int
- Data.Iteratee.Base.StreamChunk: fromList :: (StreamChunk c el) => [el] -> c el
+ Data.Iteratee.Base.StreamChunk: fromList :: StreamChunk c el => [el] -> c el
- Data.Iteratee.Base.StreamChunk: head :: (StreamChunk c el) => c el -> el
+ Data.Iteratee.Base.StreamChunk: head :: StreamChunk c el => c el -> el
- Data.Iteratee.Base.StreamChunk: length :: (StreamChunk c el) => c el -> Int
+ Data.Iteratee.Base.StreamChunk: length :: StreamChunk c el => c el -> Int
- Data.Iteratee.Base.StreamChunk: null :: (StreamChunk c el) => c el -> Bool
+ Data.Iteratee.Base.StreamChunk: null :: StreamChunk c el => c el -> Bool
- Data.Iteratee.Base.StreamChunk: readFromPtr :: (ReadableChunk s el) => Ptr (el) -> Int -> IO (s el)
+ Data.Iteratee.Base.StreamChunk: readFromPtr :: ReadableChunk s el => Ptr (el) -> Int -> IO (s el)
- Data.Iteratee.Base.StreamChunk: splitAt :: (StreamChunk c el) => Int -> c el -> (c el, c el)
+ Data.Iteratee.Base.StreamChunk: splitAt :: StreamChunk c el => Int -> c el -> (c el, c el)
- Data.Iteratee.Base.StreamChunk: tail :: (StreamChunk c el) => c el -> c el
+ Data.Iteratee.Base.StreamChunk: tail :: StreamChunk c el => c el -> c el
- Data.Iteratee.Base.StreamChunk: toList :: (StreamChunk c el) => c el -> [el]
+ Data.Iteratee.Base.StreamChunk: toList :: StreamChunk c el => c el -> [el]
- Data.Iteratee.Char: line :: (Monad m) => IterateeG [] Char m (Either Line Line)
+ Data.Iteratee.Char: line :: Monad m => IterateeG [] Char m (Either Line Line)
- Data.Iteratee.Char: readLines :: (Monad m) => IterateeG [] Char m (Either [Line] [Line])
+ Data.Iteratee.Char: readLines :: Monad m => IterateeG [] Char m (Either [Line] [Line])

Files

CONTRIBUTORS view
@@ -1,9 +1,11 @@ Thanks to the following individuals for contributing to this project. +Brian Buecking Oleg Kiselyov Brian Lewis John Lato Echo Nolan+Conrad Parker Paulo Tanimoto Magnus Therning Johan Tibell
iteratee.cabal view
@@ -1,5 +1,5 @@ name:          iteratee-version:       0.3.5+version:       0.3.6 synopsis:      Iteratee-based I/O description:   The IterateeGM monad provides strict, safe, and functional I/O. In addition@@ -10,7 +10,7 @@ license:       BSD3 license-file:  LICENSE homepage:      http://inmachina.net/~jwlato/haskell/iteratee-tested-with:   GHC == 6.10.4+tested-with:   GHC == 6.12.1 stability:     experimental  cabal-version: >= 1.6@@ -62,7 +62,6 @@     bytestring            >= 0.9   && < 0.10,     containers            >= 0.2   && < 0.4,     extensible-exceptions >= 0.1   && < 0.2,-    haskell98             >= 1     && < 2,     transformers          >= 0.2.0.0 && < 0.3    exposed-modules:@@ -74,6 +73,7 @@     Data.Iteratee.Char     Data.Iteratee.IO     Data.Iteratee.IO.Handle+    Data.Iteratee.IO.Interact     Data.Iteratee.WrappedByteString    if flag(includeCodecs)@@ -101,7 +101,7 @@   if flag(buildTests)     build-depends:       QuickCheck                 >= 2   && < 3,-      test-framework             >= 0.2 && < 0.3,+      test-framework             >= 0.3 && < 0.4,       test-framework-quickcheck2 >= 0.2 && < 0.3   else     executable: False
src/Data/Iteratee/Base.hs view
@@ -35,6 +35,7 @@   head,   heads,   peek,+  last,   skipToEof,   length,   -- ** Nested iteratee combinators@@ -44,6 +45,7 @@   rigidMapStream,   looseMapStream,   convStream,+  convStateStream,   filter,   -- ** Folds   foldl,@@ -52,6 +54,8 @@   -- ** Special Folds   sum,   product,+  -- ** Monadic variants of iteratees+  mapM_,   -- * Enumerators   -- ** Basic enumerators   enumEof,@@ -69,7 +73,7 @@ ) where -import Prelude hiding (head, drop, dropWhile, take, break, foldl, foldl1, length, filter, sum, product)+import Prelude hiding (head, last, drop, dropWhile, take, break, foldl, foldl1, length, filter, sum, product, mapM_) import qualified Prelude as P  import qualified Data.Iteratee.Base.StreamChunk as SC@@ -77,7 +81,7 @@ import qualified Data.ListLike.FoldableLL as FLL import Data.Iteratee.Base.LooseMap import Data.Iteratee.IO.Base-import Control.Monad+import Control.Monad hiding (mapM_) import Control.Applicative import Control.Monad.Trans.Class import Control.Monad.IO.Class@@ -86,7 +90,7 @@   -- |A stream is a (continuing) sequence of elements bundled in Chunks.--- The first two variants indicate termination of the stream.+-- The first variant indicates termination of the stream. -- Chunk a gives the currently available part of the stream. -- The stream is not terminated yet. -- The case (null Chunk) signifies a stream with no currently available@@ -397,6 +401,13 @@     | otherwise = return $ Done (Just $ SC.head vec) s   step stream   = return $ Done Nothing stream +-- | Attempt to skip to the last element of the stream and return it+last :: (SC.StreamChunk s el, Monad m) => IterateeG s el m el+last = do x <- head+          next <- peek+          case next of+              Just _  -> last+              Nothing -> return x  -- |Skip the rest of the stream skipToEof :: (Monad m) => IterateeG s el m ()@@ -573,6 +584,38 @@  {-# INLINE convStream #-} +-- |Convert one stream into another while continually updating an internal+-- state. The state of type 't' is updated by the supplied function, which+-- maybe returns a tuple consisting of the updated state, the remaining+-- unprocessed portion of the input stream, and the output stream.+-- In order to produce elements of the output stream from data that spans+-- stream chunks, the remaining portion of the input stream is passed to the+-- following iteration of the supplied function, which should prepend it to+-- its input stream chunk.+-- The supplied function should return Nothing on EOF.+convStateStream :: MonadIO m =>+  (t -> s el -> IterateeG s el m (Maybe (t, s el, s' el'))) ->+  t -> s el ->+  EnumeratorN s el s' el' m b+convStateStream outer state pre inner = outer state pre >>= convStateCheck outer inner++{-# INLINE convStateStream #-}++convStateCheck :: (MonadIO m) =>+     (t -> s el -> IterateeG s el m (Maybe (t, s el, s' el')))+     -> IterateeG s' el' m b+     -> Maybe (t, s el, s' el')+     -> IterateeG s el m (IterateeG s' el' m b)+convStateCheck outer inner (Just (state', remainder, result)) =+  lift (runIter inner (Chunk result)) >>= docase+  where+    docase (Done a _) = return . return $ a+    docase (Cont k Nothing)  = convStateStream outer state' remainder k+    docase (Cont _ (Just e)) = return $ throwErr e+convStateCheck _ iter (Nothing) = return iter++{-# INLINE convStateCheck #-}+ -- |Creates an enumerator with only elements from the stream that -- satisfy the predicate function. filter :: (LL.ListLike (s el) el, Monad m) =>@@ -751,3 +794,18 @@ -- |A variant of join for Iteratees in a monad. joinIM :: (Monad m) => m (IterateeG s el m a) -> IterateeG s el m a joinIM m = IterateeG (\str -> m >>= flip runIter str)++-- ------------------------------------------------------------------------+-- Monadic variants of iteratees++-- | Map a monadic function over all elements of a stream, and ignore the result+mapM_ :: (LL.ListLike (s el) el, MonadIO m)+         => (el -> m ()) -> IterateeG s el m ()+mapM_ f = IterateeG step+  where+  step (Chunk xs) | LL.null xs = return $ Cont (IterateeG step) Nothing+  step (Chunk xs)              = do LL.mapM_ f xs+                                    return $ Cont (IterateeG step) Nothing+  step stream                  = return $ Done () stream++{-# INLINE mapM_ #-}
src/Data/Iteratee/Char.hs view
@@ -31,7 +31,7 @@ where  import qualified Data.Iteratee.Base as Iter-import Data.Iteratee.Base hiding (break)+import Data.Iteratee.Base hiding (break, last) import Data.Char import Control.Monad.IO.Class import qualified Data.ListLike as LL
src/Data/Iteratee/IO/Fd.hs view
@@ -9,9 +9,11 @@   -- * File enumerators   -- ** FileDescriptor based enumerators   enumFd+  ,enumFdFollow   ,enumFdRandom   -- * Iteratee drivers   ,fileDriverFd+  ,fileDriverFollowFd   ,fileDriverRandomFd #endif )@@ -65,6 +67,34 @@     check p  (Cont i Nothing) = loop i p     check _p (Cont _ (Just e)) = return $ throwErr e +-- |The enumerator of a POSIX File Descriptor: a variation of enumFd+-- that follows the tail of growing input.+enumFdFollow :: forall s el a.(ReadableChunk s el) =>+  Fd ->+  EnumeratorGM s el IO a+enumFdFollow fd iter' =+  liftIO (mallocForeignPtrBytes (fromIntegral buffer_size)) >>= loop iter'+  where+    buffer_size = fromIntegral $ 4096 - mod 4096 (sizeOf (undefined :: el))+    loop iter fp = do+      s <- readFollow iter fp+      checkres fp iter s+    readFollow iter fp = do+        liftIO . withForeignPtr fp $ \p -> do+          liftIO $ GHC.Conc.threadWaitRead fd+          n <- myfdRead fd (castPtr p) buffer_size+          case n of+            Left _errno -> return $ Left "IO error"+            Right 0 -> do liftIO $ threadDelay (250 * 1000)+                          readFollow iter fp+            Right n' -> liftM (Right . Just) $ readFromPtr p (fromIntegral n')+    checkres fp iter = either (flip enumErr iter)+                              (maybe (return iter)+                                     (check fp <=< runIter iter . Chunk))+    check _p (Done x _) = return . return $ x+    check p  (Cont i Nothing) = loop i p+    check _p (Cont _ (Just e)) = return $ throwErr e+ -- |The enumerator of a POSIX File Descriptor: a variation of enumFd that -- supports RandomIO (seek requests) enumFdRandom :: forall s el m a.(ReadableChunk s el, MonadIO m) =>@@ -127,6 +157,23 @@ fileDriverFd iter filepath = do   fd <- liftIO $ openFd filepath ReadOnly Nothing defaultFileFlags   result <- enumFd fd iter >>= run+  liftIO $ closeFd fd+  return result++-- |Process a file using the given IterateeGM.  This function wraps+-- enumFdFollow as a convenience.+-- The first iteratee is used to scan through to the end of the file, using+-- enumFd. The second iteratee is used from then onwards on the growing tail+-- of the file, using enumFdFollow.+fileDriverFollowFd :: (ReadableChunk s el) =>+  IterateeG s el IO a ->+  (a -> IterateeG s el IO b) ->+  FilePath ->+  IO b+fileDriverFollowFd scanIter followIter filepath = do+  fd <- liftIO $ openFd filepath ReadOnly Nothing defaultFileFlags+  state <- enumFd fd scanIter >>= run+  result <- enumFdFollow fd (followIter state) >>= run   liftIO $ closeFd fd   return result 
+ src/Data/Iteratee/IO/Interact.hs view
@@ -0,0 +1,31 @@+module Data.Iteratee.IO.Interact (+  ioIter+) where++import Control.Monad.IO.Class (MonadIO, liftIO)++import Data.Iteratee+import qualified Data.Iteratee.Base.StreamChunk as SC++-- | Use an IO function to choose what iteratee to run.+-- Typically this function handles user interaction and+-- returns with a simple iteratee such as 'head' or 'seek'.+-- +-- The IO function takes a value of type 'a' as input, and+-- should return 'Right a' to continue, or 'Left b'+-- to terminate. Upon termination, ioIter will return 'Done b'.+--+-- The second argument to 'ioIter' is used as the initial input+-- to the IO function, and on each successive iteration the+-- previously returned value is used as input. Put another way,+-- the value of type 'a' is used like a fold accumulator.+-- The value of type 'b' is typically some form of control code+-- that the application uses to signal the reason for termination.+ioIter :: (SC.StreamChunk s el, MonadIO m)+       => (a -> IO (Either b (IterateeG s el m a))) -> a -> IterateeG s el m b+ioIter f a = do i'e <- liftIO $ f a+                case i'e of+                     Left e  -> return e+                     Right i -> do a' <- i+                                   ioIter f a'+
tests/QCUtils.hs view
@@ -9,7 +9,7 @@ import Data.Iteratee import qualified Data.Iteratee as I import Data.Iteratee.Base.StreamChunk (StreamChunk)-import Control.Monad.Identity+import Data.Functor.Identity  -- Show instance instance (Show a, StreamChunk s el) => Show (IterateeG s el Identity a) where
tests/testIteratee.hs view
@@ -14,7 +14,7 @@ import qualified Data.Iteratee.Char as IC import qualified Data.Iteratee as Iter import qualified Data.Iteratee.Base.StreamChunk as SC-import Control.Monad.Identity+import Data.Functor.Identity import Data.Monoid import qualified Data.ListLike as LL