module Data.Boombox.IO where import Data.Boombox.Tape import Data.Boombox.Head import Control.Monad.IO.Class import qualified System.IO as IO import qualified Data.ByteString as BS import Data.Int hGetContentsN :: MonadIO m => Int -> IO.Handle -> Tape (Head Int64) m (Maybe BS.ByteString) hGetContentsN n h = go 0 where go i = Tape $ do c <- liftIO $ BS.hGetSome h n let l = BS.length c if l <= 0 then return (Nothing, Head i $ maybe (go i) go) else return (Just c, Head i $ maybe (go (i + fromIntegral l)) (\j -> Tape $ liftIO (IO.hSeek h IO.AbsoluteSeek (fromIntegral j)) >> unconsTape (go j))) hGetContents :: MonadIO m => IO.Handle -> Tape (Head Int64) m (Maybe BS.ByteString) hGetContents = hGetContentsN 4080 readFile :: MonadIO m => FilePath -> Tape (Head Int64) m (Maybe BS.ByteString) readFile path = effect $ hGetContents <$> liftIO (IO.openFile path IO.ReadMode)