Add more int-encoding functions

This commit is contained in:
Andrew Martin 2019-09-04 10:49:14 -04:00
parent 7ed17f5b6d
commit f62d5ebde8
2 changed files with 57 additions and 8 deletions

View file

@ -33,6 +33,9 @@ module Data.ByteArray.Builder
, word16Dec , word16Dec
, word8Dec , word8Dec
, int64Dec , int64Dec
, int32Dec
, int16Dec
, int8Dec
, intDec , intDec
, word64PaddedUpperHex , word64PaddedUpperHex
, word32PaddedUpperHex , word32PaddedUpperHex
@ -58,7 +61,7 @@ import Data.ByteArray.Builder.Unsafe (stringUtf8,cstring)
import Data.ByteString.Short.Internal (ShortByteString(SBS)) import Data.ByteString.Short.Internal (ShortByteString(SBS))
import Data.Bytes.Types (Bytes(Bytes),MutableBytes(MutableBytes)) import Data.Bytes.Types (Bytes(Bytes),MutableBytes(MutableBytes))
import Data.Char (ord) import Data.Char (ord)
import Data.Int (Int64) import Data.Int (Int64,Int32,Int16,Int8)
import Data.Primitive import Data.Primitive
import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..)) import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..))
import Data.Text.Short (ShortText) import Data.Text.Short (ShortText)
@ -293,6 +296,27 @@ doubleDec w = fromBounded Nat.constant (Bounded.doubleDec w)
int64Dec :: Int64 -> Builder int64Dec :: Int64 -> Builder
int64Dec w = fromBounded Nat.constant (Bounded.int64Dec w) int64Dec w = fromBounded Nat.constant (Bounded.int64Dec w)
-- | 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
int32Dec w = fromBounded Nat.constant (Bounded.int32Dec w)
-- | 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
int16Dec w = fromBounded Nat.constant (Bounded.int16Dec w)
-- | 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
int8Dec w = fromBounded Nat.constant (Bounded.int8Dec w)
-- | Encodes a signed machine-sized integer as decimal. -- | Encodes a signed machine-sized integer as decimal.
-- This encoding never starts with a zero unless the argument was zero. -- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers -- Negative numbers are preceded by a minus sign. Positive numbers

View file

@ -30,6 +30,9 @@ module Data.ByteArray.Builder.Bounded
, word16Dec , word16Dec
, word8Dec , word8Dec
, int64Dec , int64Dec
, int32Dec
, int16Dec
, int8Dec
, intDec , intDec
, word64PaddedUpperHex , word64PaddedUpperHex
, word32PaddedUpperHex , word32PaddedUpperHex
@ -55,7 +58,7 @@ import Data.Char (ord)
import Data.Primitive import Data.Primitive
import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..)) import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..))
import GHC.Exts import GHC.Exts
import GHC.Int (Int64(I64#)) import GHC.Int (Int64(I64#),Int32(I32#),Int16(I16#),Int8(I8#))
import GHC.ST (ST(ST)) import GHC.ST (ST(ST))
import GHC.TypeLits (type (+)) import GHC.TypeLits (type (+))
import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#)) import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#))
@ -163,14 +166,35 @@ word8Dec (W8# w) = wordCommonDec# w
-- Negative numbers are preceded by a minus sign. Positive numbers -- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything. -- are not preceded by anything.
int64Dec :: Int64 -> Builder 20 int64Dec :: Int64 -> Builder 20
int64Dec (I64# w) = int64Dec# w int64Dec (I64# w) = intCommonDec# w
-- | 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 (I32# w) = intCommonDec# 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 (I16# w) = intCommonDec# 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 (I8# w) = intCommonDec# w
-- | Requires up to 20 bytes. Encodes a signed machine-sized integer -- | Requires up to 20 bytes. Encodes a signed machine-sized integer
-- as decimal. This encoding never starts with a zero unless the -- as decimal. This encoding never starts with a zero unless the
-- argument was zero. Negative numbers are preceded by a minus sign. -- argument was zero. Negative numbers are preceded by a minus sign.
-- Positive numbers are not preceded by anything. -- Positive numbers are not preceded by anything.
intDec :: Int -> Builder 20 intDec :: Int -> Builder 20
intDec (I# w) = int64Dec# w intDec (I# w) = intCommonDec# w
-- Requires a number of bytes that is bounded by the size of -- Requires a number of bytes that is bounded by the size of
-- the word. This is only used internally. -- the word. This is only used internally.
@ -196,10 +220,11 @@ internalWordLoop arr off0 x0 = go off0 x0 where
reverseBytes arr off0 (off - 1) reverseBytes arr off0 (off - 1)
pure off pure off
-- | Requires up to 19 bytes. -- Requires up to 20 bytes. Can be less depending on what the
int64Dec# :: Int# -> Builder 20 -- size of the argument is known to be. Unsafe.
{-# noinline int64Dec# #-} intCommonDec# :: Int# -> Builder n
int64Dec# w# = Unsafe.construct $ \arr off0 -> case compare w 0 of {-# noinline intCommonDec# #-}
intCommonDec# w# = Unsafe.construct $ \arr off0 -> case compare w 0 of
GT -> internalWordLoop arr off0 (fromIntegral w) GT -> internalWordLoop arr off0 (fromIntegral w)
EQ -> do EQ -> do
writeByteArray arr off0 (c2w '0') writeByteArray arr off0 (c2w '0')