module PtrPoker.ByteString where

import Data.ByteString
import qualified Data.ByteString.Builder as Builder
import qualified Data.ByteString.Builder.Extra as Builder
import qualified Data.ByteString.Builder.Scientific as ScientificBuilder
import Data.ByteString.Internal
import qualified Data.ByteString.Lazy as Lazy
import qualified PtrPoker.Compat.Text as TextCompat
import qualified PtrPoker.Ffi as Ffi
import PtrPoker.Prelude hiding (empty)

builderWithStrategy :: Builder.AllocationStrategy -> Builder.Builder -> ByteString
builderWithStrategy :: AllocationStrategy -> Builder -> ByteString
builderWithStrategy AllocationStrategy
strategy Builder
builder =
  Builder
builder
    Builder -> (Builder -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
& AllocationStrategy -> ByteString -> Builder -> ByteString
Builder.toLazyByteStringWith AllocationStrategy
strategy ByteString
Lazy.empty
    ByteString -> (ByteString -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
& ByteString -> ByteString
Lazy.toStrict

scientific :: Scientific -> ByteString
scientific :: Scientific -> ByteString
scientific Scientific
sci =
  Scientific
sci
    Scientific -> (Scientific -> Builder) -> Builder
forall a b. a -> (a -> b) -> b
& Scientific -> Builder
ScientificBuilder.scientificBuilder
    Builder -> (Builder -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
& AllocationStrategy -> Builder -> ByteString
builderWithStrategy (Int -> Int -> AllocationStrategy
Builder.untrimmedStrategy Int
128 Int
128)

double :: Double -> ByteString
double :: Double -> ByteString
double Double
dbl =
  Int -> (Ptr Word8 -> IO Int) -> ByteString
unsafeCreateUptoN
    Int
25
    ( \Ptr Word8
ptr ->
        Double -> Ptr Word8 -> IO CInt
Ffi.pokeDouble Double
dbl Ptr Word8
ptr
          IO CInt -> (IO CInt -> IO Int) -> IO Int
forall a b. a -> (a -> b) -> b
& (CInt -> Int) -> IO CInt -> IO Int
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
    )

unsafeCreateDownToN :: Int -> (Ptr Word8 -> IO Int) -> ByteString
unsafeCreateDownToN :: Int -> (Ptr Word8 -> IO Int) -> ByteString
unsafeCreateDownToN Int
allocSize Ptr Word8 -> IO Int
populate =
  IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
    ForeignPtr Word8
fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocByteString Int
allocSize
    Int
actualSize <- ForeignPtr Word8 -> (Ptr Word8 -> IO Int) -> IO Int
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp (\Ptr Word8
p -> Ptr Word8 -> IO Int
populate (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
p (Int -> Int
forall a. Enum a => a -> a
pred Int
allocSize)))
    ByteString -> IO ByteString
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$! ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
fp (Int
allocSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
actualSize) Int
actualSize

{-# INLINE textUtf8 #-}
textUtf8 :: Text -> ByteString
textUtf8 :: Text -> ByteString
textUtf8 = Text -> ByteString
TextCompat.encodeInUtf8