module Codec.MIME.QuotedPrintable
( decode
, encode
) where
import Data.Char
decode :: String -> String
decode :: String -> String
decode String
"" = String
""
decode (Char
'=':Char
'\r':Char
'\n':String
xs) = String -> String
decode String
xs
decode (Char
'=':Char
x1:Char
x2:String
xs)
| Char -> Bool
isHexDigit Char
x1 Bool -> Bool -> Bool
&& Char -> Bool
isHexDigit Char
x2 =
Int -> Char
chr (Char -> Int
digitToInt Char
x1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
16 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Char -> Int
digitToInt Char
x2) Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
decode String
xs
decode (Char
'=':String
xs) = Char
'='Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
decode String
xs
decode (Char
x1:String
xs) = Char
x1Char -> String -> String
forall a. a -> [a] -> [a]
:String -> String
decode String
xs
encode :: String -> String
encode :: String -> String
encode String
xs = Int -> String -> String
encodeLength Int
0 String
xs
encodeLength :: Int -> String -> String
encodeLength :: Int -> String -> String
encodeLength Int
_ String
"" = String
""
encodeLength Int
n (Char
x:String
xs)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
72 = Char
'='Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'\r'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'\n'Char -> String -> String
forall a. a -> [a] -> [a]
:Int -> String -> String
encodeLength Int
0 (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
xs)
encodeLength Int
_ (Char
'=':String
xs)
= Char
'='Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'3'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'D'Char -> String -> String
forall a. a -> [a] -> [a]
:Int -> String -> String
encodeLength Int
0 String
xs
encodeLength Int
n (Char
x:String
xs)
| Int
ox Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0x100 = String -> String
forall a. HasCallStack => String -> a
error (String
"QuotedPrintable.encode: encountered > 8 bit character: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char, Int) -> String
forall a. Show a => a -> String
show (Char
x,Int
ox))
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
72 = Char
'='Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'\r'Char -> String -> String
forall a. a -> [a] -> [a]
:Char
'\n'Char -> String -> String
forall a. a -> [a] -> [a]
:Int -> String -> String
encodeLength Int
0 (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
xs)
| Int
ox Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0x21 Bool -> Bool -> Bool
&& Int
ox Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x7e = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String -> String
encodeLength (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
xs
| Int
ox Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x09 Bool -> Bool -> Bool
|| Int
ox Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x20 = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String -> String
encodeLength (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
xs
| Bool
otherwise = Char
'='Char -> String -> String
forall a. a -> [a] -> [a]
:Int -> Char
showH (Int
ox Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
0x10)Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> Char
showH (Int
ox Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
0x10)Char -> String -> String
forall a. a -> [a] -> [a]
:Int -> String -> String
encodeLength (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
3) String
xs
where
ox :: Int
ox = Char -> Int
ord Char
x
showH :: Int -> Char
showH Int
v
| Int
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
10 = Int -> Char
chr (Int
ord_0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
v)
| Bool
otherwise = Int -> Char
chr (Int
ord_A Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
10))
ord_0 :: Int
ord_0 = Char -> Int
ord Char
'0'
ord_A :: Int
ord_A = Char -> Int
ord Char
'A'