{-# LANGUAGE BangPatterns , UnicodeSyntax #-} -- |This is an auxiliary parser utilities for parsing things related -- on HTTP protocol. -- -- In general you don't have to use this module directly. module Network.HTTP.Lucu.Parser.Http ( isCtl , isSeparator , isChar , isToken , listOf , token , lws , text , separator , quotedStr , qvalue ) where import Network.HTTP.Lucu.Parser -- |@'isCtl' c@ is 'Prelude.False' iff @0x20 <= @c@ < 0x7F@. isCtl :: Char -> Bool isCtl c | c < '\x1f' = True | c >= '\x7f' = True | otherwise = False -- |@'isSeparator' c@ is 'Prelude.True' iff c is one of HTTP -- separators. isSeparator :: Char -> Bool isSeparator '(' = True isSeparator ')' = True isSeparator '<' = True isSeparator '>' = True isSeparator '@' = True isSeparator ',' = True isSeparator ';' = True isSeparator ':' = True isSeparator '\\' = True isSeparator '"' = True isSeparator '/' = True isSeparator '[' = True isSeparator ']' = True isSeparator '?' = True isSeparator '=' = True isSeparator '{' = True isSeparator '}' = True isSeparator ' ' = True isSeparator '\t' = True isSeparator _ = False -- |@'isChar' c@ is 'Prelude.True' iff @c <= 0x7f@. isChar :: Char -> Bool isChar c | c <= '\x7f' = True | otherwise = False -- |@'isToken' c@ is equivalent to @not ('isCtl' c || 'isSeparator' -- c)@ isToken :: Char -> Bool isToken c = c `seq` not (isCtl c || isSeparator c) -- |@'listOf' p@ is similar to @'Network.HTTP.Lucu.Parser.sepBy' p -- ('Network.HTTP.Lucu.Parser.char' \',\')@ but it allows any -- occurrences of LWS before and after each tokens. listOf :: Parser a -> Parser [a] listOf !p = do _ <- many lws sepBy p $! do _ <- many lws _ <- char ',' many lws -- |'token' is equivalent to @'Network.HTTP.Lucu.Parser.many1' $ -- 'Network.HTTP.Lucu.Parser.satisfy' 'isToken'@ token :: Parser String token = many1 $! satisfy isToken -- |'lws' is an HTTP LWS: @'Network.HTTP.Lucu.Parser.crlf'? -- ('Network.HTTP.Lucu.Parser.sp' | 'Network.HTTP.Lucu.Parser.ht')+@ lws :: Parser String lws = do s <- option "" crlf xs <- many1 (sp <|> ht) return (s ++ xs) -- |'text' accepts one character which doesn't satisfy 'isCtl'. text :: Parser Char text = satisfy (not . isCtl) -- |'separator' accepts one character which satisfies 'isSeparator'. separator :: Parser Char separator = satisfy isSeparator -- |'quotedStr' accepts a string surrounded by double quotation -- marks. Quotes can be escaped by backslashes. quotedStr :: Parser String quotedStr = do _ <- char '"' xs <- many (qdtext <|> quotedPair) _ <- char '"' return $ foldr (++) "" xs where qdtext = do c <- satisfy (/= '"') return [c] quotedPair = do _ <- char '\\' c <- satisfy isChar return [c] -- |'qvalue' accepts a so-called qvalue. qvalue :: Parser Double qvalue = do x <- char '0' xs <- option "" $ do y <- char '.' ys <- many digit -- 本當は三文字までに制限 return (y:ys) return $ read (x:xs) <|> do x <- char '1' xs <- option "" $ do y <- char '.' ys <- many (char '0') -- 本當は三文字までに制限 return (y:ys) return $ read (x:xs)