Bryan O'Sullivan avatar Bryan O'Sullivan committed 37ce26b

Add a fast hex number parser.

Comments (0)

Files changed (1)

Data/Attoparsec/Char8.hs

     , isHorizontalSpace
 
     -- * Numeric parsers
+    , hexNumber
     --, int
     --, integer
     --, double
 import Data.Attoparsec.Internal (Parser, (<?>))
 import Data.ByteString.Internal (c2w, w2c)
 -- import Data.ByteString.Lex.Double (readDouble)
-import Data.Char (toLower)
 import Data.Word (Word8)
 import Prelude hiding (takeWhile)
 import qualified Data.Attoparsec as A
 import qualified Data.Attoparsec.Internal as I
 import qualified Data.ByteString.Char8 as B
+import qualified Data.ByteString as B8
+
+toLower :: Word8 -> Word8
+toLower w | w >= 65 && w <= 90 = w + 32
+          | otherwise          = w
 
 -- | Satisfy a literal string, ignoring case.
 stringCI :: B.ByteString -> Parser B.ByteString
-stringCI = I.stringTransform (B.map toLower)
+stringCI = I.stringTransform (B8.map toLower)
 {-# INLINE stringCI #-}
 
 takeWhile1 :: (Char -> Bool) -> Parser B.ByteString
 double :: Parser Double
 double = numeric "Double" readDouble
 -}
+
+hexNumber :: Integral a => Parser a
+{-# SPECIALISE hexNumber :: Parser Int #-}
+hexNumber = fromHex `fmap` I.takeWhile1 isHexDigit
+  where isHexDigit w = (w >= 48 && w <= 57) || (x >= 97 && x <= 102)
+            where x = toLower w
+        fromHex = B8.foldl' step 0
+        step a w | w >= 48 && w <= 57  = a * 16 + fromIntegral (w - 48)
+                 | x >= 97 && x <= 102 = a * 16 + fromIntegral (x - 87)
+                 | otherwise           = error "impossible"
+            where x = toLower w
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.