2024-11-11 10:49:00 +01:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2024, stelar7 <dudedbz@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <LibWeb/IndexedDB/Internal/Key.h>
|
|
|
|
|
#include <LibWeb/Infra/ByteSequences.h>
|
|
|
|
|
#include <LibWeb/Infra/Strings.h>
|
|
|
|
|
|
|
|
|
|
namespace Web::IndexedDB {
|
|
|
|
|
|
2025-01-08 23:09:56 +01:00
|
|
|
|
GC_DEFINE_ALLOCATOR(Key);
|
|
|
|
|
|
|
|
|
|
Key::~Key() = default;
|
|
|
|
|
|
|
|
|
|
GC::Ref<Key> Key::create(JS::Realm& realm, KeyType key, KeyValue value)
|
|
|
|
|
{
|
|
|
|
|
return realm.create<Key>(key, value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-11 10:49:00 +01:00
|
|
|
|
// https://w3c.github.io/IndexedDB/#compare-two-keys
|
2025-01-08 23:09:56 +01:00
|
|
|
|
i8 Key::compare_two_keys(GC::Ref<Key> a, GC::Ref<Key> b)
|
2024-11-11 10:49:00 +01:00
|
|
|
|
{
|
|
|
|
|
// 1. Let ta be the type of a.
|
2025-01-08 23:09:56 +01:00
|
|
|
|
auto ta = a->type();
|
2024-11-11 10:49:00 +01:00
|
|
|
|
|
|
|
|
|
// 2. Let tb be the type of b.
|
2025-01-08 23:09:56 +01:00
|
|
|
|
auto tb = b->type();
|
2024-11-11 10:49:00 +01:00
|
|
|
|
|
|
|
|
|
// 3. If ta does not equal tb, then run these steps:
|
|
|
|
|
if (ta != tb) {
|
|
|
|
|
// 1. If ta is array, then return 1.
|
|
|
|
|
if (ta == KeyType::Array)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 1. If tb is array, then return -1.
|
|
|
|
|
if (tb == KeyType::Array)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 1. If ta is binary, then return 1.
|
|
|
|
|
if (ta == KeyType::Binary)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 1. If tb is binary, then return -1.
|
|
|
|
|
if (tb == KeyType::Binary)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 1. If ta is string, then return 1.
|
|
|
|
|
if (ta == KeyType::String)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 1. If tb is string, then return -1.
|
|
|
|
|
if (tb == KeyType::String)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 1. If ta is date, then return 1.
|
|
|
|
|
if (ta == KeyType::Date)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 1. Assert: tb is date.
|
|
|
|
|
VERIFY(tb == KeyType::Date);
|
|
|
|
|
|
|
|
|
|
// 1. Return -1.
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. Let va be the value of a.
|
2025-01-08 23:09:56 +01:00
|
|
|
|
auto va = a->value();
|
2024-11-11 10:49:00 +01:00
|
|
|
|
|
|
|
|
|
// 5. Let vb be the value of b.
|
2025-01-08 23:09:56 +01:00
|
|
|
|
auto vb = b->value();
|
2024-11-11 10:49:00 +01:00
|
|
|
|
|
|
|
|
|
// 6. Switch on ta:
|
|
|
|
|
switch (ta) {
|
2025-04-25 17:59:06 +02:00
|
|
|
|
case KeyType::Invalid:
|
|
|
|
|
VERIFY_NOT_REACHED();
|
2024-11-11 10:49:00 +01:00
|
|
|
|
// number
|
|
|
|
|
// date
|
|
|
|
|
case KeyType::Number:
|
|
|
|
|
case KeyType::Date: {
|
|
|
|
|
auto a_value = va.get<double>();
|
|
|
|
|
auto b_value = vb.get<double>();
|
|
|
|
|
|
|
|
|
|
// 1. If va is greater than vb, then return 1.
|
|
|
|
|
if (a_value > b_value)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 2. If va is less than vb, then return -1.
|
|
|
|
|
if (a_value < b_value)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 3. Return 0.
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// string
|
|
|
|
|
case KeyType::String: {
|
|
|
|
|
auto a_value = va.get<AK::String>();
|
|
|
|
|
auto b_value = vb.get<AK::String>();
|
|
|
|
|
|
|
|
|
|
// 1. If va is code unit less than vb, then return -1.
|
|
|
|
|
if (Infra::code_unit_less_than(a_value, b_value))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 2. If vb is code unit less than va, then return 1.
|
|
|
|
|
if (Infra::code_unit_less_than(b_value, a_value))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 3. Return 0.
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// binary
|
|
|
|
|
case KeyType::Binary: {
|
|
|
|
|
auto a_value = va.get<ByteBuffer>();
|
|
|
|
|
auto b_value = vb.get<ByteBuffer>();
|
|
|
|
|
|
|
|
|
|
// 1. If va is byte less than vb, then return -1.
|
|
|
|
|
if (Infra::is_byte_less_than(a_value, b_value))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 2. If vb is byte less than va, then return 1.
|
|
|
|
|
if (Infra::is_byte_less_than(b_value, a_value))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 3. Return 0.
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// array
|
|
|
|
|
case KeyType::Array: {
|
2025-01-08 23:09:56 +01:00
|
|
|
|
auto a_value = va.get<Vector<GC::Root<Key>>>();
|
|
|
|
|
auto b_value = vb.get<Vector<GC::Root<Key>>>();
|
2024-11-11 10:49:00 +01:00
|
|
|
|
|
|
|
|
|
// 1. Let length be the lesser of va’s size and vb’s size.
|
|
|
|
|
auto length = min(a_value.size(), b_value.size());
|
|
|
|
|
|
|
|
|
|
// 2. Let i be 0.
|
|
|
|
|
u64 i = 0;
|
|
|
|
|
|
|
|
|
|
// 3. While i is less than length, then:
|
|
|
|
|
while (i < length) {
|
|
|
|
|
// 1. Let c be the result of recursively comparing two keys with va[i] and vb[i].
|
2025-01-08 23:09:56 +01:00
|
|
|
|
auto c = compare_two_keys(*a_value[i], *b_value[i]);
|
2024-11-11 10:49:00 +01:00
|
|
|
|
|
|
|
|
|
// 2. If c is not 0, return c.
|
|
|
|
|
if (c != 0)
|
|
|
|
|
return c;
|
|
|
|
|
|
|
|
|
|
// 3. Increase i by 1.
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. If va’s size is greater than vb’s size, then return 1.
|
|
|
|
|
if (a_value.size() > b_value.size())
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
// 5. If va’s size is less than vb’s size, then return -1.
|
|
|
|
|
if (a_value.size() < b_value.size())
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// 6. Return 0.
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VERIFY_NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-13 15:39:12 +02:00
|
|
|
|
String Key::dump() const
|
|
|
|
|
{
|
|
|
|
|
return m_value.visit(
|
|
|
|
|
[](Vector<GC::Root<Key>> const& value) {
|
|
|
|
|
StringBuilder sb;
|
|
|
|
|
sb.append("["sv);
|
|
|
|
|
for (auto const& key : value) {
|
|
|
|
|
sb.append(key->dump());
|
|
|
|
|
sb.append(", "sv);
|
|
|
|
|
}
|
|
|
|
|
sb.append("]"sv);
|
|
|
|
|
return MUST(sb.to_string());
|
|
|
|
|
},
|
|
|
|
|
[](ByteBuffer const& value) {
|
|
|
|
|
return MUST(String::formatted("{}", value.span()));
|
|
|
|
|
},
|
|
|
|
|
[](auto const& value) {
|
|
|
|
|
return MUST(String::formatted("{}", value));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-11 10:49:00 +01:00
|
|
|
|
}
|