int search(unsigned char *x, int m, unsigned char *y, int n) { int d, hx, hy, i, j, count; BEGIN_PREPROCESSING count = 0; /* Preprocessing */ for (d = i = 1; i < m; ++i) d = (d<<1); for (hy = hx = i = 0; i < m; ++i) { hx = ((hx<<1) + x[i]); hy = ((hy<<1) + y[i]); } END_PREPROCESSING /* Searching */ BEGIN_SEARCHING j = 0; while (j <= n-m) { if (hx == hy && memcmp(x, y + j, m) == 0) OUTPUT(j); hy = REHASH(y[j], y[j + m], hy); ++j; } END_SEARCHING return count; }
/*! \internal */ int qFindByteArray( const char *haystack0, int haystackLen, int from, const char *needle, int needleLen) { const int l = haystackLen; const int sl = needleLen; if (from < 0) from += l; if (uint(sl + from) > (uint)l) return -1; if (!sl) return from; if (!l) return -1; if (sl == 1) return findChar(haystack0, haystackLen, needle[0], from); /* We use the Boyer-Moore algorithm in cases where the overhead for the skip table should pay off, otherwise we use a simple hash function. */ if (l > 500 && sl > 5) return qFindByteArrayBoyerMoore(haystack0, haystackLen, from, needle, needleLen); /* We use some hashing for efficiency's sake. Instead of comparing strings, we compare the hash value of str with that of a part of this QString. Only if that matches, we call memcmp(). */ const char *haystack = haystack0 + from; const char *end = haystack0 + (l - sl); const uint sl_minus_1 = sl - 1; uint hashNeedle = 0, hashHaystack = 0; int idx; for (idx = 0; idx < sl; ++idx) { hashNeedle = ((hashNeedle<<1) + needle[idx]); hashHaystack = ((hashHaystack<<1) + haystack[idx]); } hashHaystack -= *(haystack + sl_minus_1); while (haystack <= end) { hashHaystack += *(haystack + sl_minus_1); if (hashHaystack == hashNeedle && *needle == *haystack && memcmp(needle, haystack, sl) == 0) return haystack - haystack0; REHASH(*haystack); ++haystack; } return -1; }
static int insensitiveIndexOf(const QByteArray& target, const QByteArray &source, int from, int off, int len) { #ifndef USE_FANCY_MATCH_ALGORITHM const char* const matchBegin = target.constData(); const char* const matchEnd = matchBegin + target.length(); const char* const begin = source.constData() + off; const char* const end = begin + len - (target.length() - 1); const char* it = begin + from; while (it < end) { if (toupper(*it++) == toupper(*matchBegin)) { const char* restart = it; // See if the remainder matches const char* searchIt = it; const char* matchIt = matchBegin + 1; do { if (matchIt == matchEnd) return ((it - 1) - begin); // We may find the next place to search in our scan if ((restart == it) && (*searchIt == *(it - 1))) restart = searchIt; } while (toupper(*searchIt++) == toupper(*matchIt++)); // No match it = restart; } } return -1; #else // Based on QByteArray::indexOf, except use strncasecmp for // case-insensitive string comparison const int ol = target.length(); if (from > len || ol + from > len) return -1; if (ol == 0) return from; const char *needle = target.data(); const char *haystack = source.data() + off + from; const char *end = source.data() + off + (len - ol); const uint ol_minus_1 = ol - 1; uint hashNeedle = 0, hashHaystack = 0; int idx; for (idx = 0; idx < ol; ++idx) { hashNeedle = ((hashNeedle<<1) + needle[idx]); hashHaystack = ((hashHaystack<<1) + haystack[idx]); } hashHaystack -= *(haystack + ol_minus_1); while (haystack <= end) { hashHaystack += *(haystack + ol_minus_1); if (hashHaystack == hashNeedle && *needle == *haystack && strncasecmp(needle, haystack, ol) == 0) { return haystack - source.data(); } REHASH(*haystack); ++haystack; } return -1; #endif }