From f62d5ebde8090b4a29b9ddb0511e52916d73e0b3 Mon Sep 17 00:00:00 2001 From: Andrew Martin Date: Wed, 4 Sep 2019 10:49:14 -0400 Subject: [PATCH] Add more int-encoding functions --- src/Data/ByteArray/Builder.hs | 26 +++++++++++++++++- src/Data/ByteArray/Builder/Bounded.hs | 39 ++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/Data/ByteArray/Builder.hs b/src/Data/ByteArray/Builder.hs index 3fd7f36..f4045ef 100644 --- a/src/Data/ByteArray/Builder.hs +++ b/src/Data/ByteArray/Builder.hs @@ -33,6 +33,9 @@ module Data.ByteArray.Builder , word16Dec , word8Dec , int64Dec + , int32Dec + , int16Dec + , int8Dec , intDec , word64PaddedUpperHex , word32PaddedUpperHex @@ -58,7 +61,7 @@ import Data.ByteArray.Builder.Unsafe (stringUtf8,cstring) import Data.ByteString.Short.Internal (ShortByteString(SBS)) import Data.Bytes.Types (Bytes(Bytes),MutableBytes(MutableBytes)) import Data.Char (ord) -import Data.Int (Int64) +import Data.Int (Int64,Int32,Int16,Int8) import Data.Primitive import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..)) import Data.Text.Short (ShortText) @@ -293,6 +296,27 @@ doubleDec w = fromBounded Nat.constant (Bounded.doubleDec w) int64Dec :: Int64 -> Builder 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. -- This encoding never starts with a zero unless the argument was zero. -- Negative numbers are preceded by a minus sign. Positive numbers diff --git a/src/Data/ByteArray/Builder/Bounded.hs b/src/Data/ByteArray/Builder/Bounded.hs index 04cc186..e45442f 100644 --- a/src/Data/ByteArray/Builder/Bounded.hs +++ b/src/Data/ByteArray/Builder/Bounded.hs @@ -30,6 +30,9 @@ module Data.ByteArray.Builder.Bounded , word16Dec , word8Dec , int64Dec + , int32Dec + , int16Dec + , int8Dec , intDec , word64PaddedUpperHex , word32PaddedUpperHex @@ -55,7 +58,7 @@ import Data.Char (ord) import Data.Primitive import Data.Primitive.ByteArray.Offset (MutableByteArrayOffset(..)) 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.TypeLits (type (+)) 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 -- are not preceded by anything. 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 -- 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 (I# w) = int64Dec# w +intDec (I# w) = intCommonDec# w -- Requires a number of bytes that is bounded by the size of -- the word. This is only used internally. @@ -196,10 +220,11 @@ internalWordLoop arr off0 x0 = go off0 x0 where reverseBytes arr off0 (off - 1) pure off --- | Requires up to 19 bytes. -int64Dec# :: Int# -> Builder 20 -{-# noinline int64Dec# #-} -int64Dec# w# = Unsafe.construct $ \arr off0 -> case compare w 0 of +-- 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# w# = Unsafe.construct $ \arr off0 -> case compare w 0 of GT -> internalWordLoop arr off0 (fromIntegral w) EQ -> do writeByteArray arr off0 (c2w '0')