{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}
module Unison.Util.Bytes
( Bytes (..),
Chunk (..),
fromByteString,
toByteString,
fromWord8s,
toWord8s,
fromBase16,
toBase16,
fromBase32,
toBase32,
fromBase64,
toBase64,
fromByteArray,
toByteArray,
fromBase64UrlUnpadded,
toBase64UrlUnpadded,
chunkFromByteString,
byteStringToChunk,
chunkToByteString,
fromChunks,
chunks,
byteStringChunks,
toArray,
fromArray,
toLazyByteString,
fromLazyByteString,
flatten,
at,
index16be,
index16le,
index32be,
index32le,
index64be,
index64le,
take,
drop,
indexOf,
size,
empty,
encodeNat16be,
decodeNat16be,
encodeNat32be,
decodeNat32be,
encodeNat64be,
decodeNat64be,
encodeNat16le,
decodeNat16le,
encodeNat32le,
decodeNat32le,
encodeNat64le,
decodeNat64le,
decodeUtf8,
encodeUtf8,
zlibCompress,
zlibDecompress,
gzipCompress,
gzipDecompress,
zstdCompress,
zstdDecompress,
hash64AddBytes,
)
where
import Basement.Block.Mutable (Block (Block))
import Codec.Compression.GZip qualified as GZip
import Codec.Compression.Zlib qualified as Zlib
import Codec.Compression.Zstd qualified as Zstd
import Control.DeepSeq (NFData (..))
import Control.Exception (throw)
import Control.Monad.Primitive (unsafeIOToPrim, unsafePrimToIO)
import Control.Monad.ST (ST, runST)
import Data.ByteArray qualified as BA
import Data.ByteArray.Encoding qualified as BE
import Data.ByteString qualified as B
import Data.ByteString.Lazy qualified as LB
import Data.ByteString.Lazy.Search qualified as SS
import Data.Char
import Data.Digest.Murmur64 (Hash64, hash64AddInt)
import Data.Primitive.ByteArray
( ByteArray (ByteArray),
MutableByteArray,
byteArrayFromListN,
compareByteArrays,
copyByteArray,
copyByteArrayToPtr,
emptyByteArray,
indexByteArray,
newByteArray,
runByteArray,
sizeofByteArray,
unsafeFreezeByteArray,
writeByteArray,
)
import Data.Primitive.Ptr (Ptr, copyPtrToMutableByteArray)
import Data.Semigroup (Semigroup (..))
import Data.Text qualified as Text
import Foreign.Ptr (plusPtr)
import GHC.ByteOrder (ByteOrder (..), targetByteOrder)
import Unison.Prelude hiding (ByteString, empty)
import Unison.Util.Rope qualified as R
import Prelude hiding (drop, take)
withByteArrayST ::
(BA.ByteArrayAccess a) => a -> (Ptr Word8 -> ST s ()) -> ST s ()
withByteArrayST :: forall a s.
ByteArrayAccess a =>
a -> (Ptr Word8 -> ST s ()) -> ST s ()
withByteArrayST a
a Ptr Word8 -> ST s ()
k =
IO () -> ST s ()
forall (m :: * -> *) a. PrimMonad m => IO a -> m a
unsafeIOToPrim (IO () -> ST s ()) -> IO () -> ST s ()
forall a b. (a -> b) -> a -> b
$ a -> (Ptr Word8 -> IO ()) -> IO ()
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
forall p a. a -> (Ptr p -> IO a) -> IO a
BA.withByteArray a
a (ST s () -> IO ()
forall (m :: * -> *) a. PrimBase m => m a -> IO a
unsafePrimToIO (ST s () -> IO ()) -> (Ptr Word8 -> ST s ()) -> Ptr Word8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Word8 -> ST s ()
k)
data Chunk = Chunk
{ Chunk -> Int
_off :: {-# UNPACK #-} !Int,
Chunk -> Int
chunkSize :: {-# UNPACK #-} !Int,
Chunk -> ByteArray
_arr :: {-# UNPACK #-} !ByteArray
}
emptyChunk :: Chunk
emptyChunk :: Chunk
emptyChunk = Int -> Int -> ByteArray -> Chunk
Chunk Int
0 Int
0 ByteArray
emptyByteArray
instance Eq Chunk where
Chunk Int
ol Int
ll ByteArray
al == :: Chunk -> Chunk -> Bool
== Chunk Int
or Int
lr ByteArray
ar =
Int
ll Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lr Bool -> Bool -> Bool
&& ByteArray -> Int -> ByteArray -> Int -> Int -> Ordering
compareByteArrays ByteArray
al Int
ol ByteArray
ar Int
or Int
ll Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ
{-# INLINE (==) #-}
instance Ord Chunk where
Chunk Int
ol Int
ll ByteArray
al compare :: Chunk -> Chunk -> Ordering
`compare` Chunk Int
or Int
lr ByteArray
ar =
ByteArray -> Int -> ByteArray -> Int -> Int -> Ordering
compareByteArrays ByteArray
al Int
ol ByteArray
ar Int
or (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
ll Int
lr) Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
ll Int
lr
{-# INLINE compare #-}
concatChunks :: [Chunk] -> Chunk
concatChunks :: [Chunk] -> Chunk
concatChunks [Chunk]
cs =
Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
len \MutableByteArray s
m ->
let go :: Int -> [Chunk] -> ST s ()
go !Int
_ [] = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
go !Int
mo (Chunk Int
o Int
l ByteArray
a : [Chunk]
cs) =
MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
mo ByteArray
a Int
o Int
l ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> [Chunk] -> ST s ()
go (Int
mo Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l) [Chunk]
cs
in Int -> [Chunk] -> ST s ()
go Int
0 [Chunk]
cs
where
len :: Int
len = (Int -> Chunk -> Int) -> Int -> [Chunk] -> Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Int
acc (Chunk Int
_ Int
l ByteArray
_) -> Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l) Int
0 [Chunk]
cs
{-# INLINE concatChunks #-}
foldl'Chunk :: (r -> Word8 -> r) -> r -> Chunk -> r
foldl'Chunk :: forall r. (r -> Word8 -> r) -> r -> Chunk -> r
foldl'Chunk r -> Word8 -> r
f r
z (Chunk Int
o Int
l ByteArray
a) = r -> Int -> r
go r
z Int
o
where
n :: Int
n = Int
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l
go :: r -> Int -> r
go !r
acc Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = r -> Int -> r
go (r -> Word8 -> r
f r
acc (Word8 -> r) -> Word8 -> r
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
a Int
i) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = r
acc
instance Semigroup Chunk where
cl :: Chunk
cl@(Chunk Int
ol Int
ll ByteArray
al) <> :: Chunk -> Chunk -> Chunk
<> cr :: Chunk
cr@(Chunk Int
or Int
lr ByteArray
ar)
| Int
ll Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Chunk
cr
| Int
lr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Chunk
cl
| Bool
otherwise =
Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk (Int
ll Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
lr) \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 ByteArray
al Int
ol Int
ll ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
ll ByteArray
ar Int
or Int
lr
sconcat :: NonEmpty Chunk -> Chunk
sconcat NonEmpty Chunk
cs = [Chunk] -> Chunk
concatChunks (NonEmpty Chunk -> [Chunk]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Chunk
cs)
stimes :: forall b. Integral b => b -> Chunk -> Chunk
stimes b
i c :: Chunk
c@(Chunk Int
o Int
l ByteArray
a)
| Integer
j Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
1 = Chunk
emptyChunk
| Integer
j Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1 = Chunk
c
| Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
j Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
m = [Char] -> Chunk
forall a. HasCallStack => [Char] -> a
error [Char]
"stimes @Chunk: size too large"
| Int
k <- b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
i = Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k) \MutableByteArray s
m ->
let go :: Int -> ST s ()
go Int
0 = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
go (Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract Int
1 -> Int
n) =
MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
l) ByteArray
a Int
o Int
l ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ST s ()
go Int
n
in Int -> ST s ()
go Int
k
where
j :: Integer
j :: Integer
j = b -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
i
m :: Integer
m :: Integer
m = Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
forall a. Bounded a => a
maxBound :: Int)
instance Monoid Chunk where
mempty :: Chunk
mempty = Chunk
emptyChunk
mconcat :: [Chunk] -> Chunk
mconcat = [Chunk] -> Chunk
concatChunks
newtype Bytes = Bytes {Bytes -> Rope Chunk
underlying :: R.Rope Chunk}
deriving stock (Bytes -> Bytes -> Bool
(Bytes -> Bytes -> Bool) -> (Bytes -> Bytes -> Bool) -> Eq Bytes
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Bytes -> Bytes -> Bool
== :: Bytes -> Bytes -> Bool
$c/= :: Bytes -> Bytes -> Bool
/= :: Bytes -> Bytes -> Bool
Eq, Eq Bytes
Eq Bytes =>
(Bytes -> Bytes -> Ordering)
-> (Bytes -> Bytes -> Bool)
-> (Bytes -> Bytes -> Bool)
-> (Bytes -> Bytes -> Bool)
-> (Bytes -> Bytes -> Bool)
-> (Bytes -> Bytes -> Bytes)
-> (Bytes -> Bytes -> Bytes)
-> Ord Bytes
Bytes -> Bytes -> Bool
Bytes -> Bytes -> Ordering
Bytes -> Bytes -> Bytes
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Bytes -> Bytes -> Ordering
compare :: Bytes -> Bytes -> Ordering
$c< :: Bytes -> Bytes -> Bool
< :: Bytes -> Bytes -> Bool
$c<= :: Bytes -> Bytes -> Bool
<= :: Bytes -> Bytes -> Bool
$c> :: Bytes -> Bytes -> Bool
> :: Bytes -> Bytes -> Bool
$c>= :: Bytes -> Bytes -> Bool
>= :: Bytes -> Bytes -> Bool
$cmax :: Bytes -> Bytes -> Bytes
max :: Bytes -> Bytes -> Bytes
$cmin :: Bytes -> Bytes -> Bytes
min :: Bytes -> Bytes -> Bytes
Ord)
deriving newtype (NonEmpty Bytes -> Bytes
Bytes -> Bytes -> Bytes
(Bytes -> Bytes -> Bytes)
-> (NonEmpty Bytes -> Bytes)
-> (forall b. Integral b => b -> Bytes -> Bytes)
-> Semigroup Bytes
forall b. Integral b => b -> Bytes -> Bytes
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: Bytes -> Bytes -> Bytes
<> :: Bytes -> Bytes -> Bytes
$csconcat :: NonEmpty Bytes -> Bytes
sconcat :: NonEmpty Bytes -> Bytes
$cstimes :: forall b. Integral b => b -> Bytes -> Bytes
stimes :: forall b. Integral b => b -> Bytes -> Bytes
Semigroup, Semigroup Bytes
Bytes
Semigroup Bytes =>
Bytes
-> (Bytes -> Bytes -> Bytes) -> ([Bytes] -> Bytes) -> Monoid Bytes
[Bytes] -> Bytes
Bytes -> Bytes -> Bytes
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: Bytes
mempty :: Bytes
$cmappend :: Bytes -> Bytes -> Bytes
mappend :: Bytes -> Bytes -> Bytes
$cmconcat :: [Bytes] -> Bytes
mconcat :: [Bytes] -> Bytes
Monoid)
instance R.Sized Chunk where size :: Chunk -> Int
size = Chunk -> Int
chunkSize
instance R.Drop Chunk where
drop :: Int -> Chunk -> Chunk
drop Int
n c :: Chunk
c@(Chunk Int
o Int
l ByteArray
a)
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Chunk
c
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
l = Chunk
emptyChunk
| Bool
otherwise = Int -> Int -> ByteArray -> Chunk
Chunk (Int
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n) (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) ByteArray
a
instance R.Take Chunk where
take :: Int -> Chunk -> Chunk
take Int
0 Chunk
_ = Chunk
emptyChunk
take Int
n c :: Chunk
c@(Chunk Int
o Int
l ByteArray
a)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l = Int -> Int -> ByteArray -> Chunk
Chunk Int
o Int
n ByteArray
a
| Bool
otherwise = Chunk
c
instance R.Index Chunk Word8 where
unsafeIndex :: Int -> Chunk -> Word8
unsafeIndex Int
n (Chunk Int
o Int
_ ByteArray
a) = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
a (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
o)
instance R.Reverse Chunk where
reverse :: Chunk -> Chunk
reverse (Chunk Int
o Int
l ByteArray
a) = Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
l \MutableByteArray s
m ->
let e :: Int
e = Int
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
go :: Int -> ST s ()
go Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l = MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
i (Word8 -> ST s ()) -> Word8 -> ST s ()
forall a b. (a -> b) -> a -> b
$ forall a. Prim a => ByteArray -> Int -> a
indexByteArray @Word8 ByteArray
a (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i)
| Bool
otherwise = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
in Int -> ST s ()
go Int
0
instance NFData Bytes where rnf :: Bytes -> ()
rnf Bytes
_ = ()
createByteArray ::
Int -> (forall s. MutableByteArray s -> ST s ()) -> ByteArray
createByteArray :: Int -> (forall s. MutableByteArray s -> ST s ()) -> ByteArray
createByteArray Int
sz forall s. MutableByteArray s -> ST s ()
f =
(forall s. ST s (MutableByteArray s)) -> ByteArray
runByteArray ((forall s. ST s (MutableByteArray s)) -> ByteArray)
-> (forall s. ST s (MutableByteArray s)) -> ByteArray
forall a b. (a -> b) -> a -> b
$
Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
sz ST s (MutableByteArray s)
-> (MutableByteArray s -> ST s (MutableByteArray s))
-> ST s (MutableByteArray s)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \MutableByteArray s
ma -> MutableByteArray s
ma MutableByteArray s -> ST s () -> ST s (MutableByteArray s)
forall a b. a -> ST s b -> ST s a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ MutableByteArray s -> ST s ()
forall s. MutableByteArray s -> ST s ()
f MutableByteArray s
ma
{-# INLINE createByteArray #-}
createChunk ::
Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk :: Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
sz forall s. MutableByteArray s -> ST s ()
f = Int -> Int -> ByteArray -> Chunk
Chunk Int
0 Int
sz (ByteArray -> Chunk) -> ByteArray -> Chunk
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> ByteArray
createByteArray Int
sz MutableByteArray s -> ST s ()
forall s. MutableByteArray s -> ST s ()
f
{-# INLINE createChunk #-}
gCreateChunk ::
Int -> (forall s. MutableByteArray s -> ST s r) -> (Chunk, r)
gCreateChunk :: forall r.
Int -> (forall s. MutableByteArray s -> ST s r) -> (Chunk, r)
gCreateChunk Int
sz forall s. MutableByteArray s -> ST s r
f = (forall s. ST s (Chunk, r)) -> (Chunk, r)
forall a. (forall s. ST s a) -> a
runST do
MutableByteArray s
ma <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
sz
r
r <- MutableByteArray s -> ST s r
forall s. MutableByteArray s -> ST s r
f MutableByteArray s
ma
(,r
r) (Chunk -> (Chunk, r))
-> (ByteArray -> Chunk) -> ByteArray -> (Chunk, r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> ByteArray -> Chunk
Chunk Int
0 Int
sz (ByteArray -> (Chunk, r)) -> ST s ByteArray -> ST s (Chunk, r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
ma
{-# INLINE gCreateChunk #-}
whenLittleEndian :: (a -> a) -> a -> a
whenLittleEndian :: forall a. (a -> a) -> a -> a
whenLittleEndian
| ByteOrder
LittleEndian <- ByteOrder
targetByteOrder = \a -> a
f a
x -> a -> a
f a
x
| Bool
otherwise = \a -> a
_ a
x -> a
x
{-# INLINE whenLittleEndian #-}
whenBigEndian :: (a -> a) -> a -> a
whenBigEndian :: forall a. (a -> a) -> a -> a
whenBigEndian
| ByteOrder
BigEndian <- ByteOrder
targetByteOrder = \a -> a
f a
x -> a -> a
f a
x
| Bool
otherwise = \a -> a
_ a
x -> a
x
{-# INLINE whenBigEndian #-}
extractChunkArr :: Int -> Int -> Bytes -> ByteArray
Int
ix Int
ln (Bytes Rope Chunk
bs) = Int -> Chunk -> ByteArray
fixAlign Int
ln (Chunk -> ByteArray) -> Chunk -> ByteArray
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Rope Chunk -> Chunk
forall a. (Monoid a, Sized a, Drop a) => Int -> Int -> Rope a -> a
R.extractChunk Int
ix Int
ln Rope Chunk
bs
fixAlign :: Int -> Chunk -> ByteArray
fixAlign :: Int -> Chunk -> ByteArray
fixAlign Int
ln (Chunk Int
o Int
_ ByteArray
ba)
| Int
o Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ByteArray
ba
| Bool
otherwise = Int -> (forall s. MutableByteArray s -> ST s ()) -> ByteArray
createByteArray Int
ln (\MutableByteArray s
m -> MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 ByteArray
ba Int
o Int
ln)
null :: Bytes -> Bool
null :: Bytes -> Bool
null = Rope Chunk -> Bool
forall a. Sized a => Rope a -> Bool
R.null (Rope Chunk -> Bool) -> (Bytes -> Rope Chunk) -> Bytes -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> Rope Chunk
underlying
empty :: Bytes
empty :: Bytes
empty = Bytes
forall a. Monoid a => a
mempty
isAsciiChunk :: Chunk -> Bool
isAsciiChunk :: Chunk -> Bool
isAsciiChunk (Chunk Int
o Int
l ByteArray
a) = Int -> Bool
test Int
o
where
n :: Int
n = Int
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l
test :: Int -> Bool
test Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n = Bool
True
| forall a. Prim a => ByteArray -> Int -> a
indexByteArray @Word8 ByteArray
a Int
i Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x7F = Int -> Bool
test (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = Bool
False
isAscii :: Bytes -> Bool
isAscii :: Bytes -> Bool
isAscii Bytes
b = (Chunk -> Bool) -> [Chunk] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Chunk -> Bool
isAsciiChunk (Bytes -> [Chunk]
chunks Bytes
b)
fromByteString :: B.ByteString -> Bytes
fromByteString :: ByteString -> Bytes
fromByteString ByteString
b = Bytes -> Chunk -> Bytes
snoc Bytes
empty (ByteString -> Chunk
byteStringToChunk ByteString
b)
toByteString :: Bytes -> B.ByteString
toByteString :: Bytes -> ByteString
toByteString Bytes
b = [ByteString] -> ByteString
B.concat ((Chunk -> ByteString) -> [Chunk] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Chunk -> ByteString
chunkToByteString (Bytes -> [Chunk]
chunks Bytes
b))
toArray :: (BA.ByteArray b) => Bytes -> b
toArray :: forall b. ByteArray b => Bytes -> b
toArray (Bytes Rope Chunk
r) =
Int -> (Ptr Word8 -> IO ()) -> b
forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
BA.allocAndFreeze (Rope Chunk -> Int
forall a. Sized a => a -> Int
R.size Rope Chunk
r) \(Ptr Word8
p :: Ptr Word8) ->
let f :: Int -> Chunk -> IO ()
f Int
po (Chunk Int
o Int
l ByteArray
a)
| (Ptr Word8
p :: Ptr Word8) <- Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
po =
Ptr Word8 -> ByteArray -> Int -> Int -> IO ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Ptr a -> ByteArray -> Int -> Int -> m ()
copyByteArrayToPtr Ptr Word8
p ByteArray
a Int
o Int
l
in (Int -> Chunk -> IO ()) -> Rope Chunk -> IO ()
forall (f :: * -> *) a.
(Applicative f, Sized a) =>
(Int -> a -> f ()) -> Rope a -> f ()
R.traverseWithPos_ Int -> Chunk -> IO ()
f Rope Chunk
r
{-# INLINE toArray #-}
fromArray :: (BA.ByteArrayAccess b) => b -> Bytes
fromArray :: forall b. ByteArrayAccess b => b -> Bytes
fromArray b
b = Bytes -> Chunk -> Bytes
snoc Bytes
empty (b -> Chunk
forall b. ByteArrayAccess b => b -> Chunk
arrayToChunk b
b)
fromByteArray :: Int -> Int -> ByteArray -> Bytes
fromByteArray :: Int -> Int -> ByteArray -> Bytes
fromByteArray Int
o Int
l ByteArray
ba = Bytes -> Chunk -> Bytes
snoc Bytes
empty (Int -> Int -> ByteArray -> Chunk
Chunk Int
o Int
l ByteArray
ba)
toByteArray :: Bytes -> ByteArray
toByteArray :: Bytes -> ByteArray
toByteArray (Bytes Rope Chunk
r)
| R.One (Chunk Int
0 Int
l ByteArray
a) <- Rope Chunk
r,
Int
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== ByteArray -> Int
sizeofByteArray ByteArray
a =
ByteArray
a
| Bool
otherwise =
Int -> (forall s. MutableByteArray s -> ST s ()) -> ByteArray
createByteArray (Rope Chunk -> Int
forall a. Sized a => a -> Int
R.size Rope Chunk
r) \MutableByteArray s
m ->
(Int -> Chunk -> ST s ()) -> Rope Chunk -> ST s ()
forall (f :: * -> *) a.
(Applicative f, Sized a) =>
(Int -> a -> f ()) -> Rope a -> f ()
R.traverseWithPos_ (MutableByteArray (PrimState (ST s)) -> Int -> Chunk -> ST s ()
forall {m :: * -> *}.
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> Chunk -> m ()
f MutableByteArray s
MutableByteArray (PrimState (ST s))
m) Rope Chunk
r
where
f :: MutableByteArray (PrimState m) -> Int -> Chunk -> m ()
f MutableByteArray (PrimState m)
m Int
p (Chunk Int
o Int
l ByteArray
a) = MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray (PrimState m)
m Int
p ByteArray
a Int
o Int
l
byteStringToChunk, chunkFromByteString :: B.ByteString -> Chunk
byteStringToChunk :: ByteString -> Chunk
byteStringToChunk ByteString
bs
| Int
sz Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Chunk
emptyChunk
| Bool
otherwise = Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
sz \MutableByteArray s
m ->
ByteString -> (Ptr Word8 -> ST s ()) -> ST s ()
forall a s.
ByteArrayAccess a =>
a -> (Ptr Word8 -> ST s ()) -> ST s ()
withByteArrayST ByteString
bs \Ptr Word8
p ->
MutableByteArray (PrimState (ST s))
-> Int -> Ptr Word8 -> Int -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutableByteArray (PrimState m) -> Int -> Ptr a -> Int -> m ()
copyPtrToMutableByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 Ptr Word8
p Int
sz
where
sz :: Int
sz = ByteString -> Int
B.length ByteString
bs
chunkFromByteString :: ByteString -> Chunk
chunkFromByteString = ByteString -> Chunk
byteStringToChunk
chunkToByteString :: Chunk -> B.ByteString
chunkToByteString :: Chunk -> ByteString
chunkToByteString (Chunk Int
o Int
l ByteArray
a)
| Int
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ByteString
B.empty
| Bool
otherwise =
Int -> (Ptr Word8 -> IO ()) -> ByteString
forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
BA.allocAndFreeze Int
l \(Ptr Word8
p :: Ptr Word8) ->
Ptr Word8 -> ByteArray -> Int -> Int -> IO ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Ptr a -> ByteArray -> Int -> Int -> m ()
copyByteArrayToPtr Ptr Word8
p ByteArray
a Int
o Int
l
zlibCompress :: Bytes -> Bytes
zlibCompress :: Bytes -> Bytes
zlibCompress = ByteString -> Bytes
fromLazyByteString (ByteString -> Bytes) -> (Bytes -> ByteString) -> Bytes -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
Zlib.compress (ByteString -> ByteString)
-> (Bytes -> ByteString) -> Bytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteString
toLazyByteString
gzipCompress :: Bytes -> Bytes
gzipCompress :: Bytes -> Bytes
gzipCompress = ByteString -> Bytes
fromLazyByteString (ByteString -> Bytes) -> (Bytes -> ByteString) -> Bytes -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
GZip.compress (ByteString -> ByteString)
-> (Bytes -> ByteString) -> Bytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteString
toLazyByteString
zstdCompress :: Int -> Bytes -> Bytes
zstdCompress :: Int -> Bytes -> Bytes
zstdCompress Int
level = ByteString -> Bytes
fromByteString (ByteString -> Bytes) -> (Bytes -> ByteString) -> Bytes -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString -> ByteString
Zstd.compress Int
level (ByteString -> ByteString)
-> (Bytes -> ByteString) -> Bytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteString
toByteString
gzipDecompress :: Bytes -> Bytes
gzipDecompress :: Bytes -> Bytes
gzipDecompress = ByteString -> Bytes
fromLazyByteString (ByteString -> Bytes) -> (Bytes -> ByteString) -> Bytes -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
GZip.decompress (ByteString -> ByteString)
-> (Bytes -> ByteString) -> Bytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteString
toLazyByteString
zlibDecompress :: Bytes -> Bytes
zlibDecompress :: Bytes -> Bytes
zlibDecompress = ByteString -> Bytes
fromLazyByteString (ByteString -> Bytes) -> (Bytes -> ByteString) -> Bytes -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
Zlib.decompress (ByteString -> ByteString)
-> (Bytes -> ByteString) -> Bytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteString
toLazyByteString
data ZstdDecompressException = ZstdDecompressException String deriving (Int -> ZstdDecompressException -> ShowS
[ZstdDecompressException] -> ShowS
ZstdDecompressException -> [Char]
(Int -> ZstdDecompressException -> ShowS)
-> (ZstdDecompressException -> [Char])
-> ([ZstdDecompressException] -> ShowS)
-> Show ZstdDecompressException
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ZstdDecompressException -> ShowS
showsPrec :: Int -> ZstdDecompressException -> ShowS
$cshow :: ZstdDecompressException -> [Char]
show :: ZstdDecompressException -> [Char]
$cshowList :: [ZstdDecompressException] -> ShowS
showList :: [ZstdDecompressException] -> ShowS
Show, Show ZstdDecompressException
Typeable ZstdDecompressException
(Typeable ZstdDecompressException, Show ZstdDecompressException) =>
(ZstdDecompressException -> SomeException)
-> (SomeException -> Maybe ZstdDecompressException)
-> (ZstdDecompressException -> [Char])
-> (ZstdDecompressException -> Bool)
-> Exception ZstdDecompressException
SomeException -> Maybe ZstdDecompressException
ZstdDecompressException -> Bool
ZstdDecompressException -> [Char]
ZstdDecompressException -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> [Char])
-> (e -> Bool)
-> Exception e
$ctoException :: ZstdDecompressException -> SomeException
toException :: ZstdDecompressException -> SomeException
$cfromException :: SomeException -> Maybe ZstdDecompressException
fromException :: SomeException -> Maybe ZstdDecompressException
$cdisplayException :: ZstdDecompressException -> [Char]
displayException :: ZstdDecompressException -> [Char]
$cbacktraceDesired :: ZstdDecompressException -> Bool
backtraceDesired :: ZstdDecompressException -> Bool
Exception)
zstdDecompress :: Bytes -> Bytes
zstdDecompress :: Bytes -> Bytes
zstdDecompress = ByteString -> Bytes
fromByteString (ByteString -> Bytes) -> (Bytes -> ByteString) -> Bytes -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decompress -> ByteString
getOrThrow (Decompress -> ByteString)
-> (Bytes -> Decompress) -> Bytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Decompress
Zstd.decompress (ByteString -> Decompress)
-> (Bytes -> ByteString) -> Bytes -> Decompress
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteString
toByteString
where
getOrThrow :: Decompress -> ByteString
getOrThrow (Zstd.Decompress ByteString
bs) = ByteString
bs
getOrThrow Decompress
Zstd.Skip = ByteString
B.empty
getOrThrow (Zstd.Error [Char]
err) = ZstdDecompressException -> ByteString
forall a e. (HasCallStack, Exception e) => e -> a
throw (ZstdDecompressException -> ByteString)
-> ZstdDecompressException -> ByteString
forall a b. (a -> b) -> a -> b
$ [Char] -> ZstdDecompressException
ZstdDecompressException [Char]
err
toLazyByteString :: Bytes -> LB.ByteString
toLazyByteString :: Bytes -> ByteString
toLazyByteString Bytes
b = [ByteString] -> ByteString
LB.fromChunks ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ (Chunk -> ByteString) -> [Chunk] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Chunk -> ByteString
chunkToByteString ([Chunk] -> [ByteString]) -> [Chunk] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Bytes -> [Chunk]
chunks Bytes
b
fromLazyByteString :: LB.ByteString -> Bytes
fromLazyByteString :: ByteString -> Bytes
fromLazyByteString ByteString
b = [Chunk] -> Bytes
fromChunks (ByteString -> Chunk
byteStringToChunk (ByteString -> Chunk) -> [ByteString] -> [Chunk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> [ByteString]
LB.toChunks ByteString
b)
size :: Bytes -> Int
size :: Bytes -> Int
size = Rope Chunk -> Int
forall a. Sized a => a -> Int
R.size (Rope Chunk -> Int) -> (Bytes -> Rope Chunk) -> Bytes -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> Rope Chunk
underlying
chunks :: Bytes -> [Chunk]
chunks :: Bytes -> [Chunk]
chunks (Bytes Rope Chunk
bs) = Rope Chunk -> [Chunk]
forall a. Rope a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Rope Chunk
bs
byteStringChunks :: Bytes -> [B.ByteString]
byteStringChunks :: Bytes -> [ByteString]
byteStringChunks Bytes
bs = Chunk -> ByteString
chunkToByteString (Chunk -> ByteString) -> [Chunk] -> [ByteString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bytes -> [Chunk]
chunks Bytes
bs
fromChunks :: [Chunk] -> Bytes
fromChunks :: [Chunk] -> Bytes
fromChunks = (Bytes -> Chunk -> Bytes) -> Bytes -> [Chunk] -> Bytes
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Bytes -> Chunk -> Bytes
snoc Bytes
empty
cons :: Chunk -> Bytes -> Bytes
cons :: Chunk -> Bytes -> Bytes
cons Chunk
b (Bytes Rope Chunk
bs) = Rope Chunk -> Bytes
Bytes (Chunk -> Rope Chunk -> Rope Chunk
forall a. (Sized a, Semigroup a) => a -> Rope a -> Rope a
R.cons Chunk
b Rope Chunk
bs)
snoc :: Bytes -> Chunk -> Bytes
snoc :: Bytes -> Chunk -> Bytes
snoc (Bytes Rope Chunk
bs) Chunk
b = Rope Chunk -> Bytes
Bytes (Rope Chunk -> Chunk -> Rope Chunk
forall a. (Sized a, Semigroup a) => Rope a -> a -> Rope a
R.snoc Rope Chunk
bs Chunk
b)
flatten :: Bytes -> Bytes
flatten :: Bytes -> Bytes
flatten Bytes
bs = Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes)
-> (ByteArray -> Rope Chunk) -> ByteArray -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Rope Chunk)
-> (ByteArray -> Chunk) -> ByteArray -> Rope Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> ByteArray -> Chunk
Chunk Int
0 Int
sz (ByteArray -> Bytes) -> ByteArray -> Bytes
forall a b. (a -> b) -> a -> b
$ Bytes -> ByteArray
toByteArray Bytes
bs
where
sz :: Int
sz = Bytes -> Int
size Bytes
bs
take :: Int -> Bytes -> Bytes
take :: Int -> Bytes -> Bytes
take Int
n (Bytes Rope Chunk
bs) = Rope Chunk -> Bytes
Bytes (Int -> Rope Chunk -> Rope Chunk
forall a. Take a => Int -> a -> a
R.take Int
n Rope Chunk
bs)
drop :: Int -> Bytes -> Bytes
drop :: Int -> Bytes -> Bytes
drop Int
n (Bytes Rope Chunk
bs) = Rope Chunk -> Bytes
Bytes (Int -> Rope Chunk -> Rope Chunk
forall a. Drop a => Int -> a -> a
R.drop Int
n Rope Chunk
bs)
indexOf :: Bytes -> Bytes -> Maybe Word64
indexOf :: Bytes -> Bytes -> Maybe Word64
indexOf Bytes
needle Bytes
haystack =
case ByteString -> ByteString -> [Int64]
SS.indices ByteString
needle' ByteString
haystack' of
[] -> Maybe Word64
forall a. Maybe a
Nothing
(Int64
i : [Int64]
_) -> Word64 -> Maybe Word64
forall a. a -> Maybe a
Just (Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i)
where
needle' :: ByteString
needle' = Bytes -> ByteString
toByteString Bytes
needle
haystack' :: ByteString
haystack' = Bytes -> ByteString
toLazyByteString Bytes
haystack
at, index :: Int -> Bytes -> Maybe Word8
at :: Int -> Bytes -> Maybe Word8
at Int
n (Bytes Rope Chunk
bs) = Int -> Rope Chunk -> Maybe Word8
forall a ch. (Sized a, Index a ch) => Int -> Rope a -> Maybe ch
R.index Int
n Rope Chunk
bs
index :: Int -> Bytes -> Maybe Word8
index = Int -> Bytes -> Maybe Word8
at
index16be :: Int -> Bytes -> Maybe Word16
index16be :: Int -> Bytes -> Maybe Word16
index16be Int
i Bytes
bs
| Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Bytes -> Int
size Bytes
bs = Maybe Word16
forall a. Maybe a
Nothing
| ByteArray
ba <- Int -> Int -> Bytes -> ByteArray
extractChunkArr Int
i Int
2 Bytes
bs =
Word16 -> Maybe Word16
forall a. a -> Maybe a
Just (Word16 -> Maybe Word16)
-> (Word16 -> Word16) -> Word16 -> Maybe Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> Word16) -> Word16 -> Word16
forall a. (a -> a) -> a -> a
whenLittleEndian Word16 -> Word16
byteSwap16 (Word16 -> Maybe Word16) -> Word16 -> Maybe Word16
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word16
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
index16le :: Int -> Bytes -> Maybe Word16
index16le :: Int -> Bytes -> Maybe Word16
index16le Int
i Bytes
bs
| Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Bytes -> Int
size Bytes
bs = Maybe Word16
forall a. Maybe a
Nothing
| ByteArray
ba <- Int -> Int -> Bytes -> ByteArray
extractChunkArr Int
i Int
2 Bytes
bs =
Word16 -> Maybe Word16
forall a. a -> Maybe a
Just (Word16 -> Maybe Word16)
-> (Word16 -> Word16) -> Word16 -> Maybe Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> Word16) -> Word16 -> Word16
forall a. (a -> a) -> a -> a
whenBigEndian Word16 -> Word16
byteSwap16 (Word16 -> Maybe Word16) -> Word16 -> Maybe Word16
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word16
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
index32be :: Int -> Bytes -> Maybe Word32
index32be :: Int -> Bytes -> Maybe Word32
index32be Int
i Bytes
bs
| Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Bytes -> Int
size Bytes
bs = Maybe Word32
forall a. Maybe a
Nothing
| ByteArray
ba <- Int -> Int -> Bytes -> ByteArray
extractChunkArr Int
i Int
4 Bytes
bs =
Word32 -> Maybe Word32
forall a. a -> Maybe a
Just (Word32 -> Maybe Word32)
-> (Word32 -> Word32) -> Word32 -> Maybe Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word32) -> Word32 -> Word32
forall a. (a -> a) -> a -> a
whenLittleEndian Word32 -> Word32
byteSwap32 (Word32 -> Maybe Word32) -> Word32 -> Maybe Word32
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word32
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
index32le :: Int -> Bytes -> Maybe Word32
index32le :: Int -> Bytes -> Maybe Word32
index32le Int
i Bytes
bs
| Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Bytes -> Int
size Bytes
bs = Maybe Word32
forall a. Maybe a
Nothing
| ByteArray
ba <- Int -> Int -> Bytes -> ByteArray
extractChunkArr Int
i Int
4 Bytes
bs =
Word32 -> Maybe Word32
forall a. a -> Maybe a
Just (Word32 -> Maybe Word32)
-> (Word32 -> Word32) -> Word32 -> Maybe Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word32) -> Word32 -> Word32
forall a. (a -> a) -> a -> a
whenBigEndian Word32 -> Word32
byteSwap32 (Word32 -> Maybe Word32) -> Word32 -> Maybe Word32
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word32
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
index64be :: Int -> Bytes -> Maybe Word64
index64be :: Int -> Bytes -> Maybe Word64
index64be Int
i Bytes
bs
| Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Bytes -> Int
size Bytes
bs = Maybe Word64
forall a. Maybe a
Nothing
| ByteArray
ba <- Int -> Int -> Bytes -> ByteArray
extractChunkArr Int
i Int
8 Bytes
bs =
Word64 -> Maybe Word64
forall a. a -> Maybe a
Just (Word64 -> Maybe Word64)
-> (Word64 -> Word64) -> Word64 -> Maybe Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64) -> Word64 -> Word64
forall a. (a -> a) -> a -> a
whenLittleEndian Word64 -> Word64
byteSwap64 (Word64 -> Maybe Word64) -> Word64 -> Maybe Word64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word64
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
index64le :: Int -> Bytes -> Maybe Word64
index64le :: Int -> Bytes -> Maybe Word64
index64le Int
i Bytes
bs
| Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Bytes -> Int
size Bytes
bs = Maybe Word64
forall a. Maybe a
Nothing
| ByteArray
ba <- Int -> Int -> Bytes -> ByteArray
extractChunkArr Int
i Int
8 Bytes
bs =
Word64 -> Maybe Word64
forall a. a -> Maybe a
Just (Word64 -> Maybe Word64)
-> (Word64 -> Word64) -> Word64 -> Maybe Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64) -> Word64 -> Word64
forall a. (a -> a) -> a -> a
whenBigEndian Word64 -> Word64
byteSwap64 (Word64 -> Maybe Word64) -> Word64 -> Maybe Word64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word64
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
dropBlock :: Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock :: Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
nBytes (Bytes Rope Chunk
chunks)
| Rope Chunk -> Int
forall a. Sized a => a -> Int
R.size Rope Chunk
chunks Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
nBytes = Maybe (Chunk, Bytes)
forall a. Maybe a
Nothing
| Bool
otherwise = case Rope Chunk -> Maybe (Chunk, Rope Chunk)
forall a. Sized a => Rope a -> Maybe (a, Rope a)
R.uncons Rope Chunk
chunks of
Maybe (Chunk, Rope Chunk)
Nothing -> Maybe (Chunk, Bytes)
forall a. Maybe a
Nothing
Just (Chunk
c, Rope Chunk
cs)
| Chunk -> Int
forall a. Sized a => a -> Int
R.size Chunk
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
nBytes ->
(Chunk, Bytes) -> Maybe (Chunk, Bytes)
forall a. a -> Maybe a
Just (Chunk
c, Rope Chunk -> Bytes
Bytes Rope Chunk
cs)
| Chunk -> Int
forall a. Sized a => a -> Int
R.size Chunk
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
nBytes ->
(Chunk, Bytes) -> Maybe (Chunk, Bytes)
forall a. a -> Maybe a
Just (Int -> Chunk -> Chunk
forall a. Take a => Int -> a -> a
R.take Int
nBytes Chunk
c, Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> Rope Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Chunk -> Rope Chunk -> Rope Chunk
forall a. (Sized a, Semigroup a) => a -> Rope a -> Rope a
R.cons (Int -> Chunk -> Chunk
forall a. Drop a => Int -> a -> a
R.drop Int
nBytes Chunk
c) Rope Chunk
cs)
| Chunk Int
o Int
l ByteArray
a <- Chunk
c ->
(Chunk, Bytes) -> Maybe (Chunk, Bytes)
forall a. a -> Maybe a
Just ((Chunk, Bytes) -> Maybe (Chunk, Bytes))
-> (Chunk, Bytes) -> Maybe (Chunk, Bytes)
forall a b. (a -> b) -> a -> b
$ Int
-> (forall s. MutableByteArray s -> ST s Bytes) -> (Chunk, Bytes)
forall r.
Int -> (forall s. MutableByteArray s -> ST s r) -> (Chunk, r)
gCreateChunk Int
nBytes \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 ByteArray
a Int
o Int
l ST s () -> ST s Bytes -> ST s Bytes
forall a b. ST s a -> ST s b -> ST s b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> MutableByteArray s -> Int -> Rope Chunk -> ST s Bytes
forall s. MutableByteArray s -> Int -> Rope Chunk -> ST s Bytes
crawl MutableByteArray s
m Int
l Rope Chunk
cs
where
crawl :: MutableByteArray s -> Int -> R.Rope Chunk -> ST s Bytes
crawl :: forall s. MutableByteArray s -> Int -> Rope Chunk -> ST s Bytes
crawl MutableByteArray s
m Int
pos Rope Chunk
chunks = case Rope Chunk -> Maybe (Chunk, Rope Chunk)
forall a. Sized a => Rope a -> Maybe (a, Rope a)
R.uncons Rope Chunk
chunks of
Just (c :: Chunk
c@(Chunk Int
o Int
l ByteArray
a), Rope Chunk
cs)
| Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
pos Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
nBytes ->
Rope Chunk -> Bytes
Bytes Rope Chunk
cs Bytes -> ST s () -> ST s Bytes
forall a b. a -> ST s b -> ST s a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
pos ByteArray
a Int
o Int
l
| Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
nBytes,
Int
ln <- Int
nBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
pos,
Chunk
c <- Int -> Chunk -> Chunk
forall a. Drop a => Int -> a -> a
R.drop Int
ln Chunk
c ->
Rope Chunk -> Bytes
Bytes (Chunk -> Rope Chunk -> Rope Chunk
forall a. (Sized a, Semigroup a) => a -> Rope a -> Rope a
R.cons Chunk
c Rope Chunk
cs) Bytes -> ST s () -> ST s Bytes
forall a b. a -> ST s b -> ST s a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
pos ByteArray
a Int
o Int
ln
Maybe (Chunk, Rope Chunk)
_ -> Bytes -> ST s Bytes
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bytes -> ST s Bytes) -> Bytes -> ST s Bytes
forall a b. (a -> b) -> a -> b
$ Rope Chunk -> Bytes
Bytes Rope Chunk
chunks
decodeNat64be :: Bytes -> Maybe (Word64, Bytes)
decodeNat64be :: Bytes -> Maybe (Word64, Bytes)
decodeNat64be Bytes
bs = case Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
8 Bytes
bs of
Just (Chunk
head, Bytes
rest) -> (Word64, Bytes) -> Maybe (Word64, Bytes)
forall a. a -> Maybe a
Just (Word64
w, Bytes
rest)
where
ba :: ByteArray
ba = Int -> Chunk -> ByteArray
fixAlign Int
8 Chunk
head
w :: Word64
w = (Word64 -> Word64) -> Word64 -> Word64
forall a. (a -> a) -> a -> a
whenLittleEndian Word64 -> Word64
byteSwap64 (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word64
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
Maybe (Chunk, Bytes)
Nothing -> Maybe (Word64, Bytes)
forall a. Maybe a
Nothing
decodeNat64le :: Bytes -> Maybe (Word64, Bytes)
decodeNat64le :: Bytes -> Maybe (Word64, Bytes)
decodeNat64le Bytes
bs = case Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
8 Bytes
bs of
Just (Chunk
head, Bytes
rest) -> (Word64, Bytes) -> Maybe (Word64, Bytes)
forall a. a -> Maybe a
Just (Word64
w, Bytes
rest)
where
ba :: ByteArray
ba = Int -> Chunk -> ByteArray
fixAlign Int
8 Chunk
head
w :: Word64
w = (Word64 -> Word64) -> Word64 -> Word64
forall a. (a -> a) -> a -> a
whenBigEndian Word64 -> Word64
byteSwap64 (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word64
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
Maybe (Chunk, Bytes)
Nothing -> Maybe (Word64, Bytes)
forall a. Maybe a
Nothing
decodeNat32be :: Bytes -> Maybe (Word64, Bytes)
decodeNat32be :: Bytes -> Maybe (Word64, Bytes)
decodeNat32be Bytes
bs = case Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
4 Bytes
bs of
Just (Chunk
head, Bytes
rest) -> (Word64, Bytes) -> Maybe (Word64, Bytes)
forall a. a -> Maybe a
Just (Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
w, Bytes
rest)
where
ba :: ByteArray
ba = Int -> Chunk -> ByteArray
fixAlign Int
4 Chunk
head
w :: Word32
w = (Word32 -> Word32) -> Word32 -> Word32
forall a. (a -> a) -> a -> a
whenLittleEndian Word32 -> Word32
byteSwap32 (Word32 -> Word32) -> Word32 -> Word32
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word32
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
Maybe (Chunk, Bytes)
Nothing -> Maybe (Word64, Bytes)
forall a. Maybe a
Nothing
decodeNat32le :: Bytes -> Maybe (Word64, Bytes)
decodeNat32le :: Bytes -> Maybe (Word64, Bytes)
decodeNat32le Bytes
bs = case Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
4 Bytes
bs of
Just (Chunk
head, Bytes
rest) -> (Word64, Bytes) -> Maybe (Word64, Bytes)
forall a. a -> Maybe a
Just (Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
w, Bytes
rest)
where
ba :: ByteArray
ba = Int -> Chunk -> ByteArray
fixAlign Int
4 Chunk
head
w :: Word32
w = (Word32 -> Word32) -> Word32 -> Word32
forall a. (a -> a) -> a -> a
whenBigEndian Word32 -> Word32
byteSwap32 (Word32 -> Word32) -> Word32 -> Word32
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word32
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
Maybe (Chunk, Bytes)
Nothing -> Maybe (Word64, Bytes)
forall a. Maybe a
Nothing
decodeNat16be :: Bytes -> Maybe (Word64, Bytes)
decodeNat16be :: Bytes -> Maybe (Word64, Bytes)
decodeNat16be Bytes
bs = case Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
2 Bytes
bs of
Just (Chunk
head, Bytes
rest) -> (Word64, Bytes) -> Maybe (Word64, Bytes)
forall a. a -> Maybe a
Just (Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
w, Bytes
rest)
where
ba :: ByteArray
ba = Int -> Chunk -> ByteArray
fixAlign Int
2 Chunk
head
w :: Word16
w = (Word16 -> Word16) -> Word16 -> Word16
forall a. (a -> a) -> a -> a
whenLittleEndian Word16 -> Word16
byteSwap16 (Word16 -> Word16) -> Word16 -> Word16
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word16
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
Maybe (Chunk, Bytes)
Nothing -> Maybe (Word64, Bytes)
forall a. Maybe a
Nothing
decodeNat16le :: Bytes -> Maybe (Word64, Bytes)
decodeNat16le :: Bytes -> Maybe (Word64, Bytes)
decodeNat16le Bytes
bs = case Int -> Bytes -> Maybe (Chunk, Bytes)
dropBlock Int
2 Bytes
bs of
Just (Chunk
head, Bytes
rest) -> (Word64, Bytes) -> Maybe (Word64, Bytes)
forall a. a -> Maybe a
Just (Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
w, Bytes
rest)
where
ba :: ByteArray
ba = Int -> Chunk -> ByteArray
fixAlign Int
2 Chunk
head
w :: Word16
w = (Word16 -> Word16) -> Word16 -> Word16
forall a. (a -> a) -> a -> a
whenBigEndian Word16 -> Word16
byteSwap16 (Word16 -> Word16) -> Word16 -> Word16
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word16
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
ba Int
0
Maybe (Chunk, Bytes)
Nothing -> Maybe (Word64, Bytes)
forall a. Maybe a
Nothing
encodeNat64be :: Word64 -> Bytes
encodeNat64be :: Word64 -> Bytes
encodeNat64be Word64
n =
Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> (Chunk -> Rope Chunk) -> Chunk -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Bytes) -> Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
8 \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s)) -> Int -> Word64 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 (Word64 -> ST s ()) -> (Word64 -> Word64) -> Word64 -> ST s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64) -> Word64 -> Word64
forall a. (a -> a) -> a -> a
whenLittleEndian Word64 -> Word64
byteSwap64 (Word64 -> ST s ()) -> Word64 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n
encodeNat32be :: Word64 -> Bytes
encodeNat32be :: Word64 -> Bytes
encodeNat32be Word64
n =
Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> (Chunk -> Rope Chunk) -> Chunk -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Bytes) -> Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
4 \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s)) -> Int -> Word32 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 (Word32 -> ST s ()) -> (Word32 -> Word32) -> Word32 -> ST s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word32) -> Word32 -> Word32
forall a. (a -> a) -> a -> a
whenLittleEndian Word32 -> Word32
byteSwap32 (Word32 -> ST s ()) -> Word32 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n
encodeNat16be :: Word64 -> Bytes
encodeNat16be :: Word64 -> Bytes
encodeNat16be Word64
n =
Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> (Chunk -> Rope Chunk) -> Chunk -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Bytes) -> Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
2 \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s)) -> Int -> Word16 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 (Word16 -> ST s ()) -> (Word16 -> Word16) -> Word16 -> ST s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> Word16) -> Word16 -> Word16
forall a. (a -> a) -> a -> a
whenLittleEndian Word16 -> Word16
byteSwap16 (Word16 -> ST s ()) -> Word16 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n
encodeNat64le :: Word64 -> Bytes
encodeNat64le :: Word64 -> Bytes
encodeNat64le Word64
n =
Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> (Chunk -> Rope Chunk) -> Chunk -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Bytes) -> Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
8 \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s)) -> Int -> Word64 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 (Word64 -> ST s ()) -> (Word64 -> Word64) -> Word64 -> ST s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64) -> Word64 -> Word64
forall a. (a -> a) -> a -> a
whenBigEndian Word64 -> Word64
byteSwap64 (Word64 -> ST s ()) -> Word64 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n
encodeNat32le :: Word64 -> Bytes
encodeNat32le :: Word64 -> Bytes
encodeNat32le Word64
n =
Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> (Chunk -> Rope Chunk) -> Chunk -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Bytes) -> Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
4 \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s)) -> Int -> Word32 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 (Word32 -> ST s ()) -> (Word32 -> Word32) -> Word32 -> ST s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word32) -> Word32 -> Word32
forall a. (a -> a) -> a -> a
whenBigEndian Word32 -> Word32
byteSwap32 (Word32 -> ST s ()) -> Word32 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n
encodeNat16le :: Word64 -> Bytes
encodeNat16le :: Word64 -> Bytes
encodeNat16le Word64
n =
Rope Chunk -> Bytes
Bytes (Rope Chunk -> Bytes) -> (Chunk -> Rope Chunk) -> Chunk -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk -> Rope Chunk
forall a. Sized a => a -> Rope a
R.one (Chunk -> Bytes) -> Chunk -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> (forall s. MutableByteArray s -> ST s ()) -> Chunk
createChunk Int
2 \MutableByteArray s
m ->
MutableByteArray (PrimState (ST s)) -> Int -> Word16 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
m Int
0 (Word16 -> ST s ()) -> (Word16 -> Word16) -> Word16 -> ST s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> Word16) -> Word16 -> Word16
forall a. (a -> a) -> a -> a
whenBigEndian Word16 -> Word16
byteSwap16 (Word16 -> ST s ()) -> Word16 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n
toBase16 :: Bytes -> Bytes
toBase16 :: Bytes -> Bytes
toBase16 Bytes
bs = (Bytes -> Chunk -> Bytes) -> Bytes -> [Chunk] -> Bytes
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Bytes -> Chunk -> Bytes
step Bytes
empty (Bytes -> [Chunk]
chunks Bytes
bs)
where
step :: Bytes -> Chunk -> Bytes
step Bytes
bs Chunk
b =
Bytes -> Chunk -> Bytes
snoc
Bytes
bs
( forall b. ByteArrayAccess b => b -> Chunk
arrayToChunk @BA.Bytes (Bytes -> Chunk) -> Bytes -> Chunk
forall a b. (a -> b) -> a -> b
$
Base -> Bytes -> Bytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
BE.convertToBase Base
BE.Base16 (forall b. ByteArray b => Chunk -> b
chunkToArray @BA.Bytes Chunk
b)
)
chunkToArray, arrayFromChunk :: (BA.ByteArray b) => Chunk -> b
chunkToArray :: forall b. ByteArray b => Chunk -> b
chunkToArray (Chunk Int
o Int
l ByteArray
a) =
Int -> (Ptr Word8 -> IO ()) -> b
forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
BA.allocAndFreeze Int
l ((Ptr Word8 -> IO ()) -> b) -> (Ptr Word8 -> IO ()) -> b
forall a b. (a -> b) -> a -> b
$ \(Ptr Word8
ptr :: Ptr Word8) ->
Ptr Word8 -> ByteArray -> Int -> Int -> IO ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Ptr a -> ByteArray -> Int -> Int -> m ()
copyByteArrayToPtr Ptr Word8
ptr ByteArray
a Int
o Int
l
arrayFromChunk :: forall b. ByteArray b => Chunk -> b
arrayFromChunk = Chunk -> b
forall b. ByteArray b => Chunk -> b
chunkToArray
arrayToChunk, chunkFromArray :: (BA.ByteArrayAccess b) => b -> Chunk
arrayToChunk :: forall b. ByteArrayAccess b => b -> Chunk
arrayToChunk b
bs = case b -> Block Word8
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert b
bs :: Block Word8 of
Block ByteArray#
bs -> Int -> Int -> ByteArray -> Chunk
Chunk Int
0 Int
n (ByteArray# -> ByteArray
ByteArray ByteArray#
bs)
where
n :: Int
n = b -> Int
forall ba. ByteArrayAccess ba => ba -> Int
BA.length b
bs
{-# INLINE arrayToChunk #-}
chunkFromArray :: forall b. ByteArrayAccess b => b -> Chunk
chunkFromArray = b -> Chunk
forall b. ByteArrayAccess b => b -> Chunk
arrayToChunk
fromBase16 :: Bytes -> Either Text.Text Bytes
fromBase16 :: Bytes -> Either Text Bytes
fromBase16 = Base -> Bytes -> Either Text Bytes
fromBase Base
BE.Base16
toBase32, toBase64, toBase64UrlUnpadded :: Bytes -> Bytes
toBase32 :: Bytes -> Bytes
toBase32 = Base -> Bytes -> Bytes
toBase Base
BE.Base32
toBase64 :: Bytes -> Bytes
toBase64 = Base -> Bytes -> Bytes
toBase Base
BE.Base64
toBase64UrlUnpadded :: Bytes -> Bytes
toBase64UrlUnpadded = Base -> Bytes -> Bytes
toBase Base
BE.Base64URLUnpadded
fromBase32, fromBase64, fromBase64UrlUnpadded :: Bytes -> Either Text.Text Bytes
fromBase32 :: Bytes -> Either Text Bytes
fromBase32 = Base -> Bytes -> Either Text Bytes
fromBase Base
BE.Base32
fromBase64 :: Bytes -> Either Text Bytes
fromBase64 = Base -> Bytes -> Either Text Bytes
fromBase Base
BE.Base64
fromBase64UrlUnpadded :: Bytes -> Either Text Bytes
fromBase64UrlUnpadded = Base -> Bytes -> Either Text Bytes
fromBase Base
BE.Base64URLUnpadded
fromBase :: BE.Base -> Bytes -> Either Text.Text Bytes
fromBase :: Base -> Bytes -> Either Text Bytes
fromBase Base
e Bytes
bs = case Base -> Bytes -> Either [Char] Bytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> Either [Char] bout
BE.convertFromBase Base
e (forall b. ByteArray b => Bytes -> b
toArray @BA.Bytes Bytes
bs) of
Left [Char]
e -> Text -> Either Text Bytes
forall a b. a -> Either a b
Left ([Char] -> Text
Text.pack [Char]
e)
Right Bytes
b -> Bytes -> Either Text Bytes
forall a b. b -> Either a b
Right (Bytes -> Either Text Bytes) -> Bytes -> Either Text Bytes
forall a b. (a -> b) -> a -> b
$ Bytes -> Chunk -> Bytes
snoc Bytes
empty (Bytes -> Chunk
forall b. ByteArrayAccess b => b -> Chunk
chunkFromArray (Bytes
b :: BA.Bytes))
toBase :: BE.Base -> Bytes -> Bytes
toBase :: Base -> Bytes -> Bytes
toBase Base
e Bytes
bs = Bytes -> Chunk -> Bytes
snoc Bytes
empty (Bytes -> Chunk
forall b. ByteArrayAccess b => b -> Chunk
arrayToChunk Bytes
arr)
where
arr :: BA.Bytes
arr :: Bytes
arr = Base -> Bytes -> Bytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
BE.convertToBase Base
e (forall b. ByteArray b => Bytes -> b
toArray @BA.Bytes Bytes
bs)
toWord8s :: Bytes -> [Word8]
toWord8s :: Bytes -> [Word8]
toWord8s Bytes
bs = Bytes -> [Chunk]
chunks Bytes
bs [Chunk] -> (Chunk -> [Word8]) -> [Word8]
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Chunk -> [Word8]
forall {a}. Prim a => Chunk -> [a]
toList
where
toList :: Chunk -> [a]
toList (Chunk Int
o Int
l ByteArray
a) = Int -> [a]
unf Int
o
where
n :: Int
n = Int
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l
unf :: Int -> [a]
unf Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = ByteArray -> Int -> a
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
a Int
i a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> [a]
unf (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = []
fromWord8s :: [Word8] -> Bytes
fromWord8s :: [Word8] -> Bytes
fromWord8s [Word8]
bs = Bytes -> Chunk -> Bytes
snoc Bytes
empty (Chunk -> Bytes) -> (ByteArray -> Chunk) -> ByteArray -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> ByteArray -> Chunk
Chunk Int
0 Int
sz (ByteArray -> Bytes) -> ByteArray -> Bytes
forall a b. (a -> b) -> a -> b
$ Int -> [Word8] -> ByteArray
forall a. Prim a => Int -> [a] -> ByteArray
byteArrayFromListN Int
sz [Word8]
bs
where
!sz :: Int
sz = [Word8] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Word8]
bs
hash64AddBytes :: Bytes -> Hash64 -> Hash64
hash64AddBytes :: Bytes -> Hash64 -> Hash64
hash64AddBytes Bytes
bs Hash64
h = (Hash64 -> Chunk -> Hash64) -> Hash64 -> Rope Chunk -> Hash64
forall b a. (b -> a -> b) -> b -> Rope a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Hash64 -> Chunk -> Hash64
addChunk Hash64
h (Rope Chunk -> Hash64) -> Rope Chunk -> Hash64
forall a b. (a -> b) -> a -> b
$ Bytes -> Rope Chunk
underlying Bytes
bs
where
addChunk :: Hash64 -> Chunk -> Hash64
addChunk = (Hash64 -> Word8 -> Hash64) -> Hash64 -> Chunk -> Hash64
forall r. (r -> Word8 -> r) -> r -> Chunk -> r
foldl'Chunk (\Hash64
h Word8
b -> Int -> Hash64 -> Hash64
hash64AddInt (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b) Hash64
h)
instance Show Bytes where
show :: Bytes -> [Char]
show Bytes
bs = Bytes -> [Word8]
toWord8s (Bytes -> Bytes
toBase16 Bytes
bs) [Word8] -> (Word8 -> [Char]) -> [Char]
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
w -> [Int -> Char
chr (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w)]