IndexValueStore::Iterator IndexValueStore::reverseFind(const IDBKeyData& key, const IDBKeyData& primaryKey, CursorDuplicity duplicity) { ASSERT(!key.isNull()); ASSERT(!primaryKey.isNull()); IDBKeyRangeData range; range.upperKey = key; range.upperOpen = false; auto iterator = highestReverseIteratorInRange(range); if (iterator == m_orderedKeys.rend()) return { }; auto record = m_records.get(*iterator); ASSERT(record); auto primaryIterator = record->reverseFind(primaryKey, duplicity); if (primaryIterator.isValid()) return { *this, duplicity, iterator, primaryIterator }; // If we didn't find a primary key iterator in this entry, // we need to move on to start of the next record. iterator++; if (iterator == m_orderedKeys.rend()) return { }; record = m_records.get(*iterator); ASSERT(record); primaryIterator = record->reverseBegin(duplicity); ASSERT(primaryIterator.isValid()); return { *this, duplicity, iterator, primaryIterator }; }
static inline void cleanPath(Vector<UChar, 512>& path) { // FIXME: Should not do this in the query or anchor part. int pos; while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) { int prev = reverseFind(path.data(), path.size(), '/', pos - 1); // don't remove the host, i.e. http://foo.org/../foo.html if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/')) path.remove(pos, 3); else path.remove(prev, pos - prev + 3); } // FIXME: Should not do this in the query part. // Set refPos to -2 to mean "I haven't looked for the anchor yet". // We don't want to waste a function call on the search for the the anchor // in the vast majority of cases where there is no "//" in the path. pos = 0; int refPos = -2; while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) { if (refPos == -2) refPos = find(path.data(), path.size(), '#'); if (refPos > 0 && pos >= refPos) break; if (pos == 0 || path[pos - 1] != ':') path.remove(pos); else pos += 2; } // FIXME: Should not do this in the query or anchor part. while ((pos = findSlashDotSlash(path.data(), path.size())) != -1) path.remove(pos, 2); }
void fillDeviceList(const char* dev, DeviceList& device_list) override { const char* token = nullptr; int device_index = 0; const char* end = dev + stringLength(dev); while (end > dev) { token = reverseFind(dev, token, ':'); char device[32]; if (token) { copyNString(device, (int)sizeof(device), token + 1, int(end - token - 1)); } else { copyNString(device, (int)sizeof(device), dev, int(end - dev)); } end = token; device_list.m_devices[device_index] = getDevice(device); ASSERT(device_list.m_devices[device_index]); ++device_index; } device_list.m_devices[device_index] = nullptr; }
static inline void cleanPath(Vector<UChar, 512>& path) { // FIXME: Should not do this in the query or anchor part. size_t pos; while ((pos = findSlashDotDotSlash(path.data(), path.size())) != notFound) { size_t prev = reverseFind(path.data(), path.size(), '/', pos - 1); // don't remove the host, i.e. http://foo.org/../foo.html if (prev == notFound || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/')) path.remove(pos, 3); else path.remove(prev, pos - prev + 3); } // FIXME: Should not do this in the query part. pos = 0; if ((pos = findSlashSlash(path.data(), path.size(), pos)) != notFound) { size_t refPos = find(path.data(), path.size(), '#'); while (refPos == 0 || refPos == notFound || pos < refPos) { if (pos == 0 || path[pos - 1] != ':') path.remove(pos); else pos += 2; if ((pos = findSlashSlash(path.data(), path.size(), pos)) == notFound) break; } } // FIXME: Should not do this in the query or anchor part. while ((pos = findSlashDotSlash(path.data(), path.size())) != notFound) path.remove(pos, 2); }
static void cleanSlashDotDotSlashes(Vector<UChar, 512>& path, size_t firstSlash) { size_t slash = firstSlash; do { size_t previousSlash = slash ? reverseFind(path.data(), path.size(), '/', slash - 1) : notFound; // Don't remove the host, i.e. http://foo.org/../foo.html if (previousSlash == notFound || (previousSlash > 3 && path[previousSlash - 2] == ':' && path[previousSlash - 1] == '/')) { path[slash] = 0; path[slash + 1] = 0; path[slash + 2] = 0; } else { for (size_t i = previousSlash; i < slash + 3; ++i) path[i] = 0; } slash += 3; } while ((slash = findSlashDotDotSlash(path.data(), path.size(), slash)) != notFound); squeezeOutNullCharacters(path); }
// Get the string from the last occurrence of the given string. const VerySimpleReadOnlyString VerySimpleReadOnlyString::fromLast(const VerySimpleReadOnlyString & find, const bool includeFind) const { const unsigned int pos = reverseFind(find); return VerySimpleReadOnlyString(pos == (unsigned int)length ? (includeFind ? data : "") : &data[includeFind ? pos : pos + (unsigned int)find.length], pos == (unsigned int)length ? (includeFind ? (unsigned int)length : 0) : (includeFind ? (unsigned int)length - pos : (unsigned int)length - pos - (unsigned int)find.length)); }
// Get the string up to the last occurrence of the given string const VerySimpleReadOnlyString VerySimpleReadOnlyString::upToLast(const VerySimpleReadOnlyString & find, const bool includeFind) const { const unsigned int pos = reverseFind(find); return VerySimpleReadOnlyString(pos == (unsigned int)length && includeFind ? "" : data, includeFind ? (pos == (unsigned int)length ? 0 : pos + (unsigned int)find.length) : pos); }