-- | Read and write files. module Data.Repa.Flow.Auto.SizedIO ( -- * Buckets module Data.Repa.Flow.IO.Bucket -- * Sourcing , sourceBytes , sourceChars , sourceLines , sourceRecords , sourceTSV , sourceCSV ) where import Data.Repa.Flow.Auto import Data.Repa.Flow.IO.Bucket import Data.Repa.Array.Generic as A import Data.Repa.Array.Material as A import Data.Repa.Array.Meta.Delayed as A import qualified Data.Repa.Flow.Generic as G import qualified Data.Repa.Flow.Generic.IO as G import Data.Word import Data.Char #include "repa-flow.h" -- Sourcing --------------------------------------------------------------------------------------- -- | Like `F.sourceBytes`, but with the default chunk size. sourceBytes :: Integer -> Array B Bucket -> IO (Sources Word8) sourceBytes i bs = G.map_i (A.convert A) =<< G.sourceBytes i bs {-# INLINE sourceBytes #-} -- | Like `F.sourceChars`, but with the default chunk size. sourceChars :: Integer -> Array B Bucket -> IO (Sources Char) sourceChars i bs = G.map_i (A.convert A) =<< G.sourceChars i bs {-# INLINE sourceChars #-} -- | Like `F.sourceLines`, but with the default chunk size and error action. sourceLines :: Integer -- ^ Size of chunk to read in bytes. -> IO () -- ^ Action to perform if we can't get a -- whole record. -> Array B Bucket -- ^ Buckets. -> IO (Sources (Array A Char)) sourceLines nChunk fails bs = G.map_i ((A.convert A). chopChunk) =<< G.sourceRecords nChunk isNewLine fails bs where isNewLine :: Word8 -> Bool isNewLine x = x == nl {-# INLINE isNewLine #-} chopChunk chunk = A.mapElems (A.computeS A . A.map (chr . fromIntegral)) $ A.trimEnds (== nl) chunk {-# INLINE chopChunk #-} nl :: Word8 !nl = fromIntegral $ ord '\n' {-# NOINLINE sourceLines #-} -- | Like `F.sourceRecords`, but with the default chunk size and error action. sourceRecords :: Integer -- ^ Size of chunk to read in bytes. -> (Word8 -> Bool) -- ^ Detect the end of a record. -> IO () -- ^ Action to perform if we can't get a -- whole record. -> Array B Bucket -- ^ File handles. -> IO (Sources (Array A Word8)) sourceRecords i pSep aFail bs = G.map_i (A.convert A) =<< G.sourceRecords i pSep aFail bs {-# INLINE sourceRecords #-} -- | Read a file containing Comma-Separated-Values. sourceCSV :: Integer -- ^ Chunk length. -> IO () -- ^ Action to perform if we find line longer -- than the chunk length. -> Array B Bucket -- ^ Buckets -> IO (Sources (Array A (Array A Char))) sourceCSV i aFail bs = G.map_i (A.convert A) =<< G.sourceCSV i aFail bs {-# INLINE sourceCSV #-} -- | Read a file containing Tab-Separated-Values. sourceTSV :: Integer -- ^ Chunk length. -> IO () -- ^ Action to perform if we find line longer -- than the chunk length. -> Array B Bucket -- ^ Buckets -> IO (Sources (Array A (Array A Char))) sourceTSV i aFail bs = G.map_i (A.convert A) =<< G.sourceTSV i aFail bs {-# INLINE sourceTSV #-}