{-# 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.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.Exts (Addr#)
import GHC.Ptr (Ptr(..), castPtr)
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
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#)
return $ BS p 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
fp <- Ptr Word8 -> IO () -> IO (ForeignPtr Word8)
forall a. Ptr a -> IO () -> IO (ForeignPtr a)
FC.newForeignPtr Ptr Word8
p IO ()
f
return $ BS fp 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
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)
l <- c_strlen cstr
return $! BS fp (fromIntegral l)
unsafePackCStringLen :: CStringLen -> IO ByteString
unsafePackCStringLen :: CStringLen -> IO ByteString
unsafePackCStringLen (CString
ptr,Int
len) = do
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)
return $! BS fp (fromIntegral len)
unsafePackMallocCString :: CString -> IO ByteString
unsafePackMallocCString :: CString -> IO ByteString
unsafePackMallocCString CString
cstr = do
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)
len <- c_strlen cstr
return $! BS fp (fromIntegral len)
unsafePackMallocCStringLen :: CStringLen -> IO ByteString
unsafePackMallocCStringLen :: CStringLen -> IO ByteString
unsafePackMallocCStringLen (CString
cstr, Int
len) = do
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)
return $! BS fp 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)