module Codec.MIME.String.Internal.Utils where import Data.Char isAsciiDigit :: Char -> Bool isAsciiDigit c = isAscii c && isDigit c isAsciiHexDigit :: Char -> Bool isAsciiHexDigit c = isAscii c && isHexDigit c isAsciiPrint :: Char -> Bool isAsciiPrint c = isAscii c && isPrint c isAsciiAlpha :: Char -> Bool isAsciiAlpha c = isAscii c && isAlpha c isAsciiAlphaNum :: Char -> Bool isAsciiAlphaNum c = isAscii c && isAlphaNum c asciiToLower :: Char -> Char asciiToLower c | isAscii c = toLower c | otherwise = c asciiToUpper :: Char -> Char asciiToUpper c | isAscii c = toUpper c | otherwise = c splits :: Int -> [a] -> [[a]] splits _ [] = [] splits n xs = case splitAt n xs of (ys, zs) -> ys:splits n zs box :: a -> [a] box x = [x] dropFromEndWhile :: (a -> Bool) -> [a] -> [a] dropFromEndWhile p = foldr (\x xs -> if null xs && p x then [] else x:xs) [] -- We are generous about what we allow as line terminators. Any of -- \r \n \r\n \n\r will satisfy us. my_lines :: String -> [String] my_lines xs = case get_line xs of (ys, Nothing) -> [ys] (ys, Just zs) -> ys:my_lines zs get_line :: String -> (String, Maybe String) get_line xs = case break is_cr_or_lf xs of (ys, z1:z2:zs) | is_cr_or_lf z2 && z1 /= z2 -> (ys, Just zs) (ys, _:zs) -> (ys, Just zs) (ys, "") -> (ys, Nothing) is_cr_or_lf :: Char -> Bool is_cr_or_lf '\r' = True is_cr_or_lf '\n' = True is_cr_or_lf _ = False