module Database.Franz.Internal (getInt64le, runGetRecv) where
import qualified Data.ByteString as B
import Data.IORef
import Data.Serialize hiding (getInt64le)
import Network.Socket as S
import Network.Socket.ByteString as SB
import System.Endian (fromLE64)
getInt64le :: Num a => Get a
getInt64le = fromIntegral . fromLE64 <$> getWord64host
{-# INLINE getInt64le #-}
runGetRecv :: IORef B.ByteString -> S.Socket -> Get a -> IO (Either String a)
runGetRecv refBuf sock m = do
lo <- readIORef refBuf
let go (Done a lo') = do
writeIORef refBuf lo'
return $ Right a
go (Partial cont) = SB.recv sock 4096 >>= go . cont
go (Fail str lo') = do
writeIORef refBuf lo'
return $ Left $ show sock ++ str
bs <- if B.null lo
then SB.recv sock 4096
else pure lo
go $ runGetPartial m bs