module Codec.Binary.Util
( toHex
, fromHex
, EncIncData(..)
, EncIncRes(..)
, DecIncData(..)
, DecIncRes(..)
, encoder
, decoder
) where
import Data.Array
import Data.Bits
import Data.Char
import Data.Word
import qualified Data.Map as M
hexEncMap :: [(Word8, Char)]
hexEncMap = [Word8] -> [Char] -> [(Word8, Char)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Word8
0..] [Char]
"0123456789ABCDEF"
hexEncodeArray :: Array Word8 Char
hexEncodeArray :: Array Word8 Char
hexEncodeArray = (Word8, Word8) -> [(Word8, Char)] -> Array Word8 Char
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Word8
0, Word8
16) [(Word8, Char)]
hexEncMap
hexDecodeMap :: M.Map Char Word8
hexDecodeMap :: Map Char Word8
hexDecodeMap = [(Char, Word8)] -> Map Char Word8
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Char
b, Word8
a) | (Word8
a, Char
b) <- [(Word8, Char)]
hexEncMap]
toHex :: Word8 -> String
toHex :: Word8 -> [Char]
toHex Word8
o = let
hn :: Word8
hn = Word8
o Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`shiftR` Int
4
ln :: Word8
ln = Word8
o Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0xf
in [Array Word8 Char
hexEncodeArray Array Word8 Char -> Word8 -> Char
forall i e. Ix i => Array i e -> i -> e
! Word8
hn, Array Word8 Char
hexEncodeArray Array Word8 Char -> Word8 -> Char
forall i e. Ix i => Array i e -> i -> e
! Word8
ln]
fromHex :: String -> Maybe Word8
fromHex :: [Char] -> Maybe Word8
fromHex = let
dec :: [Maybe a] -> Maybe a
dec [Just a
hn, Just a
ln] = let
o :: a
o = a
hn a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
4 a -> a -> a
forall a. Bits a => a -> a -> a
.|. a
ln
in a -> Maybe a
forall a. a -> Maybe a
Just a
o
dec [Maybe a]
_ = Maybe a
forall a. Maybe a
Nothing
in [Maybe Word8] -> Maybe Word8
forall {a}. Bits a => [Maybe a] -> Maybe a
dec ([Maybe Word8] -> Maybe Word8)
-> ([Char] -> [Maybe Word8]) -> [Char] -> Maybe Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Maybe Word8) -> [Char] -> [Maybe Word8]
forall a b. (a -> b) -> [a] -> [b]
map ((Char -> Map Char Word8 -> Maybe Word8)
-> Map Char Word8 -> Char -> Maybe Word8
forall a b c. (a -> b -> c) -> b -> a -> c
flip Char -> Map Char Word8 -> Maybe Word8
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Map Char Word8
hexDecodeMap (Char -> Maybe Word8) -> (Char -> Char) -> Char -> Maybe Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Char
toUpper)
data EncIncData = EChunk [Word8]
| EDone
data EncIncRes i = EPart i (EncIncData -> EncIncRes i)
| EFinal i
encoder :: (EncIncData -> EncIncRes [a]) -> [Word8] -> [a]
encoder EncIncData -> EncIncRes [a]
f [Word8]
os = case EncIncData -> EncIncRes [a]
f ([Word8] -> EncIncData
EChunk [Word8]
os) of
EPart [a]
r1 EncIncData -> EncIncRes [a]
f' -> case EncIncData -> EncIncRes [a]
f' EncIncData
EDone of
EFinal [a]
r2 -> [a]
r1 [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
r2
data DecIncData i = DChunk i
| DDone
data DecIncRes i = DPart [Word8] (DecIncData i -> DecIncRes i)
| DFinal [Word8] i
| DFail [Word8] i
decoder :: (DecIncData i -> DecIncRes i) -> i -> Maybe [Word8]
decoder :: forall i. (DecIncData i -> DecIncRes i) -> i -> Maybe [Word8]
decoder DecIncData i -> DecIncRes i
f i
s = let
d :: DecIncRes i
d = DecIncData i -> DecIncRes i
f (i -> DecIncData i
forall i. i -> DecIncData i
DChunk i
s)
in case DecIncRes i
d of
DFinal [Word8]
da i
_ -> [Word8] -> Maybe [Word8]
forall a. a -> Maybe a
Just [Word8]
da
DFail [Word8]
_ i
_ -> Maybe [Word8]
forall a. Maybe a
Nothing
DPart [Word8]
da DecIncData i -> DecIncRes i
f -> let
d' :: DecIncRes i
d' = DecIncData i -> DecIncRes i
f DecIncData i
forall i. DecIncData i
DDone
in case DecIncRes i
d' of
DFinal [Word8]
da' i
_ -> [Word8] -> Maybe [Word8]
forall a. a -> Maybe a
Just ([Word8] -> Maybe [Word8]) -> [Word8] -> Maybe [Word8]
forall a b. (a -> b) -> a -> b
$ [Word8]
da [Word8] -> [Word8] -> [Word8]
forall a. [a] -> [a] -> [a]
++ [Word8]
da'
DFail [Word8]
_ i
_ -> Maybe [Word8]
forall a. Maybe a
Nothing
DPart [Word8]
_ DecIncData i -> DecIncRes i
_ -> Maybe [Word8]
forall a. Maybe a
Nothing