@@ -0,0 +1,58 @@
1+{-# LANGUAGE OverloadedStrings, MagicHash, BangPatterns #-}
2+
3+-- Copyright : Erik de Castro Lopo <erikd@mega-nerd.com>
4+-- License : BSD3
5+
6+module ReadInt (readInt64) where
7+
8+-- This function lives in its own file because the MagicHash pragma interacts
9+-- poorly with the CPP pragma.
10+
11+import Data.ByteString (ByteString)
12+import Data.Int (Int64)
13+import GHC.Prim
14+import GHC.Types
15+
16+import qualified Data.ByteString.Char8 as B
17+import qualified Data.Char as C
18+
19+-- This function is used to parse the Content-Length field of HTTP headers and
20+-- is a performance hot spot. It should only be replaced with something
21+-- significantly and provably faster.
22+--
23+-- It needs to be able work correctly on 32 bit CPUs for file sizes > 2G so we
24+-- use Int64 here and then make a generic 'readInt' that allows conversion to
25+-- Int and Integer.
26+
27+readInt64 :: ByteString -> Int64
28+readInt64 bs =
29+ B.foldl' (\i c -> i * 10 + fromIntegral (mhDigitToInt c)) 0
30+ $ B.takeWhile C.isDigit bs
31+{- NOINLINE readInt64MH #-}
32+
33+data Table = Table !Addr#
34+
35+{- NOINLINE mhDigitToInt #-}
36+mhDigitToInt :: Char -> Int
37+mhDigitToInt (C# i) = I# (word2Int# (indexWord8OffAddr# addr (ord# i)))
38+ where
39+ !(Table addr) = table
40+ table :: Table
41+ table = Table
42+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
43+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
44+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
45+ \\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\x00\x00\x00\x00\x00\
46+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
47+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
48+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
49+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
50+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
51+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
52+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
53+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
54+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
55+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
56+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
57+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
58+