{-# LANGUAGE ScopedTypeVariables #-}

module Language.JavaScript.Inline.Examples.Utils where

import qualified Data.ByteString.Internal as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Unsafe as BS
import Foreign
import System.IO.Unsafe

storableToLBS :: Storable a => a -> LBS.ByteString
storableToLBS :: a -> ByteString
storableToLBS a
a =
  IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
    (ByteString -> ByteString) -> IO ByteString -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> ByteString
LBS.fromStrict (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$
      Int -> (Ptr Word8 -> IO ()) -> IO ByteString
BS.create (a -> Int
forall a. Storable a => a -> Int
sizeOf a
a) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p ->
        Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Word8 -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p) a
a

storableFromLBS :: forall a. Storable a => LBS.ByteString -> IO a
storableFromLBS :: ByteString -> IO a
storableFromLBS ByteString
s = ByteString -> (CStringLen -> IO a) -> IO a
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLen (ByteString -> ByteString
LBS.toStrict ByteString
s) ((CStringLen -> IO a) -> IO a) -> (CStringLen -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
p, Int
len) ->
  if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)
    then Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek (Ptr CChar -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
p)
    else String -> IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Language.JavaScript.Inline.Examples.Utils.storableFromLBS"