{-# 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 c :: ByteString
c cs :: ByteString
cs) = ByteString -> ByteString -> ByteString
Chunk (ByteString -> ByteString
B16.encode ByteString
c) (ByteString -> ByteString
encode ByteString
cs)
encode 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 c :: ByteString
c ~(y :: ByteString
y,z :: ByteString
z)
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = (ByteString -> ByteString -> ByteString
chunk ByteString
h ByteString
y, ByteString
z)
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1 Bool -> Bool -> Bool
&& Word8 -> Bool
isHex (ByteString -> Word8
B.unsafeHead ByteString
t) =
case ByteString
z of
Chunk a :: ByteString
a as :: ByteString
as | Word8 -> Bool
isHex (ByteString -> Word8
B.unsafeHead ByteString
a)
-> let (q :: ByteString
q,_) = 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
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 (h :: ByteString
h,t :: 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 w :: Word8
w = (Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 48 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= 57) Bool -> Bool -> Bool
|| (Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 97 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= 102) Bool -> Bool -> Bool
|| (Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= 65 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= 70)