boombox-0.0: src/Data/Boombox/IO.hs
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)