{-# LANGUAGE MagicHash #-}

module HsForeign.CppStd
  ( -- * StdString
    StdString
  , newStdString
  , maybeNewStdString
  , hs_new_std_string
  , hs_new_std_string_def
  , hs_std_string_size
  , hs_std_string_cstr
  , hs_delete_std_string
  , unsafePeekStdString
    -- * StdVector
  , StdVector

  ) where

import           Data.ByteString                (ByteString)
import qualified Data.ByteString.Unsafe         as BS
import           Data.Word
import           Foreign.Ptr

import           HsForeign.String (withByteString)

-------------------------------------------------------------------------------
-- StdString

data StdString

-- | New a c++ std::string from proviced bytestring.
--
-- The memory should be deallocated using delete when no longer required.
newStdString :: ByteString -> IO (Ptr StdString)
newStdString :: ByteString -> IO (Ptr StdString)
newStdString ByteString
bs = ByteString
-> (Ptr Word8 -> Int -> IO (Ptr StdString)) -> IO (Ptr StdString)
forall a. ByteString -> (Ptr Word8 -> Int -> IO a) -> IO a
withByteString ByteString
bs ((Ptr Word8 -> Int -> IO (Ptr StdString)) -> IO (Ptr StdString))
-> (Ptr Word8 -> Int -> IO (Ptr StdString)) -> IO (Ptr StdString)
forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> Int -> IO (Ptr StdString)
hs_new_std_string

maybeNewStdString :: Maybe ByteString -> IO (Ptr StdString)
maybeNewStdString :: Maybe ByteString -> IO (Ptr StdString)
maybeNewStdString Maybe ByteString
Nothing   = Ptr StdString -> IO (Ptr StdString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ptr StdString
forall a. Ptr a
nullPtr
maybeNewStdString (Just ByteString
bs) = ByteString -> IO (Ptr StdString)
newStdString ByteString
bs

unsafePeekStdString :: Ptr StdString -> IO ByteString
unsafePeekStdString :: Ptr StdString -> IO ByteString
unsafePeekStdString Ptr StdString
stdstring = do
  Int
siz <- Ptr StdString -> IO Int
hs_std_string_size Ptr StdString
stdstring
  Ptr Word8
ptr <- Ptr StdString -> IO (Ptr Word8)
hs_std_string_cstr Ptr StdString
stdstring
  Ptr Word8 -> Int -> IO () -> IO ByteString
BS.unsafePackCStringFinalizer Ptr Word8
ptr Int
siz (Ptr StdString -> IO ()
hs_delete_std_string Ptr StdString
stdstring)
{-# INLINE unsafePeekStdString #-}

foreign import ccall unsafe hs_new_std_string :: Ptr Word8 -> Int -> IO (Ptr StdString)
foreign import ccall unsafe hs_new_std_string_def :: IO (Ptr StdString)
foreign import ccall unsafe hs_std_string_size :: Ptr StdString -> IO Int
foreign import ccall unsafe hs_std_string_cstr :: Ptr StdString -> IO (Ptr Word8)
foreign import ccall unsafe hs_delete_std_string :: Ptr StdString -> IO ()

-------------------------------------------------------------------------------
-- StdVector

data StdVector a

peekStdVectorOfString :: Ptr (StdVector StdString) -> [ByteString]
peekStdVectorOfString :: Ptr (StdVector StdString) -> [ByteString]
peekStdVectorOfString = Ptr (StdVector StdString) -> [ByteString]
forall a. HasCallStack => a
undefined