{-# LANGUAGE LambdaCase #-}

module Simplex.Chat.Mobile.Shared where

import qualified Data.ByteString as B
import Data.ByteString.Internal (ByteString (..))
import qualified Data.ByteString.Lazy as LB
import qualified Data.ByteString.Lazy.Internal as LB
import Foreign
import Foreign.C (CInt, CString)

type CJSONString = CString

type JSONByteString = LB.ByteString

getByteString :: Ptr Word8 -> CInt -> IO ByteString
getByteString :: Ptr Word8 -> CInt -> IO ByteString
getByteString Ptr Word8
ptr CInt
len = do
  ForeignPtr Word8
fp <- Ptr Word8 -> IO (ForeignPtr Word8)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ Ptr Word8
ptr
  ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
fp Int
0 (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
len)
{-# INLINE getByteString #-}

putByteString :: Ptr Word8 -> ByteString -> IO ()
putByteString :: Ptr Word8 -> ByteString -> IO ()
putByteString Ptr Word8
ptr (PS ForeignPtr Word8
fp Int
offset Int
len) =
  ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr Word8
ptr (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
offset) Int
len
{-# INLINE putByteString #-}

putLazyByteString :: Ptr Word8 -> LB.ByteString -> IO ()
putLazyByteString :: Ptr Word8 -> ByteString -> IO ()
putLazyByteString Ptr Word8
ptr = \case
  ByteString
LB.Empty -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  LB.Chunk ByteString
ch ByteString
s -> do
    Ptr Word8 -> ByteString -> IO ()
putByteString Ptr Word8
ptr ByteString
ch
    Ptr Word8 -> ByteString -> IO ()
putLazyByteString (Ptr Word8
ptr Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` ByteString -> Int
B.length ByteString
ch) ByteString
s

newCStringFromBS :: ByteString -> IO CString
newCStringFromBS :: ByteString -> IO CString
newCStringFromBS ByteString
s = do
  let len :: Int
len = ByteString -> Int
B.length ByteString
s
  Ptr Word8
buf <- Int -> IO (Ptr Word8)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  Ptr Word8 -> ByteString -> IO ()
putByteString Ptr Word8
buf ByteString
s
  Ptr Word8 -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
buf Int
len (Word8
0 :: Word8)
  CString -> IO CString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CString -> IO CString) -> CString -> IO CString
forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
buf

newCStringFromLazyBS :: LB.ByteString -> IO CString
newCStringFromLazyBS :: ByteString -> IO CString
newCStringFromLazyBS ByteString
s = do
  let len :: Int
len = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int) -> Int64 -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> Int64
LB.length ByteString
s
  Ptr Word8
buf <- Int -> IO (Ptr Word8)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  Ptr Word8 -> ByteString -> IO ()
putLazyByteString Ptr Word8
buf ByteString
s
  Ptr Word8 -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
buf Int
len (Word8
0 :: Word8)
  CString -> IO CString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CString -> IO CString) -> CString -> IO CString
forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
buf