{-# LANGUAGE ImportQualifiedPost #-}
module Sel.Internal.Sodium where
import Control.Monad.Trans.Class (lift)
import Data.ByteString (StrictByteString)
import Data.ByteString qualified as ByteString
import Foreign (ForeignPtr)
import Foreign.C (CSize, CUChar)
import LibSodium.Bindings.Utils
import System.IO.Unsafe (unsafeDupablePerformIO)
import Sel.Internal.Scoped
import Sel.Internal.Scoped.Foreign
binaryToHex :: ForeignPtr CUChar -> CSize -> StrictByteString
binaryToHex :: ForeignPtr CUChar -> CSize -> StrictByteString
binaryToHex ForeignPtr CUChar
fPtr CSize
size = IO StrictByteString -> StrictByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO StrictByteString -> StrictByteString)
-> (Scoped IO StrictByteString -> IO StrictByteString)
-> Scoped IO StrictByteString
-> StrictByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scoped IO StrictByteString -> IO StrictByteString
forall (m :: * -> *) a. Applicative m => Scoped m a -> m a
use (Scoped IO StrictByteString -> StrictByteString)
-> Scoped IO StrictByteString -> StrictByteString
forall a b. (a -> b) -> a -> b
$ do
let hexLength :: CSize
hexLength = CSize
size CSize -> CSize -> CSize
forall a. Num a => a -> a -> a
* CSize
2 CSize -> CSize -> CSize
forall a. Num a => a -> a -> a
+ CSize
1
hexPtr <- ForeignPtr CChar -> Scoped IO (Ptr CChar)
forall a. ForeignPtr a -> Scoped IO (Ptr a)
foreignPtr (ForeignPtr CChar -> Scoped IO (Ptr CChar))
-> Scoped IO (ForeignPtr CChar) -> Scoped IO (Ptr CChar)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> Scoped IO (ForeignPtr CChar)
forall a. Int -> Scoped IO (ForeignPtr a)
mallocForeignPtrBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
hexLength)
ptr <- foreignPtr fPtr
lift $ ByteString.packCString =<< sodiumBin2Hex hexPtr hexLength ptr size