module Network.NineP.File
( simpleFile
, simpleFileBy
, rwFile
) where
import Control.Concurrent.Chan
import Control.Exception
import Control.Monad.EmbedIO
import Data.ByteString.Lazy.Char8 (ByteString)
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Convertible.Base
import Data.StateRef
import Data.Word
import Prelude hiding (read)
import Network.NineP.Error
import Network.NineP.Internal.File
simpleRead :: (Monad m, EmbedIO m) => m ByteString -> Word64 -> Word32 -> ErrorT NineError m ByteString
simpleRead get offset count = case offset of
_ -> do
r <- lift $ tryE $ get
either (throwError . OtherError . (show :: SomeException -> String))
(return . B.take (fromIntegral count)) r
simpleWrite :: (Monad m, EmbedIO m) => (ByteString -> m ()) -> Word64 -> ByteString -> ErrorT NineError m Word32
simpleWrite put offset d = case offset of
_ -> do
r <- lift $ tryE $ put d
either (throwError . OtherError . (show :: SomeException -> String))
(const $ return $ fromIntegral $ B.length d) r
rwFile :: forall m. (EmbedIO m)
=> String
-> Maybe (m ByteString)
-> Maybe (ByteString -> m ())
-> NineFile m
rwFile name rc wc = simpleFileBy name (maybe (fst nulls) id rc, maybe (snd nulls) id wc) (id, id)
nulls :: MonadIO m => (m a, a -> m ())
nulls = (throw $ Underflow, const $ return ())
simpleFile :: forall a b m rr wr. (Monad m, EmbedIO m, ReadRef rr m a, Convertible a ByteString, WriteRef wr m b, Convertible ByteString b)
=> String
-> rr
-> wr
-> NineFile m
simpleFile name rr wr = simpleFileBy name (readReference rr, writeReference wr) (convert, convert)
simpleFileBy :: forall a b m. (Monad m, EmbedIO m)
=> String
-> (m a, b -> m ())
-> (a -> ByteString, ByteString -> b)
-> NineFile m
simpleFileBy name (rd, wr) (rdc, wrc) = (boringFile name :: NineFile m) {
read = simpleRead $ liftM rdc $ rd,
write = simpleWrite $ wr . wrc
}