Bryan O'Sullivan avatar Bryan O'Sullivan committed 87212e9

API improvements.

Comments (0)

Files changed (2)

Data/Attoparsec/Char8.hs

 
     -- * Text parsing
     , I.endOfLine
+    , isEndOfLine
+    , isHorizontalSpace
 
     -- * Numeric parsers
     --, int
 skipSpace = skipWhile isSpace >> return ()
 {-# INLINE skipSpace #-}
 
+isEndOfLine :: Word8 -> Bool
+isEndOfLine w = w == 13 || w == 10
+{-# INLINE isEndOfLine #-}
+
+isHorizontalSpace :: Word8 -> Bool
+isHorizontalSpace w = w == 32 || w == 9
+{-# INLINE isHorizontalSpace #-}
+
 {-
 numeric :: String -> (B.ByteString -> Maybe (a,B.ByteString)) -> Parser a
 numeric desc f = do

examples/RFC2616.hs

 
 import Control.Applicative hiding (many)
 import Data.Attoparsec as P
-import Data.Attoparsec.Char8 (char8, endOfLine)
+import Data.Attoparsec.Char8 (char8, endOfLine, isEndOfLine, isHorizontalSpace)
 import Data.Word (Word8)
 import qualified Data.ByteString.Char8 as B
 
 isToken :: Word8 -> Bool
-isToken w = w <= 127 && notInClass "\0-\31()<>@,;:\\\"/[]?={} \t" w
+isToken w = notInClass "\0-\31()<>@,;:\\\"/[]?={} \t\128-\255" w
 
-skipSpaces :: Parser ()
-skipSpaces = satisfy spc *> skipWhile spc
-    where spc = inClass " \t"
+skipHSpaces :: Parser ()
+skipHSpaces = satisfy isHorizontalSpace *> skipWhile isHorizontalSpace
 
 data Request = Request {
       requestMethod   :: !B.ByteString
 
 requestLine :: Parser Request
 requestLine = do
-  method <- P.takeWhile isToken
-  skipSpaces
-  uri <- P.takeWhile (notInClass " \t")
-  skipSpaces >> string "HTTP/"
-  proto <- P.takeWhile (inClass "0-9.")
-  endOfLine
+  method <- P.takeWhile1 isToken <* skipHSpaces
+  uri <- P.takeWhile1 (not . isHorizontalSpace) <* skipHSpaces <* string "HTTP/"
+  proto <- P.takeWhile1 isDigitOrDot <* endOfLine
   return $! Request method uri proto
+ where
+  isDigitOrDot w = (w >= 48 && w <= 57) || w == 46
 
 data Header = Header {
       headerName  :: !B.ByteString
 
 messageHeader :: Parser Header
 messageHeader = do
-  header <- P.takeWhile isToken
-  char8 ':' *> skipSpaces
-  body <- takeTill (inClass "\r\n")
-  endOfLine
-  bodies <- many $ satisfy (inClass " \t") *> skipSpaces *>
-                   takeTill (inClass "\r\n") <* endOfLine
-  return $! Header header (body:bodies)
+  header <- P.takeWhile1 isToken <* char8 ':' <* skipHSpaces
+  body <- takeTill isEndOfLine <* endOfLine
+  conts <- many $ skipHSpaces *> takeTill isEndOfLine <* endOfLine
+  return $! Header header (body:conts)
 
 request :: Parser (Request, [Header])
 request = (,) <$> requestLine <*> many messageHeader <* endOfLine
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.