module Ptr.Receive.Core where
import Ptr.Prelude
write :: (Ptr Word8 -> Int -> IO (Either Text Int)) -> ForeignPtr Word8 -> IORef (Int, Int) -> Int -> Int -> Ptr Word8 -> IO (Either Text ())
write :: (Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
write Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize Int
howMany Ptr Word8
destination =
do
(Int
offset, Int
end) <- forall a. IORef a -> IO a
readIORef IORef (Int, Int)
bufferStateRef
if Int
end forall a. Eq a => a -> a -> Bool
== Int
offset
then
(Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
fetchMany Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize Int
howMany Ptr Word8
destination
else
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
bufferFP forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bufferPtr ->
let amountInBuffer :: Int
amountInBuffer = Int
end forall a. Num a => a -> a -> a
- Int
offset
in if Int
amountInBuffer forall a. Ord a => a -> a -> Bool
>= Int
howMany
then
do
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr Word8
destination (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
bufferPtr Int
offset) Int
howMany
forall a. IORef a -> a -> IO ()
writeIORef IORef (Int, Int)
bufferStateRef (Int
offset forall a. Num a => a -> a -> a
+ Int
howMany, Int
end)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right ())
else do
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr Word8
destination (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
bufferPtr Int
offset) Int
amountInBuffer
(Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
fetchMany Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize (Int
howMany forall a. Num a => a -> a -> a
- Int
amountInBuffer) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
destination Int
amountInBuffer)
fetchMany :: (Ptr Word8 -> Int -> IO (Either Text Int)) -> ForeignPtr Word8 -> IORef (Int, Int) -> Int -> Int -> Ptr Word8 -> IO (Either Text ())
fetchMany :: (Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
fetchMany Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize Int
remaining Ptr Word8
destination =
if Int
remaining forall a. Ord a => a -> a -> Bool
>= Int
chunkSize
then
Ptr Word8
-> Int -> (Int -> IO (Either Text ())) -> IO (Either Text ())
fetchingSome Ptr Word8
destination Int
chunkSize forall a b. (a -> b) -> a -> b
$ \Int
amountFetched ->
if Int
amountFetched forall a. Eq a => a -> a -> Bool
== Int
remaining
then
do
forall a. IORef a -> a -> IO ()
writeIORef IORef (Int, Int)
bufferStateRef (Int
0, Int
0)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right ())
else
(Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
fetchMany Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize (Int
remaining forall a. Num a => a -> a -> a
- Int
amountFetched) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
destination Int
amountFetched)
else
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
bufferFP forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bufferPtr ->
Ptr Word8
-> Int -> (Int -> IO (Either Text ())) -> IO (Either Text ())
fetchingSome Ptr Word8
bufferPtr Int
chunkSize forall a b. (a -> b) -> a -> b
$ \Int
amountFetched ->
do
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr Word8
destination Ptr Word8
bufferPtr Int
remaining
forall a. IORef a -> a -> IO ()
writeIORef IORef (Int, Int)
bufferStateRef (Int
remaining, Int
amountFetched)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right ())
where
fetchingSome :: Ptr Word8
-> Int -> (Int -> IO (Either Text ())) -> IO (Either Text ())
fetchingSome Ptr Word8
destination Int
amount Int -> IO (Either Text ())
handle =
do
Either Text Int
fetchResult <- Ptr Word8 -> Int -> IO (Either Text Int)
fetch Ptr Word8
destination Int
amount
case Either Text Int
fetchResult of
Left Text
msg -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left Text
msg)
Right Int
amountFetched ->
if Int
amountFetched forall a. Eq a => a -> a -> Bool
== Int
0
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left Text
"End of input")
else Int -> IO (Either Text ())
handle Int
amountFetched
peek :: (Ptr Word8 -> Int -> IO (Either Text Int)) -> ForeignPtr Word8 -> IORef (Int, Int) -> Int -> Int -> (Ptr Word8 -> IO peekd) -> IO (Either Text peekd)
peek :: forall peekd.
(Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> (Ptr Word8 -> IO peekd)
-> IO (Either Text peekd)
peek Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize Int
howMany Ptr Word8 -> IO peekd
peek =
do
(Int
offset, Int
end) <- forall a. IORef a -> IO a
readIORef IORef (Int, Int)
bufferStateRef
let amountInBuffer :: Int
amountInBuffer = Int
end forall a. Num a => a -> a -> a
- Int
offset
in if Int
amountInBuffer forall a. Ord a => a -> a -> Bool
>= Int
howMany
then
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
bufferFP forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bufferPtr ->
do
peekd
peekd <- Ptr Word8 -> IO peekd
peek Ptr Word8
bufferPtr
forall a. IORef a -> a -> IO ()
writeIORef IORef (Int, Int)
bufferStateRef (Int
offset forall a. Num a => a -> a -> a
+ Int
howMany, Int
end)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right peekd
peekd)
else
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
howMany forall a b. (a -> b) -> a -> b
$ \Ptr Word8
tmpPtr ->
do
Either Text ()
writeResult <-
if Int
end forall a. Eq a => a -> a -> Bool
== Int
offset
then
(Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
fetchMany Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize Int
howMany Ptr Word8
tmpPtr
else
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
bufferFP forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bufferPtr ->
do
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr Word8
tmpPtr (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
bufferPtr Int
offset) Int
amountInBuffer
(Ptr Word8 -> Int -> IO (Either Text Int))
-> ForeignPtr Word8
-> IORef (Int, Int)
-> Int
-> Int
-> Ptr Word8
-> IO (Either Text ())
fetchMany Ptr Word8 -> Int -> IO (Either Text Int)
fetch ForeignPtr Word8
bufferFP IORef (Int, Int)
bufferStateRef Int
chunkSize (Int
howMany forall a. Num a => a -> a -> a
- Int
amountInBuffer) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
tmpPtr Int
amountInBuffer)
case Either Text ()
writeResult of
Right () -> do
peekd
peekd <- Ptr Word8 -> IO peekd
peek Ptr Word8
tmpPtr
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right peekd
peekd)
Left Text
msg -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left Text
msg)