{-# LANGUAGE CPP #-}
{-# LANGUAGE Unsafe #-}

{-# OPTIONS_HADDOCK not-home #-}

{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE ViewPatterns #-}

#include "bytestring-cpp-macros.h"

-- |
-- Module      : Data.ByteString.Internal.Type
-- Copyright   : (c) Don Stewart 2006-2008
--               (c) Duncan Coutts 2006-2012
-- License     : BSD-style
-- Maintainer  : dons00@gmail.com, duncan@community.haskell.org
-- Stability   : unstable
-- Portability : non-portable
--
-- The 'ByteString' type, its instances, and whatever related
-- utilities the bytestring developers see fit to use internally.
--
module Data.ByteString.Internal.Type (

        -- * The @ByteString@ type and representation
        ByteString
        ( BS
        , PS -- backwards compatibility shim
        ),

        StrictByteString,

        -- * Internal indexing
        findIndexOrLength,

        -- * Conversion with lists: packing and unpacking
        packBytes, packUptoLenBytes, unsafePackLenBytes,
        packChars, packUptoLenChars, unsafePackLenChars,
        unpackBytes, unpackAppendBytesLazy, unpackAppendBytesStrict,
        unpackChars, unpackAppendCharsLazy, unpackAppendCharsStrict,
        unsafePackAddress, unsafePackLenAddress,
        unsafePackLiteral, unsafePackLenLiteral,

        -- * Low level imperative construction
        empty,
        createFp,
        createFpUptoN,
        createFpUptoN',
        createFpAndTrim,
        createFpAndTrim',
        unsafeCreateFp,
        unsafeCreateFpUptoN,
        unsafeCreateFpUptoN',
        create,
        createUptoN,
        createUptoN',
        createAndTrim,
        createAndTrim',
        unsafeCreate,
        unsafeCreateUptoN,
        unsafeCreateUptoN',
        mallocByteString,

        -- * Conversion to and from ForeignPtrs
        mkDeferredByteString,
        fromForeignPtr,
        toForeignPtr,
        fromForeignPtr0,
        toForeignPtr0,

        -- * Utilities
        nullForeignPtr,
        peekFp,
        pokeFp,
        peekFpByteOff,
        pokeFpByteOff,
        minusForeignPtr,
        memcpyFp,
        deferForeignPtrAvailability,
        unsafeDupablePerformIO,
        SizeOverflowException,
        overflowError,
        checkedAdd,
        checkedMultiply,

        -- * Standard C Functions
        c_strlen,
        c_free_finalizer,

        memchr,
        memcmp,
        memcpy,
        memset,

        -- * cbits functions
        c_reverse,
        c_intersperse,
        c_maximum,
        c_minimum,
        c_count,
        c_count_ba,
        c_elem_index,
        c_sort,
        c_int_dec,
        c_int_dec_padded9,
        c_uint_dec,
        c_uint_hex,
        c_long_long_int_dec,
        c_long_long_int_dec_padded18,
        c_long_long_uint_dec,
        c_long_long_uint_hex,
        cIsValidUtf8BA,
        cIsValidUtf8BASafe,
        cIsValidUtf8,
        cIsValidUtf8Safe,

        -- * Chars
        w2c, c2w, isSpaceWord8, isSpaceChar8,

        -- * Deprecated and unmentionable
        accursedUnutterablePerformIO,

        -- * Exported compatibility shim
        plusForeignPtr,
        unsafeWithForeignPtr
  ) where

import Prelude hiding (concat, null)
import qualified Data.List as List

import Foreign.ForeignPtr       (ForeignPtr, withForeignPtr)
import Foreign.Ptr
import Foreign.Storable         (Storable(..))
import Foreign.C.Types
import Foreign.C.String         (CString)
import Foreign.Marshal.Utils
import Foreign.Marshal.Alloc    (finalizerFree)

#if PURE_HASKELL
import qualified Data.ByteString.Internal.Pure as Pure
import Data.Bits                (toIntegralSized, Bits)
import Data.Maybe               (fromMaybe)
import Control.Monad            ((<$!>))
#endif

import Data.Semigroup           (Semigroup (..))
import Data.List.NonEmpty       (NonEmpty ((:|)))

import Control.DeepSeq          (NFData(rnf))

import Data.String              (IsString(..))

import Control.Exception        (assert, throw, Exception)

import Data.Bits                ((.&.))
import Data.Char                (ord)
import Data.Word

import Data.Data                (Data(..), mkConstr, mkNoRepType, Constr, DataType, Fixity(Prefix), constrIndex)

import GHC.Base                 (nullAddr#,realWorld#,unsafeChr,unpackCString#)
import GHC.Exts                 (IsList(..), Addr#, minusAddr#, ByteArray#, runRW#, lazy)

#if HS_timesInt2_PRIMOP_AVAILABLE
import GHC.Exts                (timesInt2#)
#else
import GHC.Exts                ( timesWord2#
                               , or#
                               , uncheckedShiftRL#
                               , int2Word#
                               , word2Int#
                               )
import Data.Bits               (finiteBitSize)
#endif

import GHC.IO                   (IO(IO))
import GHC.ForeignPtr           (ForeignPtr(ForeignPtr)
#if !HS_cstringLength_AND_FinalPtr_AVAILABLE
                                , newForeignPtr_
#endif
                                , mallocPlainForeignPtrBytes)

import GHC.ForeignPtr           (plusForeignPtr)

#if HS_cstringLength_AND_FinalPtr_AVAILABLE
import GHC.Exts                 (cstringLength#)
import GHC.ForeignPtr           (ForeignPtrContents(FinalPtr))
#else
import GHC.Ptr                  (Ptr(..))
#endif

import GHC.Int                  (Int (..))

#if HS_unsafeWithForeignPtr_AVAILABLE
import GHC.ForeignPtr           (unsafeWithForeignPtr)
#endif

import qualified Language.Haskell.TH.Lib as TH
import qualified Language.Haskell.TH.Syntax as TH

#if !HS_unsafeWithForeignPtr_AVAILABLE
unsafeWithForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr = withForeignPtr
#endif

-- CFILES stuff is Hugs only
{-# CFILES cbits/fpstring.c #-}

minusForeignPtr :: ForeignPtr a -> ForeignPtr b -> Int
minusForeignPtr :: forall a b. ForeignPtr a -> ForeignPtr b -> Int
minusForeignPtr (ForeignPtr Addr#
addr1 ForeignPtrContents
_) (ForeignPtr Addr#
addr2 ForeignPtrContents
_)
  = Int# -> Int
I# (Addr# -> Addr# -> Int#
minusAddr# Addr#
addr1 Addr#
addr2)

peekFp :: Storable a => ForeignPtr a -> IO a
peekFp :: forall a. Storable a => ForeignPtr a -> IO a
peekFp ForeignPtr a
fp = ForeignPtr a -> (Ptr a -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr a
fp Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek

pokeFp :: Storable a => ForeignPtr a -> a -> IO ()
pokeFp :: forall a. Storable a => ForeignPtr a -> a -> IO ()
pokeFp ForeignPtr a
fp a
val = ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr a
fp ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
p a
val

peekFpByteOff :: Storable a => ForeignPtr a -> Int -> IO a
peekFpByteOff :: forall a. Storable a => ForeignPtr a -> Int -> IO a
peekFpByteOff ForeignPtr a
fp Int
off = ForeignPtr a -> (Ptr a -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr a
fp ((Ptr a -> IO a) -> IO a) -> (Ptr a -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Ptr a
p ->
  Ptr a -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr a
p Int
off

pokeFpByteOff :: Storable a => ForeignPtr b -> Int -> a -> IO ()
pokeFpByteOff :: forall a b. Storable a => ForeignPtr b -> Int -> a -> IO ()
pokeFpByteOff ForeignPtr b
fp Int
off a
val = ForeignPtr b -> (Ptr b -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr b
fp ((Ptr b -> IO ()) -> IO ()) -> (Ptr b -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr b
p ->
  Ptr b -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr b
p Int
off a
val

-- | Most operations on a 'ByteString' need to read from the buffer
-- given by its @ForeignPtr Word8@ field.  But since most operations
-- on @ByteString@ are (nominally) pure, their implementations cannot
-- see the IO state thread that was used to initialize the contents of
-- that buffer.  This means that under some circumstances, these
-- buffer-reads may be executed before the writes used to initialize
-- the buffer are executed, with unpredictable results.
--
-- 'deferForeignPtrAvailability' exists to help solve this problem.
-- At runtime, a call @'deferForeignPtrAvailability' x@ is equivalent
-- to @pure $! x@, but the former is more opaque to the simplifier, so
-- that reads from the pointer in its result cannot be executed until
-- the @'deferForeignPtrAvailability' x@ call is complete.
--
-- The opaque bits evaporate during CorePrep, so using
-- 'deferForeignPtrAvailability' incurs no direct overhead.
--
-- @since 0.11.5.0
deferForeignPtrAvailability :: ForeignPtr a -> IO (ForeignPtr a)
deferForeignPtrAvailability :: forall a. ForeignPtr a -> IO (ForeignPtr a)
deferForeignPtrAvailability (ForeignPtr Addr#
addr0# ForeignPtrContents
guts) = (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
 -> IO (ForeignPtr a))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s0 ->
  case ((State# RealWorld -> (# State# RealWorld, Addr# #))
 -> (# State# RealWorld, Addr# #))
-> (State# RealWorld -> (# State# RealWorld, Addr# #))
-> (# State# RealWorld, Addr# #)
forall a. a -> a
lazy (State# RealWorld -> (# State# RealWorld, Addr# #))
-> (# State# RealWorld, Addr# #)
forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
_ -> (# State# RealWorld
s0, Addr#
addr0# #)) of
    (# State# RealWorld
s1, Addr#
addr1# #) -> (# State# RealWorld
s1, Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
addr1# ForeignPtrContents
guts #)

-- | Variant of 'fromForeignPtr0' that calls 'deferForeignPtrAvailability'
--
-- @since 0.11.5.0
mkDeferredByteString :: ForeignPtr Word8 -> Int -> IO ByteString
mkDeferredByteString :: ForeignPtr Word8 -> Int -> IO ByteString
mkDeferredByteString ForeignPtr Word8
fp Int
len = do
  deferredFp <- ForeignPtr Word8 -> IO (ForeignPtr Word8)
forall a. ForeignPtr a -> IO (ForeignPtr a)
deferForeignPtrAvailability ForeignPtr Word8
fp
  pure $! BS deferredFp len

unsafeDupablePerformIO :: IO a -> a
-- Why does this exist? In base-4.15.1.0 until at least base-4.18.0.0,
-- the version of unsafeDupablePerformIO in base prevents unboxing of
-- its results with an opaque call to GHC.Exts.lazy, for reasons described
-- in Note [unsafePerformIO and strictness] in GHC.IO.Unsafe. (See
-- https://hackage.haskell.org/package/base-4.18.0.0/docs/src/GHC.IO.Unsafe.html#line-30 .)
-- Even if we accept the (very questionable) premise that the sort of
-- function described in that note should work, we expect no such
-- calls to be made in the context of bytestring.  (And we really want
-- unboxing!)
unsafeDupablePerformIO :: forall a. IO a -> a
unsafeDupablePerformIO (IO State# RealWorld -> (# State# RealWorld, a #)
act) = case (State# RealWorld -> (# State# RealWorld, a #))
-> (# State# RealWorld, a #)
forall o. (State# RealWorld -> o) -> o
runRW# State# RealWorld -> (# State# RealWorld, a #)
act of (# State# RealWorld
_, a
res #) -> a
res



-- -----------------------------------------------------------------------------

-- | A space-efficient representation of a 'Word8' vector, supporting many
-- efficient operations.
--
-- A 'ByteString' contains 8-bit bytes, or by using the operations from
-- "Data.ByteString.Char8" it can be interpreted as containing 8-bit
-- characters.
--
data ByteString = BS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
                     {-# UNPACK #-} !Int                -- length
                     -- ^ @since 0.11.0.0

-- | Type synonym for the strict flavour of 'ByteString'.
--
-- @since 0.11.2.0
type StrictByteString = ByteString

-- |
-- @'PS' foreignPtr offset length@ represents a 'ByteString' with data
-- backed by a given @foreignPtr@, starting at a given @offset@ in bytes
-- and of a specified @length@.
--
-- This pattern is used to emulate the legacy 'ByteString' data
-- constructor, so that pre-existing code generally doesn't need to
-- change to benefit from the simplified 'BS' constructor and can
-- continue to function unchanged.
--
-- /Note:/ Matching with this constructor will always be given a 0 offset,
-- as the base will be manipulated by 'plusForeignPtr' instead.
--
pattern PS :: ForeignPtr Word8 -> Int -> Int -> ByteString
pattern $mPS :: forall {r}.
ByteString
-> (ForeignPtr Word8 -> Int -> Int -> r) -> ((# #) -> r) -> r
$bPS :: ForeignPtr Word8 -> Int -> Int -> ByteString
PS fp zero len <- BS fp ((0,) -> (zero, len)) where
  PS ForeignPtr Word8
fp Int
o Int
len = ForeignPtr Word8 -> Int -> ByteString
BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
fp Int
o) Int
len
{-# COMPLETE PS #-}

instance Eq  ByteString where
    == :: ByteString -> ByteString -> Bool
(==)    = ByteString -> ByteString -> Bool
eq

instance Ord ByteString where
    compare :: ByteString -> ByteString -> Ordering
compare = ByteString -> ByteString -> Ordering
compareBytes

instance Semigroup ByteString where
    <> :: ByteString -> ByteString -> ByteString
(<>)    = ByteString -> ByteString -> ByteString
append
    sconcat :: NonEmpty ByteString -> ByteString
sconcat (ByteString
b:|[ByteString]
bs) = [ByteString] -> ByteString
concat (ByteString
bByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
bs)
    {-# INLINE stimes #-}
    stimes :: forall b. Integral b => b -> ByteString -> ByteString
stimes  = b -> ByteString -> ByteString
forall b. Integral b => b -> ByteString -> ByteString
stimesPolymorphic

instance Monoid ByteString where
    mempty :: ByteString
mempty  = ByteString
empty
    mappend :: ByteString -> ByteString -> ByteString
mappend = ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
(<>)
    mconcat :: [ByteString] -> ByteString
mconcat = [ByteString] -> ByteString
concat

instance NFData ByteString where
    rnf :: ByteString -> ()
rnf BS{} = ()

instance Show ByteString where
    showsPrec :: Int -> ByteString -> ShowS
showsPrec Int
p ByteString
ps String
r = Int -> String -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p (ByteString -> String
unpackChars ByteString
ps) String
r

instance Read ByteString where
    readsPrec :: Int -> ReadS ByteString
readsPrec Int
p String
str = [ (String -> ByteString
packChars String
x, String
y) | (String
x, String
y) <- Int -> ReadS String
forall a. Read a => Int -> ReadS a
readsPrec Int
p String
str ]

-- | @since 0.10.12.0
instance IsList ByteString where
  type Item ByteString = Word8
  fromList :: [Item ByteString] -> ByteString
fromList = [Word8] -> ByteString
[Item ByteString] -> ByteString
packBytes
  toList :: ByteString -> [Item ByteString]
toList   = ByteString -> [Word8]
ByteString -> [Item ByteString]
unpackBytes

-- | Beware: 'fromString' truncates multi-byte characters to octets.
-- e.g. "枯朶に烏のとまりけり秋の暮" becomes �6k�nh~�Q��n�
instance IsString ByteString where
    {-# INLINE fromString #-}
    fromString :: String -> ByteString
fromString = String -> ByteString
packChars

instance Data ByteString where
  gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ByteString -> c ByteString
gfoldl forall d b. Data d => c (d -> b) -> d -> c b
f forall g. g -> c g
z ByteString
txt = ([Word8] -> ByteString) -> c ([Word8] -> ByteString)
forall g. g -> c g
z [Word8] -> ByteString
packBytes c ([Word8] -> ByteString) -> [Word8] -> c ByteString
forall d b. Data d => c (d -> b) -> d -> c b
`f` ByteString -> [Word8]
unpackBytes ByteString
txt
  toConstr :: ByteString -> Constr
toConstr ByteString
_     = Constr
packConstr
  gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ByteString
gunfold forall b r. Data b => c (b -> r) -> c r
k forall r. r -> c r
z Constr
c = case Constr -> Int
constrIndex Constr
c of
    Int
1 -> c ([Word8] -> ByteString) -> c ByteString
forall b r. Data b => c (b -> r) -> c r
k (([Word8] -> ByteString) -> c ([Word8] -> ByteString)
forall r. r -> c r
z [Word8] -> ByteString
packBytes)
    Int
_ -> String -> c ByteString
forall a. (?callStack::CallStack) => String -> a
error String
"gunfold: unexpected constructor of strict ByteString"
  dataTypeOf :: ByteString -> DataType
dataTypeOf ByteString
_   = DataType
byteStringDataType

packConstr :: Constr
packConstr :: Constr
packConstr = DataType -> String -> [String] -> Fixity -> Constr
mkConstr DataType
byteStringDataType String
"pack" [] Fixity
Prefix

byteStringDataType :: DataType
byteStringDataType :: DataType
byteStringDataType = String -> DataType
mkNoRepType String
"Data.ByteString.ByteString"

-- | @since 0.11.2.0
instance TH.Lift ByteString where
#if MIN_VERSION_template_haskell(2,16,0)
-- template-haskell-2.16 first ships with ghc-8.10
  lift :: forall (m :: * -> *). Quote m => ByteString -> m Exp
lift (BS ForeignPtr Word8
ptr Int
len) = [| unsafePackLenLiteral |]
    m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`TH.appE` Lit -> m Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
TH.litE (Integer -> Lit
TH.integerL (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len))
    m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`TH.appE` Lit -> m Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
TH.litE (Bytes -> Lit
TH.BytesPrimL (Bytes -> Lit) -> Bytes -> Lit
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Word -> Word -> Bytes
TH.Bytes ForeignPtr Word8
ptr Word
0 (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len))
#else
  lift bs@(BS _ len) = [| unsafePackLenLiteral |]
    `TH.appE` TH.litE (TH.integerL (fromIntegral len))
    `TH.appE` TH.litE (TH.StringPrimL $ unpackBytes bs)
#endif

#if MIN_VERSION_template_haskell(2,17,0)
-- template-haskell-2.17 first ships with ghc-9.0
  liftTyped :: forall (m :: * -> *). Quote m => ByteString -> Code m ByteString
liftTyped = m Exp -> Code m ByteString
forall a (m :: * -> *). Quote m => m Exp -> Code m a
TH.unsafeCodeCoerce (m Exp -> Code m ByteString)
-> (ByteString -> m Exp) -> ByteString -> Code m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> m Exp
forall t (m :: * -> *). (Lift t, Quote m) => t -> m Exp
forall (m :: * -> *). Quote m => ByteString -> m Exp
TH.lift
#elif MIN_VERSION_template_haskell(2,16,0)
-- template-haskell-2.16 first ships with ghc-8.10
  liftTyped = TH.unsafeTExpCoerce . TH.lift
#endif

------------------------------------------------------------------------
-- Internal indexing

-- | 'findIndexOrLength' is a variant of findIndex, that returns the length
-- of the string if no element is found, rather than Nothing.
findIndexOrLength :: (Word8 -> Bool) -> ByteString -> Int
findIndexOrLength :: (Word8 -> Bool) -> ByteString -> Int
findIndexOrLength Word8 -> Bool
k (BS ForeignPtr Word8
x Int
l) =
    IO Int -> Int
forall a. IO a -> a
accursedUnutterablePerformIO (IO Int -> Int) -> IO Int -> Int
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> IO Int
g ForeignPtr Word8
x
  where
    g :: ForeignPtr Word8 -> IO Int
g ForeignPtr Word8
ptr = Int -> IO Int
go Int
0
      where
        go :: Int -> IO Int
go !Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
l    = Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
l
              | Bool
otherwise = do w <- ForeignPtr Word8 -> IO Word8
forall a. Storable a => ForeignPtr a -> IO a
peekFp (ForeignPtr Word8 -> IO Word8) -> ForeignPtr Word8 -> IO Word8
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8
ptr ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
n
                               if k w
                                 then return n
                                 else go (n+1)
{-# INLINE findIndexOrLength #-}

------------------------------------------------------------------------
-- Packing and unpacking from lists

packBytes :: [Word8] -> ByteString
packBytes :: [Word8] -> ByteString
packBytes [Word8]
ws = Int -> [Word8] -> ByteString
unsafePackLenBytes ([Word8] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [Word8]
ws) [Word8]
ws

packChars :: [Char] -> ByteString
packChars :: String -> ByteString
packChars String
cs = Int -> String -> ByteString
unsafePackLenChars (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length String
cs) String
cs

{-# INLINE [0] packChars #-}

{-# RULES
"ByteString packChars/packAddress" forall s .
   packChars (unpackCString# s) = unsafePackLiteral s
 #-}

unsafePackLenBytes :: Int -> [Word8] -> ByteString
unsafePackLenBytes :: Int -> [Word8] -> ByteString
unsafePackLenBytes Int
len [Word8]
xs0 =
    Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
len ((ForeignPtr Word8 -> IO ()) -> ByteString)
-> (ForeignPtr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
p -> ForeignPtr Word8 -> [Word8] -> IO ()
forall {b}. Storable b => ForeignPtr b -> [b] -> IO ()
go ForeignPtr Word8
p [Word8]
xs0
  where
    go :: ForeignPtr b -> [b] -> IO ()
go !ForeignPtr b
_ []     = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    go !ForeignPtr b
p (b
x:[b]
xs) = ForeignPtr b -> b -> IO ()
forall a. Storable a => ForeignPtr a -> a -> IO ()
pokeFp ForeignPtr b
p b
x IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ForeignPtr b -> [b] -> IO ()
go (ForeignPtr b
p ForeignPtr b -> Int -> ForeignPtr b
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
1) [b]
xs

unsafePackLenChars :: Int -> [Char] -> ByteString
unsafePackLenChars :: Int -> String -> ByteString
unsafePackLenChars Int
len String
cs0 =
    Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
len ((ForeignPtr Word8 -> IO ()) -> ByteString)
-> (ForeignPtr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
p -> ForeignPtr Word8 -> String -> IO ()
go ForeignPtr Word8
p String
cs0
  where
    go :: ForeignPtr Word8 -> String -> IO ()
go !ForeignPtr Word8
_ []     = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    go !ForeignPtr Word8
p (Char
c:String
cs) = ForeignPtr Word8 -> Word8 -> IO ()
forall a. Storable a => ForeignPtr a -> a -> IO ()
pokeFp ForeignPtr Word8
p (Char -> Word8
c2w Char
c) IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ForeignPtr Word8 -> String -> IO ()
go (ForeignPtr Word8
p ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
1) String
cs


-- | /O(n)/ Pack a null-terminated sequence of bytes, pointed to by an
-- Addr\# (an arbitrary machine address assumed to point outside the
-- garbage-collected heap) into a @ByteString@. A much faster way to
-- create an 'Addr#' is with an unboxed string literal, than to pack a
-- boxed string. A unboxed string literal is compiled to a static @char
-- []@ by GHC. Establishing the length of the string requires a call to
-- @strlen(3)@, so the 'Addr#' must point to a null-terminated buffer (as
-- is the case with @\"string\"\#@ literals in GHC). Use 'Data.ByteString.Unsafe.unsafePackAddressLen'
-- if you know the length of the string statically.
--
-- An example:
--
-- > literalFS = unsafePackAddress "literal"#
--
-- This function is /unsafe/. If you modify the buffer pointed to by the
-- original 'Addr#' this modification will be reflected in the resulting
-- @ByteString@, breaking referential transparency.
--
-- Note this also won't work if your 'Addr#' has embedded @\'\\0\'@ characters in
-- the string, as @strlen@ will return too short a length.
--
unsafePackAddress :: Addr# -> IO ByteString
unsafePackAddress :: Addr# -> IO ByteString
unsafePackAddress Addr#
addr# = do
#if HS_cstringLength_AND_FinalPtr_AVAILABLE
    Int -> Addr# -> IO ByteString
unsafePackLenAddress (Int# -> Int
I# (Addr# -> Int#
cstringLength# Addr#
addr#)) Addr#
addr#
#else
    l <- c_strlen (Ptr addr#)
    unsafePackLenAddress (fromIntegral l) addr#
#endif
{-# INLINE unsafePackAddress #-}

-- | See 'unsafePackAddress'. This function is similar,
-- but takes an additional length argument rather then computing
-- it with @strlen@.
-- Therefore embedding @\'\\0\'@ characters is possible.
--
-- @since 0.11.2.0
unsafePackLenAddress :: Int -> Addr# -> IO ByteString
unsafePackLenAddress :: Int -> Addr# -> IO ByteString
unsafePackLenAddress Int
len Addr#
addr# = do
#if HS_cstringLength_AND_FinalPtr_AVAILABLE
    ByteString -> IO ByteString
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> ByteString
BS (Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
addr# ForeignPtrContents
FinalPtr) Int
len)
#else
    p <- newForeignPtr_ (Ptr addr#)
    return $ BS p len
#endif
{-# INLINE unsafePackLenAddress #-}

-- | See 'unsafePackAddress'. This function has similar behavior. Prefer
-- this function when the address in known to be an @Addr#@ literal. In
-- that context, there is no need for the sequencing guarantees that 'IO'
-- provides. On GHC 9.0 and up, this function uses the @FinalPtr@ data
-- constructor for @ForeignPtrContents@.
--
-- @since 0.11.1.0
unsafePackLiteral :: Addr# -> ByteString
unsafePackLiteral :: Addr# -> ByteString
unsafePackLiteral Addr#
addr# =
#if HS_cstringLength_AND_FinalPtr_AVAILABLE
  Int -> Addr# -> ByteString
unsafePackLenLiteral (Int# -> Int
I# (Addr# -> Int#
cstringLength# Addr#
addr#)) Addr#
addr#
#else
  let len = accursedUnutterablePerformIO (c_strlen (Ptr addr#))
   in unsafePackLenLiteral (fromIntegral len) addr#
#endif
{-# INLINE unsafePackLiteral #-}


-- | See 'unsafePackLiteral'. This function is similar,
-- but takes an additional length argument rather then computing
-- it with @strlen@.
-- Therefore embedding @\'\\0\'@ characters is possible.
--
-- @since 0.11.2.0
unsafePackLenLiteral :: Int -> Addr# -> ByteString
unsafePackLenLiteral :: Int -> Addr# -> ByteString
unsafePackLenLiteral Int
len Addr#
addr# =
#if HS_cstringLength_AND_FinalPtr_AVAILABLE
  ForeignPtr Word8 -> Int -> ByteString
BS (Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
addr# ForeignPtrContents
FinalPtr) Int
len
#else
  -- newForeignPtr_ allocates a MutVar# internally. If that MutVar#
  -- gets commoned up with the MutVar# of some unrelated ForeignPtr,
  -- it may prevent automatic finalization for that other ForeignPtr.
  -- So we avoid accursedUnutterablePerformIO here.
  BS (unsafeDupablePerformIO (newForeignPtr_ (Ptr addr#))) len
#endif
{-# INLINE unsafePackLenLiteral #-}

packUptoLenBytes :: Int -> [Word8] -> (ByteString, [Word8])
packUptoLenBytes :: Int -> [Word8] -> (ByteString, [Word8])
packUptoLenBytes Int
len [Word8]
xs0 =
    Int
-> (ForeignPtr Word8 -> IO (Int, [Word8])) -> (ByteString, [Word8])
forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateFpUptoN' Int
len ((ForeignPtr Word8 -> IO (Int, [Word8])) -> (ByteString, [Word8]))
-> (ForeignPtr Word8 -> IO (Int, [Word8])) -> (ByteString, [Word8])
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
p0 ->
      let p_end :: ForeignPtr Word8
p_end = ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
p0 Int
len
          go :: ForeignPtr Word8 -> [Word8] -> IO (Int, [Word8])
go !ForeignPtr Word8
p []              = (Int, [Word8]) -> IO (Int, [Word8])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8
p ForeignPtr Word8 -> ForeignPtr Word8 -> Int
forall a b. ForeignPtr a -> ForeignPtr b -> Int
`minusForeignPtr` ForeignPtr Word8
p0, [])
          go !ForeignPtr Word8
p [Word8]
xs | ForeignPtr Word8
p ForeignPtr Word8 -> ForeignPtr Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== ForeignPtr Word8
p_end = (Int, [Word8]) -> IO (Int, [Word8])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
len, [Word8]
xs)
          go !ForeignPtr Word8
p (Word8
x:[Word8]
xs)          = ForeignPtr Word8 -> Word8 -> IO ()
forall a. Storable a => ForeignPtr a -> a -> IO ()
pokeFp ForeignPtr Word8
p Word8
x IO () -> IO (Int, [Word8]) -> IO (Int, [Word8])
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ForeignPtr Word8 -> [Word8] -> IO (Int, [Word8])
go (ForeignPtr Word8
p ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
1) [Word8]
xs
      in ForeignPtr Word8 -> [Word8] -> IO (Int, [Word8])
go ForeignPtr Word8
p0 [Word8]
xs0

packUptoLenChars :: Int -> [Char] -> (ByteString, [Char])
packUptoLenChars :: Int -> String -> (ByteString, String)
packUptoLenChars Int
len String
cs0 =
    Int
-> (ForeignPtr Word8 -> IO (Int, String)) -> (ByteString, String)
forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateFpUptoN' Int
len ((ForeignPtr Word8 -> IO (Int, String)) -> (ByteString, String))
-> (ForeignPtr Word8 -> IO (Int, String)) -> (ByteString, String)
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
p0 ->
      let p_end :: ForeignPtr Word8
p_end = ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
p0 Int
len
          go :: ForeignPtr Word8 -> String -> IO (Int, String)
go !ForeignPtr Word8
p []              = (Int, String) -> IO (Int, String)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8
p ForeignPtr Word8 -> ForeignPtr Word8 -> Int
forall a b. ForeignPtr a -> ForeignPtr b -> Int
`minusForeignPtr` ForeignPtr Word8
p0, [])
          go !ForeignPtr Word8
p String
cs | ForeignPtr Word8
p ForeignPtr Word8 -> ForeignPtr Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== ForeignPtr Word8
p_end = (Int, String) -> IO (Int, String)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
len, String
cs)
          go !ForeignPtr Word8
p (Char
c:String
cs)          = ForeignPtr Word8 -> Word8 -> IO ()
forall a. Storable a => ForeignPtr a -> a -> IO ()
pokeFp ForeignPtr Word8
p (Char -> Word8
c2w Char
c) IO () -> IO (Int, String) -> IO (Int, String)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ForeignPtr Word8 -> String -> IO (Int, String)
go (ForeignPtr Word8
p ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
1) String
cs
      in ForeignPtr Word8 -> String -> IO (Int, String)
go ForeignPtr Word8
p0 String
cs0

-- Unpacking bytestrings into lists efficiently is a tradeoff: on the one hand
-- we would like to write a tight loop that just blasts the list into memory, on
-- the other hand we want it to be unpacked lazily so we don't end up with a
-- massive list data structure in memory.
--
-- Our strategy is to combine both: we will unpack lazily in reasonable sized
-- chunks, where each chunk is unpacked strictly.
--
-- unpackBytes and unpackChars do the lazy loop, while unpackAppendBytes and
-- unpackAppendChars do the chunks strictly.

unpackBytes :: ByteString -> [Word8]
unpackBytes :: ByteString -> [Word8]
unpackBytes ByteString
bs = ByteString -> [Word8] -> [Word8]
unpackAppendBytesLazy ByteString
bs []

unpackChars :: ByteString -> [Char]
unpackChars :: ByteString -> String
unpackChars ByteString
bs = ByteString -> ShowS
unpackAppendCharsLazy ByteString
bs []

unpackAppendBytesLazy :: ByteString -> [Word8] -> [Word8]
unpackAppendBytesLazy :: ByteString -> [Word8] -> [Word8]
unpackAppendBytesLazy (BS ForeignPtr Word8
fp Int
len) [Word8]
xs
  | Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
100 = ByteString -> [Word8] -> [Word8]
unpackAppendBytesStrict (ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
fp Int
len) [Word8]
xs
  | Bool
otherwise  = ByteString -> [Word8] -> [Word8]
unpackAppendBytesStrict (ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
fp Int
100) [Word8]
remainder
  where
    remainder :: [Word8]
remainder  = ByteString -> [Word8] -> [Word8]
unpackAppendBytesLazy (ForeignPtr Word8 -> Int -> ByteString
BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
fp Int
100) (Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
100)) [Word8]
xs

  -- Why 100 bytes you ask? Because on a 64bit machine the list we allocate
  -- takes just shy of 4k which seems like a reasonable amount.
  -- (5 words per list element, 8 bytes per word, 100 elements = 4000 bytes)

unpackAppendCharsLazy :: ByteString -> [Char] -> [Char]
unpackAppendCharsLazy :: ByteString -> ShowS
unpackAppendCharsLazy (BS ForeignPtr Word8
fp Int
len) String
cs
  | Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
100 = ByteString -> ShowS
unpackAppendCharsStrict (ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
fp Int
len) String
cs
  | Bool
otherwise  = ByteString -> ShowS
unpackAppendCharsStrict (ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
fp Int
100) String
remainder
  where
    remainder :: String
remainder  = ByteString -> ShowS
unpackAppendCharsLazy (ForeignPtr Word8 -> Int -> ByteString
BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
fp Int
100) (Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
100)) String
cs

-- For these unpack functions, since we're unpacking the whole list strictly we
-- build up the result list in an accumulator. This means we have to build up
-- the list starting at the end. So our traversal starts at the end of the
-- buffer and loops down until we hit the sentinal:

unpackAppendBytesStrict :: ByteString -> [Word8] -> [Word8]
unpackAppendBytesStrict :: ByteString -> [Word8] -> [Word8]
unpackAppendBytesStrict (BS ForeignPtr Word8
fp Int
len) [Word8]
xs =
    IO [Word8] -> [Word8]
forall a. IO a -> a
accursedUnutterablePerformIO (IO [Word8] -> [Word8]) -> IO [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> (Ptr Word8 -> IO [Word8]) -> IO [Word8]
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO [Word8]) -> IO [Word8])
-> (Ptr Word8 -> IO [Word8]) -> IO [Word8]
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
base ->
      Ptr Word8 -> Ptr Word8 -> [Word8] -> IO [Word8]
forall {b}. Storable b => Ptr b -> Ptr b -> [b] -> IO [b]
loop (Ptr Word8
base Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (-Int
1)) (Ptr Word8
base Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (-Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
len)) [Word8]
xs
  where
    loop :: Ptr b -> Ptr b -> [b] -> IO [b]
loop !Ptr b
sentinal !Ptr b
p [b]
acc
      | Ptr b
p Ptr b -> Ptr b -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr b
sentinal = [b] -> IO [b]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [b]
acc
      | Bool
otherwise     = do x <- Ptr b -> IO b
forall a. Storable a => Ptr a -> IO a
peek Ptr b
p
                           loop sentinal (p `plusPtr` (-1)) (x:acc)

unpackAppendCharsStrict :: ByteString -> [Char] -> [Char]
unpackAppendCharsStrict :: ByteString -> ShowS
unpackAppendCharsStrict (BS ForeignPtr Word8
fp Int
len) String
xs =
    IO String -> String
forall a. IO a -> a
accursedUnutterablePerformIO (IO String -> String) -> IO String -> String
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> (Ptr Word8 -> IO String) -> IO String
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO String) -> IO String)
-> (Ptr Word8 -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
base ->
      Ptr Word8 -> Ptr Word8 -> String -> IO String
loop (Ptr Word8
base Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (-Int
1)) (Ptr Word8
base Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (-Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
len)) String
xs
  where
    loop :: Ptr Word8 -> Ptr Word8 -> String -> IO String
loop !Ptr Word8
sentinal !Ptr Word8
p String
acc
      | Ptr Word8
p Ptr Word8 -> Ptr Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr Word8
sentinal = String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
acc
      | Bool
otherwise     = do x <- Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
p
                           loop sentinal (p `plusPtr` (-1)) (w2c x:acc)

------------------------------------------------------------------------

-- | The 0 pointer. Used to indicate the empty Bytestring.
nullForeignPtr :: ForeignPtr Word8
#if HS_cstringLength_AND_FinalPtr_AVAILABLE
nullForeignPtr :: ForeignPtr Word8
nullForeignPtr = Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
nullAddr# ForeignPtrContents
FinalPtr
#else
nullForeignPtr = ForeignPtr nullAddr# (error "nullForeignPtr")
#endif

-- ---------------------------------------------------------------------
-- Low level constructors

-- | /O(1)/ Build a ByteString from a ForeignPtr.
--
-- If you do not need the offset parameter then you should be using
-- 'Data.ByteString.Unsafe.unsafePackCStringLen' or
-- 'Data.ByteString.Unsafe.unsafePackCStringFinalizer' instead.
--
fromForeignPtr :: ForeignPtr Word8
               -> Int -- ^ Offset
               -> Int -- ^ Length
               -> ByteString
fromForeignPtr :: ForeignPtr Word8 -> Int -> Int -> ByteString
fromForeignPtr ForeignPtr Word8
fp Int
o = ForeignPtr Word8 -> Int -> ByteString
BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
fp Int
o)
{-# INLINE fromForeignPtr #-}

-- | @since 0.11.0.0
fromForeignPtr0 :: ForeignPtr Word8
                -> Int -- ^ Length
                -> ByteString
fromForeignPtr0 :: ForeignPtr Word8 -> Int -> ByteString
fromForeignPtr0 = ForeignPtr Word8 -> Int -> ByteString
BS
{-# INLINE fromForeignPtr0 #-}

-- | /O(1)/ Deconstruct a ForeignPtr from a ByteString
toForeignPtr :: ByteString -> (ForeignPtr Word8, Int, Int) -- ^ (ptr, offset, length)
toForeignPtr :: ByteString -> (ForeignPtr Word8, Int, Int)
toForeignPtr (BS ForeignPtr Word8
ps Int
l) = (ForeignPtr Word8
ps, Int
0, Int
l)
{-# INLINE toForeignPtr #-}

-- | /O(1)/ Deconstruct a ForeignPtr from a ByteString
--
-- @since 0.11.0.0
toForeignPtr0 :: ByteString -> (ForeignPtr Word8, Int) -- ^ (ptr, length)
toForeignPtr0 :: ByteString -> (ForeignPtr Word8, Int)
toForeignPtr0 (BS ForeignPtr Word8
ps Int
l) = (ForeignPtr Word8
ps, Int
l)
{-# INLINE toForeignPtr0 #-}

-- | A way of creating ByteStrings outside the IO monad. The @Int@
-- argument gives the final size of the ByteString.
unsafeCreateFp :: Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp :: Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
l ForeignPtr Word8 -> IO ()
f = IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (Int -> (ForeignPtr Word8 -> IO ()) -> IO ByteString
createFp Int
l ForeignPtr Word8 -> IO ()
f)
{-# INLINE unsafeCreateFp #-}

-- | Like 'unsafeCreateFp' but instead of giving the final size of the
-- ByteString, it is just an upper bound. The inner action returns
-- the actual size. Unlike 'createFpAndTrim' the ByteString is not
-- reallocated if the final size is less than the estimated size.
unsafeCreateFpUptoN :: Int -> (ForeignPtr Word8 -> IO Int) -> ByteString
unsafeCreateFpUptoN :: Int -> (ForeignPtr Word8 -> IO Int) -> ByteString
unsafeCreateFpUptoN Int
l ForeignPtr Word8 -> IO Int
f = IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpUptoN Int
l ForeignPtr Word8 -> IO Int
f)
{-# INLINE unsafeCreateFpUptoN #-}

unsafeCreateFpUptoN'
  :: Int -> (ForeignPtr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateFpUptoN' :: forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateFpUptoN' Int
l ForeignPtr Word8 -> IO (Int, a)
f = IO (ByteString, a) -> (ByteString, a)
forall a. IO a -> a
unsafeDupablePerformIO (Int -> (ForeignPtr Word8 -> IO (Int, a)) -> IO (ByteString, a)
forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> IO (ByteString, a)
createFpUptoN' Int
l ForeignPtr Word8 -> IO (Int, a)
f)
{-# INLINE unsafeCreateFpUptoN' #-}

-- | Create ByteString of size @l@ and use action @f@ to fill its contents.
createFp :: Int -> (ForeignPtr Word8 -> IO ()) -> IO ByteString
createFp :: Int -> (ForeignPtr Word8 -> IO ()) -> IO ByteString
createFp Int
len ForeignPtr Word8 -> IO ()
action = Bool -> IO ByteString -> IO ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ do
    fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocByteString Int
len
    action fp
    mkDeferredByteString fp len
{-# INLINE createFp #-}

-- | Given a maximum size @l@ and an action @f@ that fills the 'ByteString'
-- starting at the given 'Ptr' and returns the actual utilized length,
-- @`createFpUptoN'` l f@ returns the filled 'ByteString'.
createFpUptoN :: Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpUptoN :: Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpUptoN Int
maxLen ForeignPtr Word8 -> IO Int
action = Bool -> IO ByteString -> IO ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ do
    fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocByteString Int
maxLen
    len <- action fp
    assert (0 <= len && len <= maxLen) $ mkDeferredByteString fp len
{-# INLINE createFpUptoN #-}

-- | Like 'createFpUptoN', but also returns an additional value created by the
-- action.
createFpUptoN' :: Int -> (ForeignPtr Word8 -> IO (Int, a)) -> IO (ByteString, a)
createFpUptoN' :: forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> IO (ByteString, a)
createFpUptoN' Int
maxLen ForeignPtr Word8 -> IO (Int, a)
action = Bool -> IO (ByteString, a) -> IO (ByteString, a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (IO (ByteString, a) -> IO (ByteString, a))
-> IO (ByteString, a) -> IO (ByteString, a)
forall a b. (a -> b) -> a -> b
$ do
    fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocByteString Int
maxLen
    (len, res) <- action fp
    bs <- mkDeferredByteString fp len
    assert (0 <= len && len <= maxLen) $ pure (bs, res)
{-# INLINE createFpUptoN' #-}

-- | Given the maximum size needed and a function to make the contents
-- of a ByteString, createFpAndTrim makes the 'ByteString'. The generating
-- function is required to return the actual final size (<= the maximum
-- size), and the resulting byte array is reallocated to this size.
--
-- createFpAndTrim is the main mechanism for creating custom, efficient
-- ByteString functions, using Haskell or C functions to fill the space.
--
createFpAndTrim :: Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpAndTrim :: Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpAndTrim Int
maxLen ForeignPtr Word8 -> IO Int
action = Bool -> IO ByteString -> IO ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ do
    fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocByteString Int
maxLen
    len <- action fp
    if assert (0 <= len && len <= maxLen) $ len >= maxLen
        then mkDeferredByteString fp maxLen
        else createFp len $ \ForeignPtr Word8
dest -> ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
dest ForeignPtr Word8
fp Int
len
{-# INLINE createFpAndTrim #-}

createFpAndTrim' :: Int -> (ForeignPtr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)
createFpAndTrim' :: forall a.
Int -> (ForeignPtr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)
createFpAndTrim' Int
maxLen ForeignPtr Word8 -> IO (Int, Int, a)
action = Bool -> IO (ByteString, a) -> IO (ByteString, a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (IO (ByteString, a) -> IO (ByteString, a))
-> IO (ByteString, a) -> IO (ByteString, a)
forall a b. (a -> b) -> a -> b
$ do
    fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocByteString Int
maxLen
    (off, len, res) <- action fp
    assert (
      0 <= len && len <= maxLen && -- length OK
      (len == 0 || (0 <= off && off <= maxLen - len)) -- offset OK
      ) $ pure ()
    bs <- if len >= maxLen
        then mkDeferredByteString fp maxLen -- entire buffer used => offset is zero
        else createFp len $ \ForeignPtr Word8
dest ->
               ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
dest (ForeignPtr Word8
fp ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
off) Int
len
    return (bs, res)
{-# INLINE createFpAndTrim' #-}


wrapAction :: (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction :: forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction = (ForeignPtr Word8 -> (Ptr Word8 -> IO res) -> IO res)
-> (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
forall a b c. (a -> b -> c) -> b -> a -> c
flip ForeignPtr Word8 -> (Ptr Word8 -> IO res) -> IO res
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr
  -- Cannot use unsafeWithForeignPtr, because action can diverge

-- | A way of creating ByteStrings outside the IO monad. The @Int@
-- argument gives the final size of the ByteString.
unsafeCreate :: Int -> (Ptr Word8 -> IO ()) -> ByteString
unsafeCreate :: Int -> (Ptr Word8 -> IO ()) -> ByteString
unsafeCreate Int
l Ptr Word8 -> IO ()
f = Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
l ((Ptr Word8 -> IO ()) -> ForeignPtr Word8 -> IO ()
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO ()
f)
{-# INLINE unsafeCreate #-}

-- | Like 'unsafeCreate' but instead of giving the final size of the
-- ByteString, it is just an upper bound. The inner action returns
-- the actual size. Unlike 'createAndTrim' the ByteString is not
-- reallocated if the final size is less than the estimated size.
unsafeCreateUptoN :: Int -> (Ptr Word8 -> IO Int) -> ByteString
unsafeCreateUptoN :: Int -> (Ptr Word8 -> IO Int) -> ByteString
unsafeCreateUptoN Int
l Ptr Word8 -> IO Int
f = Int -> (ForeignPtr Word8 -> IO Int) -> ByteString
unsafeCreateFpUptoN Int
l ((Ptr Word8 -> IO Int) -> ForeignPtr Word8 -> IO Int
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO Int
f)
{-# INLINE unsafeCreateUptoN #-}

-- | @since 0.10.12.0
unsafeCreateUptoN' :: Int -> (Ptr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateUptoN' :: forall a. Int -> (Ptr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateUptoN' Int
l Ptr Word8 -> IO (Int, a)
f = Int -> (ForeignPtr Word8 -> IO (Int, a)) -> (ByteString, a)
forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> (ByteString, a)
unsafeCreateFpUptoN' Int
l ((Ptr Word8 -> IO (Int, a)) -> ForeignPtr Word8 -> IO (Int, a)
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO (Int, a)
f)
{-# INLINE unsafeCreateUptoN' #-}

-- | Create ByteString of size @l@ and use action @f@ to fill its contents.
create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
create Int
l Ptr Word8 -> IO ()
action = Int -> (ForeignPtr Word8 -> IO ()) -> IO ByteString
createFp Int
l ((Ptr Word8 -> IO ()) -> ForeignPtr Word8 -> IO ()
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO ()
action)
{-# INLINE create #-}

-- | Given a maximum size @l@ and an action @f@ that fills the 'ByteString'
-- starting at the given 'Ptr' and returns the actual utilized length,
-- @`createUptoN'` l f@ returns the filled 'ByteString'.
createUptoN :: Int -> (Ptr Word8 -> IO Int) -> IO ByteString
createUptoN :: Int -> (Ptr Word8 -> IO Int) -> IO ByteString
createUptoN Int
l Ptr Word8 -> IO Int
action = Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpUptoN Int
l ((Ptr Word8 -> IO Int) -> ForeignPtr Word8 -> IO Int
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO Int
action)
{-# INLINE createUptoN #-}

-- | Like 'createUptoN', but also returns an additional value created by the
-- action.
--
-- @since 0.10.12.0
createUptoN' :: Int -> (Ptr Word8 -> IO (Int, a)) -> IO (ByteString, a)
createUptoN' :: forall a. Int -> (Ptr Word8 -> IO (Int, a)) -> IO (ByteString, a)
createUptoN' Int
l Ptr Word8 -> IO (Int, a)
action = Int -> (ForeignPtr Word8 -> IO (Int, a)) -> IO (ByteString, a)
forall a.
Int -> (ForeignPtr Word8 -> IO (Int, a)) -> IO (ByteString, a)
createFpUptoN' Int
l ((Ptr Word8 -> IO (Int, a)) -> ForeignPtr Word8 -> IO (Int, a)
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO (Int, a)
action)
{-# INLINE createUptoN' #-}

-- | Given the maximum size needed and a function to make the contents
-- of a ByteString, createAndTrim makes the 'ByteString'. The generating
-- function is required to return the actual final size (<= the maximum
-- size), and the resulting byte array is reallocated to this size.
--
-- createAndTrim is the main mechanism for creating custom, efficient
-- ByteString functions, using Haskell or C functions to fill the space.
--
createAndTrim :: Int -> (Ptr Word8 -> IO Int) -> IO ByteString
createAndTrim :: Int -> (Ptr Word8 -> IO Int) -> IO ByteString
createAndTrim Int
l Ptr Word8 -> IO Int
action = Int -> (ForeignPtr Word8 -> IO Int) -> IO ByteString
createFpAndTrim Int
l ((Ptr Word8 -> IO Int) -> ForeignPtr Word8 -> IO Int
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO Int
action)
{-# INLINE createAndTrim #-}

createAndTrim' :: Int -> (Ptr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)
createAndTrim' :: forall a.
Int -> (Ptr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)
createAndTrim' Int
l Ptr Word8 -> IO (Int, Int, a)
action = Int -> (ForeignPtr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)
forall a.
Int -> (ForeignPtr Word8 -> IO (Int, Int, a)) -> IO (ByteString, a)
createFpAndTrim' Int
l ((Ptr Word8 -> IO (Int, Int, a))
-> ForeignPtr Word8 -> IO (Int, Int, a)
forall res. (Ptr Word8 -> IO res) -> ForeignPtr Word8 -> IO res
wrapAction Ptr Word8 -> IO (Int, Int, a)
action)
{-# INLINE createAndTrim' #-}


-- | Wrapper of 'Foreign.ForeignPtr.mallocForeignPtrBytes' with faster implementation for GHC
--
mallocByteString :: Int -> IO (ForeignPtr a)
mallocByteString :: forall a. Int -> IO (ForeignPtr a)
mallocByteString = Int -> IO (ForeignPtr a)
forall a. Int -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes
{-# INLINE mallocByteString #-}

------------------------------------------------------------------------
-- Implementations for Eq, Ord and Monoid instances

eq :: ByteString -> ByteString -> Bool
eq :: ByteString -> ByteString -> Bool
eq a :: ByteString
a@(BS ForeignPtr Word8
fp Int
len) b :: ByteString
b@(BS ForeignPtr Word8
fp' Int
len')
  | Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
len' = Bool
False    -- short cut on length
  | ForeignPtr Word8
fp ForeignPtr Word8 -> ForeignPtr Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== ForeignPtr Word8
fp'   = Bool
True     -- short cut for the same string
  | Bool
otherwise   = ByteString -> ByteString -> Ordering
compareBytes ByteString
a ByteString
b Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ
{-# INLINE eq #-}
-- ^ still needed

compareBytes :: ByteString -> ByteString -> Ordering
compareBytes :: ByteString -> ByteString -> Ordering
compareBytes (BS ForeignPtr Word8
_   Int
0)    (BS ForeignPtr Word8
_   Int
0)    = Ordering
EQ  -- short cut for empty strings
compareBytes (BS ForeignPtr Word8
fp1 Int
len1) (BS ForeignPtr Word8
fp2 Int
len2) =
    IO Ordering -> Ordering
forall a. IO a -> a
accursedUnutterablePerformIO (IO Ordering -> Ordering) -> IO Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$
      ForeignPtr Word8 -> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp1 ((Ptr Word8 -> IO Ordering) -> IO Ordering)
-> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p1 ->
      ForeignPtr Word8 -> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp2 ((Ptr Word8 -> IO Ordering) -> IO Ordering)
-> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p2 -> do
        i <- Ptr Word8 -> Ptr Word8 -> Int -> IO CInt
memcmp Ptr Word8
p1 Ptr Word8
p2 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
len1 Int
len2)
        return $! case i `compare` 0 of
                    Ordering
EQ  -> Int
len1 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Int
len2
                    Ordering
x   -> Ordering
x


-- | /O(1)/ The empty 'ByteString'
empty :: ByteString
-- This enables bypassing #457 by not using (polymorphic) mempty in
-- any definitions used by the (Monoid ByteString) instance
empty :: ByteString
empty = ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
nullForeignPtr Int
0

append :: ByteString -> ByteString -> ByteString
append :: ByteString -> ByteString -> ByteString
append (BS ForeignPtr Word8
_   Int
0)    ByteString
b                  = ByteString
b
append ByteString
a             (BS ForeignPtr Word8
_   Int
0)    = ByteString
a
append (BS ForeignPtr Word8
fp1 Int
len1) (BS ForeignPtr Word8
fp2 Int
len2) =
    Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp (String -> Int -> Int -> Int
checkedAdd String
"append" Int
len1 Int
len2) ((ForeignPtr Word8 -> IO ()) -> ByteString)
-> (ForeignPtr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
destptr1 -> do
      let destptr2 :: ForeignPtr Word8
destptr2 = ForeignPtr Word8
destptr1 ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
len1
      ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
destptr1 ForeignPtr Word8
fp1 Int
len1
      ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
destptr2 ForeignPtr Word8
fp2 Int
len2

concat :: [ByteString] -> ByteString
concat :: [ByteString] -> ByteString
concat = \[ByteString]
bss0 -> [ByteString] -> [ByteString] -> ByteString
goLen0 [ByteString]
bss0 [ByteString]
bss0
    -- The idea here is we first do a pass over the input list to determine:
    --
    --  1. is a copy necessary? e.g. @concat []@, @concat [mempty, "hello"]@,
    --     and @concat ["hello", mempty, mempty]@ can all be handled without
    --     copying.
    --  2. if a copy is necessary, how large is the result going to be?
    --
    -- If a copy is necessary then we create a buffer of the appropriate size
    -- and do another pass over the input list, copying the chunks into the
    -- buffer. Also, since foreign calls aren't entirely free we skip over
    -- empty chunks while copying.
    --
    -- We pass the original [ByteString] (bss0) through as an argument through
    -- goLen0, goLen1, and goLen since we will need it again in goCopy. Passing
    -- it as an explicit argument avoids capturing it in these functions'
    -- closures which would result in unnecessary closure allocation.
  where
    -- It's still possible that the result is empty
    goLen0 :: [ByteString] -> [ByteString] -> ByteString
goLen0 [ByteString]
_    []                     = ByteString
empty
    goLen0 [ByteString]
bss0 (BS ForeignPtr Word8
_ Int
0     :[ByteString]
bss)    = [ByteString] -> [ByteString] -> ByteString
goLen0 [ByteString]
bss0 [ByteString]
bss
    goLen0 [ByteString]
bss0 (ByteString
bs           :[ByteString]
bss)    = [ByteString] -> ByteString -> [ByteString] -> ByteString
goLen1 [ByteString]
bss0 ByteString
bs [ByteString]
bss

    -- It's still possible that the result is a single chunk
    goLen1 :: [ByteString] -> ByteString -> [ByteString] -> ByteString
goLen1 [ByteString]
_    ByteString
bs []                  = ByteString
bs
    goLen1 [ByteString]
bss0 ByteString
bs (BS ForeignPtr Word8
_ Int
0  :[ByteString]
bss)    = [ByteString] -> ByteString -> [ByteString] -> ByteString
goLen1 [ByteString]
bss0 ByteString
bs [ByteString]
bss
    goLen1 [ByteString]
bss0 ByteString
bs (BS ForeignPtr Word8
_ Int
len:[ByteString]
bss)    = [ByteString] -> Int -> [ByteString] -> ByteString
goLen [ByteString]
bss0 (String -> Int -> Int -> Int
checkedAdd String
"concat" Int
len' Int
len) [ByteString]
bss
      where BS ForeignPtr Word8
_ Int
len' = ByteString
bs

    -- General case, just find the total length we'll need
    goLen :: [ByteString] -> Int -> [ByteString] -> ByteString
goLen [ByteString]
bss0 !Int
total (BS ForeignPtr Word8
_ Int
len:[ByteString]
bss) = [ByteString] -> Int -> [ByteString] -> ByteString
goLen [ByteString]
bss0 Int
total' [ByteString]
bss
      where total' :: Int
total' = String -> Int -> Int -> Int
checkedAdd String
"concat" Int
total Int
len
    goLen [ByteString]
bss0 Int
total [] =
      Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
total ((ForeignPtr Word8 -> IO ()) -> ByteString)
-> (ForeignPtr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
ptr -> [ByteString] -> ForeignPtr Word8 -> IO ()
goCopy [ByteString]
bss0 ForeignPtr Word8
ptr

    -- Copy the data
    goCopy :: [ByteString] -> ForeignPtr Word8 -> IO ()
goCopy []                  !ForeignPtr Word8
_   = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    goCopy (BS ForeignPtr Word8
_  Int
0  :[ByteString]
bss) !ForeignPtr Word8
ptr = [ByteString] -> ForeignPtr Word8 -> IO ()
goCopy [ByteString]
bss ForeignPtr Word8
ptr
    goCopy (BS ForeignPtr Word8
fp Int
len:[ByteString]
bss) !ForeignPtr Word8
ptr = do
      ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
ptr ForeignPtr Word8
fp Int
len
      [ByteString] -> ForeignPtr Word8 -> IO ()
goCopy [ByteString]
bss (ForeignPtr Word8
ptr ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
len)
{-# NOINLINE concat #-}

{-# RULES
"ByteString concat [] -> empty"
   concat [] = empty
"ByteString concat [bs] -> bs" forall x.
   concat [x] = x
 #-}

-- | Repeats the given ByteString n times.
-- Polymorphic wrapper to make sure any generated
-- specializations are reasonably small.
stimesPolymorphic :: Integral a => a -> ByteString -> ByteString
{-# INLINABLE stimesPolymorphic #-}
stimesPolymorphic :: forall b. Integral b => b -> ByteString -> ByteString
stimesPolymorphic a
nRaw !ByteString
bs = case Integer -> Maybe Int
checkedIntegerToInt Integer
n of
  Just Int
nInt
    | Int
nInt Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0  -> Int -> ByteString -> ByteString
stimesNonNegativeInt Int
nInt ByteString
bs
    | Bool
otherwise  -> ByteString
stimesNegativeErr
  Maybe Int
Nothing
    | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0  -> ByteString
stimesNegativeErr
    | BS ForeignPtr Word8
_ Int
0 <- ByteString
bs  -> ByteString
empty
    | Bool
otherwise     -> ByteString
stimesOverflowErr
  where  n :: Integer
n = a -> Integer
forall a. Integral a => a -> Integer
toInteger a
nRaw
  -- By exclusively using n instead of nRaw, the semantics are kept simple
  -- and the likelihood of potentially dangerous mistakes minimized.


{-
Note [Float error calls out of INLINABLE things]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If a function is marked INLINE or INLINABLE, then when ghc inlines or
specializes it, it duplicates the function body exactly as written.

This feature is useful for systems of rewrite rules, but sometimes
comes at a code-size cost.  One situation where this cost generally
comes with no compensating up-side is when the function in question
calls `error` or something similar.

Such an `error` call is not meaningfully improved by the extra context
inlining or specialization provides, and if inlining or specialization
happens in a different module from where the function was originally
defined, CSE will not be able to de-duplicate the error call floated
out of the inlined RHS and the error call floated out of the original
RHS.  See also https://gitlab.haskell.org/ghc/ghc/-/issues/23823

To mitigate this, we manually float the error calls out of INLINABLE
functions when it is possible to do so.
-}

stimesNegativeErr :: ByteString
-- See Note [Float error calls out of INLINABLE things]
stimesNegativeErr :: ByteString
stimesNegativeErr
  = String -> ByteString
forall a. String -> a
errorWithoutStackTrace String
"stimes @ByteString: non-negative multiplier expected"

stimesOverflowErr :: ByteString
-- See Note [Float error calls out of INLINABLE things]
stimesOverflowErr :: ByteString
stimesOverflowErr = String -> ByteString
forall a. String -> a
overflowError String
"stimes"

-- | Repeats the given ByteString n times.
stimesNonNegativeInt :: Int -> ByteString -> ByteString
stimesNonNegativeInt :: Int -> ByteString -> ByteString
stimesNonNegativeInt Int
n (BS ForeignPtr Word8
fp Int
len)
  | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ByteString
empty
  | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
fp Int
len
  | Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ByteString
empty
  | Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
n ((ForeignPtr Word8 -> IO ()) -> ByteString)
-> (ForeignPtr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
destfptr -> do
      byte <- ForeignPtr Word8 -> IO Word8
forall a. Storable a => ForeignPtr a -> IO a
peekFp ForeignPtr Word8
fp
      unsafeWithForeignPtr destfptr $ \Ptr Word8
destptr ->
        Ptr Word8 -> Word8 -> Int -> IO ()
forall a. Ptr a -> Word8 -> Int -> IO ()
fillBytes Ptr Word8
destptr Word8
byte Int
n
  | Bool
otherwise = Int -> (ForeignPtr Word8 -> IO ()) -> ByteString
unsafeCreateFp Int
size ((ForeignPtr Word8 -> IO ()) -> ByteString)
-> (ForeignPtr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
destptr -> do
      ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
destptr ForeignPtr Word8
fp Int
len
      ForeignPtr Word8 -> Int -> IO ()
fillFrom ForeignPtr Word8
destptr Int
len
  where
    size :: Int
size = String -> Int -> Int -> Int
checkedMultiply String
"stimes" Int
n Int
len
    halfSize :: Int
halfSize = (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2 -- subtraction and division won't overflow

    fillFrom :: ForeignPtr Word8 -> Int -> IO ()
    fillFrom :: ForeignPtr Word8 -> Int -> IO ()
fillFrom ForeignPtr Word8
destptr Int
copied
      | Int
copied Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
halfSize = do
        ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp (ForeignPtr Word8
destptr ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
copied) ForeignPtr Word8
destptr Int
copied
        ForeignPtr Word8 -> Int -> IO ()
fillFrom ForeignPtr Word8
destptr (Int
copied Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)
      | Bool
otherwise = ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp (ForeignPtr Word8
destptr ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` Int
copied) ForeignPtr Word8
destptr (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
copied)


------------------------------------------------------------------------

-- | Conversion between 'Word8' and 'Char'. Should compile to a no-op.
w2c :: Word8 -> Char
w2c :: Word8 -> Char
w2c = Int -> Char
unsafeChr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE w2c #-}

-- | Unsafe conversion between 'Char' and 'Word8'. This is a no-op and
-- silently truncates to 8 bits Chars > '\255'. It is provided as
-- convenience for ByteString construction.
c2w :: Char -> Word8
c2w :: Char -> Word8
c2w = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> (Char -> Int) -> Char -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord
{-# INLINE c2w #-}

-- | Selects words corresponding to white-space characters in the Latin-1 range
isSpaceWord8 :: Word8 -> Bool
isSpaceWord8 :: Word8 -> Bool
isSpaceWord8 Word8
w8 =
    -- Avoid the cost of narrowing arithmetic results to Word8,
    -- the conversion from Word8 to Word is free.
    let w :: Word
        !w :: Word
w = Word8 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w8
     in Word
w Word -> Word -> Word
forall a. Bits a => a -> a -> a
.&. Word
0x50 Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0    -- Quick non-whitespace filter
        Bool -> Bool -> Bool
&& Word
w Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
0x21 Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
> Word
0x7e -- Second non-whitespace filter
        Bool -> Bool -> Bool
&& ( Word
w Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0x20     -- SP
          Bool -> Bool -> Bool
|| Word
w Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0xa0     -- NBSP
          Bool -> Bool -> Bool
|| Word
w Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
0x09 Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
5) -- HT, NL, VT, FF, CR
{-# INLINE isSpaceWord8 #-}

-- | Selects white-space characters in the Latin-1 range
isSpaceChar8 :: Char -> Bool
isSpaceChar8 :: Char -> Bool
isSpaceChar8 = Word8 -> Bool
isSpaceWord8 (Word8 -> Bool) -> (Char -> Word8) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Word8
c2w
{-# INLINE isSpaceChar8 #-}

------------------------------------------------------------------------

-- | The type of exception raised by 'overflowError'
-- and on failure by overflow-checked arithmetic operations.
newtype SizeOverflowException
  = SizeOverflowException String

instance Show SizeOverflowException where
  show :: SizeOverflowException -> String
show (SizeOverflowException String
err) = String
err

instance Exception SizeOverflowException

-- | Raises a 'SizeOverflowException',
-- with a message using the given function name.
overflowError :: String -> a
overflowError :: forall a. String -> a
overflowError String
fun = SizeOverflowException -> a
forall a e. (?callStack::CallStack, Exception e) => e -> a
throw (SizeOverflowException -> a) -> SizeOverflowException -> a
forall a b. (a -> b) -> a -> b
$ String -> SizeOverflowException
SizeOverflowException String
msg
  where msg :: String
msg = String
"Data.ByteString." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
fun String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": size overflow"

-- | Add two non-negative numbers.
-- Calls 'overflowError' on overflow.
checkedAdd :: String -> Int -> Int -> Int
{-# INLINE checkedAdd #-}
checkedAdd :: String -> Int -> Int -> Int
checkedAdd String
fun Int
x Int
y
  -- checking "r < 0" here matches the condition in mallocPlainForeignPtrBytes,
  -- helping the compiler see the latter is redundant in some places
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0     = String -> Int
forall a. String -> a
overflowError String
fun
  | Bool
otherwise = Int
r
  where r :: Int
r = Bool -> Int -> Int
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
x Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y

-- | Multiplies two non-negative numbers.
-- Calls 'overflowError' on overflow.
checkedMultiply :: String -> Int -> Int -> Int
{-# INLINE checkedMultiply #-}
checkedMultiply :: String -> Int -> Int -> Int
checkedMultiply String
fun !x :: Int
x@(I# Int#
x#) !y :: Int
y@(I# Int#
y#) = Bool -> Int -> Int
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
x Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$
#if HS_timesInt2_PRIMOP_AVAILABLE
  case Int# -> Int# -> (# Int#, Int#, Int# #)
timesInt2# Int#
x# Int#
y# of
    (# Int#
0#, Int#
_, Int#
result #) -> Int# -> Int
I# Int#
result
    (# Int#, Int#, Int# #)
_ -> String -> Int
forall a. String -> a
overflowError String
fun
#else
  case timesWord2# (int2Word# x#) (int2Word# y#) of
    (# hi, lo #) -> case or# hi (uncheckedShiftRL# lo shiftAmt) of
      0## -> I# (word2Int# lo)
      _   -> overflowError fun
  where !(I# shiftAmt) = finiteBitSize (0 :: Word) - 1
#endif


-- | Attempts to convert an 'Integer' value to an 'Int', returning
-- 'Nothing' if doing so would result in an overflow.
checkedIntegerToInt :: Integer -> Maybe Int
{-# INLINE checkedIntegerToInt #-}
-- We could use Data.Bits.toIntegralSized, but this hand-rolled
-- version is currently a bit faster as of GHC 9.2.
-- It's even faster to just match on the Integer constructors, but
-- we'd still need a fallback implementation for integer-simple.
checkedIntegerToInt :: Integer -> Maybe Int
checkedIntegerToInt Integer
x
  | Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
res = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
res
  | Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
  where  res :: Int
res = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
x :: Int


------------------------------------------------------------------------

-- | This \"function\" has a superficial similarity to 'System.IO.Unsafe.unsafePerformIO' but
-- it is in fact a malevolent agent of chaos. It unpicks the seams of reality
-- (and the 'IO' monad) so that the normal rules no longer apply. It lulls you
-- into thinking it is reasonable, but when you are not looking it stabs you
-- in the back and aliases all of your mutable buffers. The carcass of many a
-- seasoned Haskell programmer lie strewn at its feet.
--
-- Witness the trail of destruction:
--
-- * <https://github.com/haskell/bytestring/commit/71c4b438c675aa360c79d79acc9a491e7bbc26e7>
--
-- * <https://github.com/haskell/bytestring/commit/210c656390ae617d9ee3b8bcff5c88dd17cef8da>
--
-- * <https://github.com/haskell/aeson/commit/720b857e2e0acf2edc4f5512f2b217a89449a89d>
--
-- * <https://ghc.haskell.org/trac/ghc/ticket/3486>
--
-- * <https://ghc.haskell.org/trac/ghc/ticket/3487>
--
-- * <https://ghc.haskell.org/trac/ghc/ticket/7270>
--
-- * <https://gitlab.haskell.org/ghc/ghc/-/issues/22204>
--
-- Do not talk about \"safe\"! You do not know what is safe!
--
-- Yield not to its blasphemous call! Flee traveller! Flee or you will be
-- corrupted and devoured!
--
{-# INLINE accursedUnutterablePerformIO #-}
accursedUnutterablePerformIO :: IO a -> a
accursedUnutterablePerformIO :: forall a. IO a -> a
accursedUnutterablePerformIO (IO State# RealWorld -> (# State# RealWorld, a #)
m) = case State# RealWorld -> (# State# RealWorld, a #)
m State# RealWorld
realWorld# of (# State# RealWorld
_, a
r #) -> a
r

-- ---------------------------------------------------------------------
--
-- Standard C functions
--

memchr :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)
memcmp :: Ptr Word8 -> Ptr Word8 -> Int -> IO CInt
{-# DEPRECATED memset "Use Foreign.Marshal.Utils.fillBytes instead" #-}
-- | deprecated since @bytestring-0.11.5.0@
memset :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)

#if !PURE_HASKELL

foreign import ccall unsafe "string.h strlen" c_strlen
    :: CString -> IO CSize

foreign import ccall unsafe "string.h memchr" c_memchr
    :: Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)
memchr :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)
memchr Ptr Word8
p Word8
w CSize
sz = Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)
c_memchr Ptr Word8
p (Word8 -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w) CSize
sz

foreign import ccall unsafe "string.h memcmp" c_memcmp
    :: Ptr Word8 -> Ptr Word8 -> CSize -> IO CInt
memcmp :: Ptr Word8 -> Ptr Word8 -> Int -> IO CInt
memcmp Ptr Word8
p Ptr Word8
q Int
s = Ptr Word8 -> Ptr Word8 -> CSize -> IO CInt
c_memcmp Ptr Word8
p Ptr Word8
q (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)

foreign import ccall unsafe "string.h memset" c_memset
    :: Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)
memset :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)
memset Ptr Word8
p Word8
w CSize
sz = Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)
c_memset Ptr Word8
p (Word8 -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w) CSize
sz

#else

c_strlen :: CString -> IO CSize
c_strlen p = checkedCast <$!> Pure.strlen (castPtr p)

memchr p w len = Pure.memchr p w (checkedCast len)

memcmp p q s = checkedCast <$!> Pure.memcmp p q s

memset p w len = p <$ fillBytes p w (checkedCast len)

#endif

{-# DEPRECATED memcpy "Use Foreign.Marshal.Utils.copyBytes instead" #-}
-- | deprecated since @bytestring-0.11.5.0@
memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
memcpy = Ptr Word8 -> Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes

memcpyFp :: ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp :: ForeignPtr Word8 -> ForeignPtr Word8 -> Int -> IO ()
memcpyFp ForeignPtr Word8
fp ForeignPtr Word8
fq Int
s = ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p ->
                     ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fq ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
q -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr Word8
p Ptr Word8
q Int
s

c_free_finalizer :: FunPtr (Ptr Word8 -> IO ())
c_free_finalizer :: FunPtr (Ptr Word8 -> IO ())
c_free_finalizer = FunPtr (Ptr Word8 -> IO ())
forall a. FinalizerPtr a
finalizerFree



-- ---------------------------------------------------------------------
--
-- Uses our C code
--

#if !PURE_HASKELL

foreign import ccall unsafe "static fpstring.h fps_reverse" c_reverse
    :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()

foreign import ccall unsafe "static fpstring.h fps_intersperse" c_intersperse
    :: Ptr Word8 -> Ptr Word8 -> CSize -> Word8 -> IO ()

foreign import ccall unsafe "static fpstring.h fps_maximum" c_maximum
    :: Ptr Word8 -> CSize -> IO Word8

foreign import ccall unsafe "static fpstring.h fps_minimum" c_minimum
    :: Ptr Word8 -> CSize -> IO Word8

foreign import ccall unsafe "static fpstring.h fps_count" c_count
    :: Ptr Word8 -> CSize -> Word8 -> IO CSize

-- fps_count works with both pointers and ByteArray#
foreign import ccall unsafe "static fpstring.h fps_count" c_count_ba
    :: ByteArray# -> CSize -> Word8 -> IO CSize

foreign import ccall unsafe "static fpstring.h fps_sort" c_sort
    :: Ptr Word8 -> CSize -> IO ()

foreign import ccall unsafe "static sbs_elem_index"
    c_elem_index :: ByteArray# -> Word8 -> CSize -> IO CPtrdiff



foreign import ccall unsafe "static _hs_bytestring_uint_dec" c_uint_dec
    :: CUInt -> Ptr Word8 -> IO (Ptr Word8)

foreign import ccall unsafe "static _hs_bytestring_long_long_uint_dec" c_long_long_uint_dec
    :: CULLong -> Ptr Word8 -> IO (Ptr Word8)

foreign import ccall unsafe "static _hs_bytestring_int_dec" c_int_dec
    :: CInt -> Ptr Word8 -> IO (Ptr Word8)

foreign import ccall unsafe "static _hs_bytestring_long_long_int_dec" c_long_long_int_dec
    :: CLLong -> Ptr Word8 -> IO (Ptr Word8)

foreign import ccall unsafe "static _hs_bytestring_uint_hex" c_uint_hex
    :: CUInt -> Ptr Word8 -> IO (Ptr Word8)

foreign import ccall unsafe "static _hs_bytestring_long_long_uint_hex" c_long_long_uint_hex
    :: CULLong -> Ptr Word8 -> IO (Ptr Word8)

foreign import ccall unsafe "static _hs_bytestring_int_dec_padded9"
    c_int_dec_padded9 :: CInt -> Ptr Word8 -> IO ()

foreign import ccall unsafe "static _hs_bytestring_long_long_int_dec_padded18"
    c_long_long_int_dec_padded18 :: CLLong -> Ptr Word8 -> IO ()

-- We import bytestring_is_valid_utf8 both unsafe and safe. For small inputs
-- we can use the unsafe version to get a bit more performance, but for large
-- inputs the safe version should be used to avoid GC synchronization pauses
-- in multithreaded contexts.

foreign import ccall unsafe "bytestring_is_valid_utf8" cIsValidUtf8BA
  :: ByteArray# -> CSize -> IO CInt

foreign import ccall safe "bytestring_is_valid_utf8" cIsValidUtf8BASafe
  :: ByteArray# -> CSize -> IO CInt

foreign import ccall unsafe "bytestring_is_valid_utf8" cIsValidUtf8
  :: Ptr Word8 -> CSize -> IO CInt

foreign import ccall safe "bytestring_is_valid_utf8" cIsValidUtf8Safe
  :: Ptr Word8 -> CSize -> IO CInt


#else

----------------------------------------------------------------
-- Haskell version of functions in fpstring.c
----------------------------------------------------------------

-- | Reverse n-bytes from the second pointer into the first
c_reverse :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()
c_reverse p1 p2 sz = Pure.reverseBytes p1 p2 (checkedCast sz)

-- | find maximum char in a packed string
c_maximum :: Ptr Word8 -> CSize -> IO Word8
c_maximum ptr sz = Pure.findMaximum ptr (checkedCast sz)

-- | find minimum char in a packed string
c_minimum :: Ptr Word8 -> CSize -> IO Word8
c_minimum ptr sz = Pure.findMinimum ptr (checkedCast sz)

-- | count the number of occurrences of a char in a string
c_count :: Ptr Word8 -> CSize -> Word8 -> IO CSize
c_count ptr sz c = checkedCast <$!> Pure.countOcc ptr (checkedCast sz) c

-- | count the number of occurrences of a char in a string
c_count_ba :: ByteArray# -> Int -> Word8 -> IO CSize
c_count_ba ba o c = checkedCast <$!> Pure.countOccBA ba o c

-- | duplicate a string, interspersing the character through the elements of the
-- duplicated string
c_intersperse :: Ptr Word8 -> Ptr Word8 -> CSize -> Word8 -> IO ()
c_intersperse p1 p2 sz e = Pure.intersperse p1 p2 (checkedCast sz) e

-- | Quick sort bytes
c_sort :: Ptr Word8 -> CSize -> IO ()
c_sort ptr sz = Pure.quickSort ptr (checkedCast sz)

c_elem_index :: ByteArray# -> Word8 -> CSize -> IO CPtrdiff
c_elem_index ba e sz = checkedCast <$!> Pure.elemIndex ba e (checkedCast sz)

cIsValidUtf8BA :: ByteArray# -> CSize -> IO CInt
cIsValidUtf8BA ba sz = bool_to_cint <$> Pure.isValidUtf8BA ba (checkedCast sz)

cIsValidUtf8 :: Ptr Word8 -> CSize -> IO CInt
cIsValidUtf8 ptr sz = bool_to_cint <$> Pure.isValidUtf8 ptr (checkedCast sz)

-- Pure module is compiled with `-fno-omit-yields` so it's always safe (it won't
-- block on large inputs)

cIsValidUtf8BASafe :: ByteArray# -> CSize -> IO CInt
cIsValidUtf8BASafe = cIsValidUtf8BA

cIsValidUtf8Safe :: Ptr Word8 -> CSize -> IO CInt
cIsValidUtf8Safe = cIsValidUtf8

bool_to_cint :: Bool -> CInt
bool_to_cint True = 1
bool_to_cint False = 0

checkedCast :: (Bits a, Bits b, Integral a, Integral b) => a -> b
checkedCast x =
  fromMaybe (errorWithoutStackTrace "checkedCast: overflow")
            (toIntegralSized x)

----------------------------------------------------------------
-- Haskell version of functions in itoa.c
----------------------------------------------------------------

c_int_dec :: CInt -> Ptr Word8 -> IO (Ptr Word8)
c_int_dec = Pure.encodeSignedDec

c_long_long_int_dec :: CLLong -> Ptr Word8 -> IO (Ptr Word8)
c_long_long_int_dec = Pure.encodeSignedDec

c_uint_dec :: CUInt -> Ptr Word8 -> IO (Ptr Word8)
c_uint_dec = Pure.encodeUnsignedDec

c_long_long_uint_dec :: CULLong -> Ptr Word8 -> IO (Ptr Word8)
c_long_long_uint_dec = Pure.encodeUnsignedDec

c_uint_hex :: CUInt -> Ptr Word8 -> IO (Ptr Word8)
c_uint_hex = Pure.encodeUnsignedHex

c_long_long_uint_hex :: CULLong -> Ptr Word8 -> IO (Ptr Word8)
c_long_long_uint_hex = Pure.encodeUnsignedHex

c_int_dec_padded9 :: CInt -> Ptr Word8 -> IO ()
c_int_dec_padded9 = Pure.encodeUnsignedDecPadded 9

c_long_long_int_dec_padded18 :: CLLong -> Ptr Word8 -> IO ()
c_long_long_int_dec_padded18 = Pure.encodeUnsignedDecPadded 18

#endif