-- |
-- Utils for dealing with integer numbers.
module PostgreSQL.Binary.Integral where

import qualified Data.ByteString as B
import PostgreSQL.Binary.Prelude

{-# INLINEABLE pack #-}
pack :: (Bits a, Num a) => B.ByteString -> a
pack :: forall a. (Bits a, Num a) => ByteString -> a
pack =
  forall a. (a -> Word8 -> a) -> a -> ByteString -> a
B.foldl' (\a
n Word8
h -> forall a. Bits a => a -> Int -> a
shiftL a
n Int
8 forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
h) a
0

{-# INLINE unpackBySize #-}
unpackBySize :: (Bits a, Integral a) => Int -> a -> B.ByteString
unpackBySize :: forall a. (Bits a, Integral a) => Int -> a -> ByteString
unpackBySize Int
n a
x =
  [Word8] -> ByteString
B.pack forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Int -> Word8
f forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse [Int
0 .. Int
n forall a. Num a => a -> a -> a
- Int
1]
  where
    f :: Int -> Word8
f Int
s =
      forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. Bits a => a -> Int -> a
shiftR a
x (Int
8 forall a. Num a => a -> a -> a
* Int
s)