{-# language CPP #-}
{-# language BangPatterns #-}
{-# language BinaryLiterals #-}
{-# language DataKinds #-}
{-# language KindSignatures #-}
{-# language LambdaCase #-}
{-# language MagicHash #-}
{-# language RankNTypes #-}
{-# language ScopedTypeVariables #-}
{-# language TypeApplications #-}
{-# language TypeOperators #-}
{-# language UnboxedTuples #-}
{-# language UnliftedFFITypes #-}

-- | The functions in this module are explict about the maximum number
-- of bytes they require.
module Data.Bytes.Builder.Bounded
  ( -- * Builder
    Builder
    -- * Execute
  , run
  , runByteString
  , pasteGrowST
    -- * Combine
  , empty
  , append
    -- * Bounds Manipulation
  , weaken
  , substitute
    -- * Encode Integral Types
    -- ** Human-Readable
  , word64Dec
  , word32Dec
  , word16Dec
  , word8Dec
  , wordDec
  , int64Dec
  , int32Dec
  , int16Dec
  , int8Dec
  , intDec
    -- * Unsigned Words
    -- ** Wide Words
  , word128PaddedLowerHex
  , word128PaddedUpperHex
  , word256PaddedLowerHex
  , word256PaddedUpperHex
    -- ** 64-bit
  , word64PaddedLowerHex
  , word64PaddedUpperHex
    -- ** 48-bit
  , word48PaddedLowerHex
    -- ** 32-bit
  , word32PaddedLowerHex
  , word32PaddedUpperHex
    -- ** 16-bit
  , word16PaddedLowerHex
  , word16PaddedUpperHex
  , word16LowerHex
  , word16UpperHex
    -- ** 8-bit
  , word8PaddedLowerHex
  , word8PaddedUpperHex
  , word8LowerHex
  , ascii
  , ascii2
  , ascii3
  , ascii4
  , ascii5
  , ascii6
  , ascii7
  , ascii8
  , char
    -- ** Native
  , wordPaddedDec2
  , wordPaddedDec4
  , wordPaddedDec9
    -- ** Machine-Readable
    -- *** One
  , word8
    -- **** Big Endian
  , word256BE
  , word128BE
  , word64BE
  , word32BE
  , word16BE
  , int64BE
  , int32BE
  , int16BE
    -- **** Little Endian
  , word256LE
  , word128LE
  , word64LE
  , word32LE
  , word16LE
  , int64LE
  , int32LE
  , int16LE
    -- **** LEB128
  , wordLEB128
  , word32LEB128
  , word64LEB128
    -- * Encode Floating-Point Types
  , doubleDec
  ) where

import Arithmetic.Types (type (<=), type (:=:))
import Control.Monad.Primitive (primitive_)
import Control.Monad.ST (ST)
import Control.Monad.ST.Run (runByteArrayST,runIntByteArrayST)
import Data.Bits
import Data.Bytes.Builder.Bounded.Unsafe (Builder(..))
import Data.ByteString (ByteString)
import Data.Char (ord)
import Data.Primitive (MutableByteArray(..),ByteArray,writeByteArray)
import Data.Primitive (readByteArray,newByteArray,unsafeFreezeByteArray)
import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..))
import Data.WideWord (Word128(Word128),Word256(Word256))
import GHC.Exts
import GHC.Int (Int64(I64#),Int32(I32#),Int16(I16#),Int8(I8#))
import GHC.IO (unsafeIOToST)
import GHC.ST (ST(ST))
import GHC.TypeLits (type (+))
import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#))
import Data.Bytes.Types (Bytes(Bytes))

import qualified Compat as C

import qualified Arithmetic.Lte as Lte
import qualified Arithmetic.Nat as Nat
import qualified Arithmetic.Types as Arithmetic
import qualified Data.Bytes as Bytes
import qualified Data.Bytes.Builder.Bounded.Unsafe as Unsafe
import qualified Data.Primitive as PM

-- | Execute the bounded builder. If the size is a constant,
-- use @Arithmetic.Nat.constant@ as the first argument to let
-- GHC conjure up this value for you.
run ::
     Arithmetic.Nat n
  -> Builder n -- ^ Builder
  -> ByteArray
{-# inline run #-}
run :: forall (n :: Nat). Nat n -> Builder n -> ByteArray
run Nat n
n Builder n
b = (forall s. ST s ByteArray) -> ByteArray
runByteArrayST forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray s
arr <- forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (forall (n :: Nat). Nat n -> Int
Nat.demote Nat n
n)
  Int
len <- forall (n :: Nat) s.
Builder n -> MutableByteArray s -> Int -> ST s Int
Unsafe.pasteST Builder n
b MutableByteArray s
arr Int
0
  forall s. MutableByteArray s -> Int -> ST s ()
shrinkMutableByteArray MutableByteArray s
arr Int
len
  forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
arr

-- | Variant of 'run' that puts the result in a pinned buffer and
-- packs it up in a 'ByteString'.
runByteString ::
     Arithmetic.Nat n
  -> Builder n -- ^ Builder
  -> ByteString
{-# inline runByteString #-}
runByteString :: forall (n :: Nat). Nat n -> Builder n -> ByteString
runByteString Nat n
n Builder n
b =
  let (Int
finalLen,ByteArray
r) = (forall s. ST s (Int, ByteArray)) -> (Int, ByteArray)
runIntByteArrayST forall a b. (a -> b) -> a -> b
$ do
        MutableByteArray s
arr <- forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newPinnedByteArray (forall (n :: Nat). Nat n -> Int
Nat.demote Nat n
n)
        Int
len <- forall (n :: Nat) s.
Builder n -> MutableByteArray s -> Int -> ST s Int
Unsafe.pasteST Builder n
b MutableByteArray s
arr Int
0
        forall s. MutableByteArray s -> Int -> ST s ()
shrinkMutableByteArray MutableByteArray s
arr Int
len
        ByteArray
arr' <- forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
arr
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
len,ByteArray
arr')
   in Bytes -> ByteString
Bytes.pinnedToByteString (ByteArray -> Int -> Int -> Bytes
Bytes ByteArray
r Int
0 Int
finalLen)

-- | Paste the builder into the byte array starting at offset zero.
-- This reallocates the byte array if it cannot accomodate the builder,
-- growing it by the minimum amount necessary.
pasteGrowST ::
     Arithmetic.Nat n
  -> Builder n
  -> MutableByteArrayOffset s
     -- ^ Initial buffer, used linearly. Do not reuse this argument.
  -> ST s (MutableByteArrayOffset s)
     -- ^ Final buffer that accomodated the builder.
{-# inline pasteGrowST #-}
pasteGrowST :: forall (n :: Nat) s.
Nat n
-> Builder n
-> MutableByteArrayOffset s
-> ST s (MutableByteArrayOffset s)
pasteGrowST Nat n
n Builder n
b !(MutableByteArrayOffset{$sel:array:MutableByteArrayOffset :: forall s. MutableByteArrayOffset s -> MutableByteArray s
array=MutableByteArray s
arr0,$sel:offset:MutableByteArrayOffset :: forall s. MutableByteArrayOffset s -> Int
offset=Int
off0}) = do
  Int
sz0 <- forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
PM.getSizeofMutableByteArray MutableByteArray s
arr0
  let req :: Int
req = forall (n :: Nat). Nat n -> Int
Nat.demote Nat n
n
  let sz1 :: Int
sz1 = Int
off0 forall a. Num a => a -> a -> a
+ Int
req
  if Int
sz1 forall a. Ord a => a -> a -> Bool
<= Int
sz0
    then do
      Int
off1 <- forall (n :: Nat) s.
Builder n -> MutableByteArray s -> Int -> ST s Int
Unsafe.pasteST Builder n
b MutableByteArray s
arr0 Int
off0
      forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall s. MutableByteArray s -> Int -> MutableByteArrayOffset s
MutableByteArrayOffset MutableByteArray s
arr0 Int
off1)
    else do
      MutableByteArray s
arr1 <- forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> m (MutableByteArray (PrimState m))
PM.resizeMutableByteArray MutableByteArray s
arr0 Int
sz1
      Int
off1 <- forall (n :: Nat) s.
Builder n -> MutableByteArray s -> Int -> ST s Int
Unsafe.pasteST Builder n
b MutableByteArray s
arr1 Int
off0
      forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall s. MutableByteArray s -> Int -> MutableByteArrayOffset s
MutableByteArrayOffset MutableByteArray s
arr1 Int
off1)

-- | The monoidal unit of `append`
empty :: Builder 0
empty :: Builder 0
empty = forall (a :: Nat).
(forall s.
 MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #))
-> Builder a
Builder forall a b. (a -> b) -> a -> b
$ \MutableByteArray# s
_ Int#
off0 State# s
s0 -> (# State# s
s0, Int#
off0 #)

infixr 9 `append`

-- | Concatenate two builders.
append :: Builder m -> Builder n -> Builder (m + n)
append :: forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
append = forall (m :: Nat) (n :: Nat) (p :: Nat).
Builder m -> Builder n -> Builder p
unsafeAppend

unsafeAppend :: Builder m -> Builder n -> Builder p
unsafeAppend :: forall (m :: Nat) (n :: Nat) (p :: Nat).
Builder m -> Builder n -> Builder p
unsafeAppend (Builder forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
f) (Builder forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
g) =
  forall (a :: Nat).
(forall s.
 MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #))
-> Builder a
Builder forall a b. (a -> b) -> a -> b
$ \MutableByteArray# s
arr Int#
off0 State# s
s0 -> case forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
f MutableByteArray# s
arr Int#
off0 State# s
s0 of
    (# State# s
s1, Int#
r #) -> forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
g MutableByteArray# s
arr Int#
r State# s
s1

-- | Weaken the bound on the maximum number of bytes required. For example,
-- to use two builders with unequal bounds in a disjunctive setting:
--
-- > import qualified Arithmetic.Lte as Lte
-- >
-- > buildNumber :: Either Double Word64 -> Builder 32
-- > buildNumber = \case
-- >   Left d  -> doubleDec d
-- >   Right w -> weaken (Lte.constant @19 @32) (word64Dec w)
weaken :: forall m n. (m <= n) -> Builder m -> Builder n
weaken :: forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken !m <= n
_ (Builder forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
f) = forall (a :: Nat).
(forall s.
 MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #))
-> Builder a
Builder forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
f

-- | Replace the upper bound on size with an equal number.
substitute :: forall m n. (m :=: n) -> Builder m -> Builder n
substitute :: forall (m :: Nat) (n :: Nat). (m :=: n) -> Builder m -> Builder n
substitute !m :=: n
_ (Builder forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
f) = forall (a :: Nat).
(forall s.
 MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #))
-> Builder a
Builder forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
f

-- | Encode a double-floating-point number, using decimal notation or
-- scientific notation depending on the magnitude. This has undefined
-- behavior when representing @+inf@, @-inf@, and @NaN@. It will not
-- crash, but the generated numbers will be nonsense.
doubleDec :: Double -> Builder 32
doubleDec :: Double -> Builder 32
doubleDec (D# Double#
d) = forall (a :: Nat).
(forall s.
 MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #))
-> Builder a
Builder (\MutableByteArray# s
arr Int#
off0 State# s
s0 -> forall s.
Double#
-> MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
doubleDec# Double#
d MutableByteArray# s
arr Int#
off0 State# s
s0)

-- | Requires up to 19 bytes. Encodes an unsigned 64-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
word64Dec :: Word64 -> Builder 19
word64Dec :: Word64 -> Builder 19
word64Dec (W64# Word#
w) = forall (n :: Nat). Word# -> Builder n
wordCommonDec#
#if MIN_VERSION_base(4,17,0)
    (word64ToWord# w)
#else
    Word#
w
#endif

-- | Requires up to 10 bytes. Encodes an unsigned 32-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
word32Dec :: Word32 -> Builder 10
word32Dec :: Word32 -> Builder 10
word32Dec (W32# Word32#
w) = forall (n :: Nat). Word# -> Builder n
wordCommonDec# (Word32# -> Word#
C.word32ToWord# Word32#
w)

-- | Requires up to 5 bytes. Encodes an unsigned 16-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
word16Dec :: Word16 -> Builder 5
word16Dec :: Word16 -> Builder 5
word16Dec (W16# Word16#
w) = forall (n :: Nat). Word# -> Builder n
wordCommonDec# (Word16# -> Word#
C.word16ToWord# Word16#
w)

-- | Requires up to 3 bytes. Encodes an unsigned 8-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
word8Dec :: Word8 -> Builder 3
word8Dec :: Word8 -> Builder 3
word8Dec (W8# Word8#
w) =
  -- We unroll the loop when encoding Word8s. This speeds things
  -- up IPv4 encoding by about 10% in the @ip@ library. We can
  -- encode Word8s at twice this speed by using a lookup table.
  -- However, I (Andrew Martin) am concerned that although lookup
  -- table perform very well in microbenchmarks, they can thrash
  -- L1 cache in real applications.
  Word# -> Builder 3
word8Dec# (Word8# -> Word#
C.word8ToWord# Word8#
w)

-- | Requires up to 19 bytes. Encodes an unsigned machine-sized integer
-- as decimal. This encoding never starts with a zero unless the argument
-- was zero.
wordDec :: Word -> Builder 19
wordDec :: Word -> Builder 19
wordDec (W# Word#
w) = forall (n :: Nat). Word# -> Builder n
wordCommonDec# Word#
w

-- | Requires up to 20 bytes. Encodes a signed 64-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything.
int64Dec :: Int64 -> Builder 20
int64Dec :: Int64 -> Builder 20
int64Dec (I64# Int#
w) = forall (n :: Nat). Int# -> Builder n
intCommonDec#
#if MIN_VERSION_base(4,17,0)
    (int64ToInt# w)
#else
    Int#
w
#endif

-- | Requires up to 11 bytes. Encodes a signed 32-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything.
int32Dec :: Int32 -> Builder 11
int32Dec :: Int32 -> Builder 11
int32Dec (I32# Int32#
w) = forall (n :: Nat). Int# -> Builder n
intCommonDec# (Int32# -> Int#
C.int32ToInt# Int32#
w)

-- | Requires up to 6 bytes. Encodes a signed 16-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything.
int16Dec :: Int16 -> Builder 6
int16Dec :: Int16 -> Builder 6
int16Dec (I16# Int16#
w) = forall (n :: Nat). Int# -> Builder n
intCommonDec# (Int16# -> Int#
C.int16ToInt# Int16#
w)

-- | Requires up to 4 bytes. Encodes a signed 8-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything.
int8Dec :: Int8 -> Builder 4
int8Dec :: Int8 -> Builder 4
int8Dec (I8# Int8#
w) = forall (n :: Nat). Int# -> Builder n
intCommonDec# (Int8# -> Int#
C.int8ToInt# Int8#
w)

-- | Requires up to 20 bytes. Encodes a signed machine-sized integer
-- as decimal. This encoding never starts with a zero unless the
-- argument was zero. Negative numbers are preceded by a minus sign.
-- Positive numbers are not preceded by anything.
intDec :: Int -> Builder 20
intDec :: Int -> Builder 20
intDec (I# Int#
w) = forall (n :: Nat). Int# -> Builder n
intCommonDec# Int#
w

word8Dec# :: Word# -> Builder 3
{-# noinline word8Dec# #-}
word8Dec# :: Word# -> Builder 3
word8Dec# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off0 -> do
  let !(I# Int#
off0# ) = Int
off0
      !(!Word
x,!Word
ones) = forall a. Integral a => a -> a -> (a, a)
quotRem Word
w Word
10
      !(hundreds :: Word
hundreds@(W# Word#
hundreds# ),tens :: Word
tens@(W# Word#
tens# )) = forall a. Integral a => a -> a -> (a, a)
quotRem Word
x Word
10
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off0 (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
hundreds forall a. Num a => a -> a -> a
+ Word
0x30) :: Word8)
  let !hasHundreds :: Int#
hasHundreds = Word# -> Word# -> Int#
gtWord# Word#
hundreds# Word#
0##
      !off1 :: Int
off1@(I# Int#
off1# ) = Int# -> Int
I# (Int#
off0# Int# -> Int# -> Int#
+# Int#
hasHundreds)
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off1 (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
tens forall a. Num a => a -> a -> a
+ Word
0x30) :: Word8)
  let !off2 :: Int
off2 = Int# -> Int
I# (Int#
off1# Int# -> Int# -> Int#
+# (Int# -> Int# -> Int#
orI# Int#
hasHundreds (Word# -> Word# -> Int#
gtWord# Word#
tens# Word#
0## )))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off2 (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
ones forall a. Num a => a -> a -> a
+ Word
0x30) :: Word8)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off2 forall a. Num a => a -> a -> a
+ Int
1)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- Requires a number of bytes that is bounded by the size of
-- the word. This is only used internally.
wordCommonDec# :: Word# -> Builder n
{-# noinline wordCommonDec# #-}
wordCommonDec# :: forall (n :: Nat). Word# -> Builder n
wordCommonDec# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off0 -> if Word64
w forall a. Eq a => a -> a -> Bool
/= Word64
0
  then forall s. MutableByteArray s -> Int -> Word -> ST s Int
internalWordLoop MutableByteArray s
arr Int
off0 (Word# -> Word
W# Word#
w#)
  else do
    forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off0 (Char -> Word8
c2w Char
'0')
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off0 forall a. Num a => a -> a -> a
+ Int
1)
  where
  w :: Word64
w = Word# -> Word64
W64#
#if MIN_VERSION_base(4,17,0)
    (wordToWord64# w#)
#else
    Word#
w#
#endif

internalWordLoop :: MutableByteArray s -> Int -> Word -> ST s Int
{-# inline internalWordLoop #-}
internalWordLoop :: forall s. MutableByteArray s -> Int -> Word -> ST s Int
internalWordLoop MutableByteArray s
arr Int
off0 Word
x0 = do
  Int
off1 <- forall s. MutableByteArray s -> Int -> Word -> ST s Int
backwardsWordLoop MutableByteArray s
arr Int
off0 Word
x0
  forall s. MutableByteArray s -> Int -> Int -> ST s ()
reverseBytes MutableByteArray s
arr Int
off0 (Int
off1 forall a. Num a => a -> a -> a
- Int
1)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
off1

backwardsWordLoop :: MutableByteArray s -> Int -> Word -> ST s Int
{-# inline backwardsWordLoop #-}
backwardsWordLoop :: forall s. MutableByteArray s -> Int -> Word -> ST s Int
backwardsWordLoop MutableByteArray s
arr Int
off0 Word
x0 = Int -> Word -> ST s Int
go Int
off0 Word
x0 where
  go :: Int -> Word -> ST s Int
go !Int
off !(Word
x :: Word) = if Word
x forall a. Ord a => a -> a -> Bool
> Word
0
    then do
      let (Word
y,Word
z) = forall a. Integral a => a -> a -> (a, a)
quotRem Word
x Word
10
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
z forall a. Num a => a -> a -> a
+ Word
0x30) :: Word8)
      Int -> Word -> ST s Int
go (Int
off forall a. Num a => a -> a -> a
+ Int
1) Word
y
    else forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
off

-- Requires up to 20 bytes. Can be less depending on what the
-- size of the argument is known to be. Unsafe.
intCommonDec# :: Int# -> Builder n
{-# noinline intCommonDec# #-}
intCommonDec# :: forall (n :: Nat). Int# -> Builder n
intCommonDec# Int#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off0 -> case forall a. Ord a => a -> a -> Ordering
compare Int64
w Int64
0 of
  Ordering
GT -> forall s. MutableByteArray s -> Int -> Word -> ST s Int
internalWordLoop MutableByteArray s
arr Int
off0 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
w)
  Ordering
EQ -> do
    forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off0 (Char -> Word8
c2w Char
'0')
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off0 forall a. Num a => a -> a -> a
+ Int
1)
  Ordering
LT -> do
    forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off0 (Char -> Word8
c2w Char
'-')
    forall s. MutableByteArray s -> Int -> Word -> ST s Int
internalWordLoop MutableByteArray s
arr (Int
off0 forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Num a => a -> a
negate Int64
w))
  where
  w :: Int64
w = Int# -> Int64
I64#
#if MIN_VERSION_base(4,17,0)
    (intToInt64# w#)
#else
    Int#
w#
#endif

-- Convert a number between 0 and 16 to the ASCII
-- representation of its hexadecimal character.
-- The use of fromIntegral causes us to incur an
-- unneeded bitmask. This actually needs a Word64
-- argument.
toHexUpper :: Word -> Word8
toHexUpper :: Word -> Word8
toHexUpper Word
w' = forall a b. (Integral a, Num b) => a -> b
fromIntegral
    forall a b. (a -> b) -> a -> b
$ (forall a. Bits a => a -> a
complement Word
theMask forall a. Bits a => a -> a -> a
.&. Word
loSolved)
  forall a. Bits a => a -> a -> a
.|. (Word
theMask forall a. Bits a => a -> a -> a
.&. Word
hiSolved)
  where
  w :: Word
w = Word
w' forall a. Bits a => a -> a -> a
.&. Word
0xF
  -- This is all ones if the value was >= 10
  theMask :: Word
theMask = (Word
1 forall a. Bits a => a -> a -> a
.&. forall a. Bits a => a -> Int -> a
unsafeShiftR (Word
w forall a. Num a => a -> a -> a
- Word
10) Int
63) forall a. Num a => a -> a -> a
- Word
1
  loSolved :: Word
loSolved = Word
w forall a. Num a => a -> a -> a
+ Word
48
  hiSolved :: Word
hiSolved = Word
w forall a. Num a => a -> a -> a
+ Word
55

toHexLower :: Word -> Word8
toHexLower :: Word -> Word8
toHexLower Word
w' = forall a b. (Integral a, Num b) => a -> b
fromIntegral
    forall a b. (a -> b) -> a -> b
$ (forall a. Bits a => a -> a
complement Word
theMask forall a. Bits a => a -> a -> a
.&. Word
loSolved)
  forall a. Bits a => a -> a -> a
.|. (Word
theMask forall a. Bits a => a -> a -> a
.&. Word
hiSolved)
  where
  w :: Word
w = Word
w' forall a. Bits a => a -> a -> a
.&. Word
0xF
  -- This is all ones if the value was >= 10
  theMask :: Word
theMask = (Word
1 forall a. Bits a => a -> a -> a
.&. forall a. Bits a => a -> Int -> a
unsafeShiftR (Word
w forall a. Num a => a -> a -> a
- Word
10) Int
63) forall a. Num a => a -> a -> a
- Word
1
  loSolved :: Word
loSolved = Word
w forall a. Num a => a -> a -> a
+ Word
48
  hiSolved :: Word
hiSolved = Word
w forall a. Num a => a -> a -> a
+ Word
87

-- | Requires exactly 64 bytes. Encodes a 256-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 64 digits. This uses
-- lowercase for the alphabetical digits.
word256PaddedLowerHex :: Word256 -> Builder 64
word256PaddedLowerHex :: Word256 -> Builder 64
word256PaddedLowerHex (Word256 Word64
w192 Word64
w128 Word64
w64 Word64
w0) =
           Word64 -> Builder 16
word64PaddedLowerHex Word64
w192
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedLowerHex Word64
w128
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedLowerHex Word64
w64
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedLowerHex Word64
w0

-- | Requires exactly 64 bytes. Encodes a 256-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 64 digits. This uses
-- uppercase for the alphabetical digits.
word256PaddedUpperHex :: Word256 -> Builder 64
word256PaddedUpperHex :: Word256 -> Builder 64
word256PaddedUpperHex (Word256 Word64
w192 Word64
w128 Word64
w64 Word64
w0) =
           Word64 -> Builder 16
word64PaddedUpperHex Word64
w192
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedUpperHex Word64
w128
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedUpperHex Word64
w64
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedUpperHex Word64
w0


-- | Requires exactly 32 bytes. Encodes a 128-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 32 digits. This uses
-- lowercase for the alphabetical digits.
word128PaddedLowerHex :: Word128 -> Builder 32
word128PaddedLowerHex :: Word128 -> Builder 32
word128PaddedLowerHex (Word128 Word64
w64 Word64
w0) =
           Word64 -> Builder 16
word64PaddedLowerHex Word64
w64
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedLowerHex Word64
w0

-- | Requires exactly 32 bytes. Encodes a 128-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 32 digits. This uses
-- uppercase for the alphabetical digits.
word128PaddedUpperHex :: Word128 -> Builder 32
word128PaddedUpperHex :: Word128 -> Builder 32
word128PaddedUpperHex (Word128 Word64
w64 Word64
w0) =
           Word64 -> Builder 16
word64PaddedUpperHex Word64
w64
  forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 16
word64PaddedUpperHex Word64
w0


-- | Requires exactly 16 bytes. Encodes a 64-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 16 digits. This uses
-- uppercase for the alphabetical digits. For example, this encodes the
-- number 1022 as @00000000000003FE@.
word64PaddedUpperHex :: Word64 -> Builder 16
word64PaddedUpperHex :: Word64 -> Builder 16
word64PaddedUpperHex (W64# Word#
w) = Word# -> Builder 16
word64PaddedUpperHex#
#if MIN_VERSION_base(4,17,0)
    (word64ToWord# w)
#else
    Word#
w
#endif


-- | Requires exactly 16 bytes. Encodes a 64-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 16 digits. This uses
-- lowercase for the alphabetical digits. For example, this encodes the
-- number 1022 as @00000000000003fe@.
word64PaddedLowerHex :: Word64 -> Builder 16
word64PaddedLowerHex :: Word64 -> Builder 16
word64PaddedLowerHex (W64# Word#
w) = Word# -> Builder 16
word64PaddedLowerHex#
#if MIN_VERSION_base(4,17,0)
    (word64ToWord# w)
#else
    Word#
w
#endif

-- | Requires exactly 12 bytes. Discards the upper 16 bits of a
-- 64-bit unsigned integer and then encodes the lower 48 bits as
-- hexadecimal, zero-padding the encoding to 12 digits. This uses
-- lowercase for the alphabetical digits. For example, this encodes the
-- number 1022 as @0000000003fe@.
word48PaddedLowerHex :: Word64 -> Builder 12
word48PaddedLowerHex :: Word64 -> Builder 12
word48PaddedLowerHex (W64# Word#
w) = Word# -> Builder 12
word48PaddedLowerHex#
#if MIN_VERSION_base(4,17,0)
    (word64ToWord# w)
#else
    Word#
w
#endif

-- | Requires exactly 8 bytes. Encodes a 32-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 8 digits. This uses
-- uppercase for the alphabetical digits.
word32PaddedUpperHex :: Word32 -> Builder 8
word32PaddedUpperHex :: Word32 -> Builder 8
word32PaddedUpperHex (W32# Word32#
w) = Word# -> Builder 8
word32PaddedUpperHex# (Word32# -> Word#
C.word32ToWord# Word32#
w)

-- | Requires exactly 8 bytes. Encodes a 32-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 8 digits. This uses
-- lowercase for the alphabetical digits.
word32PaddedLowerHex :: Word32 -> Builder 8
word32PaddedLowerHex :: Word32 -> Builder 8
word32PaddedLowerHex (W32# Word32#
w) = Word# -> Builder 8
word32PaddedLowerHex# (Word32# -> Word#
C.word32ToWord# Word32#
w)

-- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 4 digits. This uses
-- uppercase for the alphabetical digits.
--
-- >>> word16PaddedUpperHex 0xab0
-- 0AB0
word16PaddedUpperHex :: Word16 -> Builder 4
word16PaddedUpperHex :: Word16 -> Builder 4
word16PaddedUpperHex (W16# Word16#
w) = Word# -> Builder 4
word16PaddedUpperHex# (Word16# -> Word#
C.word16ToWord# Word16#
w)

-- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 4 digits. This uses
-- lowercase for the alphabetical digits.
--
-- >>> word16PaddedLowerHex 0xab0
-- 0ab0
word16PaddedLowerHex :: Word16 -> Builder 4
word16PaddedLowerHex :: Word16 -> Builder 4
word16PaddedLowerHex (W16# Word16#
w) = Word# -> Builder 4
word16PaddedLowerHex# (Word16# -> Word#
C.word16ToWord# Word16#
w)

-- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal. No leading zeroes are displayed. Letters are presented
-- in lowercase. If the number is zero, a single zero digit is used.
--
-- >>> word16LowerHex 0xab0
-- ab0
word16LowerHex :: Word16 -> Builder 4
word16LowerHex :: Word16 -> Builder 4
word16LowerHex (W16# Word16#
w) = Word# -> Builder 4
word16LowerHex# (Word16# -> Word#
C.word16ToWord# Word16#
w)

-- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal. No leading zeroes are displayed. Letters are presented
-- in uppercase. If the number is zero, a single zero digit is used.
--
-- >>> word16UpperHex 0xab0
-- AB0
word16UpperHex :: Word16 -> Builder 4
word16UpperHex :: Word16 -> Builder 4
word16UpperHex (W16# Word16#
w) = Word# -> Builder 4
word16UpperHex# (Word16# -> Word#
C.word16ToWord# Word16#
w)

-- | Requires at most 2 bytes. Encodes a 8-bit unsigned integer as
-- hexadecimal. No leading zeroes are displayed. If the number is zero,
-- a single zero digit is used.
word8LowerHex :: Word8 -> Builder 2
word8LowerHex :: Word8 -> Builder 2
word8LowerHex (W8# Word8#
w) = Word# -> Builder 2
word8LowerHex# (Word8# -> Word#
C.word8ToWord# Word8#
w)

-- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 2 digits. This uses
-- uppercase for the alphabetical digits.
word8PaddedUpperHex :: Word8 -> Builder 2
word8PaddedUpperHex :: Word8 -> Builder 2
word8PaddedUpperHex (W8# Word8#
w) = Word# -> Builder 2
word8PaddedUpperHex# (Word8# -> Word#
C.word8ToWord# Word8#
w)

-- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 2 digits. This uses
-- lowercase for the alphabetical digits.
word8PaddedLowerHex :: Word8 -> Builder 2
word8PaddedLowerHex :: Word8 -> Builder 2
word8PaddedLowerHex (W8# Word8#
w) = Word# -> Builder 2
word8PaddedLowerHex# (Word8# -> Word#
C.word8ToWord# Word8#
w)

-- TODO: Is it actually worth unrolling this loop. I suspect that it
-- might not be. Benchmark this.
word64PaddedUpperHex# :: Word# -> Builder 16
{-# noinline word64PaddedUpperHex# #-}
word64PaddedUpperHex# :: Word# -> Builder 16
word64PaddedUpperHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
60))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
56))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
52))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
48))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
44))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
40))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
36))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
32))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
8) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
28))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
9) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
10) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
20))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
11) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
12) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
13) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
14) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
15) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
16)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- TODO: Is it actually worth unrolling this loop. I suspect that it
-- might not be. Benchmark this.
word48PaddedLowerHex# :: Word# -> Builder 12
{-# noinline word48PaddedLowerHex# #-}
word48PaddedLowerHex# :: Word# -> Builder 12
word48PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
44))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
40))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
36))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
32))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
28))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
20))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
8) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
9) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
10) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
11) (Word -> Word8
toHexLower Word
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
12)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- TODO: Is it actually worth unrolling this loop. I suspect that it
-- might not be. Benchmark this.
word64PaddedLowerHex# :: Word# -> Builder 16
{-# noinline word64PaddedLowerHex# #-}
word64PaddedLowerHex# :: Word# -> Builder 16
word64PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
60))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
56))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
52))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
48))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
44))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
40))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
36))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
32))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
8) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
28))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
9) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
10) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
20))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
11) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
12) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
13) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
14) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
15) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
16)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word32PaddedUpperHex# :: Word# -> Builder 8
{-# noinline word32PaddedUpperHex# #-}
word32PaddedUpperHex# :: Word# -> Builder 8
word32PaddedUpperHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
28))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
20))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
8)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word32PaddedLowerHex# :: Word# -> Builder 8
{-# noinline word32PaddedLowerHex# #-}
word32PaddedLowerHex# :: Word# -> Builder 8
word32PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
28))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
20))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
8)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- Not sure if it is beneficial to inline this. We just let
-- GHC make the decision. Open an issue on github if this is
-- a problem.
word16PaddedUpperHex# :: Word# -> Builder 4
word16PaddedUpperHex# :: Word# -> Builder 4
word16PaddedUpperHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
4)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word16PaddedLowerHex# :: Word# -> Builder 4
word16PaddedLowerHex# :: Word# -> Builder 4
word16PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
4)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word12PaddedLowerHex# :: Word# -> Builder 3
word12PaddedLowerHex# :: Word# -> Builder 3
word12PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
3)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word12PaddedUpperHex# :: Word# -> Builder 3
word12PaddedUpperHex# :: Word# -> Builder 3
word12PaddedUpperHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
3)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- Definitely want this to inline. It's maybe a dozen instructions total.
word8PaddedUpperHex# :: Word# -> Builder 2
{-# inline word8PaddedUpperHex# #-}
word8PaddedUpperHex# :: Word# -> Builder 2
word8PaddedUpperHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexUpper (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
2)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word8PaddedLowerHex# :: Word# -> Builder 2
{-# inline word8PaddedLowerHex# #-}
word8PaddedLowerHex# :: Word# -> Builder 2
word8PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
4))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
toHexLower (forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
0))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
2)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word4PaddedLowerHex# :: Word# -> Builder 1
{-# inline word4PaddedLowerHex# #-}
word4PaddedLowerHex# :: Word# -> Builder 1
word4PaddedLowerHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexLower Word
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
1)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word4PaddedUpperHex# :: Word# -> Builder 1
{-# inline word4PaddedUpperHex# #-}
word4PaddedUpperHex# :: Word# -> Builder 1
word4PaddedUpperHex# Word#
w# = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
toHexUpper Word
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
1)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word16UpperHex# :: Word# -> Builder 4
word16UpperHex# :: Word# -> Builder 4
word16UpperHex# Word#
w#
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 1
word4PaddedUpperHex# Word#
w#)
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xFF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 2
word8PaddedUpperHex# Word#
w#)
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xFFF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 3
word12PaddedUpperHex# Word#
w#)
  | Bool
otherwise = Word# -> Builder 4
word16PaddedUpperHex# Word#
w#
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

word16LowerHex# :: Word# -> Builder 4
word16LowerHex# :: Word# -> Builder 4
word16LowerHex# Word#
w#
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 1
word4PaddedLowerHex# Word#
w#)
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xFF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 2
word8PaddedLowerHex# Word#
w#)
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xFFF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 3
word12PaddedLowerHex# Word#
w#)
  | Bool
otherwise = Word# -> Builder 4
word16PaddedLowerHex# Word#
w#
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- Precondition: argument less than 256
word8LowerHex# :: Word# -> Builder 2
word8LowerHex# :: Word# -> Builder 2
word8LowerHex# Word#
w#
  | Word
w forall a. Ord a => a -> a -> Bool
<= Word
0xF = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 1
word4PaddedLowerHex# Word#
w#)
  | Bool
otherwise = forall (m :: Nat) (n :: Nat). (m <= n) -> Builder m -> Builder n
weaken forall (a :: Nat) (b :: Nat).
(IsLte (CmpNat a b) ~ 'True) =>
a <= b
Lte.constant (Word# -> Builder 2
word8PaddedLowerHex# Word#
w#)
  where
  w :: Word
w = Word# -> Word
W# Word#
w#

-- | Encode a number less than 100 as a decimal number, zero-padding it to
-- two digits. For example: 0 is encoded as @00@, 5 is encoded as @05@, and
-- 73 is encoded as @73@.
--
-- Precondition: Argument must be less than 100. Failure to satisfy this
-- precondition will not result in a segfault, but the resulting bytes are
-- undefined. The implemention uses a heuristic for division that is inaccurate
-- for large numbers.
wordPaddedDec2 :: Word -> Builder 2
wordPaddedDec2 :: Word -> Builder 2
wordPaddedDec2 !Word
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  let d1 :: Word
d1 = Word -> Word
approxDiv10 Word
w
      d2 :: Word
d2 = Word
w forall a. Num a => a -> a -> a
- (Word
10 forall a. Num a => a -> a -> a
* Word
d1)
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
unsafeWordToWord8 (Word
d1 forall a. Num a => a -> a -> a
+ Word
48))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
unsafeWordToWord8 (Word
d2 forall a. Num a => a -> a -> a
+ Word
48))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
2)

-- | Encode a number less than 10000 as a decimal number, zero-padding it to
-- two digits. For example: 0 is encoded as @0000@, 5 is encoded as @0005@,
-- and 73 is encoded as @0073@.
--
-- Precondition: Argument must be less than 10000. Failure to satisfy this
-- precondition will not result in a segfault, but the resulting bytes are
-- undefined. The implemention uses a heuristic for division that is inaccurate
-- for large numbers.
wordPaddedDec4 :: Word -> Builder 4
wordPaddedDec4 :: Word -> Builder 4
wordPaddedDec4 !Word
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10
    (forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10
     (\MutableByteArray s
_ Int
_ Word
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
    ) MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) Word
w
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
4)

-- | Encode a number less than 1e9 as a decimal number, zero-padding it to
-- nine digits. For example: 0 is encoded as @000000000@ and 5 is encoded as
-- @000000005@.
--
-- Precondition: Argument must be less than 1e9. Failure to satisfy this
-- precondition will not result in a segfault, but the resulting bytes are
-- undefined. The implemention uses a heuristic for division that is inaccurate
-- for large numbers.
wordPaddedDec9 :: Word -> Builder 9
wordPaddedDec9 :: Word -> Builder 9
wordPaddedDec9 !Word
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10
    (forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$
     forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 forall a b. (a -> b) -> a -> b
$ forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10
     (\MutableByteArray s
_ Int
_ Word
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
    ) MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
8) Word
w
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
9)

putRem10 :: (MutableByteArray s -> Int -> Word -> ST s a) -> MutableByteArray s -> Int -> Word -> ST s a
{-# inline putRem10 #-}
putRem10 :: forall s a.
(MutableByteArray s -> Int -> Word -> ST s a)
-> MutableByteArray s -> Int -> Word -> ST s a
putRem10 MutableByteArray s -> Int -> Word -> ST s a
andThen MutableByteArray s
arr Int
off Word
dividend = do
  let quotient :: Word
quotient = Word -> Word
approxDiv10 Word
dividend
      remainder :: Word
remainder = Word
dividend forall a. Num a => a -> a -> a
- (Word
10 forall a. Num a => a -> a -> a
* Word
quotient)
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
unsafeWordToWord8 (Word
remainder forall a. Num a => a -> a -> a
+ Word
48))
  MutableByteArray s -> Int -> Word -> ST s a
andThen MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
- Int
1) Word
quotient

-- | Encode an ASCII character.
-- Precondition: Input must be an ASCII character. This is not checked.
ascii :: Char -> Builder 1
ascii :: Char -> Builder 1
ascii (C# Char#
c) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
1# ))

-- | Encode two ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii2 :: Char -> Char -> Builder 2
ascii2 :: Char -> Char -> Builder 2
ascii2 (C# Char#
c0) (C# Char#
c1) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
2# ))

-- | Encode three ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii3 :: Char -> Char -> Char -> Builder 3
ascii3 :: Char -> Char -> Char -> Builder 3
ascii3 (C# Char#
c0) (C# Char#
c1) (C# Char#
c2) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
2# ) Char#
c2)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
3# ))

-- | Encode four ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii4 :: Char -> Char -> Char -> Char -> Builder 4
ascii4 :: Char -> Char -> Char -> Char -> Builder 4
ascii4 (C# Char#
c0) (C# Char#
c1) (C# Char#
c2) (C# Char#
c3) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
2# ) Char#
c2)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
3# ) Char#
c3)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
4# ))

-- | Encode five ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii5 :: Char -> Char -> Char -> Char -> Char -> Builder 5
ascii5 :: Char -> Char -> Char -> Char -> Char -> Builder 5
ascii5 (C# Char#
c0) (C# Char#
c1) (C# Char#
c2) (C# Char#
c3) (C# Char#
c4) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
2# ) Char#
c2)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
3# ) Char#
c3)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
4# ) Char#
c4)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
5# ))

-- | Encode six ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii6 :: Char -> Char -> Char -> Char -> Char -> Char -> Builder 6
ascii6 :: Char -> Char -> Char -> Char -> Char -> Char -> Builder 6
ascii6 (C# Char#
c0) (C# Char#
c1) (C# Char#
c2) (C# Char#
c3) (C# Char#
c4) (C# Char#
c5) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
2# ) Char#
c2)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
3# ) Char#
c3)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
4# ) Char#
c4)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
5# ) Char#
c5)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
6# ))

-- | Encode seven ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii7 :: Char -> Char -> Char -> Char -> Char -> Char -> Char -> Builder 7
ascii7 :: Char -> Char -> Char -> Char -> Char -> Char -> Char -> Builder 7
ascii7 (C# Char#
c0) (C# Char#
c1) (C# Char#
c2) (C# Char#
c3) (C# Char#
c4) (C# Char#
c5) (C# Char#
c6) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
2# ) Char#
c2)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
3# ) Char#
c3)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
4# ) Char#
c4)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
5# ) Char#
c5)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
6# ) Char#
c6)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
7# ))

-- | Encode eight ASCII characters. Precondition: Must be an ASCII characters.
-- This is not checked.
ascii8 :: Char -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Builder 8
ascii8 :: Char
-> Char
-> Char
-> Char
-> Char
-> Char
-> Char
-> Char
-> Builder 8
ascii8 (C# Char#
c0) (C# Char#
c1) (C# Char#
c2) (C# Char#
c3) (C# Char#
c4) (C# Char#
c5) (C# Char#
c6) (C# Char#
c7) = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \(MutableByteArray MutableByteArray# s
arr) (I# Int#
off) -> do
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr Int#
off Char#
c0)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) Char#
c1)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
2# ) Char#
c2)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
3# ) Char#
c3)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
4# ) Char#
c4)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
5# ) Char#
c5)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
6# ) Char#
c6)
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d.
MutableByteArray# d -> Int# -> Char# -> State# d -> State# d
writeCharArray# MutableByteArray# s
arr (Int#
off Int# -> Int# -> Int#
+# Int#
7# ) Char#
c7)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# (Int#
off Int# -> Int# -> Int#
+# Int#
8# ))

-- | Encode a machine-sized word with LEB-128.
wordLEB128 :: Word -> Builder 10
{-# inline wordLEB128 #-}
wordLEB128 :: Word -> Builder 10
wordLEB128 (W# Word#
w) = forall (n :: Nat). Word -> Builder n
lebCommon (Word# -> Word
W# Word#
w)

-- | Encode a 32-bit word with LEB-128.
word32LEB128 :: Word32 -> Builder 5
{-# inline word32LEB128 #-}
word32LEB128 :: Word32 -> Builder 5
word32LEB128 (W32# Word32#
w) = forall (n :: Nat). Word -> Builder n
lebCommon (Word# -> Word
W# (Word32# -> Word#
C.word32ToWord# Word32#
w))

-- | Encode a 64-bit word with LEB-128.
word64LEB128 :: Word64 -> Builder 10
{-# inline word64LEB128 #-}
word64LEB128 :: Word64 -> Builder 10
word64LEB128 (W64# Word#
w) = forall (n :: Nat). Word -> Builder n
lebCommon (Word# -> Word
W#
#if MIN_VERSION_base(4,17,0)
    (word64ToWord# w)
#else
    Word#
w
#endif
  )

lebCommon :: Word -> Builder n
lebCommon :: forall (n :: Nat). Word -> Builder n
lebCommon !Word
w = case forall a. Integral a => a -> a -> (a, a)
quotRem Word
w Word
128 of
  (Word
q,Word
r) -> case Word
q of
    Word
0 -> forall (n :: Nat). Word8 -> Builder n
unsafeWord8 (Word -> Word8
unsafeWordToWord8 Word
r)
    Word
_ -> forall (m :: Nat) (n :: Nat) (p :: Nat).
Builder m -> Builder n -> Builder p
unsafeAppend
      (forall (n :: Nat). Word8 -> Builder n
unsafeWord8 (Word -> Word8
unsafeWordToWord8 (Word
r forall a. Bits a => a -> a -> a
.|. Word
0x80)))
      (forall (n :: Nat). Word -> Builder n
lebCommon Word
q)

-- | Encode a character as UTF-8. This only uses as much space as is required.
char :: Char -> Builder 4
char :: Char -> Builder 4
char Char
c
  | Word
codepoint forall a. Ord a => a -> a -> Bool
< Word
0x80 = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off (Word -> Word8
unsafeWordToWord8 Word
codepoint)
      forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
1)
  | Word
codepoint forall a. Ord a => a -> a -> Bool
< Word
0x800 = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off       (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteTwoOne Word
codepoint))
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteTwoTwo Word
codepoint))
      forall (m :: * -> *) a. Monad m => a -> m a
return (Int
off forall a. Num a => a -> a -> a
+ Int
2)
  | Word
codepoint forall a. Ord a => a -> a -> Bool
>= Word
0xD800 Bool -> Bool -> Bool
&& Word
codepoint forall a. Ord a => a -> a -> Bool
< Word
0xE000 = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
      -- Codepoint U+FFFD
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off       (Word8
0xEF :: Word8)
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word8
0xBF :: Word8)
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word8
0xBD :: Word8)
      forall (m :: * -> *) a. Monad m => a -> m a
return (Int
off forall a. Num a => a -> a -> a
+ Int
3)
  | Word
codepoint forall a. Ord a => a -> a -> Bool
< Word
0x10000 = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off       (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteThreeOne Word
codepoint))
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteThreeTwo Word
codepoint))
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteThreeThree Word
codepoint))
      forall (m :: * -> *) a. Monad m => a -> m a
return (Int
off forall a. Num a => a -> a -> a
+ Int
3)
  | Bool
otherwise = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off       (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteFourOne Word
codepoint))
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteFourTwo Word
codepoint))
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteFourThree Word
codepoint))
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (Word -> Word8
unsafeWordToWord8 (Word -> Word
byteFourFour Word
codepoint))
      forall (m :: * -> *) a. Monad m => a -> m a
return (Int
off forall a. Num a => a -> a -> a
+ Int
4)

  where
    codepoint :: Word
    codepoint :: Word
codepoint = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c)

    -- precondition: codepoint is less than 0x800
    byteTwoOne :: Word -> Word
    byteTwoOne :: Word -> Word
byteTwoOne Word
w = forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
6 forall a. Bits a => a -> a -> a
.|. Word
0b11000000

    byteTwoTwo :: Word -> Word
    byteTwoTwo :: Word -> Word
byteTwoTwo Word
w = (Word
w forall a. Bits a => a -> a -> a
.&. Word
0b00111111) forall a. Bits a => a -> a -> a
.|. Word
0b10000000

    -- precondition: codepoint is less than 0x1000
    byteThreeOne :: Word -> Word
    byteThreeOne :: Word -> Word
byteThreeOne Word
w = forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12 forall a. Bits a => a -> a -> a
.|. Word
0b11100000

    byteThreeTwo :: Word -> Word
    byteThreeTwo :: Word -> Word
byteThreeTwo Word
w = (Word
0b00111111 forall a. Bits a => a -> a -> a
.&. forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
6) forall a. Bits a => a -> a -> a
.|. Word
0b10000000

    byteThreeThree :: Word -> Word
    byteThreeThree :: Word -> Word
byteThreeThree Word
w = (Word
w forall a. Bits a => a -> a -> a
.&. Word
0b00111111) forall a. Bits a => a -> a -> a
.|. Word
0b10000000

    -- precondition: codepoint is less than 0x110000
    byteFourOne :: Word -> Word
    byteFourOne :: Word -> Word
byteFourOne Word
w = forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
18 forall a. Bits a => a -> a -> a
.|. Word
0b11110000

    byteFourTwo :: Word -> Word
    byteFourTwo :: Word -> Word
byteFourTwo Word
w = (Word
0b00111111 forall a. Bits a => a -> a -> a
.&. forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
12) forall a. Bits a => a -> a -> a
.|. Word
0b10000000

    byteFourThree :: Word -> Word
    byteFourThree :: Word -> Word
byteFourThree Word
w = (Word
0b00111111 forall a. Bits a => a -> a -> a
.&. forall a. Bits a => a -> Int -> a
unsafeShiftR Word
w Int
6) forall a. Bits a => a -> a -> a
.|. Word
0b10000000

    byteFourFour :: Word -> Word
    byteFourFour :: Word -> Word
byteFourFour Word
w = (Word
0b00111111 forall a. Bits a => a -> a -> a
.&. Word
w) forall a. Bits a => a -> a -> a
.|. Word
0b10000000

int64BE :: Int64 -> Builder 8
int64BE :: Int64 -> Builder 8
int64BE (I64# Int#
i) = Word64 -> Builder 8
word64BE (Word# -> Word64
W64# (
#if MIN_VERSION_base(4,17,0)
  wordToWord64# (int2Word# (int64ToInt# i))))
#else
  Int# -> Word#
int2Word# Int#
i))
#endif

int32BE :: Int32 -> Builder 4
int32BE :: Int32 -> Builder 4
int32BE (I32# Int32#
i) = Word32 -> Builder 4
word32BE (Word32# -> Word32
W32# (Word# -> Word32#
C.wordToWord32# (Int# -> Word#
int2Word# (Int32# -> Int#
C.int32ToInt# Int32#
i))))

int16BE :: Int16 -> Builder 2
int16BE :: Int16 -> Builder 2
int16BE (I16# Int16#
i) = Word16 -> Builder 2
word16BE (Word16# -> Word16
W16# (Word# -> Word16#
C.wordToWord16# (Int# -> Word#
int2Word# (Int16# -> Int#
C.int16ToInt# Int16#
i))))

int64LE :: Int64 -> Builder 8
int64LE :: Int64 -> Builder 8
int64LE (I64# Int#
i) = Word64 -> Builder 8
word64LE (Word# -> Word64
W64# (
#if MIN_VERSION_base(4,17,0)
  wordToWord64# (int2Word# (int64ToInt# i))))
#else
  Int# -> Word#
int2Word# Int#
i))
#endif


int32LE :: Int32 -> Builder 4
int32LE :: Int32 -> Builder 4
int32LE (I32# Int32#
i) = Word32 -> Builder 4
word32LE (Word32# -> Word32
W32# (Word# -> Word32#
C.wordToWord32# (Int# -> Word#
int2Word# (Int32# -> Int#
C.int32ToInt# Int32#
i))))

int16LE :: Int16 -> Builder 2
int16LE :: Int16 -> Builder 2
int16LE (I16# Int16#
i) = Word16 -> Builder 2
word16LE (Word16# -> Word16
W16# (Word# -> Word16#
C.wordToWord16# (Int# -> Word#
int2Word# (Int16# -> Int#
C.int16ToInt# Int16#
i))))

word128LE :: Word128 -> Builder 16
word128LE :: Word128 -> Builder 16
word128LE (Word128 Word64
hi Word64
lo) = forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
append (Word64 -> Builder 8
word64LE Word64
lo) (Word64 -> Builder 8
word64LE Word64
hi)

word128BE :: Word128 -> Builder 16
word128BE :: Word128 -> Builder 16
word128BE (Word128 Word64
hi Word64
lo) = forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
append (Word64 -> Builder 8
word64BE Word64
hi) (Word64 -> Builder 8
word64BE Word64
lo)

word256LE :: Word256 -> Builder 32
word256LE :: Word256 -> Builder 32
word256LE (Word256 Word64
hi Word64
mhi Word64
mlo Word64
lo) = Word64 -> Builder 8
word64LE Word64
lo forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 8
word64LE Word64
mlo forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 8
word64LE Word64
mhi forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 8
word64LE Word64
hi

word256BE :: Word256 -> Builder 32
word256BE :: Word256 -> Builder 32
word256BE (Word256 Word64
hi Word64
mhi Word64
mlo Word64
lo) = Word64 -> Builder 8
word64BE Word64
hi forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 8
word64BE Word64
mhi forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 8
word64BE Word64
mlo forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`append` Word64 -> Builder 8
word64BE Word64
lo

-- | Requires exactly 8 bytes. Dump the octets of a 64-bit
-- word in a little-endian fashion.
word64LE :: Word64 -> Builder 8
word64LE :: Word64 -> Builder 8
word64LE Word64
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
56))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
48))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
40))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
32))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off    ) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 Word64
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
8)

-- | Requires exactly 8 bytes. Dump the octets of a 64-bit
-- word in a big-endian fashion.
word64BE :: Word64 -> Builder 8
word64BE :: Word64 -> Builder 8
word64BE Word64
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off    ) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
56))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
48))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
40))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
32))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
4) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
5) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
6) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
7) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word8 Word64
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
8)

-- | Requires exactly 4 bytes. Dump the octets of a 32-bit
-- word in a little-endian fashion.
word32LE :: Word32 -> Builder 4
word32LE :: Word32 -> Builder 4
word32LE Word32
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off    ) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 Word32
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
4)

-- | Requires exactly 4 bytes. Dump the octets of a 32-bit
-- word in a big-endian fashion.
word32BE :: Word32 -> Builder 4
word32BE :: Word32 -> Builder 4
word32BE Word32
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off    ) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
w Int
24))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
w Int
16))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
2) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
3) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word32 @Word8 Word32
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
4)

-- | Requires exactly 2 bytes. Dump the octets of a 16-bit
-- word in a little-endian fashion.
word16LE :: Word16 -> Builder 2
word16LE :: Word16 -> Builder 2
word16LE Word16
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word16
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off    ) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Word8 Word16
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
2)

-- | Requires exactly 2 bytes. Dump the octets of a 16-bit
-- word in a big-endian fashion.
word16BE :: Word16 -> Builder 2
word16BE :: Word16 -> Builder 2
word16BE Word16
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off    ) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Word8 (forall a. Bits a => a -> Int -> a
unsafeShiftR Word16
w Int
8))
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr (Int
off forall a. Num a => a -> a -> a
+ Int
1) (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Word8 Word16
w)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
2)

word8 :: Word8 -> Builder 1
word8 :: Word8 -> Builder 1
word8 Word8
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off Word8
w
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
1)

unsafeWord8 :: Word8 -> Builder n
unsafeWord8 :: forall (n :: Nat). Word8 -> Builder n
unsafeWord8 Word8
w = forall (n :: Nat).
(forall s. MutableByteArray s -> Int -> ST s Int) -> Builder n
Unsafe.construct forall a b. (a -> b) -> a -> b
$ \MutableByteArray s
arr Int
off -> do
  forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
off Word8
w
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off forall a. Num a => a -> a -> a
+ Int
1)

-- Reverse the bytes in the designated slice. This takes
-- an inclusive start offset and an inclusive end offset.
reverseBytes :: MutableByteArray s -> Int -> Int -> ST s ()
{-# inline reverseBytes #-}
reverseBytes :: forall s. MutableByteArray s -> Int -> Int -> ST s ()
reverseBytes MutableByteArray s
arr Int
begin Int
end = Int -> Int -> ST s ()
go Int
begin Int
end where
  go :: Int -> Int -> ST s ()
go Int
ixA Int
ixB = if Int
ixA forall a. Ord a => a -> a -> Bool
< Int
ixB
    then do
      Word8
a :: Word8 <- forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray s
arr Int
ixA
      Word8
b :: Word8 <- forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray s
arr Int
ixB
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
ixA Word8
b
      forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray s
arr Int
ixB Word8
a
      Int -> Int -> ST s ()
go (Int
ixA forall a. Num a => a -> a -> a
+ Int
1) (Int
ixB forall a. Num a => a -> a -> a
- Int
1)
    else forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

c2w :: Char -> Word8
c2w :: Char -> Word8
c2w = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord

shrinkMutableByteArray :: MutableByteArray s -> Int -> ST s ()
shrinkMutableByteArray :: forall s. MutableByteArray s -> Int -> ST s ()
shrinkMutableByteArray (MutableByteArray MutableByteArray# s
arr) (I# Int#
sz) =
  forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall d. MutableByteArray# d -> Int# -> State# d -> State# d
shrinkMutableByteArray# MutableByteArray# s
arr Int#
sz)

-- This is adapted from androider's code in https://stackoverflow.com/a/7097567
-- The checks for infinity and NaN have been removed. Note that this is a little
-- inaccurate. This is very visible when encoding a number like 2.25, which
-- is perfectly represented as an IEEE 754 floating point number but is goofed
-- up by this function.
doubleDec# :: forall s.
  Double# -> MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
doubleDec# :: forall s.
Double#
-> MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
doubleDec# Double#
d# MutableByteArray# s
marr# Int#
off# State# s
s0 =
  case forall a s. IO a -> ST s a
unsafeIOToST (forall s. MutableByteArray# s -> Int# -> Double# -> IO Int
c_paste_double MutableByteArray# s
marr# Int#
off# Double#
d#) of
    ST STRep s Int
f -> case STRep s Int
f State# s
s0 of
      (# State# s
s1, I# Int#
r #) -> (# State# s
s1, Int#
r #)

-- Based on C code from https://stackoverflow.com/a/5558614
-- For numbers less than 1073741829, this gives a correct answer.
approxDiv10 :: Word -> Word
approxDiv10 :: Word -> Word
approxDiv10 !Word
n = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word
0x1999999A forall a. Num a => a -> a -> a
* Word
n) Int
32

unsafeWordToWord8 :: Word -> Word8
unsafeWordToWord8 :: Word -> Word8
unsafeWordToWord8 (W# Word#
w) = Word8# -> Word8
W8# (Word# -> Word8#
C.wordToWord8# Word#
w)

foreign import ccall unsafe "bytebuild_paste_double" c_paste_double ::
  MutableByteArray# s -> Int# -> Double# -> IO Int