finish out LEB for 32-bit and signed 32/64

This commit is contained in:
Eric Demko 2022-01-24 14:28:18 -05:00 committed by Andrew Martin
parent ce52044b08
commit f5709a8cd2
3 changed files with 29 additions and 13 deletions

View file

@ -58,6 +58,7 @@ library
, template-haskell >=2.16
, text-short >=0.1.3 && <0.2
, wide-word >=0.1.0.9 && <0.2
, zigzag
if flag(checked)
build-depends: primitive-checked >= 0.7 && <0.8
else

View file

@ -91,7 +91,10 @@ module Data.Bytes.Builder
, int16LE
-- **** LEB128
, intLEB128
, int32LEB128
, int64LEB128
, wordLEB128
, word32LEB128
, word64LEB128
-- *** Many
, word8Array
@ -130,19 +133,19 @@ module Data.Bytes.Builder
import Prelude hiding (replicate)
import Control.Exception (SomeException,toException)
import Control.Monad.ST (ST,runST)
import Control.Monad.IO.Class (MonadIO,liftIO)
import Data.Bits (unsafeShiftR,unsafeShiftL,xor,finiteBitSize)
import Control.Monad.ST (ST,runST)
import Data.Bits (unsafeShiftR)
import Data.Bytes.Builder.Unsafe (addCommitsLength,copyReverseCommits)
import Data.Bytes.Builder.Unsafe (Builder(Builder),commitDistance1)
import Data.Bytes.Builder.Unsafe (BuilderState(BuilderState),pasteIO)
import Data.Bytes.Builder.Unsafe (Commits(Initial,Mutable,Immutable))
import Data.Bytes.Builder.Unsafe (reverseCommitsOntoChunks)
import Data.Bytes.Builder.Unsafe (commitsOntoChunks)
import Data.Bytes.Builder.Unsafe (reverseCommitsOntoChunks)
import Data.Bytes.Builder.Unsafe (stringUtf8,cstring,fromEffect)
import Data.Bytes.Builder.Unsafe (addCommitsLength,copyReverseCommits)
import Data.ByteString.Short.Internal (ShortByteString(SBS))
import Data.Bytes.Chunks (Chunks(ChunksNil))
import Data.Bytes.Types (Bytes(Bytes),MutableBytes(MutableBytes))
import Data.ByteString.Short.Internal (ShortByteString(SBS))
import Data.Char (ord)
import Data.Foldable (foldlM)
import Data.Int (Int64,Int32,Int16,Int8)
@ -150,11 +153,12 @@ import Data.Primitive (ByteArray(..),MutableByteArray(..),PrimArray(..))
import Data.Text.Short (ShortText)
import Data.WideWord (Word128,Word256)
import Data.Word (Word64,Word32,Word16,Word8)
import Data.Word.Zigzag (toZigzag,toZigzag32,toZigzag64)
import Foreign.C.String (CStringLen)
import GHC.ByteOrder (ByteOrder(BigEndian,LittleEndian),targetByteOrder)
import GHC.Exts (Addr#,(*#))
import GHC.Exts (Int(I#),Char(C#),Int#,State#,ByteArray#,(>=#))
import GHC.Exts (RealWorld,(+#),(-#),(<#))
import GHC.Exts (Addr#,(*#))
import GHC.Integer.Logarithms.Compat (integerLog2#)
import GHC.IO (IO(IO),stToIO)
import GHC.Natural (naturalFromInteger,naturalToInteger)
@ -1058,20 +1062,27 @@ indexChar8Array (ByteArray b) (I# i) = C# (Exts.indexCharArray# b i)
c2w :: Char -> Word8
c2w = fromIntegral . ord
-- In C, this is: (n << 1) ^ (n >> (BIT_WIDTH - 1))
zigZagNative :: Int -> Word
zigZagNative s = fromIntegral @Int @Word
((unsafeShiftL s 1) `xor` (unsafeShiftR s (finiteBitSize (undefined :: Word) - 1)))
-- | Encode a signed machine-sized integer with LEB-128. This uses
-- zig-zag encoding.
intLEB128 :: Int -> Builder
intLEB128 = wordLEB128 . zigZagNative
intLEB128 = wordLEB128 . toZigzag
-- | Encode a 32-bit signed integer with LEB-128. This uses zig-zag encoding.
int32LEB128 :: Int32 -> Builder
int32LEB128 = word32LEB128 . toZigzag32
-- | Encode a 64-bit signed integer with LEB-128. This uses zig-zag encoding.
int64LEB128 :: Int64 -> Builder
int64LEB128 = word64LEB128 . toZigzag64
-- | Encode a machine-sized word with LEB-128.
wordLEB128 :: Word -> Builder
wordLEB128 w = fromBounded Nat.constant (Bounded.wordLEB128 w)
-- | Encode a 32-bit word with LEB-128.
word32LEB128 :: Word32 -> Builder
word32LEB128 w = fromBounded Nat.constant (Bounded.word32LEB128 w)
-- | Encode a 64-bit word with LEB-128.
word64LEB128 :: Word64 -> Builder
word64LEB128 w = fromBounded Nat.constant (Bounded.word64LEB128 w)

View file

@ -97,6 +97,7 @@ module Data.Bytes.Builder.Bounded
, int16LE
-- **** LEB128
, wordLEB128
, word32LEB128
, word64LEB128
-- * Encode Floating-Point Types
, doubleDec
@ -850,6 +851,10 @@ ascii8 (C# c0) (C# c1) (C# c2) (C# c3) (C# c4) (C# c5) (C# c6) (C# c7) = Unsafe.
wordLEB128 :: Word -> Builder 10
wordLEB128 (W# w) = lebCommon (W# w)
-- | Encode a 32-bit word with LEB-128.
word32LEB128 :: Word32 -> Builder 5
word32LEB128 (W32# w) = lebCommon (W# w)
-- | Encode a 64-bit word with LEB-128.
word64LEB128 :: Word64 -> Builder 10
word64LEB128 (W64# w) = lebCommon (W# w)
@ -1071,4 +1076,3 @@ unsafeWordToWord8 (W# w) = W8# w
foreign import ccall unsafe "bytebuild_paste_double" c_paste_double ::
MutableByteArray# s -> Int# -> Double# -> IO Int