Return the first location of non-empty NEEDLE within HAYSTACK, or NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This method is optimized for LONG_NEEDLE_THRESHOLD <= NEEDLE_LEN. Performance is guaranteed to be linear, with an initialization cost of 3 * NEEDLE_LEN + (1 << CHAR_BIT) operations. If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at most
| 317 | HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and |
| 318 | sublinear performance is not possible. */ |
| 319 | static RETURN_TYPE |
| 320 | two_way_long_needle (const unsigned char *haystack, size_t haystack_len, |
| 321 | const unsigned char *needle, size_t needle_len) |
| 322 | { |
| 323 | size_t i; /* Index into current byte of NEEDLE. */ |
| 324 | size_t j; /* Index into current window of HAYSTACK. */ |
| 325 | size_t period; /* The period of the right half of needle. */ |
| 326 | size_t suffix; /* The index of the right half of needle. */ |
| 327 | size_t shift_table[1U << CHAR_BIT]; /* See below. */ |
| 328 | |
| 329 | /* Factor the needle into two halves, such that the left half is |
| 330 | smaller than the global period, and the right half is |
| 331 | periodic (with a period as large as NEEDLE_LEN - suffix). */ |
| 332 | suffix = critical_factorization (needle, needle_len, &period); |
| 333 | |
| 334 | /* Populate shift_table. For each possible byte value c, |
| 335 | shift_table[c] is the distance from the last occurrence of c to |
| 336 | the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE. |
| 337 | shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0. */ |
| 338 | for (i = 0; i < 1U << CHAR_BIT; i++) |
| 339 | shift_table[i] = needle_len; |
| 340 | for (i = 0; i < needle_len; i++) |
| 341 | shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1; |
| 342 | |
| 343 | /* Perform the search. Each iteration compares the right half |
| 344 | first. */ |
| 345 | if (CMP_FUNC (needle, needle + period, suffix) == 0) |
| 346 | { |
| 347 | /* Entire needle is periodic; a mismatch can only advance by the |
| 348 | period, so use memory to avoid rescanning known occurrences |
| 349 | of the period. */ |
| 350 | size_t memory = 0; |
| 351 | size_t shift; |
| 352 | j = 0; |
| 353 | while (AVAILABLE (haystack, haystack_len, j, needle_len)) |
| 354 | { |
| 355 | /* Check the last byte first; if it does not match, then |
| 356 | shift to the next possible match location. */ |
| 357 | shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])]; |
| 358 | if (0 < shift) |
| 359 | { |
| 360 | if (memory && shift < period) |
| 361 | { |
| 362 | /* Since needle is periodic, but the last period has |
| 363 | a byte out of place, there can be no match until |
| 364 | after the mismatch. */ |
| 365 | shift = needle_len - period; |
| 366 | } |
| 367 | memory = 0; |
| 368 | j += shift; |
| 369 | continue; |
| 370 | } |
| 371 | /* Scan for matches in right half. The last byte has |
| 372 | already been matched, by virtue of the shift table. */ |
| 373 | i = MAX (suffix, memory); |
| 374 | while (i < needle_len - 1 && (CANON_ELEMENT (needle[i]) |
| 375 | == CANON_ELEMENT (haystack[i + j]))) |
| 376 | ++i; |
no test coverage detected
searching dependent graphs…