on master help sign in
use stringsearch instead of borrowing from Data.Text
commitaa7f3e5d24a536b6815bb405b1153072b2cde48c authorjay groven <jgroven@lutsendata.com> dateWed 13 Jun 2012, 20:17 (14 years ago) parentea84d79
3 files changed+7−121
wai-extra/Network/Wai/Parse.hs+6−6 wai-extra/Network/Wai/Search.hs−115 wai-extra/wai-extra.cabal+1
wai-extra/Network/Wai/Parse.hs+6−6
@@ -29,10 +29,10 @@ module Network.Wai.Parse
2929#endif
3030 ) where
3131
32+import qualified Data.ByteString.Search as Search
3233import qualified Data.ByteString as S
3334import qualified Data.ByteString.Lazy as L
3435import qualified Data.ByteString.Char8 as S8
35−import qualified Network.Wai.Search as Search
3636import Data.Word (Word8)
3737import Data.Bits
3838import Data.Maybe (fromMaybe)
@@ -281,12 +281,12 @@ data Bound = FoundBound S.ByteString S.ByteString
281281 deriving (Eq, Show)
282282
283283findBound :: S.ByteString -> S.ByteString -> Bound
284−findBound b bs =
285− case Search.index b bs of
286− Nothing -> go [S.length bs - S.length b..S.length bs - 1]
287− Just idx -> let (h, t) = S.splitAt idx bs in
288− FoundBound h $ S.drop (S.length b) t
284+findBound b bs = handleBreak $ Search.breakOn b bs
289285 where
286+ handleBreak (h, t)
287+ | S.null t = go [S.length bs - S.length b..S.length bs - 1]
288+ | otherwise = FoundBound h $ S.drop (S.length b) t
289+
290290 go [] = NoBound
291291 go (i:is)
292292 | mismatch [0..S.length b - 1] [i..S.length bs - 1] = go is
wai-extra/Network/Wai/Search.hsdeleted−115
@@ -1,115 +0,0 @@
1−{-# LANGUAGE BangPatterns, ScopedTypeVariables #-}
2−
3−-- |
4−-- Module : Network.Wai.Search
5−-- Copyright : (c) Bryan O'Sullivan 2009
6−--
7−-- License : BSD-style
8−-- Maintainer : bos@serpentine.com, rtomharper@googlemail.com,
9−-- duncan@haskell.org
10−-- Stability : experimental
11−-- Portability : GHC
12−--
13−-- Port of Data.Text.Search to ByteStrings, applied to the Wai framework
14−--
15−-- References:
16−--
17−-- * R. S. Boyer, J. S. Moore: A Fast String Searching Algorithm.
18−-- Communications of the ACM, 20, 10, 762-772 (1977)
19−--
20−-- * R. N. Horspool: Practical Fast Searching in Strings. Software -
21−-- Practice and Experience 10, 501-506 (1980)
22−--
23−-- * D. M. Sunday: A Very Fast Substring Search Algorithm.
24−-- Communications of the ACM, 33, 8, 132-142 (1990)
25−--
26−-- * F. Lundh: The Fast Search Algorithm.
27−-- <http://effbot.org/zone/stringlib.htm> (2006)
28−
29−module Network.Wai.Search
30− (
31− index
32− --, checkNeg
33− --, checkFound
34− ) where
35−
36−import qualified Data.ByteString.Unsafe as SU
37−import qualified Data.ByteString as S
38−import Data.ByteString ( ByteString )
39−import Data.Word (Word64)
40−import Data.Bits ((.|.), (.&.), shiftL)
41−
42−data PairS a b = !a :*: !b
43−
44−-- | /O(n+m)/ Find the offset of @needle@ within @haystack@. The offset
45−-- returned represents the location within the haystack ByteString
46−--
47−-- In (unlikely) bad cases, this algorithm's complexity degrades
48−-- towards /O(n*m)/.
49−index :: ByteString -- ^ Substring to search for (@needle@)
50− -> ByteString -- ^ Text to search in (@haystack@)
51− -> Maybe Int
52−index needle haystack
53− | nlen == 1 = scanOne (nindex 0)
54− | nlen <= 0 || ldiff < 0 = Nothing
55− | otherwise = scan 0
56− where
57− nlen = S.length needle
58− hlen = S.length haystack
59− ldiff = hlen - nlen
60− nlast = nlen - 1
61− z = nindex nlast
62− nindex k = SU.unsafeIndex needle k
63− hindex k = SU.unsafeIndex haystack k
64− hindex' k | k == hlen = 0
65− | otherwise = SU.unsafeIndex haystack k
66− (mask :: Word64) :*: skip = buildTable 0 0 (nlen-2)
67− buildTable !i !msk !skp
68− | i >= nlast = (msk .|. swizzle z) :*: skp
69− | otherwise = buildTable (i+1) (msk .|. swizzle c) skp'
70− where c = nindex i
71− skp' | c == z = nlen - i - 2
72− | otherwise = skp
73− swizzle k = 1 `shiftL` (fromIntegral k .&. 0x3f)
74− scan !i
75− | i > ldiff = Nothing
76− | c == z && candidateMatch 0 = Just i
77− | otherwise = scan (i + delta)
78− where c = hindex (i + nlast)
79− candidateMatch !j
80− | j >= nlast = True
81− | hindex (i+j) /= nindex j = False
82− | otherwise = candidateMatch (j+1)
83− delta | nextInPattern = nlen + 1
84− | c == z = skip + 1
85− | otherwise = 1
86− nextInPattern = mask .&. swizzle (hindex' (i+nlen)) == 0
87− scanOne c = loop 0
88− where loop !i | i >= hlen = Nothing
89− | hindex i == c = Just i
90− | otherwise = loop (i+1)
91−{-# INLINE index #-}
92−
93−-- It's not likely that one arbitrary string will ever be a substring of some
94−-- other string, so this is pretty much a negative test
95−{-
96−checkNeg :: ByteString -> ByteString -> Bool
97−checkNeg n h
98− | S.null n = True
99− | otherwise = (S.findSubstring n h) == (index n h)
100− -}
101−
102−-- Make sure that index works the same as ByteString.findSubstring when we
103−-- force matches
104−{-
105−checkFound :: ByteString -> Int -> Int -> Bool
106−checkFound bs offset len
107− | S.null n = True -- cop out
108− | otherwise = case index n bs of
109− Nothing -> False
110− _ -> checkNeg n bs
111− where
112− n = S.take len $ S.drop offset bs
113− -}
114−
115−
wai-extra/wai-extra.cabal+1
@@ -39,6 +39,7 @@ Library
3939 , blaze-builder-conduit >= 0.4 && < 0.5
4040 , ansi-terminal
4141 , resourcet >= 0.3 && < 0.4
42+ , stringsearch
4243
4344 Exposed-modules: Network.Wai.Handler.CGI
4445 Network.Wai.Middleware.AcceptOverride