encodeString :: String -> String
encodeString str = go (UTF8.encodeString str)
 where
  go "" = ""
  go (' ':xs) = '+':go xs
  go ('\r':'\n':xs) = '%':'0':'D':'%':'0':'A':go xs
  go ('\r':xs) = go ('\r':'\n':xs)
  go ('\n':xs) = go ('\r':'\n':xs)
  go (x:xs) = 
    case getEncodedChar x of
      Nothing -> x : go xs
      Just ss -> ss ++ go xs
encodeString :: String -> String
encodeString str = go (UTF8.encodeString str)
 where
  go "" = ""
  go (' ':xs) = '+':go xs
  go ('\r':'\n':xs) = '%':'0':'D':'%':'0':'A':go xs
  go ('\r':xs) = go ('\r':'\n':xs)
  go ('\n':xs) = go ('\r':'\n':xs)
  go (x:xs) = 
    case getEncodedChar x of
      Nothing -> x : go xs
      Just ss -> ss ++ go xs
encodeString str = go (UTF8.encodeString str)
 where
  go "" = ""
  go (' ':xs) = '+':go xs
  go ('\r':'\n':xs) = '%':'0':'D':'%':'0':'A':go xs
  go ('\r':xs) = go ('\r':'\n':xs)
  go ('\n':xs) = go ('\r':'\n':xs)
  go (x:xs) = 
    case getEncodedChar x of
      Nothing -> x : go xs
      Just ss -> ss ++ go xs