{-# LANGUAGE MagicHash #-}
{-# LANGUAGE Unsafe #-}
module Data.ByteString.Unsafe (
unsafeHead,
unsafeTail,
unsafeInit,
unsafeLast,
unsafeIndex,
unsafeTake,
unsafeDrop,
unsafeUseAsCString,
unsafeUseAsCStringLen,
unsafePackCString,
unsafePackCStringLen,
unsafePackMallocCString,
unsafePackMallocCStringLen,
unsafePackAddress,
unsafePackAddressLen,
unsafePackCStringFinalizer,
unsafeFinalize,
) where
import Data.ByteString.Internal
import Foreign.ForeignPtr (newForeignPtr_, newForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr, castPtr)
import Foreign.Storable (Storable(..))
import Foreign.C.String (CString, CStringLen)
import Control.Exception (assert)
import Data.Word (Word8)
import qualified Foreign.ForeignPtr as FC (finalizeForeignPtr)
import qualified Foreign.Concurrent as FC (newForeignPtr)
import GHC.Prim (Addr#)
import GHC.Ptr (Ptr(..))
unsafeHead :: ByteString -> Word8
unsafeHead :: ByteString -> Word8
unsafeHead (BS ForeignPtr Word8
x Int
l) = Bool -> Word8 -> Word8
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$
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
x ((Ptr Word8 -> IO Word8) -> IO Word8)
-> (Ptr Word8 -> IO Word8) -> IO Word8
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
p
{-# INLINE unsafeHead #-}
unsafeTail :: ByteString -> ByteString
unsafeTail :: ByteString -> ByteString
unsafeTail (BS ForeignPtr Word8
ps Int
l) = Bool -> ByteString -> ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Int -> ByteString
BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
ps Int
1) (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
{-# INLINE unsafeTail #-}
unsafeInit :: ByteString -> ByteString
unsafeInit :: ByteString -> ByteString
unsafeInit (BS ForeignPtr Word8
ps Int
l) = Bool -> ByteString -> ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
ps (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
{-# INLINE unsafeInit #-}
unsafeLast :: ByteString -> Word8
unsafeLast :: ByteString -> Word8
unsafeLast (BS ForeignPtr Word8
x Int
l) = Bool -> Word8 -> Word8
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$
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
x ((Ptr Word8 -> IO Word8) -> IO Word8)
-> (Ptr Word8 -> IO Word8) -> IO Word8
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> Ptr Word8 -> Int -> IO Word8
forall b. Ptr b -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
p (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
{-# INLINE unsafeLast #-}
unsafeIndex :: ByteString -> Int -> Word8
unsafeIndex :: ByteString -> Int -> Word8
unsafeIndex (BS ForeignPtr Word8
x Int
l) Int
i = Bool -> Word8 -> Word8
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l) (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$
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
x ((Ptr Word8 -> IO Word8) -> IO Word8)
-> (Ptr Word8 -> IO Word8) -> IO Word8
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> Ptr Word8 -> Int -> IO Word8
forall b. Ptr b -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
p Int
i
{-# INLINE unsafeIndex #-}
unsafeTake :: Int -> ByteString -> ByteString
unsafeTake :: Int -> ByteString -> ByteString
unsafeTake Int
n (BS ForeignPtr Word8
x Int
l) = Bool -> ByteString -> ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Int -> ByteString
BS ForeignPtr Word8
x Int
n
{-# INLINE unsafeTake #-}
unsafeDrop :: Int -> ByteString -> ByteString
unsafeDrop :: Int -> ByteString -> ByteString
unsafeDrop Int
n (BS ForeignPtr Word8
x Int
l) = Bool -> ByteString -> ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Int -> ByteString
BS (ForeignPtr Word8 -> Int -> ForeignPtr Word8
forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr ForeignPtr Word8
x Int
n) (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n)
{-# INLINE unsafeDrop #-}
unsafePackAddressLen :: Int -> Addr# -> IO ByteString
unsafePackAddressLen :: Int -> Addr# -> IO ByteString
unsafePackAddressLen Int
len Addr#
addr# = do
ForeignPtr Word8
p <- Ptr Word8 -> IO (ForeignPtr Word8)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (Addr# -> Ptr Word8
forall a. Addr# -> Ptr a
Ptr Addr#
addr#)
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 -> ByteString
BS ForeignPtr Word8
p Int
len
{-# INLINE unsafePackAddressLen #-}
unsafePackCStringFinalizer :: Ptr Word8 -> Int -> IO () -> IO ByteString
unsafePackCStringFinalizer :: Ptr Word8 -> Int -> IO () -> IO ByteString
unsafePackCStringFinalizer Ptr Word8
p Int
l IO ()
f = do
ForeignPtr Word8
fp <- Ptr Word8 -> IO () -> IO (ForeignPtr Word8)
forall a. Ptr a -> IO () -> IO (ForeignPtr a)
FC.newForeignPtr Ptr Word8
p IO ()
f
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 -> ByteString
BS ForeignPtr Word8
fp Int
l
unsafeFinalize :: ByteString -> IO ()
unsafeFinalize :: ByteString -> IO ()
unsafeFinalize (BS ForeignPtr Word8
p Int
_) = ForeignPtr Word8 -> IO ()
forall a. ForeignPtr a -> IO ()
FC.finalizeForeignPtr ForeignPtr Word8
p
unsafePackCString :: CString -> IO ByteString
unsafePackCString :: CString -> IO ByteString
unsafePackCString CString
cstr = do
ForeignPtr Word8
fp <- Ptr Word8 -> IO (ForeignPtr Word8)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (CString -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr CString
cstr)
CSize
l <- CString -> IO CSize
c_strlen CString
cstr
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 -> ByteString
BS ForeignPtr Word8
fp (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
l)
unsafePackCStringLen :: CStringLen -> IO ByteString
unsafePackCStringLen :: CStringLen -> IO ByteString
unsafePackCStringLen (CString
ptr,Int
len) = do
ForeignPtr Word8
fp <- Ptr Word8 -> IO (ForeignPtr Word8)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (CString -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr CString
ptr)
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 -> ByteString
BS ForeignPtr Word8
fp (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
unsafePackMallocCString :: CString -> IO ByteString
unsafePackMallocCString :: CString -> IO ByteString
unsafePackMallocCString CString
cstr = do
ForeignPtr Word8
fp <- FinalizerPtr Word8 -> Ptr Word8 -> IO (ForeignPtr Word8)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Word8
c_free_finalizer (CString -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr CString
cstr)
CSize
len <- CString -> IO CSize
c_strlen CString
cstr
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 -> ByteString
BS ForeignPtr Word8
fp (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
len)
unsafePackMallocCStringLen :: CStringLen -> IO ByteString
unsafePackMallocCStringLen :: CStringLen -> IO ByteString
unsafePackMallocCStringLen (CString
cstr, Int
len) = do
ForeignPtr Word8
fp <- FinalizerPtr Word8 -> Ptr Word8 -> IO (ForeignPtr Word8)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Word8
c_free_finalizer (CString -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr CString
cstr)
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 -> ByteString
BS ForeignPtr Word8
fp Int
len
unsafeUseAsCString :: ByteString -> (CString -> IO a) -> IO a
unsafeUseAsCString :: forall a. ByteString -> (CString -> IO a) -> IO a
unsafeUseAsCString (BS ForeignPtr Word8
ps Int
_) CString -> IO a
action = ForeignPtr Word8 -> (Ptr Word8 -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
ps ((Ptr Word8 -> IO a) -> IO a) -> (Ptr Word8 -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> CString -> IO a
action (Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p)
unsafeUseAsCStringLen :: ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen :: forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen (BS ForeignPtr Word8
ps Int
l) CStringLen -> IO a
action = ForeignPtr Word8 -> (Ptr Word8 -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
ps ((Ptr Word8 -> IO a) -> IO a) -> (Ptr Word8 -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> CStringLen -> IO a
action (Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p, Int
l)