module Codec.Binary.EncodingQ.String ( encode, decode) where
import Codec.MIME.String.Internal.Utils
import Data.Bits
import Data.Char
encode :: Int -> String -> [String]
encode _ "" = []
encode len xs = enc len 0 id id xs
enc :: Int -> Int
-> ([String] -> [String]) -> (String -> String)
-> String
-> [String]
enc _ _ acc_list acc_string "" = acc_list [acc_string ""]
enc len so_far acc_list acc_string (c:cs)
= if so_far' > len
then enc len new_len (acc_list . (acc_string "" :)) id cs
else enc len new_len acc_list (acc_string . (encoded ++)) cs
where encoded = if isAsciiPrint c && (c /= ' ') && (c /= '?')
then [c]
else ['=', x1, x2]
new_len = length encoded
so_far' = so_far + new_len
o = ord c
x1 = toUpper $ intToDigit (o `shiftR` 4)
x2 = toUpper $ intToDigit (o .&. 0xF)
decode :: String -> String
decode ('=':c1:c2:cs)
| isAsciiHexDigit c1 && isAsciiHexDigit c2
= chr ((digitToInt c1 `shiftL` 4) + digitToInt c2):decode cs
decode ('_':cs) = ' ':decode cs
decode (c:cs) = c:decode cs
decode "" = ""