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) -- | Better implementation of 'Data.Serialize.getInt64le' 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