{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_HADDOCK hide, prune #-}
module Data.ByteString.Lazy.Search.Internal.BoyerMoore (
matchLL
, matchSL
, matchNOL
, replaceAllL
, breakSubstringL
, breakAfterL
, breakFindAfterL
, splitKeepEndL
, splitKeepFrontL
, splitDropL
) where
import Data.ByteString.Search.Internal.Utils
(occurs, suffShifts, ldrop, lsplit, keep, release, strictify)
import Data.ByteString.Search.Substitution
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.ByteString.Unsafe (unsafeIndex)
import Data.Array.Base (unsafeAt)
import Data.Word (Word8)
import Data.Int (Int64)
{-# INLINE matchLL #-}
matchLL :: L.ByteString
-> L.ByteString
-> [Int64]
matchLL :: ByteString -> ByteString -> [Int64]
matchLL ByteString
pat = [ByteString] -> [Int64]
search ([ByteString] -> [Int64])
-> (ByteString -> [ByteString]) -> ByteString -> [Int64]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
where
search :: [ByteString] -> [Int64]
search = Bool -> ByteString -> [ByteString] -> [Int64]
lazySearcher Bool
True (ByteString -> ByteString
strictify ByteString
pat)
{-# INLINE matchSL #-}
matchSL :: S.ByteString
-> L.ByteString
-> [Int64]
matchSL :: ByteString -> ByteString -> [Int64]
matchSL ByteString
pat = [ByteString] -> [Int64]
search ([ByteString] -> [Int64])
-> (ByteString -> [ByteString]) -> ByteString -> [Int64]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
where
search :: [ByteString] -> [Int64]
search = Bool -> ByteString -> [ByteString] -> [Int64]
lazySearcher Bool
True ByteString
pat
{-# INLINE matchNOL #-}
matchNOL :: S.ByteString
-> L.ByteString
-> [Int64]
matchNOL :: ByteString -> ByteString -> [Int64]
matchNOL ByteString
pat = [ByteString] -> [Int64]
search ([ByteString] -> [Int64])
-> (ByteString -> [ByteString]) -> ByteString -> [Int64]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
where
search :: [ByteString] -> [Int64]
search = Bool -> ByteString -> [ByteString] -> [Int64]
lazySearcher Bool
False ByteString
pat
{-# INLINE replaceAllL #-}
replaceAllL :: Substitution rep
=> S.ByteString
-> rep
-> L.ByteString
-> L.ByteString
replaceAllL :: forall rep.
Substitution rep =>
ByteString -> rep -> ByteString -> ByteString
replaceAllL ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = \rep
sub -> rep -> ByteString -> ByteString
forall a. Substitution a => a -> ByteString -> ByteString
prependCycle rep
sub
| ByteString -> Int
S.length ByteString
pat Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 =
let breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
repl :: ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
repl [ByteString] -> [ByteString]
subst [ByteString]
strs
| [ByteString] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
strs = []
| Bool
otherwise =
case [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
strs of
([ByteString]
pre, [ByteString]
mtch) ->
[ByteString]
pre [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ case [ByteString]
mtch of
[] -> []
[ByteString]
_ -> [ByteString] -> [ByteString]
subst (([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
repl [ByteString] -> [ByteString]
subst (Int -> [ByteString] -> [ByteString]
ldrop Int
1 [ByteString]
mtch))
in \rep
sub -> let repl1 :: [ByteString] -> [ByteString]
repl1 = ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
repl (rep -> [ByteString] -> [ByteString]
forall a. Substitution a => a -> [ByteString] -> [ByteString]
substitution rep
sub)
in [ByteString] -> ByteString
L.fromChunks ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
repl1 ([ByteString] -> [ByteString])
-> (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
| Bool
otherwise =
let repl :: ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
repl = ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
lazyRepl ByteString
pat
in \rep
sub -> let repl1 :: [ByteString] -> [ByteString]
repl1 = ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
repl (rep -> [ByteString] -> [ByteString]
forall a. Substitution a => a -> [ByteString] -> [ByteString]
substitution rep
sub)
in [ByteString] -> ByteString
L.fromChunks ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
repl1 ([ByteString] -> [ByteString])
-> (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
{-# INLINE breakSubstringL #-}
breakSubstringL :: S.ByteString
-> L.ByteString
-> (L.ByteString, L.ByteString)
breakSubstringL :: ByteString -> ByteString -> (ByteString, ByteString)
breakSubstringL ByteString
pat = [ByteString] -> (ByteString, ByteString)
breaker ([ByteString] -> (ByteString, ByteString))
-> (ByteString -> [ByteString])
-> ByteString
-> (ByteString, ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
where
lbrk :: [ByteString] -> ([ByteString], [ByteString])
lbrk = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
breaker :: [ByteString] -> (ByteString, ByteString)
breaker [ByteString]
strs = let ([ByteString]
f, [ByteString]
b) = [ByteString] -> ([ByteString], [ByteString])
lbrk [ByteString]
strs
in ([ByteString] -> ByteString
L.fromChunks [ByteString]
f, [ByteString] -> ByteString
L.fromChunks [ByteString]
b)
breakAfterL :: S.ByteString
-> L.ByteString
-> (L.ByteString, L.ByteString)
breakAfterL :: ByteString -> ByteString -> (ByteString, ByteString)
breakAfterL ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = \ByteString
str -> (ByteString
L.empty, ByteString
str)
breakAfterL ByteString
pat = [ByteString] -> (ByteString, ByteString)
breaker' ([ByteString] -> (ByteString, ByteString))
-> (ByteString -> [ByteString])
-> ByteString
-> (ByteString, ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
breaker' :: [ByteString] -> (ByteString, ByteString)
breaker' [ByteString]
strs =
let ([ByteString]
pre, [ByteString]
mtch) = [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
strs
([ByteString]
pl, [ByteString]
a) = if [ByteString] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
mtch then ([],[]) else Int -> [ByteString] -> ([ByteString], [ByteString])
lsplit Int
patLen [ByteString]
mtch
in ([ByteString] -> ByteString
L.fromChunks ([ByteString]
pre [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
pl), [ByteString] -> ByteString
L.fromChunks [ByteString]
a)
breakFindAfterL :: S.ByteString
-> L.ByteString
-> ((L.ByteString, L.ByteString), Bool)
breakFindAfterL :: ByteString -> ByteString -> ((ByteString, ByteString), Bool)
breakFindAfterL ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = \ByteString
str -> ((ByteString
L.empty, ByteString
str), Bool
True)
breakFindAfterL ByteString
pat = [ByteString] -> ((ByteString, ByteString), Bool)
breaker' ([ByteString] -> ((ByteString, ByteString), Bool))
-> (ByteString -> [ByteString])
-> ByteString
-> ((ByteString, ByteString), Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
breaker' :: [ByteString] -> ((ByteString, ByteString), Bool)
breaker' [ByteString]
strs =
let ([ByteString]
pre, [ByteString]
mtch) = [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
strs
([ByteString]
pl, [ByteString]
a) = if [ByteString] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
mtch then ([],[]) else Int -> [ByteString] -> ([ByteString], [ByteString])
lsplit Int
patLen [ByteString]
mtch
in (([ByteString] -> ByteString
L.fromChunks ([ByteString]
pre [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
pl), [ByteString] -> ByteString
L.fromChunks [ByteString]
a), Bool -> Bool
not ([ByteString] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
mtch))
{-# INLINE splitKeepEndL #-}
splitKeepEndL :: S.ByteString
-> L.ByteString
-> [L.ByteString]
splitKeepEndL :: ByteString -> ByteString -> [ByteString]
splitKeepEndL ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = [ByteString] -> ByteString -> [ByteString]
forall a b. a -> b -> a
const (ByteString -> [ByteString]
forall a. a -> [a]
repeat ByteString
L.empty)
| Bool
otherwise =
let splitter :: [ByteString] -> [[ByteString]]
splitter = ByteString -> [ByteString] -> [[ByteString]]
lazySplitKeepEnd ByteString
pat
in ([ByteString] -> ByteString) -> [[ByteString]] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map [ByteString] -> ByteString
L.fromChunks ([[ByteString]] -> [ByteString])
-> (ByteString -> [[ByteString]]) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [[ByteString]]
splitter ([ByteString] -> [[ByteString]])
-> (ByteString -> [ByteString]) -> ByteString -> [[ByteString]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
{-# INLINE splitKeepFrontL #-}
splitKeepFrontL :: S.ByteString
-> L.ByteString
-> [L.ByteString]
splitKeepFrontL :: ByteString -> ByteString -> [ByteString]
splitKeepFrontL ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = [ByteString] -> ByteString -> [ByteString]
forall a b. a -> b -> a
const (ByteString -> [ByteString]
forall a. a -> [a]
repeat ByteString
L.empty)
| Bool
otherwise =
let splitter :: [ByteString] -> [[ByteString]]
splitter = ByteString -> [ByteString] -> [[ByteString]]
lazySplitKeepFront ByteString
pat
in ([ByteString] -> ByteString) -> [[ByteString]] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map [ByteString] -> ByteString
L.fromChunks ([[ByteString]] -> [ByteString])
-> (ByteString -> [[ByteString]]) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [[ByteString]]
splitter ([ByteString] -> [[ByteString]])
-> (ByteString -> [ByteString]) -> ByteString -> [[ByteString]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
{-# INLINE splitDropL #-}
splitDropL :: S.ByteString
-> L.ByteString
-> [L.ByteString]
splitDropL :: ByteString -> ByteString -> [ByteString]
splitDropL ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = [ByteString] -> ByteString -> [ByteString]
forall a b. a -> b -> a
const (ByteString -> [ByteString]
forall a. a -> [a]
repeat ByteString
L.empty)
| Bool
otherwise =
let splitter :: [ByteString] -> [[ByteString]]
splitter = ByteString -> [ByteString] -> [[ByteString]]
lazySplitDrop ByteString
pat
in ([ByteString] -> ByteString) -> [[ByteString]] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map [ByteString] -> ByteString
L.fromChunks ([[ByteString]] -> [ByteString])
-> (ByteString -> [[ByteString]]) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [[ByteString]]
splitter ([ByteString] -> [[ByteString]])
-> (ByteString -> [ByteString]) -> ByteString -> [[ByteString]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks
lazySearcher :: Bool -> S.ByteString -> [S.ByteString] -> [Int64]
lazySearcher :: Bool -> ByteString -> [ByteString] -> [Int64]
lazySearcher Bool
_ !ByteString
pat
| ByteString -> Bool
S.null ByteString
pat =
let zgo :: t -> [ByteString] -> [t]
zgo !t
prior [] = [t
prior]
zgo t
prior (!ByteString
str : [ByteString]
rest) =
let !l :: Int
l = ByteString -> Int
S.length ByteString
str
!prior' :: t
prior' = t
prior t -> t -> t
forall a. Num a => a -> a -> a
+ Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l
in [t
prior t -> t -> t
forall a. Num a => a -> a -> a
+ Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i | Int
i <- [Int
0 .. Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]] [t] -> [t] -> [t]
forall a. [a] -> [a] -> [a]
++ t -> [ByteString] -> [t]
zgo t
prior' [ByteString]
rest
in Int64 -> [ByteString] -> [Int64]
forall {t}. Num t => t -> [ByteString] -> [t]
zgo Int64
0
| ByteString -> Int
S.length ByteString
pat Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 =
let !w :: Word8
w = ByteString -> Word8
S.head ByteString
pat
ixes :: ByteString -> [Int]
ixes = Word8 -> ByteString -> [Int]
S.elemIndices Word8
w
go :: t -> [ByteString] -> [t]
go t
_ [] = []
go !t
prior (!ByteString
str : [ByteString]
rest)
= let !prior' :: t
prior' = t
prior t -> t -> t
forall a. Num a => a -> a -> a
+ Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
S.length ByteString
str)
in (Int -> t) -> [Int] -> [t]
forall a b. (a -> b) -> [a] -> [b]
map ((t -> t -> t
forall a. Num a => a -> a -> a
+ t
prior) (t -> t) -> (Int -> t) -> Int -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (ByteString -> [Int]
ixes ByteString
str) [t] -> [t] -> [t]
forall a. [a] -> [a] -> [a]
++ t -> [ByteString] -> [t]
go t
prior' [ByteString]
rest
in Int64 -> [ByteString] -> [Int64]
forall {t}. Num t => t -> [ByteString] -> [t]
go Int64
0
lazySearcher !Bool
overlap ByteString
pat = [ByteString] -> [Int64]
searcher
where
{-# INLINE patAt #-}
patAt :: Int -> Word8
patAt :: Int -> Word8
patAt !Int
i = ByteString -> Int -> Word8
unsafeIndex ByteString
pat Int
i
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
!patEnd :: Int
patEnd = Int
patLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
{-# INLINE preEnd #-}
preEnd :: Int
preEnd = Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
!maxLen :: Int
maxLen = Int
forall a. Bounded a => a
maxBound Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patLen
!occT :: UArray Int Int
occT = ByteString -> UArray Int Int
occurs ByteString
pat
!suffT :: UArray Int Int
suffT = ByteString -> UArray Int Int
suffShifts ByteString
pat
!skip :: Int
skip = if Bool
overlap then UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
suffT Int
0 else Int
patLen
!kept :: Int
kept = Int
patLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
skip
!pe :: Word8
pe = Int -> Word8
patAt Int
patEnd
{-# INLINE occ #-}
occ :: a -> Int
occ !a
w = UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
occT (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
w)
{-# INLINE suff #-}
suff :: Int -> Int
suff !Int
i = UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
suffT Int
i
searcher :: [ByteString] -> [Int64]
searcher [ByteString]
lst = case [ByteString]
lst of
[] -> []
(ByteString
h : [ByteString]
t) ->
if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
S.length ByteString
h
then [Char] -> [Int64]
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazySearcher"
else Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
0 [] ByteString
h [ByteString]
t Int
0 Int
patEnd
seek :: Int64 -> [S.ByteString] -> S.ByteString
-> [S.ByteString] -> Int -> Int -> [Int64]
seek :: Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek !Int64
prior ![ByteString]
past !ByteString
str [ByteString]
future !Int
diffPos !Int
patPos
| Int
strPos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
case [ByteString]
past of
(ByteString
h : [ByteString]
t) ->
let !hLen :: Int
hLen = ByteString -> Int
S.length ByteString
h
in Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek (Int64
prior Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
- Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
hLen) [ByteString]
t ByteString
h (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
future)
(Int
diffPos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
hLen) Int
patPos
[] -> [Char] -> [Int64]
forall a. HasCallStack => [Char] -> a
error [Char]
"seek back too far!"
| Int
strEnd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
strPos =
case [ByteString]
future of
(ByteString
h : [ByteString]
t) ->
let {-# INLINE prior' #-}
prior' :: Int64
prior' = Int64
prior Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
strLen
!diffPos' :: Int
diffPos' = Int
diffPos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
strLen
{-# INLINE past' #-}
past' :: [ByteString]
past' = Int -> [ByteString] -> [ByteString]
release (-Int
diffPos') (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
past)
in if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
S.length ByteString
h
then [Char] -> [Int64]
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazySearcher"
else Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior' [ByteString]
past' ByteString
h [ByteString]
t Int
diffPos' Int
patPos
[] -> []
| Int
patPos Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
patEnd = Int -> [Int64]
checkEnd Int
strPos
| Int
diffPos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int -> Int -> [Int64]
matcherN Int
diffPos Int
patPos
| Bool
otherwise = Int -> Int -> [Int64]
matcherP Int
diffPos Int
patPos
where
!strPos :: Int
strPos = Int
diffPos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patPos
!strLen :: Int
strLen = ByteString -> Int
S.length ByteString
str
!strEnd :: Int
strEnd = Int
strLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
!maxDiff :: Int
maxDiff = Int
strLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patLen
{-# INLINE strAt #-}
strAt :: Int -> Word8
strAt !Int
i = ByteString -> Int -> Word8
unsafeIndex ByteString
str Int
i
checkEnd :: Int -> [Int64]
checkEnd !Int
sI
| Int
strEnd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sI = Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) Int
patEnd
| Bool
otherwise =
case Int -> Word8
strAt Int
sI of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
pe ->
if Int
sI Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
patEnd
then case Int
sI of
Int
0 -> Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future (-Int
patEnd) Int
preEnd
Int
_ -> Int -> Int -> [Int64]
matcherN (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) Int
preEnd
else Int -> Int -> [Int64]
matcherP (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) Int
preEnd
| Bool
otherwise -> Int -> [Int64]
checkEnd (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
matcherN :: Int -> Int -> [Int64]
matcherN !Int
diff !Int
patI =
case Int -> Word8
strAt (Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future Int
diff (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else Int -> Int -> [Int64]
matcherN Int
diff (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise ->
let {-# INLINE badShift #-}
badShift :: Int
badShift = Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c
{-# INLINE goodShift #-}
goodShift :: Int
goodShift = Int -> Int
suff Int
patI
!diff' :: Int
diff' = Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
badShift Int
goodShift
in if Int
maxDiff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
diff'
then Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future Int
diff' Int
patEnd
else Int -> [Int64]
checkEnd (Int
diff' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
matcherP :: Int -> Int -> [Int64]
matcherP !Int
diff !Int
patI =
case Int -> Word8
strAt (Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then Int64
prior Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
diff Int64 -> [Int64] -> [Int64]
forall a. a -> [a] -> [a]
:
let !diff' :: Int
diff' = Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
skip
in if Int
maxDiff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
diff'
then Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future Int
diff' Int
patEnd
else
if Int
skip Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
patLen
then
Int -> [Int64]
checkEnd (Int
diff' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
else
Int -> Int -> [Int64]
afterMatch Int
diff' Int
patEnd
else Int -> Int -> [Int64]
matcherP Int
diff (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise ->
let {-# INLINE badShift #-}
badShift :: Int
badShift = Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c
{-# INLINE goodShift #-}
goodShift :: Int
goodShift = Int -> Int
suff Int
patI
!diff' :: Int
diff' = Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
badShift Int
goodShift
in if Int
maxDiff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
diff'
then Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future Int
diff' Int
patEnd
else Int -> [Int64]
checkEnd (Int
diff' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
afterMatch :: Int -> Int -> [Int64]
afterMatch !Int
diff !Int
patI =
case Int -> Word8
strAt (Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
kept
then Int64
prior Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
diff Int64 -> [Int64] -> [Int64]
forall a. a -> [a] -> [a]
:
let !diff' :: Int
diff' = Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
skip
in if Int
maxDiff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
diff'
then Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future Int
diff' Int
patEnd
else Int -> Int -> [Int64]
afterMatch Int
diff' Int
patEnd
else Int -> Int -> [Int64]
afterMatch Int
diff (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
patEnd ->
Int -> [Int64]
checkEnd (Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
patEnd) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
| Bool
otherwise ->
let {-# INLINE badShift #-}
badShift :: Int
badShift = Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c
{-# INLINE goodShift #-}
goodShift :: Int
goodShift = Int -> Int
suff Int
patI
!diff' :: Int
diff' = Int
diff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
badShift Int
goodShift
in if Int
maxDiff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
diff'
then Int64
-> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> [Int64]
seek Int64
prior [ByteString]
past ByteString
str [ByteString]
future Int
diff' Int
patEnd
else Int -> [Int64]
checkEnd (Int
diff' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
lazyBreak ::S.ByteString -> [S.ByteString] -> ([S.ByteString], [S.ByteString])
lazyBreak :: ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak !ByteString
pat
| ByteString -> Bool
S.null ByteString
pat = \[ByteString]
lst -> ([],[ByteString]
lst)
| ByteString -> Int
S.length ByteString
pat Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 =
let !w :: Word8
w = ByteString -> Word8
S.head ByteString
pat
go :: [ByteString] -> ([ByteString], [ByteString])
go [] = ([], [])
go (!ByteString
str : [ByteString]
rest) =
case Word8 -> ByteString -> [Int]
S.elemIndices Word8
w ByteString
str of
[] -> let ([ByteString]
pre, [ByteString]
post) = [ByteString] -> ([ByteString], [ByteString])
go [ByteString]
rest in (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
pre, [ByteString]
post)
(Int
i:[Int]
_) -> if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then ([], ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
rest)
else ([Int -> ByteString -> ByteString
S.take Int
i ByteString
str], Int -> ByteString -> ByteString
S.drop Int
i ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
rest)
in [ByteString] -> ([ByteString], [ByteString])
go
lazyBreak ByteString
pat = [ByteString] -> ([ByteString], [ByteString])
breaker
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
!patEnd :: Int
patEnd = Int
patLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
!occT :: UArray Int Int
occT = ByteString -> UArray Int Int
occurs ByteString
pat
!suffT :: UArray Int Int
suffT = ByteString -> UArray Int Int
suffShifts ByteString
pat
!maxLen :: Int
maxLen = Int
forall a. Bounded a => a
maxBound Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patLen
!pe :: Word8
pe = Int -> Word8
patAt Int
patEnd
{-# INLINE patAt #-}
patAt :: Int -> Word8
patAt !Int
i = ByteString -> Int -> Word8
unsafeIndex ByteString
pat Int
i
{-# INLINE occ #-}
occ :: a -> Int
occ !a
w = UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
occT (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
w)
{-# INLINE suff #-}
suff :: Int -> Int
suff !Int
i = UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
suffT Int
i
breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
lst =
case [ByteString]
lst of
[] -> ([],[])
(ByteString
h:[ByteString]
t) ->
if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
S.length ByteString
h
then [Char] -> ([ByteString], [ByteString])
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazyBreak"
else [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [] ByteString
h [ByteString]
t Int
0 Int
patEnd
seek :: [S.ByteString] -> S.ByteString -> [S.ByteString]
-> Int -> Int -> ([S.ByteString], [S.ByteString])
seek :: [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek ![ByteString]
past !ByteString
str [ByteString]
future !Int
offset !Int
patPos
| Int
strPos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
case [ByteString]
past of
[] -> [Char] -> ([ByteString], [ByteString])
forall a. HasCallStack => [Char] -> a
error [Char]
"not enough past!"
(ByteString
h : [ByteString]
t) -> [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
t ByteString
h (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
future) (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ByteString -> Int
S.length ByteString
h) Int
patPos
| Int
strEnd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
strPos =
case [ByteString]
future of
[] -> ((ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
-> [ByteString]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> (ByteString -> [ByteString] -> [ByteString])
-> ByteString
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)) [ByteString] -> [ByteString]
forall a. a -> a
id [ByteString]
past [ByteString
str], [])
(ByteString
h : [ByteString]
t) ->
let !off' :: Int
off' = Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
strLen
([ByteString]
past', ![ByteString]
discharge) = Int -> [ByteString] -> ([ByteString], [ByteString])
keep (-Int
off') (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
past)
in if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
S.length ByteString
h
then [Char] -> ([ByteString], [ByteString])
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazyBreak (future)"
else let ([ByteString]
pre,[ByteString]
post) = [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
past' ByteString
h [ByteString]
t Int
off' Int
patPos
in ((ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
-> [ByteString]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> (ByteString -> [ByteString] -> [ByteString])
-> ByteString
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)) [ByteString] -> [ByteString]
forall a. a -> a
id [ByteString]
discharge [ByteString]
pre, [ByteString]
post)
| Int
patPos Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
patEnd = Int -> ([ByteString], [ByteString])
checkEnd Int
strPos
| Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int -> Int -> ([ByteString], [ByteString])
matcherN Int
offset Int
patPos
| Bool
otherwise = Int -> Int -> ([ByteString], [ByteString])
matcherP Int
offset Int
patPos
where
{-# INLINE strAt #-}
strAt :: Int -> Word8
strAt !Int
i = ByteString -> Int -> Word8
unsafeIndex ByteString
str Int
i
!strLen :: Int
strLen = ByteString -> Int
S.length ByteString
str
!strEnd :: Int
strEnd = Int
strLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
!maxOff :: Int
maxOff = Int
strLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patLen
!strPos :: Int
strPos = Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patPos
checkEnd :: Int -> ([ByteString], [ByteString])
checkEnd !Int
sI
| Int
strEnd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sI = [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
past ByteString
str [ByteString]
future (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) Int
patEnd
| Bool
otherwise =
case Int -> Word8
strAt Int
sI of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
pe ->
if Int
sI Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
patEnd
then (if Int
sI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
past ByteString
str [ByteString]
future (-Int
patEnd) (Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else Int -> Int -> ([ByteString], [ByteString])
matcherN (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) (Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
else Int -> Int -> ([ByteString], [ByteString])
matcherP (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) (Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise -> Int -> ([ByteString], [ByteString])
checkEnd (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
matcherN :: Int -> Int -> ([ByteString], [ByteString])
matcherN !Int
off !Int
patI =
case Int -> Word8
strAt (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
past ByteString
str [ByteString]
future Int
off (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else Int -> Int -> ([ByteString], [ByteString])
matcherN Int
off (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise ->
let !off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int -> Int
suff Int
patI) (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
in if Int
maxOff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
off'
then [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
past ByteString
str [ByteString]
future Int
off' Int
patEnd
else Int -> ([ByteString], [ByteString])
checkEnd (Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
matcherP :: Int -> Int -> ([ByteString], [ByteString])
matcherP !Int
off !Int
patI =
case Int -> Word8
strAt (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then let !pre :: [ByteString]
pre = if Int
off Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [] else [Int -> ByteString -> ByteString
S.take Int
off ByteString
str]
!post :: ByteString
post = Int -> ByteString -> ByteString
S.drop Int
off ByteString
str
in ((ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
-> [ByteString]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> (ByteString -> [ByteString] -> [ByteString])
-> ByteString
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)) [ByteString] -> [ByteString]
forall a. a -> a
id [ByteString]
past [ByteString]
pre, ByteString
postByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
future)
else Int -> Int -> ([ByteString], [ByteString])
matcherP Int
off (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise ->
let !off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int -> Int
suff Int
patI) (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
in if Int
maxOff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
off'
then [ByteString]
-> ByteString
-> [ByteString]
-> Int
-> Int
-> ([ByteString], [ByteString])
seek [ByteString]
past ByteString
str [ByteString]
future Int
off' Int
patEnd
else Int -> ([ByteString], [ByteString])
checkEnd (Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
lazySplitKeepFront :: S.ByteString -> [S.ByteString] -> [[S.ByteString]]
lazySplitKeepFront :: ByteString -> [ByteString] -> [[ByteString]]
lazySplitKeepFront ByteString
pat = [ByteString] -> [[ByteString]]
splitter'
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
splitter' :: [ByteString] -> [[ByteString]]
splitter' [ByteString]
strs = case [ByteString] -> [[ByteString]]
splitter [ByteString]
strs of
([]:[[ByteString]]
rest) -> [[ByteString]]
rest
[[ByteString]]
other -> [[ByteString]]
other
splitter :: [ByteString] -> [[ByteString]]
splitter [] = []
splitter [ByteString]
strs =
case [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
strs of
([ByteString]
pre, [ByteString]
mtch) ->
[ByteString]
pre [ByteString] -> [[ByteString]] -> [[ByteString]]
forall a. a -> [a] -> [a]
: case [ByteString]
mtch of
[] -> []
[ByteString]
_ -> case Int -> [ByteString] -> ([ByteString], [ByteString])
lsplit Int
patLen [ByteString]
mtch of
([ByteString]
pt, [ByteString]
rst) ->
if [ByteString] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
rst
then [[ByteString]
pt]
else let ([ByteString]
h : [[ByteString]]
t) = [ByteString] -> [[ByteString]]
splitter [ByteString]
rst
in ([ByteString]
pt [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
h) [ByteString] -> [[ByteString]] -> [[ByteString]]
forall a. a -> [a] -> [a]
: [[ByteString]]
t
lazySplitKeepEnd :: S.ByteString -> [S.ByteString] -> [[S.ByteString]]
lazySplitKeepEnd :: ByteString -> [ByteString] -> [[ByteString]]
lazySplitKeepEnd ByteString
pat = [ByteString] -> [[ByteString]]
splitter
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
splitter :: [ByteString] -> [[ByteString]]
splitter [] = []
splitter [ByteString]
strs =
case [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
strs of
([ByteString]
pre, [ByteString]
mtch) ->
let ([ByteString]
h : [[ByteString]]
t) = if [ByteString] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
mtch
then [[]]
else case Int -> [ByteString] -> ([ByteString], [ByteString])
lsplit Int
patLen [ByteString]
mtch of
([ByteString]
pt, [ByteString]
rst) -> [ByteString]
pt [ByteString] -> [[ByteString]] -> [[ByteString]]
forall a. a -> [a] -> [a]
: [ByteString] -> [[ByteString]]
splitter [ByteString]
rst
in ([ByteString]
pre [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
h) [ByteString] -> [[ByteString]] -> [[ByteString]]
forall a. a -> [a] -> [a]
: [[ByteString]]
t
lazySplitDrop :: S.ByteString -> [S.ByteString] -> [[S.ByteString]]
lazySplitDrop :: ByteString -> [ByteString] -> [[ByteString]]
lazySplitDrop ByteString
pat = [ByteString] -> [[ByteString]]
splitter
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
breaker :: [ByteString] -> ([ByteString], [ByteString])
breaker = ByteString -> [ByteString] -> ([ByteString], [ByteString])
lazyBreak ByteString
pat
splitter :: [ByteString] -> [[ByteString]]
splitter [] = []
splitter [ByteString]
strs = [ByteString] -> [[ByteString]]
splitter' [ByteString]
strs
splitter' :: [ByteString] -> [[ByteString]]
splitter' [] = [[]]
splitter' [ByteString]
strs = case [ByteString] -> ([ByteString], [ByteString])
breaker [ByteString]
strs of
([ByteString]
pre,[ByteString]
mtch) ->
[ByteString]
pre [ByteString] -> [[ByteString]] -> [[ByteString]]
forall a. a -> [a] -> [a]
: case [ByteString]
mtch of
[] -> []
[ByteString]
_ -> [ByteString] -> [[ByteString]]
splitter' (Int -> [ByteString] -> [ByteString]
ldrop Int
patLen [ByteString]
mtch)
lazyRepl :: S.ByteString -> ([S.ByteString] -> [S.ByteString])
-> [S.ByteString] -> [S.ByteString]
lazyRepl :: ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
lazyRepl ByteString
pat = ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
replacer
where
!patLen :: Int
patLen = ByteString -> Int
S.length ByteString
pat
!patEnd :: Int
patEnd = Int
patLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
!occT :: UArray Int Int
occT = ByteString -> UArray Int Int
occurs ByteString
pat
!suffT :: UArray Int Int
suffT = ByteString -> UArray Int Int
suffShifts ByteString
pat
!maxLen :: Int
maxLen = Int
forall a. Bounded a => a
maxBound Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patLen
!pe :: Word8
pe = Int -> Word8
patAt Int
patEnd
{-# INLINE patAt #-}
patAt :: Int -> Word8
patAt !Int
i = ByteString -> Int -> Word8
unsafeIndex ByteString
pat Int
i
{-# INLINE occ #-}
occ :: a -> Int
occ !a
w = UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
occT (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
w)
{-# INLINE suff #-}
suff :: Int -> Int
suff !Int
i = UArray Int Int -> Int -> Int
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt UArray Int Int
suffT Int
i
replacer :: ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
replacer [ByteString] -> [ByteString]
sub [ByteString]
lst =
case [ByteString]
lst of
[] -> []
(ByteString
h:[ByteString]
t) ->
if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
S.length ByteString
h
then [Char] -> [ByteString]
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazyRepl"
else [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [] ByteString
h [ByteString]
t Int
0 Int
patEnd
where
chop :: Int -> [ByteString] -> [ByteString]
chop Int
_ [] = []
chop !Int
k (!ByteString
str : [ByteString]
rest)
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s =
if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
k)
then [Char] -> [ByteString]
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazyRepl (chop)"
else [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [] (Int -> ByteString -> ByteString
S.drop Int
k ByteString
str) [ByteString]
rest Int
0 Int
patEnd
| Bool
otherwise = Int -> [ByteString] -> [ByteString]
chop (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
s) [ByteString]
rest
where
!s :: Int
s = ByteString -> Int
S.length ByteString
str
seek :: [S.ByteString] -> S.ByteString -> [S.ByteString]
-> Int -> Int -> [S.ByteString]
seek :: [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek ![ByteString]
past !ByteString
str [ByteString]
fut !Int
offset !Int
patPos
| Int
strPos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
case [ByteString]
past of
[] -> [Char] -> [ByteString]
forall a. HasCallStack => [Char] -> a
error [Char]
"not enough past!"
(ByteString
h : [ByteString]
t) -> [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
t ByteString
h (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
fut) (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ByteString -> Int
S.length ByteString
h) Int
patPos
| Int
strEnd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
strPos =
case [ByteString]
fut of
[] -> (ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
-> [ByteString]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> (ByteString -> [ByteString] -> [ByteString])
-> ByteString
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)) [ByteString] -> [ByteString]
forall a. a -> a
id [ByteString]
past [ByteString
str]
(ByteString
h : [ByteString]
t) ->
let !off' :: Int
off' = Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
strLen
([ByteString]
past', ![ByteString]
discharge) = Int -> [ByteString] -> ([ByteString], [ByteString])
keep (-Int
off') (ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
past)
in if Int
maxLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
S.length ByteString
h
then [Char] -> [ByteString]
forall a. HasCallStack => [Char] -> a
error [Char]
"Overflow in BoyerMoore.lazyRepl (future)"
else (ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
-> [ByteString]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> (ByteString -> [ByteString] -> [ByteString])
-> ByteString
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)) [ByteString] -> [ByteString]
forall a. a -> a
id [ByteString]
discharge ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$
[ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
past' ByteString
h [ByteString]
t Int
off' Int
patPos
| Int
patPos Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
patEnd = Int -> [ByteString]
checkEnd Int
strPos
| Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int -> Int -> [ByteString]
matcherN Int
offset Int
patPos
| Bool
otherwise = Int -> Int -> [ByteString]
matcherP Int
offset Int
patPos
where
{-# INLINE strAt #-}
strAt :: Int -> Word8
strAt !Int
i = ByteString -> Int -> Word8
unsafeIndex ByteString
str Int
i
!strLen :: Int
strLen = ByteString -> Int
S.length ByteString
str
!strEnd :: Int
strEnd = Int
strLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
!maxOff :: Int
maxOff = Int
strLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patLen
!strPos :: Int
strPos = Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patPos
checkEnd :: Int -> [ByteString]
checkEnd !Int
sI
| Int
strEnd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sI = [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
past ByteString
str [ByteString]
fut (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) Int
patEnd
| Bool
otherwise =
case Int -> Word8
strAt Int
sI of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
pe ->
if Int
sI Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
patEnd
then (if Int
sI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
past ByteString
str [ByteString]
fut (-Int
patEnd) (Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else Int -> Int -> [ByteString]
matcherN (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) (Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
else Int -> Int -> [ByteString]
matcherP (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
patEnd) (Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise -> Int -> [ByteString]
checkEnd (Int
sI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
matcherN :: Int -> Int -> [ByteString]
matcherN !Int
off !Int
patI =
case Int -> Word8
strAt (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
past ByteString
str [ByteString]
fut Int
off (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else Int -> Int -> [ByteString]
matcherN Int
off (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise ->
let !off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int -> Int
suff Int
patI) (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
in if Int
maxOff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
off'
then [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
past ByteString
str [ByteString]
fut Int
off' Int
patEnd
else Int -> [ByteString]
checkEnd (Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)
matcherP :: Int -> Int -> [ByteString]
matcherP !Int
off !Int
patI =
case Int -> Word8
strAt (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patI) of
!Word8
c | Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Word8
patAt Int
patI ->
if Int
patI Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then (ByteString
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
-> [ByteString]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString])
-> (ByteString -> [ByteString] -> [ByteString])
-> ByteString
-> ([ByteString] -> [ByteString])
-> [ByteString]
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)) [ByteString] -> [ByteString]
forall a. a -> a
id [ByteString]
past ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$
let pre :: [ByteString] -> [ByteString]
pre = if Int
off Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then [ByteString] -> [ByteString]
forall a. a -> a
id
else (Int -> ByteString -> ByteString
S.take Int
off ByteString
str ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:)
in [ByteString] -> [ByteString]
pre ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
sub ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$
let !p :: Int
p = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patLen
in if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
strLen
then [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [] (Int -> ByteString -> ByteString
S.drop Int
p ByteString
str) [ByteString]
fut Int
0 Int
patEnd
else Int -> [ByteString] -> [ByteString]
chop (Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
strLen) [ByteString]
fut
else Int -> Int -> [ByteString]
matcherP Int
off (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise ->
let !off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int -> Int
suff Int
patI) (Int
patI Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall {a}. Integral a => a -> Int
occ Word8
c)
in if Int
maxOff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
off'
then [ByteString]
-> ByteString -> [ByteString] -> Int -> Int -> [ByteString]
seek [ByteString]
past ByteString
str [ByteString]
fut Int
off' Int
patEnd
else Int -> [ByteString]
checkEnd (Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
patEnd)