module Data.ASN1.Internal
( uintOfBytes
, intOfBytes
, bytesOfUInt
, bytesOfInt
, putVarEncodingIntegral
) where
import Data.Word
import Data.Bits
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
uintOfBytes :: ByteString -> (Int, Integer)
uintOfBytes :: ByteString -> (Int, Integer)
uintOfBytes ByteString
b = (ByteString -> Int
B.length ByteString
b, forall a. (a -> Word8 -> a) -> a -> ByteString -> a
B.foldl (\Integer
acc Word8
n -> (Integer
acc forall a. Bits a => a -> Int -> a
`shiftL` Int
8) forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
n) Integer
0 ByteString
b)
bytesOfUInt :: Integer -> [Word8]
bytesOfUInt :: Integer -> [Word8]
bytesOfUInt Integer
x = forall a. [a] -> [a]
reverse (forall {t} {a}. (Integral t, Num a, Bits a, Bits t) => t -> [a]
list Integer
x)
where list :: t -> [a]
list t
i = if t
i forall a. Ord a => a -> a -> Bool
<= t
0xff then [forall a b. (Integral a, Num b) => a -> b
fromIntegral t
i] else (forall a b. (Integral a, Num b) => a -> b
fromIntegral t
i forall a. Bits a => a -> a -> a
.&. a
0xff) forall a. a -> [a] -> [a]
: t -> [a]
list (t
i forall a. Bits a => a -> Int -> a
`shiftR` Int
8)
intOfBytes :: ByteString -> (Int, Integer)
intOfBytes :: ByteString -> (Int, Integer)
intOfBytes ByteString
b
| ByteString -> Int
B.length ByteString
b forall a. Eq a => a -> a -> Bool
== Int
0 = (Int
0, Integer
0)
| Bool
otherwise = (Int
len, if Bool
isNeg then -(Integer
maxIntLen forall a. Num a => a -> a -> a
- Integer
v forall a. Num a => a -> a -> a
+ Integer
1) else Integer
v)
where
(Int
len, Integer
v) = ByteString -> (Int, Integer)
uintOfBytes ByteString
b
maxIntLen :: Integer
maxIntLen = Integer
2 forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
8 forall a. Num a => a -> a -> a
* Int
len) forall a. Num a => a -> a -> a
- Integer
1
isNeg :: Bool
isNeg = forall a. Bits a => a -> Int -> Bool
testBit (HasCallStack => ByteString -> Word8
B.head ByteString
b) Int
7
bytesOfInt :: Integer -> [Word8]
bytesOfInt :: Integer -> [Word8]
bytesOfInt Integer
i
| Integer
i forall a. Ord a => a -> a -> Bool
> Integer
0 = if forall a. Bits a => a -> Int -> Bool
testBit (forall a. [a] -> a
head [Word8]
uints) Int
7 then Word8
0 forall a. a -> [a] -> [a]
: [Word8]
uints else [Word8]
uints
| Integer
i forall a. Eq a => a -> a -> Bool
== Integer
0 = [Word8
0]
| Bool
otherwise = if forall a. Bits a => a -> Int -> Bool
testBit (forall a. [a] -> a
head [Word8]
nints) Int
7 then [Word8]
nints else Word8
0xff forall a. a -> [a] -> [a]
: [Word8]
nints
where
uints :: [Word8]
uints = Integer -> [Word8]
bytesOfUInt (forall a. Num a => a -> a
abs Integer
i)
nints :: [Word8]
nints = forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall {a}. (Num a, Eq a) => [a] -> [a]
plusOne forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a. Bits a => a -> a
complement forall a b. (a -> b) -> a -> b
$ [Word8]
uints
plusOne :: [a] -> [a]
plusOne [] = [a
1]
plusOne (a
x:[a]
xs) = if a
x forall a. Eq a => a -> a -> Bool
== a
0xff then a
0 forall a. a -> [a] -> [a]
: [a] -> [a]
plusOne [a]
xs else (a
xforall a. Num a => a -> a -> a
+a
1) forall a. a -> [a] -> [a]
: [a]
xs
putVarEncodingIntegral :: (Bits i, Integral i) => i -> ByteString
putVarEncodingIntegral :: forall i. (Bits i, Integral i) => i -> ByteString
putVarEncodingIntegral i
i = ByteString -> ByteString
B.reverse forall a b. (a -> b) -> a -> b
$ forall a. (a -> Maybe (Word8, a)) -> a -> ByteString
B.unfoldr forall {a} {a}.
(Integral a, Bits a, Bits a, Num a) =>
(a, Bool) -> Maybe (a, (a, Bool))
genOctets (i
i,Bool
True)
where genOctets :: (a, Bool) -> Maybe (a, (a, Bool))
genOctets (a
x,Bool
first)
| a
x forall a. Ord a => a -> a -> Bool
> a
0 =
let out :: a
out = forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
x forall a. Bits a => a -> a -> a
.&. a
0x7F) forall a. Bits a => a -> a -> a
.|. (if Bool
first then a
0 else a
0x80) in
forall a. a -> Maybe a
Just (a
out, (forall a. Bits a => a -> Int -> a
shiftR a
x Int
7, Bool
False))
| Bool
otherwise = forall a. Maybe a
Nothing