{-# LANGUAGE OverloadedStrings #-}
module Data.ByteString.Base16.Lazy
(
encode
, decode
) where
import Data.Word (Word8)
import qualified Data.ByteString.Base16 as B16
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import Data.ByteString.Lazy.Internal
encode :: ByteString -> ByteString
encode :: ByteString -> ByteString
encode (Chunk ByteString
c ByteString
cs) = ByteString -> ByteString -> ByteString
Chunk (ByteString -> ByteString
B16.encode ByteString
c) (ByteString -> ByteString
encode ByteString
cs)
encode ByteString
Empty = ByteString
Empty
decode :: ByteString -> (ByteString, ByteString)
decode :: ByteString -> (ByteString, ByteString)
decode = (ByteString
-> (ByteString, ByteString) -> (ByteString, ByteString))
-> (ByteString, ByteString)
-> ByteString
-> (ByteString, ByteString)
forall a. (ByteString -> a -> a) -> a -> ByteString -> a
foldrChunks ByteString -> (ByteString, ByteString) -> (ByteString, ByteString)
go (ByteString
Empty, ByteString
Empty)
where go :: ByteString -> (ByteString, ByteString) -> (ByteString, ByteString)
go ByteString
c ~(ByteString
y,ByteString
z)
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = (ByteString -> ByteString -> ByteString
chunk ByteString
h ByteString
y, ByteString
z)
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& Word8 -> Bool
isHex (ByteString -> Word8
B.unsafeHead ByteString
t) =
case ByteString
z of
Chunk ByteString
a ByteString
as | Word8 -> Bool
isHex (ByteString -> Word8
B.unsafeHead ByteString
a)
-> let (ByteString
q,ByteString
_) = ByteString -> (ByteString, ByteString)
B16.decode (ByteString
t ByteString -> Word8 -> ByteString
`B.snoc` ByteString -> Word8
B.unsafeHead ByteString
a)
in (ByteString -> ByteString -> ByteString
chunk ByteString
h (ByteString -> ByteString -> ByteString
chunk ByteString
q ByteString
y), ByteString -> ByteString -> ByteString
chunk (ByteString -> ByteString
B.unsafeTail ByteString
a) ByteString
as)
ByteString
_ -> (ByteString -> ByteString -> ByteString
chunk ByteString
h ByteString
y, ByteString -> ByteString -> ByteString
chunk ByteString
t ByteString
z)
| Bool
otherwise = (ByteString -> ByteString -> ByteString
chunk ByteString
h ByteString
y, ByteString -> ByteString -> ByteString
chunk ByteString
t ByteString
z)
where (ByteString
h,ByteString
t) = ByteString -> (ByteString, ByteString)
B16.decode ByteString
c
len :: Int
len = ByteString -> Int
B.length ByteString
t
isHex :: Word8 -> Bool
isHex :: Word8 -> Bool
isHex Word8
w = (Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
48 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
57) Bool -> Bool -> Bool
|| (Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
97 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
102) Bool -> Bool -> Bool
|| (Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
65 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
70)