{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE UnliftedFFITypes #-}
#include <ghcautoconf.h>
module System.OsString.Data.ByteString.Short.Internal where
import Control.Monad.ST
import Control.Exception (assert, throwIO)
import Data.ByteString.Short.Internal (ShortByteString(..), length)
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup
( Semigroup((<>)) )
import Foreign.C.Types
( CSize(..)
, CInt(..)
)
import Data.ByteString.Internal
( accursedUnutterablePerformIO
)
#endif
#if !MIN_VERSION_bytestring(0,10,9)
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.C.String ( CString, CStringLen )
import Foreign.C.Types ( CSize(..) )
import Foreign.Storable (pokeByteOff)
#endif
import Foreign.Marshal.Array (withArray0, peekArray0, newArray0, withArrayLen, peekArray)
import GHC.Exts
import GHC.Word
import GHC.ST
( ST (ST) )
import GHC.Stack ( HasCallStack )
import Prelude hiding
( length )
import qualified Data.ByteString.Short.Internal as BS
import qualified Data.Char as C
import qualified Data.List as List
_nul :: Word16
_nul :: Word16
_nul = Word16
0x00
isSpace :: Word16 -> Bool
isSpace :: Word16 -> Bool
isSpace = Char -> Bool
C.isSpace (Char -> Bool) -> (Word16 -> Char) -> Word16 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Char
word16ToChar
word16ToChar :: Word16 -> Char
word16ToChar :: Word16 -> Char
word16ToChar = Int -> Char
C.chr (Int -> Char) -> (Word16 -> Int) -> Word16 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
create :: Int -> (forall s. MBA s -> ST s ()) -> ShortByteString
create :: Int -> (forall s. MBA s -> ST s ()) -> ShortByteString
create Int
len forall s. MBA s -> ST s ()
fill =
(forall s. ST s ShortByteString) -> ShortByteString
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ShortByteString) -> ShortByteString)
-> (forall s. ST s ShortByteString) -> ShortByteString
forall a b. (a -> b) -> a -> b
$ do
mba <- Int -> ST s (MBA s)
forall s. Int -> ST s (MBA s)
newByteArray Int
len
fill mba
BA# ba# <- unsafeFreezeByteArray mba
return (SBS ba#)
{-# INLINE create #-}
asBA :: ShortByteString -> BA
asBA :: ShortByteString -> BA
asBA (SBS ByteArray#
ba#) = ByteArray# -> BA
BA# ByteArray#
ba#
data BA = BA# ByteArray#
data MBA s = MBA# (MutableByteArray# s)
newPinnedByteArray :: Int -> ST s (MBA s)
newPinnedByteArray :: forall s. Int -> ST s (MBA s)
newPinnedByteArray (I# Int#
len#) =
STRep s (MBA s) -> ST s (MBA s)
forall s a. STRep s a -> ST s a
ST (STRep s (MBA s) -> ST s (MBA s))
-> STRep s (MBA s) -> ST s (MBA s)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newPinnedByteArray# Int#
len# State# s
s of
(# State# s
s', MutableByteArray# s
mba# #) -> (# State# s
s', MutableByteArray# s -> MBA s
forall s. MutableByteArray# s -> MBA s
MBA# MutableByteArray# s
mba# #)
newByteArray :: Int -> ST s (MBA s)
newByteArray :: forall s. Int -> ST s (MBA s)
newByteArray (I# Int#
len#) =
STRep s (MBA s) -> ST s (MBA s)
forall s a. STRep s a -> ST s a
ST (STRep s (MBA s) -> ST s (MBA s))
-> STRep s (MBA s) -> ST s (MBA s)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# Int#
len# State# s
s of
(# State# s
s', MutableByteArray# s
mba# #) -> (# State# s
s', MutableByteArray# s -> MBA s
forall s. MutableByteArray# s -> MBA s
MBA# MutableByteArray# s
mba# #)
copyByteArray :: BA -> Int -> MBA s -> Int -> Int -> ST s ()
copyByteArray :: forall s. BA -> Int -> MBA s -> Int -> Int -> ST s ()
copyByteArray (BA# ByteArray#
src#) (I# Int#
src_off#) (MBA# MutableByteArray# s
dst#) (I# Int#
dst_off#) (I# Int#
len#) =
STRep s () -> ST s ()
forall s a. STRep s a -> ST s a
ST (STRep s () -> ST s ()) -> STRep s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case ByteArray#
-> Int#
-> MutableByteArray# s
-> Int#
-> Int#
-> State# s
-> State# s
forall d.
ByteArray#
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyByteArray# ByteArray#
src# Int#
src_off# MutableByteArray# s
dst# Int#
dst_off# Int#
len# State# s
s of
State# s
s' -> (# State# s
s', () #)
unsafeFreezeByteArray :: MBA s -> ST s BA
unsafeFreezeByteArray :: forall s. MBA s -> ST s BA
unsafeFreezeByteArray (MBA# MutableByteArray# s
mba#) =
STRep s BA -> ST s BA
forall s a. STRep s a -> ST s a
ST (STRep s BA -> ST s BA) -> STRep s BA -> ST s BA
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# s
mba# State# s
s of
(# State# s
s', ByteArray#
ba# #) -> (# State# s
s', ByteArray# -> BA
BA# ByteArray#
ba# #)
copyAddrToByteArray :: Ptr a -> MBA RealWorld -> Int -> Int -> ST RealWorld ()
copyAddrToByteArray :: forall a. Ptr a -> MBA RealWorld -> Int -> Int -> ST RealWorld ()
copyAddrToByteArray (Ptr Addr#
src#) (MBA# MutableByteArray# RealWorld
dst#) (I# Int#
dst_off#) (I# Int#
len#) =
STRep RealWorld () -> ST RealWorld ()
forall s a. STRep s a -> ST s a
ST (STRep RealWorld () -> ST RealWorld ())
-> STRep RealWorld () -> ST RealWorld ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case Addr#
-> MutableByteArray# RealWorld
-> Int#
-> Int#
-> State# RealWorld
-> State# RealWorld
forall d.
Addr#
-> MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
copyAddrToByteArray# Addr#
src# MutableByteArray# RealWorld
dst# Int#
dst_off# Int#
len# State# RealWorld
s of
State# RealWorld
s' -> (# State# RealWorld
s', () #)
#if !MIN_VERSION_bytestring(0,10,9)
foreign import ccall unsafe "string.h strlen" c_strlen
:: CString -> IO CSize
packCString :: CString -> IO ShortByteString
packCString cstr = do
len <- c_strlen cstr
packCStringLen (cstr, fromIntegral len)
packCStringLen :: CStringLen -> IO ShortByteString
packCStringLen (cstr, len) | len >= 0 = BS.createFromPtr cstr len
packCStringLen (_, len) =
moduleErrorIO "packCStringLen" ("negative length: " ++ show len)
useAsCString :: ShortByteString -> (CString -> IO a) -> IO a
useAsCString bs action =
allocaBytes (l+1) $ \buf -> do
BS.copyToPtr bs 0 buf (fromIntegral l)
pokeByteOff buf l (0::Word8)
action buf
where l = length bs
useAsCStringLen :: ShortByteString -> (CStringLen -> IO a) -> IO a
useAsCStringLen bs action =
allocaBytes l $ \buf -> do
BS.copyToPtr bs 0 buf (fromIntegral l)
action (buf, l)
where l = length bs
#endif
packCWString :: Ptr Word16 -> IO ShortByteString
packCWString :: Ptr Word16 -> IO ShortByteString
packCWString Ptr Word16
cwstr = do
cs <- Word16 -> Ptr Word16 -> IO [Word16]
forall a. (Storable a, Eq a) => a -> Ptr a -> IO [a]
peekArray0 Word16
_nul Ptr Word16
cwstr
return (packWord16 cs)
packCWStringLen :: (Ptr Word16, Int) -> IO ShortByteString
packCWStringLen :: (Ptr Word16, Int) -> IO ShortByteString
packCWStringLen (Ptr Word16
cp, Int
len) = do
cs <- Int -> Ptr Word16 -> IO [Word16]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
len Ptr Word16
cp
return (packWord16 cs)
useAsCWString :: ShortByteString -> (Ptr Word16 -> IO a) -> IO a
useAsCWString :: forall a. ShortByteString -> (Ptr Word16 -> IO a) -> IO a
useAsCWString = Word16 -> [Word16] -> (Ptr Word16 -> IO a) -> IO a
forall a b. Storable a => a -> [a] -> (Ptr a -> IO b) -> IO b
withArray0 Word16
_nul ([Word16] -> (Ptr Word16 -> IO a) -> IO a)
-> (ShortByteString -> [Word16])
-> ShortByteString
-> (Ptr Word16 -> IO a)
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> [Word16]
unpackWord16
useAsCWStringLen :: ShortByteString -> ((Ptr Word16, Int) -> IO a) -> IO a
useAsCWStringLen :: forall a. ShortByteString -> ((Ptr Word16, Int) -> IO a) -> IO a
useAsCWStringLen ShortByteString
bs (Ptr Word16, Int) -> IO a
action = [Word16] -> (Int -> Ptr Word16 -> IO a) -> IO a
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
withArrayLen (ShortByteString -> [Word16]
unpackWord16 ShortByteString
bs) ((Int -> Ptr Word16 -> IO a) -> IO a)
-> (Int -> Ptr Word16 -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \ Int
len Ptr Word16
ptr -> (Ptr Word16, Int) -> IO a
action (Ptr Word16
ptr, Int
len)
newCWString :: ShortByteString -> IO (Ptr Word16)
newCWString :: ShortByteString -> IO (Ptr Word16)
newCWString = Word16 -> [Word16] -> IO (Ptr Word16)
forall a. Storable a => a -> [a] -> IO (Ptr a)
newArray0 Word16
_nul ([Word16] -> IO (Ptr Word16))
-> (ShortByteString -> [Word16])
-> ShortByteString
-> IO (Ptr Word16)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> [Word16]
unpackWord16
moduleErrorIO :: String -> String -> IO a
moduleErrorIO :: forall a. [Char] -> [Char] -> IO a
moduleErrorIO [Char]
fun [Char]
msg = IOError -> IO a
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (IOError -> IO a) -> ([Char] -> IOError) -> [Char] -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IOError
userError ([Char] -> IO a) -> [Char] -> IO a
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
moduleErrorMsg [Char]
fun [Char]
msg
{-# NOINLINE moduleErrorIO #-}
moduleErrorMsg :: String -> String -> String
moduleErrorMsg :: [Char] -> [Char] -> [Char]
moduleErrorMsg [Char]
fun [Char]
msg = [Char]
"System.OsPath.Data.ByteString.Short." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
fun [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Char
':'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
' 'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
msg
packWord16 :: [Word16] -> ShortByteString
packWord16 :: [Word16] -> ShortByteString
packWord16 [Word16]
cs = Int -> [Word16] -> ShortByteString
packLenWord16 ([Word16] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [Word16]
cs) [Word16]
cs
packLenWord16 :: Int -> [Word16] -> ShortByteString
packLenWord16 :: Int -> [Word16] -> ShortByteString
packLenWord16 Int
len [Word16]
ws0 =
Int -> (forall s. MBA s -> ST s ()) -> ShortByteString
create (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) (\MBA s
mba -> MBA s -> Int -> [Word16] -> ST s ()
forall s. MBA s -> Int -> [Word16] -> ST s ()
go MBA s
mba Int
0 [Word16]
ws0)
where
go :: MBA s -> Int -> [Word16] -> ST s ()
go :: forall s. MBA s -> Int -> [Word16] -> ST s ()
go !MBA s
_ !Int
_ [] = () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
go !MBA s
mba !Int
i (Word16
w:[Word16]
ws) = do
MBA s -> Int -> Word16 -> ST s ()
forall s. MBA s -> Int -> Word16 -> ST s ()
writeWord16Array MBA s
mba Int
i Word16
w
MBA s -> Int -> [Word16] -> ST s ()
forall s. MBA s -> Int -> [Word16] -> ST s ()
go MBA s
mba (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2) [Word16]
ws
unpackWord16 :: ShortByteString -> [Word16]
unpackWord16 :: ShortByteString -> [Word16]
unpackWord16 ShortByteString
sbs = Int -> [Word16] -> [Word16]
go Int
len []
where
len :: Int
len = ShortByteString -> Int
length ShortByteString
sbs
go :: Int -> [Word16] -> [Word16]
go !Int
i ![Word16]
acc
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 = [Word16]
acc
| Bool
otherwise = let !w :: Word16
w = BA -> Int -> Word16
indexWord16Array (ShortByteString -> BA
asBA ShortByteString
sbs) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
in Int -> [Word16] -> [Word16]
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) (Word16
wWord16 -> [Word16] -> [Word16]
forall a. a -> [a] -> [a]
:[Word16]
acc)
packWord16Rev :: [Word16] -> ShortByteString
packWord16Rev :: [Word16] -> ShortByteString
packWord16Rev [Word16]
cs = Int -> [Word16] -> ShortByteString
packLenWord16Rev ([Word16] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [Word16]
cs Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) [Word16]
cs
packLenWord16Rev :: Int -> [Word16] -> ShortByteString
packLenWord16Rev :: Int -> [Word16] -> ShortByteString
packLenWord16Rev Int
len [Word16]
ws0 =
Int -> (forall s. MBA s -> ST s ()) -> ShortByteString
create Int
len (\MBA s
mba -> MBA s -> Int -> [Word16] -> ST s ()
forall s. MBA s -> Int -> [Word16] -> ST s ()
go MBA s
mba Int
len [Word16]
ws0)
where
go :: MBA s -> Int -> [Word16] -> ST s ()
go :: forall s. MBA s -> Int -> [Word16] -> ST s ()
go !MBA s
_ !Int
_ [] = () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
go !MBA s
mba !Int
i (Word16
w:[Word16]
ws) = do
MBA s -> Int -> Word16 -> ST s ()
forall s. MBA s -> Int -> Word16 -> ST s ()
writeWord16Array MBA s
mba (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) Word16
w
MBA s -> Int -> [Word16] -> ST s ()
forall s. MBA s -> Int -> [Word16] -> ST s ()
go MBA s
mba (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) [Word16]
ws
writeWord16Array :: MBA s
-> Int
-> Word16
-> ST s ()
writeWord16Array :: forall s. MBA s -> Int -> Word16 -> ST s ()
writeWord16Array (MBA# MutableByteArray# s
mba#) (I# Int#
i#) (W16# Word16#
w#) = STRep s () -> ST s ()
forall s a. STRep s a -> ST s a
ST (STRep s () -> ST s ()) -> STRep s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutableByteArray# s -> Int# -> Word16# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Word16# -> State# d -> State# d
writeWord8ArrayAsWord16# MutableByteArray# s
mba# Int#
i# (Word16# -> Word16#
word16ToLE# Word16#
w#) State# s
s of
State# s
s' -> (# State# s
s', () #)
indexWord8Array :: BA
-> Int
-> Word8
indexWord8Array :: BA -> Int -> Word8
indexWord8Array (BA# ByteArray#
ba#) (I# Int#
i#) = Word8# -> Word8
W8# (ByteArray# -> Int# -> Word8#
indexWord8Array# ByteArray#
ba# Int#
i#)
indexWord16Array :: BA
-> Int
-> Word16
indexWord16Array :: BA -> Int -> Word16
indexWord16Array (BA# ByteArray#
ba#) (I# Int#
i#) =
Word16# -> Word16
W16# (Word16# -> Word16#
word16FromLE# (ByteArray# -> Int# -> Word16#
indexWord8ArrayAsWord16# ByteArray#
ba# Int#
i#))
#if MIN_VERSION_base(4,16,0)
word16ToLE#, word16FromLE# :: Word16# -> Word16#
#else
word16ToLE#, word16FromLE# :: Word# -> Word#
#endif
#ifdef WORDS_BIGENDIAN
word16ToLE# = byteSwap16#
#else
word16ToLE# :: Word16# -> Word16#
word16ToLE# Word16#
w# = Word16#
w#
#endif
word16FromLE# :: Word16# -> Word16#
word16FromLE# = Word16# -> Word16#
word16ToLE#
setByteArray :: MBA s -> Int -> Int -> Int -> ST s ()
setByteArray :: forall s. MBA s -> Int -> Int -> Int -> ST s ()
setByteArray (MBA# MutableByteArray# s
dst#) (I# Int#
off#) (I# Int#
len#) (I# Int#
c#) =
STRep s () -> ST s ()
forall s a. STRep s a -> ST s a
ST (STRep s () -> ST s ()) -> STRep s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case MutableByteArray# s -> Int# -> Int# -> Int# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d
setByteArray# MutableByteArray# s
dst# Int#
off# Int#
len# Int#
c# State# s
s of
State# s
s' -> (# State# s
s', () #)
copyMutableByteArray :: MBA s -> Int -> MBA s -> Int -> Int -> ST s ()
copyMutableByteArray :: forall s. MBA s -> Int -> MBA s -> Int -> Int -> ST s ()
copyMutableByteArray (MBA# MutableByteArray# s
src#) (I# Int#
src_off#) (MBA# MutableByteArray# s
dst#) (I# Int#
dst_off#) (I# Int#
len#) =
STRep s () -> ST s ()
forall s a. STRep s a -> ST s a
ST (STRep s () -> ST s ()) -> STRep s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case MutableByteArray# s
-> Int#
-> MutableByteArray# s
-> Int#
-> Int#
-> State# s
-> State# s
forall d.
MutableByteArray# d
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyMutableByteArray# MutableByteArray# s
src# Int#
src_off# MutableByteArray# s
dst# Int#
dst_off# Int#
len# State# s
s of
State# s
s' -> (# State# s
s', () #)
createAndTrim :: Int -> (forall s. MBA s -> ST s (Int, a)) -> (ShortByteString, a)
createAndTrim :: forall a.
Int -> (forall s. MBA s -> ST s (Int, a)) -> (ShortByteString, a)
createAndTrim Int
l forall s. MBA s -> ST s (Int, a)
fill =
(forall s. ST s (ShortByteString, a)) -> (ShortByteString, a)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (ShortByteString, a)) -> (ShortByteString, a))
-> (forall s. ST s (ShortByteString, a)) -> (ShortByteString, a)
forall a b. (a -> b) -> a -> b
$ do
mba <- Int -> ST s (MBA s)
forall s. Int -> ST s (MBA s)
newByteArray Int
l
(l', res) <- fill mba
if assert (l' <= l) $ l' >= l
then do
BA# ba# <- unsafeFreezeByteArray mba
return (SBS ba#, res)
else do
mba2 <- newByteArray l'
copyMutableByteArray mba 0 mba2 0 l'
BA# ba# <- unsafeFreezeByteArray mba2
return (SBS ba#, res)
{-# INLINE createAndTrim #-}
createAndTrim' :: Int -> (forall s. MBA s -> ST s Int) -> ShortByteString
createAndTrim' :: Int -> (forall s. MBA s -> ST s Int) -> ShortByteString
createAndTrim' Int
l forall s. MBA s -> ST s Int
fill =
(forall s. ST s ShortByteString) -> ShortByteString
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ShortByteString) -> ShortByteString)
-> (forall s. ST s ShortByteString) -> ShortByteString
forall a b. (a -> b) -> a -> b
$ do
mba <- Int -> ST s (MBA s)
forall s. Int -> ST s (MBA s)
newByteArray Int
l
l' <- fill mba
if assert (l' <= l) $ l' >= l
then do
BA# ba# <- unsafeFreezeByteArray mba
return (SBS ba#)
else do
mba2 <- newByteArray l'
copyMutableByteArray mba 0 mba2 0 l'
BA# ba# <- unsafeFreezeByteArray mba2
return (SBS ba#)
{-# INLINE createAndTrim' #-}
createAndTrim'' :: Int -> (forall s. MBA s -> MBA s -> ST s (Int, Int)) -> (ShortByteString, ShortByteString)
createAndTrim'' :: Int
-> (forall s. MBA s -> MBA s -> ST s (Int, Int))
-> (ShortByteString, ShortByteString)
createAndTrim'' Int
l forall s. MBA s -> MBA s -> ST s (Int, Int)
fill =
(forall s. ST s (ShortByteString, ShortByteString))
-> (ShortByteString, ShortByteString)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (ShortByteString, ShortByteString))
-> (ShortByteString, ShortByteString))
-> (forall s. ST s (ShortByteString, ShortByteString))
-> (ShortByteString, ShortByteString)
forall a b. (a -> b) -> a -> b
$ do
mba1 <- Int -> ST s (MBA s)
forall s. Int -> ST s (MBA s)
newByteArray Int
l
mba2 <- newByteArray l
(l1, l2) <- fill mba1 mba2
sbs1 <- freeze' l1 mba1
sbs2 <- freeze' l2 mba2
pure (sbs1, sbs2)
where
freeze' :: Int -> MBA s -> ST s ShortByteString
freeze' :: forall s. Int -> MBA s -> ST s ShortByteString
freeze' Int
l' MBA s
mba =
if Bool -> Bool -> Bool
forall a. HasCallStack => Bool -> a -> a
assert (Int
l' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l) (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int
l' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
l
then do
BA# ba# <- MBA s -> ST s BA
forall s. MBA s -> ST s BA
unsafeFreezeByteArray MBA s
mba
return (SBS ba#)
else do
mba2 <- Int -> ST s (MBA s)
forall s. Int -> ST s (MBA s)
newByteArray Int
l'
copyMutableByteArray mba 0 mba2 0 l'
BA# ba# <- unsafeFreezeByteArray mba2
return (SBS ba#)
{-# INLINE createAndTrim'' #-}
findIndexOrLength :: (Word16 -> Bool) -> ShortByteString -> Int
findIndexOrLength :: (Word16 -> Bool) -> ShortByteString -> Int
findIndexOrLength Word16 -> Bool
k (ShortByteString -> ShortByteString
assertEven -> ShortByteString
sbs) = Int -> Int
go Int
0
where
l :: Int
l = ShortByteString -> Int
BS.length ShortByteString
sbs
ba :: BA
ba = ShortByteString -> BA
asBA ShortByteString
sbs
w :: Int -> Word16
w = BA -> Int -> Word16
indexWord16Array BA
ba
go :: Int -> Int
go !Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
l = Int
l Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
| Word16 -> Bool
k (Int -> Word16
w Int
n) = Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
| Bool
otherwise = Int -> Int
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)
{-# INLINE findIndexOrLength #-}
findFromEndUntil :: (Word16 -> Bool) -> ShortByteString -> Int
findFromEndUntil :: (Word16 -> Bool) -> ShortByteString -> Int
findFromEndUntil Word16 -> Bool
k ShortByteString
sbs = Int -> Int
go (ShortByteString -> Int
BS.length ShortByteString
sbs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
where
ba :: BA
ba = ShortByteString -> BA
asBA ShortByteString
sbs
w :: Int -> Word16
w = BA -> Int -> Word16
indexWord16Array BA
ba
go :: Int -> Int
go !Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int
0
| Word16 -> Bool
k (Int -> Word16
w Int
n) = (Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
| Bool
otherwise = Int -> Int
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
{-# INLINE findFromEndUntil #-}
assertEven :: ShortByteString -> ShortByteString
assertEven :: ShortByteString -> ShortByteString
assertEven sbs :: ShortByteString
sbs@(SBS ByteArray#
barr#)
| Int -> Bool
forall a. Integral a => a -> Bool
even (Int# -> Int
I# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
barr#)) = ShortByteString
sbs
| Bool
otherwise = [Char] -> ShortByteString
forall a. HasCallStack => [Char] -> a
error ([Char]
"Uneven number of bytes: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show (ShortByteString -> Int
BS.length ShortByteString
sbs) [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
". This is not a Word16 bytestream.")
errorEmptySBS :: HasCallStack => String -> a
errorEmptySBS :: forall a. HasCallStack => [Char] -> a
errorEmptySBS [Char]
fun = [Char] -> [Char] -> a
forall a. HasCallStack => [Char] -> [Char] -> a
moduleError [Char]
fun [Char]
"empty ShortByteString"
{-# NOINLINE errorEmptySBS #-}
moduleError :: HasCallStack => String -> String -> a
moduleError :: forall a. HasCallStack => [Char] -> [Char] -> a
moduleError [Char]
fun [Char]
msg = [Char] -> a
forall a. HasCallStack => [Char] -> a
error ([Char] -> [Char] -> [Char]
moduleErrorMsg [Char]
fun [Char]
msg)
{-# NOINLINE moduleError #-}
compareByteArraysOff :: BA
-> Int
-> BA
-> Int
-> Int
-> Int
#if MIN_VERSION_base(4,11,0)
compareByteArraysOff :: BA -> Int -> BA -> Int -> Int -> Int
compareByteArraysOff (BA# ByteArray#
ba1#) (I# Int#
ba1off#) (BA# ByteArray#
ba2#) (I# Int#
ba2off#) (I# Int#
len#) =
Int# -> Int
I# (ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#
compareByteArrays# ByteArray#
ba1# Int#
ba1off# ByteArray#
ba2# Int#
ba2off# Int#
len#)
#else
compareByteArraysOff (BA# ba1#) ba1off (BA# ba2#) ba2off len =
assert (ba1off + len <= (I# (sizeofByteArray# ba1#)))
$ assert (ba2off + len <= (I# (sizeofByteArray# ba2#)))
$ fromIntegral $ accursedUnutterablePerformIO $
c_memcmp_ByteArray ba1#
ba1off
ba2#
ba2off
(fromIntegral len)
foreign import ccall unsafe "static sbs_memcmp_off"
c_memcmp_ByteArray :: ByteArray# -> Int -> ByteArray# -> Int -> CSize -> IO CInt
#endif