17 int l =
int(qMin(len, qsizetype(255)));
18 memset(skiptable, l, 256*
sizeof(uchar));
24static inline qsizetype bm_find(
const uchar *cc, qsizetype l, qsizetype index,
const uchar *puc,
25 qsizetype pl,
const uchar *skiptable)
28 return index > l ? -1 : index;
29 const qsizetype pl_minus_one = pl - 1;
31 const uchar *current = cc + index + pl_minus_one;
32 const uchar *end = cc + l;
33 while (current < end) {
34 qsizetype skip = skiptable[*current];
38 if (*(current - skip) != puc[pl_minus_one - skip])
42 if (skip > pl_minus_one)
43 return (current - cc) - skip + 1;
47 if (skiptable[*(current - skip)] == pl)
52 if (current > end - skip)
184qsizetype QByteArrayMatcher::indexIn(
const char *str, qsizetype len, qsizetype from)
const
188 return bm_find(
reinterpret_cast<
const uchar *>(str), len, from,
189 p.p, p.l, p.q_skiptable);
203qsizetype QByteArrayMatcher::indexIn(QByteArrayView data, qsizetype from)
const
207 return bm_find(
reinterpret_cast<
const uchar *>(data.data()), data.size(), from,
208 p.p, p.l, p.q_skiptable);
224static qsizetype qFindByteArrayBoyerMoore(
225 const char *haystack, qsizetype haystackLen, qsizetype haystackOffset,
226 const char *needle, qsizetype needleLen)
228 uchar skiptable[256];
229 bm_init_skiptable((
const uchar *)needle, needleLen, skiptable);
230 if (haystackOffset < 0)
232 return bm_find((
const uchar *)haystack, haystackLen, haystackOffset,
233 (
const uchar *)needle, needleLen, skiptable);
241qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, QByteArrayView needle)
noexcept
243 const auto haystack0 = haystack.data();
244 const auto l = haystack.size();
245 const auto sl = needle.size();
246#if !QT_CONFIG(memmem)
248 return findByteArray(haystack, from, needle.front());
253 if (std::size_t(sl + from) > std::size_t(l))
261 auto where = memmem(haystack0 + from, l - from, needle.data(), sl);
262 return where ?
static_cast<
const char *>(where) - haystack0 : -1;
266
267
268
269
270 if (l > 500 && sl > 5)
271 return qFindByteArrayBoyerMoore(haystack0, l, from, needle.data(), sl);
272 return qFindByteArray(haystack0, l, from, needle.data(), sl);
275qsizetype qFindByteArray(
const char *haystack0, qsizetype l, qsizetype from,
276 const char *needle, qsizetype sl)
279
280
281
282
283 const char *haystack = haystack0 + from;
284 const char *end = haystack0 + (l - sl);
285 const qregisteruint sl_minus_1 = sl - 1;
286 qregisteruint hashNeedle = 0, hashHaystack = 0;
288 for (idx = 0; idx < sl; ++idx) {
289 hashNeedle = ((hashNeedle<<1) + needle[idx]);
290 hashHaystack = ((hashHaystack<<1) + haystack[idx]);
292 hashHaystack -= *(haystack + sl_minus_1);
294 while (haystack <= end) {
295 hashHaystack += *(haystack + sl_minus_1);
296 if (hashHaystack == hashNeedle && *needle == *haystack
297 && memcmp(needle, haystack, sl) == 0)
298 return haystack - haystack0;
300 if (sl_minus_1 <
sizeof(sl_minus_1) * CHAR_BIT)
301 hashHaystack -= qregisteruint(*haystack) << sl_minus_1;
383qsizetype
QStaticByteArrayMatcherBase::indexOfIn(
const char *needle, size_t nlen,
const char *haystack, qsizetype hlen, qsizetype from)
const noexcept
387 return bm_find(
reinterpret_cast<
const uchar *>(haystack), hlen, from,
388 reinterpret_cast<
const uchar *>(needle), nlen, m_skiptable.data);
static qsizetype bm_find(const uchar *cc, qsizetype l, qsizetype index, const uchar *puc, qsizetype pl, const uchar *skiptable)