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