{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Consensus.Storage.FS.API (
Handle (..)
, HasFS (..)
, SomeHasFS (..)
, hClose'
, hGetAll
, hGetAllAt
, hGetExactly
, hGetExactlyAt
, hPut
, hPutAll
, hPutAllStrict
, withFile
) where
import Control.Monad (foldM)
import qualified Data.ByteString as BS
import Data.ByteString.Builder (Builder)
import qualified Data.ByteString.Builder as BS
import qualified Data.ByteString.Lazy as BL
import Data.Int (Int64)
import Data.Set (Set)
import Data.Word
import NoThunks.Class (NoThunks, OnlyCheckWhnfNamed (..))
import Control.Monad.Class.MonadThrow
import Ouroboros.Consensus.Storage.FS.API.Types
import Ouroboros.Consensus.Util.CallStack
data HasFS m h = HasFS {
HasFS m h -> m String
dumpState :: m String
, HasFS m h -> HasCallStack => FsPath -> OpenMode -> m (Handle h)
hOpen :: HasCallStack => FsPath -> OpenMode -> m (Handle h)
, HasFS m h -> HasCallStack => Handle h -> m ()
hClose :: HasCallStack => Handle h -> m ()
, HasFS m h -> HasCallStack => Handle h -> m Bool
hIsOpen :: HasCallStack => Handle h -> m Bool
, HasFS m h -> HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hSeek :: HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
, HasFS m h -> HasCallStack => Handle h -> Word64 -> m ByteString
hGetSome :: HasCallStack => Handle h -> Word64 -> m BS.ByteString
, HasFS m h
-> HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSomeAt :: HasCallStack
=> Handle h
-> Word64
-> AbsOffset
-> m BS.ByteString
, HasFS m h -> HasCallStack => Handle h -> ByteString -> m Word64
hPutSome :: HasCallStack => Handle h -> BS.ByteString -> m Word64
, HasFS m h -> HasCallStack => Handle h -> Word64 -> m ()
hTruncate :: HasCallStack => Handle h -> Word64 -> m ()
, HasFS m h -> HasCallStack => Handle h -> m Word64
hGetSize :: HasCallStack => Handle h -> m Word64
, HasFS m h -> HasCallStack => FsPath -> m ()
createDirectory :: HasCallStack => FsPath -> m ()
, HasFS m h -> HasCallStack => Bool -> FsPath -> m ()
createDirectoryIfMissing :: HasCallStack => Bool -> FsPath -> m ()
, HasFS m h -> HasCallStack => FsPath -> m (Set String)
listDirectory :: HasCallStack => FsPath -> m (Set String)
, HasFS m h -> HasCallStack => FsPath -> m Bool
doesDirectoryExist :: HasCallStack => FsPath -> m Bool
, HasFS m h -> HasCallStack => FsPath -> m Bool
doesFileExist :: HasCallStack => FsPath -> m Bool
, HasFS m h -> HasCallStack => FsPath -> m ()
removeFile :: HasCallStack => FsPath -> m ()
, HasFS m h -> HasCallStack => FsPath -> FsPath -> m ()
renameFile :: HasCallStack => FsPath -> FsPath -> m ()
, HasFS m h -> FsPath -> FsErrorPath
mkFsErrorPath :: FsPath -> FsErrorPath
}
deriving Context -> HasFS m h -> IO (Maybe ThunkInfo)
Proxy (HasFS m h) -> String
(Context -> HasFS m h -> IO (Maybe ThunkInfo))
-> (Context -> HasFS m h -> IO (Maybe ThunkInfo))
-> (Proxy (HasFS m h) -> String)
-> NoThunks (HasFS m h)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *) h.
Context -> HasFS m h -> IO (Maybe ThunkInfo)
forall (m :: * -> *) h. Proxy (HasFS m h) -> String
showTypeOf :: Proxy (HasFS m h) -> String
$cshowTypeOf :: forall (m :: * -> *) h. Proxy (HasFS m h) -> String
wNoThunks :: Context -> HasFS m h -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *) h.
Context -> HasFS m h -> IO (Maybe ThunkInfo)
noThunks :: Context -> HasFS m h -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *) h.
Context -> HasFS m h -> IO (Maybe ThunkInfo)
NoThunks via OnlyCheckWhnfNamed "HasFS" (HasFS m h)
withFile :: (HasCallStack, MonadThrow m)
=> HasFS m h -> FsPath -> OpenMode -> (Handle h -> m a) -> m a
withFile :: HasFS m h -> FsPath -> OpenMode -> (Handle h -> m a) -> m a
withFile HasFS{m String
HasCallStack => Bool -> FsPath -> m ()
HasCallStack => Handle h -> m Bool
HasCallStack => Handle h -> m Word64
HasCallStack => Handle h -> m ()
HasCallStack => Handle h -> Word64 -> m ()
HasCallStack => Handle h -> Word64 -> m ByteString
HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
HasCallStack => Handle h -> ByteString -> m Word64
HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
HasCallStack => FsPath -> m Bool
HasCallStack => FsPath -> m ()
HasCallStack => FsPath -> m (Set String)
HasCallStack => FsPath -> FsPath -> m ()
HasCallStack => FsPath -> OpenMode -> m (Handle h)
FsPath -> FsErrorPath
mkFsErrorPath :: FsPath -> FsErrorPath
renameFile :: HasCallStack => FsPath -> FsPath -> m ()
removeFile :: HasCallStack => FsPath -> m ()
doesFileExist :: HasCallStack => FsPath -> m Bool
doesDirectoryExist :: HasCallStack => FsPath -> m Bool
listDirectory :: HasCallStack => FsPath -> m (Set String)
createDirectoryIfMissing :: HasCallStack => Bool -> FsPath -> m ()
createDirectory :: HasCallStack => FsPath -> m ()
hGetSize :: HasCallStack => Handle h -> m Word64
hTruncate :: HasCallStack => Handle h -> Word64 -> m ()
hPutSome :: HasCallStack => Handle h -> ByteString -> m Word64
hGetSomeAt :: HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSome :: HasCallStack => Handle h -> Word64 -> m ByteString
hSeek :: HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hIsOpen :: HasCallStack => Handle h -> m Bool
hClose :: HasCallStack => Handle h -> m ()
hOpen :: HasCallStack => FsPath -> OpenMode -> m (Handle h)
dumpState :: m String
mkFsErrorPath :: forall (m :: * -> *) h. HasFS m h -> FsPath -> FsErrorPath
renameFile :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> FsPath -> m ()
removeFile :: forall (m :: * -> *) h. HasFS m h -> HasCallStack => FsPath -> m ()
doesFileExist :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m Bool
doesDirectoryExist :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m Bool
listDirectory :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m (Set String)
createDirectoryIfMissing :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Bool -> FsPath -> m ()
createDirectory :: forall (m :: * -> *) h. HasFS m h -> HasCallStack => FsPath -> m ()
hGetSize :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Word64
hTruncate :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ()
hPutSome :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> ByteString -> m Word64
hGetSomeAt :: forall (m :: * -> *) h.
HasFS m h
-> HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSome :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ByteString
hSeek :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hIsOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Bool
hClose :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m ()
hOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> OpenMode -> m (Handle h)
dumpState :: forall (m :: * -> *) h. HasFS m h -> m String
..} FsPath
fp OpenMode
openMode = m (Handle h) -> (Handle h -> m ()) -> (Handle h -> m a) -> m a
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket (HasCallStack => FsPath -> OpenMode -> m (Handle h)
FsPath -> OpenMode -> m (Handle h)
hOpen FsPath
fp OpenMode
openMode) HasCallStack => Handle h -> m ()
Handle h -> m ()
hClose
hClose' :: (HasCallStack, Monad m) => HasFS m h -> Handle h -> m Bool
hClose' :: HasFS m h -> Handle h -> m Bool
hClose' HasFS { HasCallStack => Handle h -> m ()
hClose :: HasCallStack => Handle h -> m ()
hClose :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m ()
hClose, HasCallStack => Handle h -> m Bool
hIsOpen :: HasCallStack => Handle h -> m Bool
hIsOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Bool
hIsOpen } Handle h
h = do
Bool
isOpen <- HasCallStack => Handle h -> m Bool
Handle h -> m Bool
hIsOpen Handle h
h
if Bool
isOpen then do
HasCallStack => Handle h -> m ()
Handle h -> m ()
hClose Handle h
h
Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
else
Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
hGetExactly :: forall m h. (HasCallStack, MonadThrow m)
=> HasFS m h
-> Handle h
-> Word64
-> m BL.ByteString
hGetExactly :: HasFS m h -> Handle h -> Word64 -> m ByteString
hGetExactly HasFS m h
hasFS Handle h
h Word64
n = Word64 -> [ByteString] -> m ByteString
go Word64
n []
where
go :: Word64 -> [BS.ByteString] -> m BL.ByteString
go :: Word64 -> [ByteString] -> m ByteString
go Word64
remainingBytes [ByteString]
acc
| Word64
remainingBytes Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 = ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> m ByteString) -> ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
BL.fromChunks ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse [ByteString]
acc
| Bool
otherwise = do
ByteString
bs <- HasFS m h -> Handle h -> Word64 -> m ByteString
forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ByteString
hGetSome HasFS m h
hasFS Handle h
h Word64
remainingBytes
if ByteString -> Bool
BS.null ByteString
bs then
FsError -> m ByteString
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO FsError :: FsErrorType
-> FsErrorPath
-> String
-> Maybe Errno
-> PrettyCallStack
-> Bool
-> FsError
FsError {
fsErrorType :: FsErrorType
fsErrorType = FsErrorType
FsReachedEOF
, fsErrorPath :: FsErrorPath
fsErrorPath = HasFS m h -> FsPath -> FsErrorPath
forall (m :: * -> *) h. HasFS m h -> FsPath -> FsErrorPath
mkFsErrorPath HasFS m h
hasFS (FsPath -> FsErrorPath) -> FsPath -> FsErrorPath
forall a b. (a -> b) -> a -> b
$ Handle h -> FsPath
forall h. Handle h -> FsPath
handlePath Handle h
h
, fsErrorString :: String
fsErrorString = String
"hGetExactly found eof before reading " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bytes"
, fsErrorNo :: Maybe Errno
fsErrorNo = Maybe Errno
forall a. Maybe a
Nothing
, fsErrorStack :: PrettyCallStack
fsErrorStack = PrettyCallStack
HasCallStack => PrettyCallStack
prettyCallStack
, fsLimitation :: Bool
fsLimitation = Bool
False
}
else Word64 -> [ByteString] -> m ByteString
go (Word64
remainingBytes Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
BS.length ByteString
bs)) (ByteString
bs ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc)
hGetExactlyAt :: forall m h. (HasCallStack, MonadThrow m)
=> HasFS m h
-> Handle h
-> Word64
-> AbsOffset
-> m BL.ByteString
hGetExactlyAt :: HasFS m h -> Handle h -> Word64 -> AbsOffset -> m ByteString
hGetExactlyAt HasFS m h
hasFS Handle h
h Word64
n AbsOffset
offset = Word64 -> AbsOffset -> [ByteString] -> m ByteString
go Word64
n AbsOffset
offset []
where
go :: Word64 -> AbsOffset -> [BS.ByteString] -> m BL.ByteString
go :: Word64 -> AbsOffset -> [ByteString] -> m ByteString
go Word64
remainingBytes AbsOffset
currentOffset [ByteString]
acc
| Word64
remainingBytes Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 = ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> m ByteString) -> ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
BL.fromChunks ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse [ByteString]
acc
| Bool
otherwise = do
ByteString
bs <- HasFS m h -> Handle h -> Word64 -> AbsOffset -> m ByteString
forall (m :: * -> *) h.
HasFS m h
-> HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSomeAt HasFS m h
hasFS Handle h
h Word64
remainingBytes AbsOffset
currentOffset
let readBytes :: Int
readBytes = ByteString -> Int
BS.length ByteString
bs
if ByteString -> Bool
BS.null ByteString
bs then
FsError -> m ByteString
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO FsError :: FsErrorType
-> FsErrorPath
-> String
-> Maybe Errno
-> PrettyCallStack
-> Bool
-> FsError
FsError {
fsErrorType :: FsErrorType
fsErrorType = FsErrorType
FsReachedEOF
, fsErrorPath :: FsErrorPath
fsErrorPath = HasFS m h -> FsPath -> FsErrorPath
forall (m :: * -> *) h. HasFS m h -> FsPath -> FsErrorPath
mkFsErrorPath HasFS m h
hasFS (FsPath -> FsErrorPath) -> FsPath -> FsErrorPath
forall a b. (a -> b) -> a -> b
$ Handle h -> FsPath
forall h. Handle h -> FsPath
handlePath Handle h
h
, fsErrorString :: String
fsErrorString = String
"hGetExactlyAt found eof before reading " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bytes"
, fsErrorNo :: Maybe Errno
fsErrorNo = Maybe Errno
forall a. Maybe a
Nothing
, fsErrorStack :: PrettyCallStack
fsErrorStack = PrettyCallStack
HasCallStack => PrettyCallStack
prettyCallStack
, fsLimitation :: Bool
fsLimitation = Bool
False
}
else Word64 -> AbsOffset -> [ByteString] -> m ByteString
go (Word64
remainingBytes Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
readBytes)
(AbsOffset
currentOffset AbsOffset -> AbsOffset -> AbsOffset
forall a. Num a => a -> a -> a
+ Int -> AbsOffset
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
readBytes)
(ByteString
bs ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc)
hGetAll :: Monad m => HasFS m h -> Handle h -> m BL.ByteString
hGetAll :: HasFS m h -> Handle h -> m ByteString
hGetAll HasFS{m String
HasCallStack => Bool -> FsPath -> m ()
HasCallStack => Handle h -> m Bool
HasCallStack => Handle h -> m Word64
HasCallStack => Handle h -> m ()
HasCallStack => Handle h -> Word64 -> m ()
HasCallStack => Handle h -> Word64 -> m ByteString
HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
HasCallStack => Handle h -> ByteString -> m Word64
HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
HasCallStack => FsPath -> m Bool
HasCallStack => FsPath -> m ()
HasCallStack => FsPath -> m (Set String)
HasCallStack => FsPath -> FsPath -> m ()
HasCallStack => FsPath -> OpenMode -> m (Handle h)
FsPath -> FsErrorPath
mkFsErrorPath :: FsPath -> FsErrorPath
renameFile :: HasCallStack => FsPath -> FsPath -> m ()
removeFile :: HasCallStack => FsPath -> m ()
doesFileExist :: HasCallStack => FsPath -> m Bool
doesDirectoryExist :: HasCallStack => FsPath -> m Bool
listDirectory :: HasCallStack => FsPath -> m (Set String)
createDirectoryIfMissing :: HasCallStack => Bool -> FsPath -> m ()
createDirectory :: HasCallStack => FsPath -> m ()
hGetSize :: HasCallStack => Handle h -> m Word64
hTruncate :: HasCallStack => Handle h -> Word64 -> m ()
hPutSome :: HasCallStack => Handle h -> ByteString -> m Word64
hGetSomeAt :: HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSome :: HasCallStack => Handle h -> Word64 -> m ByteString
hSeek :: HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hIsOpen :: HasCallStack => Handle h -> m Bool
hClose :: HasCallStack => Handle h -> m ()
hOpen :: HasCallStack => FsPath -> OpenMode -> m (Handle h)
dumpState :: m String
mkFsErrorPath :: forall (m :: * -> *) h. HasFS m h -> FsPath -> FsErrorPath
renameFile :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> FsPath -> m ()
removeFile :: forall (m :: * -> *) h. HasFS m h -> HasCallStack => FsPath -> m ()
doesFileExist :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m Bool
doesDirectoryExist :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m Bool
listDirectory :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m (Set String)
createDirectoryIfMissing :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Bool -> FsPath -> m ()
createDirectory :: forall (m :: * -> *) h. HasFS m h -> HasCallStack => FsPath -> m ()
hGetSize :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Word64
hTruncate :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ()
hPutSome :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> ByteString -> m Word64
hGetSomeAt :: forall (m :: * -> *) h.
HasFS m h
-> HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSome :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ByteString
hSeek :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hIsOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Bool
hClose :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m ()
hOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> OpenMode -> m (Handle h)
dumpState :: forall (m :: * -> *) h. HasFS m h -> m String
..} Handle h
hnd = [ByteString] -> m ByteString
go [ByteString]
forall a. Monoid a => a
mempty
where
bufferSize :: Word64
bufferSize = Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
1024
go :: [ByteString] -> m ByteString
go [ByteString]
acc = do
ByteString
chunk <- HasCallStack => Handle h -> Word64 -> m ByteString
Handle h -> Word64 -> m ByteString
hGetSome Handle h
hnd Word64
bufferSize
let acc' :: [ByteString]
acc' = ByteString
chunk ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc
if ByteString -> Bool
BS.null ByteString
chunk
then ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> m ByteString) -> ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
BL.fromChunks ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse [ByteString]
acc'
else [ByteString] -> m ByteString
go [ByteString]
acc'
hGetAllAt :: Monad m
=> HasFS m h
-> Handle h
-> AbsOffset
-> m BL.ByteString
hGetAllAt :: HasFS m h -> Handle h -> AbsOffset -> m ByteString
hGetAllAt HasFS{m String
HasCallStack => Bool -> FsPath -> m ()
HasCallStack => Handle h -> m Bool
HasCallStack => Handle h -> m Word64
HasCallStack => Handle h -> m ()
HasCallStack => Handle h -> Word64 -> m ()
HasCallStack => Handle h -> Word64 -> m ByteString
HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
HasCallStack => Handle h -> ByteString -> m Word64
HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
HasCallStack => FsPath -> m Bool
HasCallStack => FsPath -> m ()
HasCallStack => FsPath -> m (Set String)
HasCallStack => FsPath -> FsPath -> m ()
HasCallStack => FsPath -> OpenMode -> m (Handle h)
FsPath -> FsErrorPath
mkFsErrorPath :: FsPath -> FsErrorPath
renameFile :: HasCallStack => FsPath -> FsPath -> m ()
removeFile :: HasCallStack => FsPath -> m ()
doesFileExist :: HasCallStack => FsPath -> m Bool
doesDirectoryExist :: HasCallStack => FsPath -> m Bool
listDirectory :: HasCallStack => FsPath -> m (Set String)
createDirectoryIfMissing :: HasCallStack => Bool -> FsPath -> m ()
createDirectory :: HasCallStack => FsPath -> m ()
hGetSize :: HasCallStack => Handle h -> m Word64
hTruncate :: HasCallStack => Handle h -> Word64 -> m ()
hPutSome :: HasCallStack => Handle h -> ByteString -> m Word64
hGetSomeAt :: HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSome :: HasCallStack => Handle h -> Word64 -> m ByteString
hSeek :: HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hIsOpen :: HasCallStack => Handle h -> m Bool
hClose :: HasCallStack => Handle h -> m ()
hOpen :: HasCallStack => FsPath -> OpenMode -> m (Handle h)
dumpState :: m String
mkFsErrorPath :: forall (m :: * -> *) h. HasFS m h -> FsPath -> FsErrorPath
renameFile :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> FsPath -> m ()
removeFile :: forall (m :: * -> *) h. HasFS m h -> HasCallStack => FsPath -> m ()
doesFileExist :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m Bool
doesDirectoryExist :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m Bool
listDirectory :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> m (Set String)
createDirectoryIfMissing :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Bool -> FsPath -> m ()
createDirectory :: forall (m :: * -> *) h. HasFS m h -> HasCallStack => FsPath -> m ()
hGetSize :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Word64
hTruncate :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ()
hPutSome :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> ByteString -> m Word64
hGetSomeAt :: forall (m :: * -> *) h.
HasFS m h
-> HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSome :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> Word64 -> m ByteString
hSeek :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> SeekMode -> Int64 -> m ()
hIsOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m Bool
hClose :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> m ()
hOpen :: forall (m :: * -> *) h.
HasFS m h -> HasCallStack => FsPath -> OpenMode -> m (Handle h)
dumpState :: forall (m :: * -> *) h. HasFS m h -> m String
..} Handle h
hnd = [ByteString] -> AbsOffset -> m ByteString
go [ByteString]
forall a. Monoid a => a
mempty
where
bufferSize :: Word64
bufferSize = Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
1024
go :: [ByteString] -> AbsOffset -> m ByteString
go [ByteString]
acc AbsOffset
offset = do
ByteString
chunk <- HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString
Handle h -> Word64 -> AbsOffset -> m ByteString
hGetSomeAt Handle h
hnd Word64
bufferSize AbsOffset
offset
let acc' :: [ByteString]
acc' = ByteString
chunk ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc
if ByteString -> Bool
BS.null ByteString
chunk
then ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> m ByteString) -> ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
BL.fromChunks ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse [ByteString]
acc'
else [ByteString] -> AbsOffset -> m ByteString
go [ByteString]
acc' (AbsOffset
offset AbsOffset -> AbsOffset -> AbsOffset
forall a. Num a => a -> a -> a
+ Int -> AbsOffset
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
BS.length ByteString
chunk))
hPutAllStrict :: forall m h
. (HasCallStack, Monad m)
=> HasFS m h
-> Handle h
-> BS.ByteString
-> m Word64
hPutAllStrict :: HasFS m h -> Handle h -> ByteString -> m Word64
hPutAllStrict HasFS m h
hasFS Handle h
h = Word64 -> ByteString -> m Word64
go Word64
0
where
go :: Word64 -> BS.ByteString -> m Word64
go :: Word64 -> ByteString -> m Word64
go !Word64
written ByteString
bs = do
Word64
n <- HasFS m h -> Handle h -> ByteString -> m Word64
forall (m :: * -> *) h.
HasFS m h -> HasCallStack => Handle h -> ByteString -> m Word64
hPutSome HasFS m h
hasFS Handle h
h ByteString
bs
let bs' :: ByteString
bs' = Int -> ByteString -> ByteString
BS.drop (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n) ByteString
bs
written' :: Word64
written' = Word64
written Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
n
if ByteString -> Bool
BS.null ByteString
bs'
then Word64 -> m Word64
forall (m :: * -> *) a. Monad m => a -> m a
return Word64
written'
else Word64 -> ByteString -> m Word64
go Word64
written' ByteString
bs'
hPutAll :: forall m h
. (HasCallStack, Monad m)
=> HasFS m h
-> Handle h
-> BL.ByteString
-> m Word64
hPutAll :: HasFS m h -> Handle h -> ByteString -> m Word64
hPutAll HasFS m h
hasFS Handle h
h = (Word64 -> ByteString -> m Word64)
-> Word64 -> [ByteString] -> m Word64
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Word64 -> ByteString -> m Word64
putChunk Word64
0 ([ByteString] -> m Word64)
-> (ByteString -> [ByteString]) -> ByteString -> m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
BL.toChunks
where
putChunk :: Word64 -> BS.ByteString -> m Word64
putChunk :: Word64 -> ByteString -> m Word64
putChunk Word64
written ByteString
chunk = do
Word64
written' <- HasFS m h -> Handle h -> ByteString -> m Word64
forall (m :: * -> *) h.
(HasCallStack, Monad m) =>
HasFS m h -> Handle h -> ByteString -> m Word64
hPutAllStrict HasFS m h
hasFS Handle h
h ByteString
chunk
Word64 -> m Word64
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> m Word64) -> Word64 -> m Word64
forall a b. (a -> b) -> a -> b
$! Word64
written Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
written'
hPut :: forall m h
. (HasCallStack, Monad m)
=> HasFS m h
-> Handle h
-> Builder
-> m Word64
hPut :: HasFS m h -> Handle h -> Builder -> m Word64
hPut HasFS m h
hasFS Handle h
g = HasFS m h -> Handle h -> ByteString -> m Word64
forall (m :: * -> *) h.
(HasCallStack, Monad m) =>
HasFS m h -> Handle h -> ByteString -> m Word64
hPutAll HasFS m h
hasFS Handle h
g (ByteString -> m Word64)
-> (Builder -> ByteString) -> Builder -> m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
BS.toLazyByteString
data SomeHasFS m where
SomeHasFS :: Eq h => HasFS m h -> SomeHasFS m
deriving Context -> SomeHasFS m -> IO (Maybe ThunkInfo)
Proxy (SomeHasFS m) -> String
(Context -> SomeHasFS m -> IO (Maybe ThunkInfo))
-> (Context -> SomeHasFS m -> IO (Maybe ThunkInfo))
-> (Proxy (SomeHasFS m) -> String)
-> NoThunks (SomeHasFS m)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *).
Context -> SomeHasFS m -> IO (Maybe ThunkInfo)
forall (m :: * -> *). Proxy (SomeHasFS m) -> String
showTypeOf :: Proxy (SomeHasFS m) -> String
$cshowTypeOf :: forall (m :: * -> *). Proxy (SomeHasFS m) -> String
wNoThunks :: Context -> SomeHasFS m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *).
Context -> SomeHasFS m -> IO (Maybe ThunkInfo)
noThunks :: Context -> SomeHasFS m -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *).
Context -> SomeHasFS m -> IO (Maybe ThunkInfo)
NoThunks via OnlyCheckWhnfNamed "SomeHasFS" (SomeHasFS m)