X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FParser%2FHttp.hs;h=77dbe7f225bb2b6c3950b497815efa077d6c98b2;hb=636a3b3334f1ede61dc1e6faa2c4a021ea9bbd5c;hp=534577c7e6c1c26d388590f5e7966eef4bd00b6a;hpb=1000bdc46cfe7b3ae550ff24ccea9f440f11b42a;p=Lucu.git diff --git a/Network/HTTP/Lucu/Parser/Http.hs b/Network/HTTP/Lucu/Parser/Http.hs index 534577c..77dbe7f 100644 --- a/Network/HTTP/Lucu/Parser/Http.hs +++ b/Network/HTTP/Lucu/Parser/Http.hs @@ -1,55 +1,99 @@ +-- |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 -- Char -> Bool - , isSeparator -- Char -> Bool - , isChar -- Char -> Bool - , token -- Parser String - , lws -- Parser String - , text -- Parser Char - , separator -- Parser Char - , quotedStr -- Parser String + ( isCtl + , isSeparator + , isChar + , isToken + , listOf + , token + , lws + , text + , separator + , quotedStr + , qvalue ) where -import qualified Data.ByteString.Lazy.Char8 as B -import Data.ByteString.Lazy.Char8 (ByteString) import Data.List import Network.HTTP.Lucu.Parser +-- |@'isCtl' c@ is False iff @0x20 <= @c@ < 0x7F@. isCtl :: Char -> Bool isCtl c | c < '\x1f' = True | c >= '\x7f' = True - | otherwise = False - + | otherwise = False +-- |@'isSeparator' c@ is True iff c is one of HTTP separators. isSeparator :: Char -> Bool -isSeparator c = elem c "()<>@,;:\\\"/[]?={} \t" - - +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 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 = p `seq` + 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 (\ c -> not (isCtl c || isSeparator c)) - +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 (\ c -> not (isCtl c)) - +-- |'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) @@ -62,3 +106,19 @@ quotedStr = do char '"' quotedPair = do q <- char '\\' c <- satisfy isChar return [c] + +-- |'qvalue' accepts a so-called qvalue. +qvalue :: Parser Double +qvalue = do x <- char '0' + xs <- option "" + $ do x <- char '.' + xs <- many digit -- 本當は三文字までに制限 + return (x:xs) + return $ read (x:xs) + <|> + do x <- char '1' + xs <- option "" + $ do x <- char '.' + xs <- many (char '0') -- 本當は三文字までに制限 + return (x:xs) + return $ read (x:xs)