@@ -10,22 +10,9 @@
10-- Stability : experimental
10-- Stability : experimental
11-- Portability : GHC
11-- Portability : GHC
13−-- Fast substring search for 'Text', based on work by Boyer, Moore,
13+-- Fast substring search for lazy 'Text', based on work by Boyer,
14−-- Horspool, Sunday, and Lundh.
14+-- Moore, Horspool, Sunday, and Lundh. Adapted from the strict
15−--
15+-- implementation.
18−-- * R. S. Boyer, J. S. Moore: A Fast String Searching Algorithm.
19−-- Communications of the ACM, 20, 10, 762-772 (1977)
21−-- * R. N. Horspool: Practical Fast Searching in Strings. Software -
22−-- Practice and Experience 10, 501-506 (1980)
24−-- * D. M. Sunday: A Very Fast Substring Search Algorithm.
25−-- Communications of the ACM, 33, 8, 132-142 (1990)
27−-- * F. Lundh: The Fast Search Algorithm.
28−-- <http://effbot.org/zone/stringlib.htm> (2006)
30module Data.Text.Lazy.Search
17module Data.Text.Lazy.Search
@@ -74,8 +61,7 @@ indices needle@(Chunk n ns) haystack@(Chunk k ks)
74 | hindex (i+j) /= nindex j = False
61 | hindex (i+j) /= nindex j = False
75 | otherwise = candidateMatch (j+1)
62 | otherwise = candidateMatch (j+1)
76 hindex = index x xs
63 hindex = index x xs
77− ldiff = hlen - nlen
64+ ldiff = wordLength haystack - nlen
78− hlen = wordLength haystack
79 nlen = wordLength needle
65 nlen = wordLength needle
80 nlast = nlen - 1
66 nlast = nlen - 1
81 nindex = index n ns
67 nindex = index n ns
@@ -104,15 +90,19 @@ indices needle@(Chunk n ns) haystack@(Chunk k ks)
104 where on = A.unsafeIndex oarr (ooff+h)
90 where on = A.unsafeIndex oarr (ooff+h)
105indices _ _ = []
91indices _ _ = []
93+-- | Fast index into a partly unpacked 'Text'. We take into account
94+-- the possibility that the caller might try to access one element
107index :: T.Text -> Text -> Int64 -> Word16
96index :: T.Text -> Text -> Int64 -> Word16
108index (T.Text arr off len) xs i
97index (T.Text arr off len) xs i
109 | j < len = A.unsafeIndex arr (off+j)
98 | j < len = A.unsafeIndex arr (off+j)
110 | otherwise = case xs of
99 | otherwise = case xs of
111− Empty | j == len -> 0
100+ Empty | j == len -> 0 -- out of bounds, but legal
112 | otherwise -> emptyError "index"
101 | otherwise -> emptyError "index"
113 Chunk c cs -> index c cs (i-fromIntegral len)
102 Chunk c cs -> index c cs (i-fromIntegral len)
114 where j = fromIntegral i
103 where j = fromIntegral i
105+-- | The number of 'Word16' values in a 'Text'.
116wordLength :: Text -> Int64
106wordLength :: Text -> Int64
117wordLength = foldlChunks sumLength 0
107wordLength = foldlChunks sumLength 0
118 where sumLength i (T.Text _ _ l) = i + fromIntegral l
108 where sumLength i (T.Text _ _ l) = i + fromIntegral l