module Codec.Binary.PythonString
( EncIncData(..)
, EncIncRes(..)
, encodeInc
, encode
, DecIncData(..)
, DecIncRes(..)
, decodeInc
, decode
, chop
, unchop
) where
import Codec.Binary.Util
import Data.Char
import Data.Maybe
import Data.Word
encodeInc :: EncIncData -> EncIncRes String
encodeInc :: EncIncData -> EncIncRes String
encodeInc EncIncData
e = EncIncData -> EncIncRes String
eI EncIncData
e
where
enc :: [Word8] -> String
enc [] = []
enc (Word8
o:[Word8]
os)
| Word8
o forall a. Ord a => a -> a -> Bool
< Word8
0x20 Bool -> Bool -> Bool
|| Word8
o forall a. Ord a => a -> a -> Bool
> Word8
0x7e = (Char
'\\' forall a. a -> [a] -> [a]
: Char
'x' forall a. a -> [a] -> [a]
: Word8 -> String
toHex Word8
o) forall a. [a] -> [a] -> [a]
++ [Word8] -> String
enc [Word8]
os
| Word8
o forall a. Eq a => a -> a -> Bool
== Word8
34 = String
"\\\"" forall a. [a] -> [a] -> [a]
++ [Word8] -> String
enc [Word8]
os
| Word8
o forall a. Eq a => a -> a -> Bool
== Word8
39 = String
"\\'" forall a. [a] -> [a] -> [a]
++ [Word8] -> String
enc [Word8]
os
| Word8
o forall a. Eq a => a -> a -> Bool
== Word8
92 = String
"\\\\" forall a. [a] -> [a] -> [a]
++ [Word8] -> String
enc [Word8]
os
| Bool
otherwise = Int -> Char
chr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
o) forall a. a -> [a] -> [a]
: [Word8] -> String
enc [Word8]
os
eI :: EncIncData -> EncIncRes String
eI EncIncData
EDone = forall i. i -> EncIncRes i
EFinal []
eI (EChunk [Word8]
bs) = forall i. i -> (EncIncData -> EncIncRes i) -> EncIncRes i
EPart ([Word8] -> String
enc [Word8]
bs) EncIncData -> EncIncRes String
encodeInc
encode :: [Word8] -> String
encode :: [Word8] -> String
encode = forall {a}. (EncIncData -> EncIncRes [a]) -> [Word8] -> [a]
encoder EncIncData -> EncIncRes String
encodeInc
decodeInc :: DecIncData String -> DecIncRes String
decodeInc :: DecIncData String -> DecIncRes String
decodeInc DecIncData String
d = String -> DecIncData String -> DecIncRes String
dI [] DecIncData String
d
where
dI :: String -> DecIncData String -> DecIncRes String
dI [] DecIncData String
DDone = forall i. [Word8] -> i -> DecIncRes i
DFinal [] []
dI String
lo DecIncData String
DDone = forall i. [Word8] -> i -> DecIncRes i
DFail [] String
lo
dI String
lo (DChunk String
s) = [Word8] -> String -> DecIncRes String
doDec [] (String
lo forall a. [a] -> [a] -> [a]
++ String
s)
where
doDec :: [Word8] -> String -> DecIncRes String
doDec [Word8]
acc [] = forall i. [Word8] -> (DecIncData i -> DecIncRes i) -> DecIncRes i
DPart [Word8]
acc (String -> DecIncData String -> DecIncRes String
dI [])
doDec [Word8]
acc s' :: String
s'@(Char
'\\':Char
'x':Char
c0:Char
c1:String
cs) = let
o :: Maybe Word8
o = String -> Maybe Word8
fromHex [Char
c0, Char
c1]
in if forall a. Maybe a -> Bool
isJust Maybe Word8
o
then [Word8] -> String -> DecIncRes String
doDec ([Word8]
acc forall a. [a] -> [a] -> [a]
++ [forall a. HasCallStack => Maybe a -> a
fromJust Maybe Word8
o]) String
cs
else forall i. [Word8] -> i -> DecIncRes i
DFail [Word8]
acc String
s'
doDec [Word8]
acc s' :: String
s'@(Char
'\\':Char
'\\':String
cs) = [Word8] -> String -> DecIncRes String
doDec ([Word8]
acc forall a. [a] -> [a] -> [a]
++ [forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'\\']) String
cs
doDec [Word8]
acc s' :: String
s'@(Char
'\\':Char
'\'':String
cs) = [Word8] -> String -> DecIncRes String
doDec ([Word8]
acc forall a. [a] -> [a] -> [a]
++ [forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'\'']) String
cs
doDec [Word8]
acc s' :: String
s'@(Char
'\\':Char
'\"':String
cs) = [Word8] -> String -> DecIncRes String
doDec ([Word8]
acc forall a. [a] -> [a] -> [a]
++ [forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'\"']) String
cs
doDec [Word8]
acc s' :: String
s'@(Char
c:String
cs)
| Char
c forall a. Eq a => a -> a -> Bool
/= Char
'\\' = [Word8] -> String -> DecIncRes String
doDec ([Word8]
acc forall a. [a] -> [a] -> [a]
++ [forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c]) String
cs
| Bool
otherwise = forall i. [Word8] -> (DecIncData i -> DecIncRes i) -> DecIncRes i
DPart [Word8]
acc (String -> DecIncData String -> DecIncRes String
dI String
s')
decode :: String -> Maybe [Word8]
decode :: String -> Maybe [Word8]
decode = forall i. (DecIncData i -> DecIncRes i) -> i -> Maybe [Word8]
decoder DecIncData String -> DecIncRes String
decodeInc
chop :: Int
-> String
-> [String]
chop :: Int -> String -> [String]
chop Int
n = let
_n :: Int
_n = forall a. Ord a => a -> a -> a
max Int
1 Int
n
_chop :: [a] -> [[a]]
_chop [] = []
_chop [a]
cs = forall a. Int -> [a] -> [a]
take Int
_n [a]
cs forall a. a -> [a] -> [a]
: [a] -> [[a]]
_chop (forall a. Int -> [a] -> [a]
drop Int
_n [a]
cs)
in forall {a}. [a] -> [[a]]
_chop
unchop :: [String]
-> String
unchop :: [String] -> String
unchop = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a. [a] -> [a] -> [a]
(++) String
""