{-# LANGUAGE ScopedTypeVariables, FlexibleContexts, OverloadedStrings #-}
module Network.NineP.File
( isDir
, simpleFile
, simpleFileBy
, simpleDirectory
, rwFile
, memoryFile
, memoryDirectory
) where
import Control.Concurrent.Chan
import Control.Exception
import Control.Monad
import Control.Monad.EmbedIO
import Control.Monad.Trans
import Data.ByteString.Lazy.Char8 (ByteString)
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Bits
import Data.Convertible.Base
import Data.IORef
import Data.StateRef
import Data.Word
import Prelude hiding (read)
import Network.NineP.Error
import Network.NineP.Internal.File
isDir :: Word32
-> Bool
isDir :: Word32 -> Bool
isDir Word32
perms = forall a. Bits a => a -> Int -> Bool
testBit Word32
perms Int
31
simpleRead :: (Monad m, EmbedIO m) => m ByteString -> Word64 -> Word32 -> m ByteString
simpleRead :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
m ByteString -> Word64 -> Word32 -> m ByteString
simpleRead m ByteString
get Word64
offset Word32
count = do
ByteString
r <- m ByteString
get
(forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
B.take (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
count) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
B.drop (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
offset)) ByteString
r
simpleWrite :: (Monad m, EmbedIO m) => (ByteString -> m ()) -> Word64 -> ByteString -> m Word32
simpleWrite :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
(ByteString -> m ()) -> Word64 -> ByteString -> m Word32
simpleWrite ByteString -> m ()
put Word64
offset ByteString
d = case Word64
offset of
Word64
_ -> do
()
r <- ByteString -> m ()
put ByteString
d
(forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ ByteString -> Int64
B.length ByteString
d) ()
r
rwFile :: forall m. (EmbedIO m)
=> String
-> Maybe (m ByteString)
-> Maybe (ByteString -> m ())
-> NineFile m
rwFile :: forall (m :: * -> *).
EmbedIO m =>
String
-> Maybe (m ByteString) -> Maybe (ByteString -> m ()) -> NineFile m
rwFile String
name Maybe (m ByteString)
rc Maybe (ByteString -> m ())
wc = forall a b (m :: * -> *).
(Monad m, EmbedIO m) =>
String
-> (m a, b -> m ())
-> (a -> ByteString, ByteString -> b)
-> NineFile m
simpleFileBy String
name (forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. (a, b) -> a
fst forall (m :: * -> *) a. MonadIO m => (m a, a -> m ())
nulls) forall a. a -> a
id Maybe (m ByteString)
rc, forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. (a, b) -> b
snd forall (m :: * -> *) a. MonadIO m => (m a, a -> m ())
nulls) forall a. a -> a
id Maybe (ByteString -> m ())
wc) (forall a. a -> a
id, forall a. a -> a
id)
nulls :: MonadIO m => (m a, a -> m ())
nulls :: forall (m :: * -> *) a. MonadIO m => (m a, a -> m ())
nulls = (forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ ArithException
Underflow, forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
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 :: 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 String
name rr
rr wr
wr = forall a b (m :: * -> *).
(Monad m, EmbedIO m) =>
String
-> (m a, b -> m ())
-> (a -> ByteString, ByteString -> b)
-> NineFile m
simpleFileBy String
name (forall sr (m :: * -> *) a. ReadRef sr m a => sr -> m a
readReference rr
rr, forall sr (m :: * -> *) a. WriteRef sr m a => sr -> a -> m ()
writeReference wr
wr) (forall a b. Convertible a b => a -> b
convert, forall a b. Convertible a b => a -> b
convert)
simpleFileBy :: forall a b m. (Monad m, EmbedIO m)
=> String
-> (m a, b -> m ())
-> (a -> ByteString, ByteString -> b)
-> NineFile m
simpleFileBy :: forall a b (m :: * -> *).
(Monad m, EmbedIO m) =>
String
-> (m a, b -> m ())
-> (a -> ByteString, ByteString -> b)
-> NineFile m
simpleFileBy String
name (m a
rd, b -> m ()
wr) (a -> ByteString
rdc, ByteString -> b
wrc) = (forall (m :: * -> *). (Monad m, EmbedIO m) => String -> NineFile m
boringFile String
name :: NineFile m) {
read :: Word64 -> Word32 -> m ByteString
read = forall (m :: * -> *).
(Monad m, EmbedIO m) =>
m ByteString -> Word64 -> Word32 -> m ByteString
simpleRead forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM a -> ByteString
rdc forall a b. (a -> b) -> a -> b
$ m a
rd,
write :: Word64 -> ByteString -> m Word32
write = forall (m :: * -> *).
(Monad m, EmbedIO m) =>
(ByteString -> m ()) -> Word64 -> ByteString -> m Word32
simpleWrite forall a b. (a -> b) -> a -> b
$ b -> m ()
wr forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> b
wrc
}
memoryFile :: forall m. (Monad m, EmbedIO m)
=> String
-> IO (NineFile m)
memoryFile :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String -> IO (NineFile m)
memoryFile String
name = do
IORef ByteString
c <- forall a. a -> IO (IORef a)
newIORef ByteString
"" :: IO (IORef ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b (m :: * -> *).
(Monad m, EmbedIO m) =>
String
-> (m a, b -> m ())
-> (a -> ByteString, ByteString -> b)
-> NineFile m
simpleFileBy String
name (
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef IORef ByteString
c,
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IORef a -> a -> IO ()
writeIORef IORef ByteString
c
) (forall a. a -> a
id, forall a. a -> a
id)
simpleDirectory :: forall m. (Monad m, EmbedIO m)
=> String
-> (String -> m (NineFile m))
-> (String -> m (NineFile m))
-> IO (NineFile m, IORef [(String, NineFile m)])
simpleDirectory :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String
-> (String -> m (NineFile m))
-> (String -> m (NineFile m))
-> IO (NineFile m, IORef [(String, NineFile m)])
simpleDirectory String
name String -> m (NineFile m)
newfile String -> m (NineFile m)
newdir = do
IORef [(String, NineFile m)]
files <- forall a. a -> IO (IORef a)
newIORef [] :: IO (IORef [(String, NineFile m)])
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (\NineFile m
f -> (NineFile m
f, IORef [(String, NineFile m)]
files)) forall a b. (a -> b) -> a -> b
$ (forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String -> [(String, NineFile m)] -> NineFile m
boringDir String
name [] :: NineFile m) {
create :: String -> Word32 -> m (NineFile m)
create = \String
name Word32
perms -> do
NineFile m
nf <- (if Word32 -> Bool
isDir Word32
perms then String -> m (NineFile m)
newdir else String -> m (NineFile m)
newfile) String
name
let nelem :: (String, NineFile m)
nelem = (String
name, NineFile m
nf)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [(String, NineFile m)]
files (\[(String, NineFile m)]
l -> ((String, NineFile m)
nelemforall a. a -> [a] -> [a]
:[(String, NineFile m)]
l, ()))
forall (m :: * -> *) a. Monad m => a -> m a
return NineFile m
nf,
getFiles :: m [NineFile m]
getFiles = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef IORef [(String, NineFile m)]
files,
descend :: String -> m (NineFile m)
descend = \String
name -> do
[(String, NineFile m)]
d <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef IORef [(String, NineFile m)]
files
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> NineError
ENoFile String
name) (forall (m :: * -> *) a. Monad m => a -> m a
return) forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
name [(String, NineFile m)]
d
}
memoryDirectory :: forall m. (Monad m, EmbedIO m)
=> String
-> IO (NineFile m)
memoryDirectory :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String -> IO (NineFile m)
memoryDirectory String
name = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String
-> (String -> m (NineFile m))
-> (String -> m (NineFile m))
-> IO (NineFile m, IORef [(String, NineFile m)])
simpleDirectory String
name (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String -> IO (NineFile m)
memoryFile) (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
(Monad m, EmbedIO m) =>
String -> IO (NineFile m)
memoryDirectory)