module Nauty.Internal.Encoding where
import qualified Data.Text.Lazy as T
import Data.Bits
import Data.Word
encodeVector :: Word64 -> [Word8] -> Word8 -> Int -> [Word8]
encodeVector :: Word64 -> [Word8] -> Word8 -> Int -> [Word8]
encodeVector Word64
lastValidBits [Word8]
bs Word8
acc Int
0 = Word8
acc Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: Word64 -> [Word8] -> Word8 -> Int -> [Word8]
encodeVector Word64
lastValidBits [Word8]
bs Word8
0 Int
6
encodeVector Word64
lastValidBits [Word8
b] Word8
acc Int
s
| (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
lastValidBits) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
s =
(Word8
acc Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR Word8
b (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
s))
Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftL Word8
b Int
s) Int
2]
| Bool
otherwise = [Word8
acc Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR Word8
b (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
s)]
encodeVector Word64
lastValidBits (Word8
b:[Word8]
bs) Word8
acc Int
r =
(Word8
acc Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR Word8
b (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r)))
Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: Word64 -> [Word8] -> Word8 -> Int -> [Word8]
encodeVector Word64
lastValidBits [Word8]
bs (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftL Word8
b Int
r) Int
2) ((Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2))
encodeVector Word64
_ [] Word8
_ Int
_ = []
numBits :: (Num a) => Word64 -> a
numBits :: forall a. Num a => Word64 -> a
numBits Word64
n = Word64 -> a
forall {t} {a}. (Num t, Num a, Bits t) => t -> a
numBits' (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
shiftR Word64
n Int
1)
where
numBits' :: t -> a
numBits' t
0 = a
1
numBits' t
n' = a
1 a -> a -> a
forall a. Num a => a -> a -> a
+ t -> a
numBits' (t -> Int -> t
forall a. Bits a => a -> Int -> a
shiftR t
n' Int
1)
encodeNumber :: Word64 -> T.Text
encodeNumber :: Word64 -> Text
encodeNumber Word64
n
| Word64
n Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
63 = String -> Text
T.pack [Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int) -> Word64 -> Int
forall a b. (a -> b) -> a -> b
$ Word64
n Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
63]
| Bool
otherwise =
let bits :: Int
bits = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ (Int
18 :: Int) Int -> Int -> Int
forall a. Num a => a -> a -> a
* (((Word64 -> Int
forall a. Num a => Word64 -> a
numBits Word64
n) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
18) :: Int
encode' :: Int -> [Word8]
encode' :: Int -> [Word8]
encode' Int
0 = [Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n]
encode' Int
s = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
shiftR Word64
n Int
s Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
63) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: Int -> [Word8]
encode' (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
6)
in String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ (Word8 -> Char) -> [Word8] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> (Word8 -> Word8) -> Word8 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+Word8
63))
([Word8] -> String) -> [Word8] -> String
forall a b. (a -> b) -> a -> b
$ (Int -> [Word8] -> [Word8]
forall a. Int -> [a] -> [a]
take (Int
bits Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
18) ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ Word8 -> [Word8]
forall a. a -> [a]
repeat Word8
63)
[Word8] -> [Word8] -> [Word8]
forall a. [a] -> [a] -> [a]
++ Int -> [Word8]
encode' (Int
bits Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
6)