attoparsec 0.8.0.1 → 0.8.0.2
raw patch · 3 files changed
+67/−23 lines, 3 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Data.Attoparsec.Char8: isDigit_w8 :: Word8 -> Bool
+ Data.Attoparsec.Char8: parseWith :: (Monad m) => (m ByteString) -> Parser a -> ByteString -> m (Result a)
Files
- Data/Attoparsec/Char8.hs +8/−1
- attoparsec.cabal +1/−1
- examples/RFC2616.hs +58/−21
Data/Attoparsec/Char8.hs view
@@ -22,6 +22,7 @@ -- * Running parsers , A.parse , A.parseTest+ , A.parseWith , A.feed -- * Combinators@@ -44,6 +45,7 @@ -- ** Fast predicates , isDigit+ , isDigit_w8 , isAlpha_iso8859_15 , isAlpha_ascii @@ -175,6 +177,11 @@ isDigit c = c >= '0' && c <= '9' {-# INLINE isDigit #-} +-- | A fast digit predicate.+isDigit_w8 :: Word8 -> Bool+isDigit_w8 w = w >= 48 && w <= 57+{-# INLINE isDigit_w8 #-}+ -- | Match any character. anyChar :: Parser Char anyChar = satisfy $ const True@@ -315,6 +322,6 @@ -- character. signed :: Num a => Parser a -> Parser a {-# SPECIALISE signed :: Parser Int -> Parser Int #-}-signed p = (negate <$> char8 '-' *> p)+signed p = (negate <$> (char8 '-' *> p)) <|> (char8 '+' *> p) <|> p
attoparsec.cabal view
@@ -1,5 +1,5 @@ name: attoparsec-version: 0.8.0.1+version: 0.8.0.2 license: BSD3 license-file: LICENSE category: Text, Parsing
examples/RFC2616.hs view
@@ -2,40 +2,48 @@ module RFC2616 (- Request(..)- , Header(..)+ Header(..)+ , Request(..)+ , Response(..) , isToken- , requestLine , messageHeader , request+ , requestLine+ , response+ , responseLine+ , lowerHeader+ , lookupHeader ) where import Control.Applicative hiding (many) import Data.Attoparsec as P-import Data.Attoparsec.Char8 (char8, endOfLine, isEndOfLine, isHorizontalSpace)+import qualified Data.Attoparsec.Char8 as P8+import Data.Attoparsec.Char8 (char8, endOfLine, isDigit_w8) import Data.Word (Word8)-import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Char8 as B hiding (map)+import qualified Data.ByteString as B (map) isToken :: Word8 -> Bool-isToken w = notInClass "\0-\31()<>@,;:\\\"/[]?={} \t\128-\255" w+isToken w = w <= 127 && notInClass "\0-\31()<>@,;:\\\"/[]?={} \t" w -skipHSpaces :: Parser ()-skipHSpaces = satisfy isHorizontalSpace *> skipWhile isHorizontalSpace+skipSpaces :: Parser ()+skipSpaces = satisfy P8.isHorizontalSpace *> skipWhile P8.isHorizontalSpace data Request = Request {- requestMethod :: !B.ByteString- , requestUri :: !B.ByteString- , requestProtocol :: !B.ByteString+ requestMethod :: !B.ByteString+ , requestUri :: !B.ByteString+ , requestVersion :: !B.ByteString } deriving (Eq, Ord, Show) +httpVersion :: Parser B.ByteString+httpVersion = string "HTTP/" *> P.takeWhile (\c -> isDigit_w8 c || c == 46)+ requestLine :: Parser Request requestLine = do- method <- P.takeWhile1 isToken <* skipHSpaces- uri <- P.takeWhile1 (not . isHorizontalSpace) <* skipHSpaces <* string "HTTP/"- proto <- P.takeWhile1 isHttpVersion <* endOfLine- return $! Request method uri proto- where- isHttpVersion w = w == 46 || w == 48 || w == 49+ method <- P.takeWhile1 isToken <* char8 ' '+ uri <- P.takeWhile1 (/=32) <* char8 ' '+ version <- httpVersion <* endOfLine+ return $! Request method uri version data Header = Header { headerName :: !B.ByteString@@ -44,10 +52,39 @@ messageHeader :: Parser Header messageHeader = do- header <- P.takeWhile1 isToken <* char8 ':' <* skipHSpaces- body <- takeTill isEndOfLine <* endOfLine- conts <- many $ skipHSpaces *> takeTill isEndOfLine <* endOfLine- return $! Header header (body:conts)+ header <- P.takeWhile isToken <* char8 ':' <* skipWhile P8.isHorizontalSpace+ body <- takeTill P8.isEndOfLine <* endOfLine+ bodies <- many $ skipSpaces *> takeTill P8.isEndOfLine <* endOfLine+ return $! Header header (body:bodies) request :: Parser (Request, [Header]) request = (,) <$> requestLine <*> many messageHeader <* endOfLine++data Response = Response {+ responseVersion :: !B.ByteString+ , responseCode :: !B.ByteString+ , responseMsg :: !B.ByteString+ } deriving (Eq, Ord, Show)++responseLine :: Parser Response+responseLine = do+ version <- httpVersion <* char8 ' '+ code <- P.takeWhile isDigit_w8 <* char8 ' '+ msg <- P.takeTill P8.isEndOfLine <* endOfLine+ return $! Response version code msg++response :: Parser (Response, [Header])+response = (,) <$> responseLine <*> many messageHeader <* endOfLine++lowerHeader :: Header -> Header+lowerHeader (Header n v) = Header (B.map toLower n) (map (B.map toLower) v)+ where toLower w | w >= 65 && w <= 90 = w + 32+ | otherwise = w++lookupHeader :: B.ByteString -> [Header] -> [B.ByteString]+lookupHeader k = go+ where+ go (Header n v:hs)+ | k == n = v+ | otherwise = go hs+ go _ = []