finish out LEB for 32-bit and signed 32/64
This commit is contained in:
parent
ce52044b08
commit
f5709a8cd2
3 changed files with 29 additions and 13 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue