{-# LANGUAGE ScopedTypeVariables, CPP, ForeignFunctionInterface,
MagicHash, UnboxedTuples #-}
{-# OPTIONS_HADDOCK not-home #-}
#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif
module Data.ByteString.Builder.ASCII
(
int8Dec
, int16Dec
, int32Dec
, int64Dec
, intDec
, integerDec
, word8Dec
, word16Dec
, word32Dec
, word64Dec
, wordDec
, floatDec
, doubleDec
, word8Hex
, word16Hex
, word32Hex
, word64Hex
, wordHex
, int8HexFixed
, int16HexFixed
, int32HexFixed
, int64HexFixed
, word8HexFixed
, word16HexFixed
, word32HexFixed
, word64HexFixed
, floatHexFixed
, doubleHexFixed
, byteStringHex
, lazyByteStringHex
) where
import Data.ByteString as S
import Data.ByteString.Lazy as L
import Data.ByteString.Builder.Internal (Builder)
import qualified Data.ByteString.Builder.Prim as P
import Foreign
#if __GLASGOW_HASKELL__ >= 811
import GHC.Num.Integer
#define HAS_INTEGER_CONSTR 1
#define quotRemInteger integerQuotRem#
#elif defined(INTEGER_GMP)
#define HAS_INTEGER_CONSTR 1
#define IS S#
# if !(MIN_VERSION_base(4,8,0))
import Data.Monoid (mappend)
# endif
# if __GLASGOW_HASKELL__ < 710
import GHC.Num (quotRemInteger)
# endif
import GHC.Integer.GMP.Internals
#endif
#if HAS_INTEGER_CONSTR
import qualified Data.ByteString.Builder.Prim.Internal as P
import Foreign.C.Types
import GHC.Types (Int(..))
#endif
{-# INLINE string7 #-}
string7 :: String -> Builder
string7 :: String -> Builder
string7 = FixedPrim Char -> String -> Builder
forall a. FixedPrim a -> [a] -> Builder
P.primMapListFixed FixedPrim Char
P.char7
{-# INLINE int8Dec #-}
int8Dec :: Int8 -> Builder
int8Dec :: Int8 -> Builder
int8Dec = BoundedPrim Int8 -> Int8 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Int8
P.int8Dec
{-# INLINE int16Dec #-}
int16Dec :: Int16 -> Builder
int16Dec :: Int16 -> Builder
int16Dec = BoundedPrim Int16 -> Int16 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Int16
P.int16Dec
{-# INLINE int32Dec #-}
int32Dec :: Int32 -> Builder
int32Dec :: Int32 -> Builder
int32Dec = BoundedPrim Int32 -> Int32 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Int32
P.int32Dec
{-# INLINE int64Dec #-}
int64Dec :: Int64 -> Builder
int64Dec :: Int64 -> Builder
int64Dec = BoundedPrim Int64 -> Int64 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Int64
P.int64Dec
{-# INLINE intDec #-}
intDec :: Int -> Builder
intDec :: Int -> Builder
intDec = BoundedPrim Int -> Int -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Int
P.intDec
{-# INLINE word8Dec #-}
word8Dec :: Word8 -> Builder
word8Dec :: Word8 -> Builder
word8Dec = BoundedPrim Word8 -> Word8 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word8
P.word8Dec
{-# INLINE word16Dec #-}
word16Dec :: Word16 -> Builder
word16Dec :: Word16 -> Builder
word16Dec = BoundedPrim Word16 -> Word16 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word16
P.word16Dec
{-# INLINE word32Dec #-}
word32Dec :: Word32 -> Builder
word32Dec :: Word32 -> Builder
word32Dec = BoundedPrim Word32 -> Word32 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word32
P.word32Dec
{-# INLINE word64Dec #-}
word64Dec :: Word64 -> Builder
word64Dec :: Word64 -> Builder
word64Dec = BoundedPrim Word64 -> Word64 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word64
P.word64Dec
{-# INLINE wordDec #-}
wordDec :: Word -> Builder
wordDec :: Word -> Builder
wordDec = BoundedPrim Word -> Word -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word
P.wordDec
{-# INLINE floatDec #-}
floatDec :: Float -> Builder
floatDec :: Float -> Builder
floatDec = String -> Builder
string7 (String -> Builder) -> (Float -> String) -> Float -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> String
forall a. Show a => a -> String
show
{-# INLINE doubleDec #-}
doubleDec :: Double -> Builder
doubleDec :: Double -> Builder
doubleDec = String -> Builder
string7 (String -> Builder) -> (Double -> String) -> Double -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> String
forall a. Show a => a -> String
show
{-# INLINE word8Hex #-}
word8Hex :: Word8 -> Builder
word8Hex :: Word8 -> Builder
word8Hex = BoundedPrim Word8 -> Word8 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word8
P.word8Hex
{-# INLINE word16Hex #-}
word16Hex :: Word16 -> Builder
word16Hex :: Word16 -> Builder
word16Hex = BoundedPrim Word16 -> Word16 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word16
P.word16Hex
{-# INLINE word32Hex #-}
word32Hex :: Word32 -> Builder
word32Hex :: Word32 -> Builder
word32Hex = BoundedPrim Word32 -> Word32 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word32
P.word32Hex
{-# INLINE word64Hex #-}
word64Hex :: Word64 -> Builder
word64Hex :: Word64 -> Builder
word64Hex = BoundedPrim Word64 -> Word64 -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word64
P.word64Hex
{-# INLINE wordHex #-}
wordHex :: Word -> Builder
wordHex :: Word -> Builder
wordHex = BoundedPrim Word -> Word -> Builder
forall a. BoundedPrim a -> a -> Builder
P.primBounded BoundedPrim Word
P.wordHex
{-# INLINE int8HexFixed #-}
int8HexFixed :: Int8 -> Builder
int8HexFixed :: Int8 -> Builder
int8HexFixed = FixedPrim Int8 -> Int8 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int8
P.int8HexFixed
{-# INLINE int16HexFixed #-}
int16HexFixed :: Int16 -> Builder
int16HexFixed :: Int16 -> Builder
int16HexFixed = FixedPrim Int16 -> Int16 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int16
P.int16HexFixed
{-# INLINE int32HexFixed #-}
int32HexFixed :: Int32 -> Builder
int32HexFixed :: Int32 -> Builder
int32HexFixed = FixedPrim Int32 -> Int32 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int32
P.int32HexFixed
{-# INLINE int64HexFixed #-}
int64HexFixed :: Int64 -> Builder
int64HexFixed :: Int64 -> Builder
int64HexFixed = FixedPrim Int64 -> Int64 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int64
P.int64HexFixed
{-# INLINE word8HexFixed #-}
word8HexFixed :: Word8 -> Builder
word8HexFixed :: Word8 -> Builder
word8HexFixed = FixedPrim Word8 -> Word8 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word8
P.word8HexFixed
{-# INLINE word16HexFixed #-}
word16HexFixed :: Word16 -> Builder
word16HexFixed :: Word16 -> Builder
word16HexFixed = FixedPrim Word16 -> Word16 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word16
P.word16HexFixed
{-# INLINE word32HexFixed #-}
word32HexFixed :: Word32 -> Builder
word32HexFixed :: Word32 -> Builder
word32HexFixed = FixedPrim Word32 -> Word32 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word32
P.word32HexFixed
{-# INLINE word64HexFixed #-}
word64HexFixed :: Word64 -> Builder
word64HexFixed :: Word64 -> Builder
word64HexFixed = FixedPrim Word64 -> Word64 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word64
P.word64HexFixed
{-# INLINE floatHexFixed #-}
floatHexFixed :: Float -> Builder
floatHexFixed :: Float -> Builder
floatHexFixed = FixedPrim Float -> Float -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Float
P.floatHexFixed
{-# INLINE doubleHexFixed #-}
doubleHexFixed :: Double -> Builder
doubleHexFixed :: Double -> Builder
doubleHexFixed = FixedPrim Double -> Double -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Double
P.doubleHexFixed
{-# NOINLINE byteStringHex #-}
byteStringHex :: S.ByteString -> Builder
byteStringHex :: ByteString -> Builder
byteStringHex = FixedPrim Word8 -> ByteString -> Builder
P.primMapByteStringFixed FixedPrim Word8
P.word8HexFixed
{-# NOINLINE lazyByteStringHex #-}
lazyByteStringHex :: L.ByteString -> Builder
lazyByteStringHex :: ByteString -> Builder
lazyByteStringHex = FixedPrim Word8 -> ByteString -> Builder
P.primMapLazyByteStringFixed FixedPrim Word8
P.word8HexFixed
#if HAS_INTEGER_CONSTR
# define PAIR(a,b) (# a,b #)
maxPow10 :: Integer
maxPow10 :: Integer
maxPow10 = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ (Int
10 :: Int) Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^ Int -> Int -> Int
forall a. a -> a -> a
P.caseWordSize_32_64 (Int
9 :: Int) Int
18
integerDec :: Integer -> Builder
integerDec :: Integer -> Builder
integerDec (IS Int#
i#) = Int -> Builder
intDec (Int# -> Int
I# Int#
i#)
integerDec Integer
i
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = FixedPrim Char -> Char -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Char
P.char8 Char
'-' Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` Integer -> Builder
go (-Integer
i)
| Bool
otherwise = Integer -> Builder
go Integer
i
where
errImpossible :: String -> a
errImpossible String
fun =
String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"integerDec: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fun String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": the impossible happened."
go :: Integer -> Builder
go :: Integer -> Builder
go Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
maxPow10 = Int -> Builder
intDec (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
n)
| Bool
otherwise =
case [Integer] -> [Int]
putH (Integer -> Integer -> [Integer]
splitf (Integer
maxPow10 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
maxPow10) Integer
n) of
(Int
x:[Int]
xs) -> Int -> Builder
intDec Int
x Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` BoundedPrim Int -> [Int] -> Builder
forall a. BoundedPrim a -> [a] -> Builder
P.primMapListBounded BoundedPrim Int
intDecPadded [Int]
xs
[] -> String -> Builder
forall a. String -> a
errImpossible String
"integerDec: go"
splitf :: Integer -> Integer -> [Integer]
splitf :: Integer -> Integer -> [Integer]
splitf Integer
pow10 Integer
n0
| Integer
pow10 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
n0 = [Integer
n0]
| Bool
otherwise = [Integer] -> [Integer]
splith (Integer -> Integer -> [Integer]
splitf (Integer
pow10 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
pow10) Integer
n0)
where
splith :: [Integer] -> [Integer]
splith [] = String -> [Integer]
forall a. String -> a
errImpossible String
"splith"
splith (Integer
n:[Integer]
ns) =
case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
pow10 of
PAIR(Integer
q,r) | Integer
q Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 -> Integer
q Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
: Integer
r Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
: [Integer] -> [Integer]
splitb [Integer]
ns
| Bool
otherwise -> Integer
r Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
: [Integer] -> [Integer]
splitb [Integer]
ns
splitb :: [Integer] -> [Integer]
splitb [] = []
splitb (Integer
n:[Integer]
ns) = case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
pow10 of
PAIR(Integer
q,r) -> Integer
q Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
: Integer
r Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
: [Integer] -> [Integer]
splitb [Integer]
ns
putH :: [Integer] -> [Int]
putH :: [Integer] -> [Int]
putH [] = String -> [Int]
forall a. String -> a
errImpossible String
"putH"
putH (Integer
n:[Integer]
ns) = case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
maxPow10 of
PAIR(Integer
x,y)
| Int
q Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 -> Int
q Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: Int
r Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Integer] -> [Int]
putB [Integer]
ns
| Bool
otherwise -> Int
r Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Integer] -> [Int]
putB [Integer]
ns
where q :: Int
q = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
x
r :: Int
r = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
y
putB :: [Integer] -> [Int]
putB :: [Integer] -> [Int]
putB [] = []
putB (Integer
n:[Integer]
ns) = case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
maxPow10 of
PAIR(Integer
q,r) -> Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
q Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
r Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Integer] -> [Int]
putB [Integer]
ns
foreign import ccall unsafe "static _hs_bytestring_int_dec_padded9"
c_int_dec_padded9 :: CInt -> Ptr Word8 -> IO ()
foreign import ccall unsafe "static _hs_bytestring_long_long_int_dec_padded18"
c_long_long_int_dec_padded18 :: CLLong -> Ptr Word8 -> IO ()
{-# INLINE intDecPadded #-}
intDecPadded :: P.BoundedPrim Int
intDecPadded :: BoundedPrim Int
intDecPadded = FixedPrim Int -> BoundedPrim Int
forall a. FixedPrim a -> BoundedPrim a
P.liftFixedToBounded (FixedPrim Int -> BoundedPrim Int)
-> FixedPrim Int -> BoundedPrim Int
forall a b. (a -> b) -> a -> b
$ FixedPrim Int -> FixedPrim Int -> FixedPrim Int
forall a. a -> a -> a
P.caseWordSize_32_64
(Int -> (Int -> Ptr Word8 -> IO ()) -> FixedPrim Int
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
P.fixedPrim Int
9 ((Int -> Ptr Word8 -> IO ()) -> FixedPrim Int)
-> (Int -> Ptr Word8 -> IO ()) -> FixedPrim Int
forall a b. (a -> b) -> a -> b
$ CInt -> Ptr Word8 -> IO ()
c_int_dec_padded9 (CInt -> Ptr Word8 -> IO ())
-> (Int -> CInt) -> Int -> Ptr Word8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral)
(Int -> (Int -> Ptr Word8 -> IO ()) -> FixedPrim Int
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
P.fixedPrim Int
18 ((Int -> Ptr Word8 -> IO ()) -> FixedPrim Int)
-> (Int -> Ptr Word8 -> IO ()) -> FixedPrim Int
forall a b. (a -> b) -> a -> b
$ CLLong -> Ptr Word8 -> IO ()
c_long_long_int_dec_padded18 (CLLong -> Ptr Word8 -> IO ())
-> (Int -> CLLong) -> Int -> Ptr Word8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CLLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral)
#else
integerDec :: Integer -> Builder
integerDec = string7 . show
#endif