1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-08 05:27:14 +09:00

AK+Everywhere: Store JSON strings as String

This commit is contained in:
Timothy Flynn 2025-02-17 13:21:07 -05:00 committed by Tim Flynn
parent e591636419
commit bc54c0cdfb
Notes: github-actions[bot] 2025-02-21 00:29:21 +00:00
33 changed files with 163 additions and 152 deletions

View file

@ -116,11 +116,17 @@ Optional<bool> JsonObject::get_bool(StringView key) const
return {};
}
Optional<String const&> JsonObject::get_string(StringView key) const
{
if (auto value = get(key); value.has_value() && value->is_string())
return value->as_string();
return {};
}
Optional<ByteString> JsonObject::get_byte_string(StringView key) const
{
auto maybe_value = get(key);
if (maybe_value.has_value() && maybe_value->is_string())
return maybe_value->as_string();
if (auto value = get_string(key); value.has_value())
return value->to_byte_string();
return {};
}

View file

@ -76,6 +76,7 @@ public:
Optional<FlatPtr> get_addr(StringView key) const;
Optional<bool> get_bool(StringView key) const;
Optional<String const&> get_string(StringView key) const;
Optional<ByteString> get_byte_string(StringView key) const;
Optional<JsonObject&> get_object(StringView key);
@ -144,7 +145,7 @@ inline void JsonValue::serialize(Builder& builder) const
[&](Empty const&) { builder.append("null"sv); },
[&](bool const& value) { builder.append(value ? "true"sv : "false"sv); },
[&](Arithmetic auto const& value) { builder.appendff("{}", value); },
[&](ByteString const& value) {
[&](String const& value) {
builder.append('\"');
builder.append_escaped_for_json(value.bytes());
builder.append('\"');

View file

@ -57,7 +57,7 @@ public:
return {};
}
ErrorOr<void> add(StringView key, ByteString const& value)
ErrorOr<void> add(StringView key, String const& value)
{
TRY(begin_item(key));
if constexpr (IsLegacyBuilder<Builder>) {

View file

@ -153,17 +153,17 @@ JsonValue::JsonValue(long long unsigned value)
}
JsonValue::JsonValue(double value)
: m_value(double { value })
{
}
JsonValue::JsonValue(ByteString const& value)
: m_value(value)
{
}
JsonValue::JsonValue(String value)
: m_value(move(value))
{
}
JsonValue::JsonValue(StringView value)
: m_value(ByteString { value })
: m_value(MUST(String::from_utf8(value)))
{
}

View file

@ -7,10 +7,10 @@
#pragma once
#include <AK/ByteString.h>
#include <AK/Forward.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/StringBuilder.h>
namespace AK {
@ -32,7 +32,7 @@ public:
i64,
u64,
double,
ByteString,
String,
NonnullOwnPtr<JsonArray>,
NonnullOwnPtr<JsonObject>>;
@ -53,9 +53,9 @@ public:
JsonValue(long unsigned);
JsonValue(long long);
JsonValue(long long unsigned);
JsonValue(double);
JsonValue(ByteString const&);
JsonValue(String);
JsonValue(StringView);
template<typename T>
@ -119,9 +119,9 @@ public:
return m_value.get<bool>();
}
ByteString const& as_string() const
String const& as_string() const
{
return m_value.get<ByteString>();
return m_value.get<String>();
}
JsonObject& as_object()
@ -155,14 +155,14 @@ public:
[](Empty const&) { return Type::Null; },
[](bool const&) { return Type::Bool; },
[](Arithmetic auto const&) { return Type::Number; },
[](ByteString const&) { return Type::String; },
[](String const&) { return Type::String; },
[](NonnullOwnPtr<JsonArray> const&) { return Type::Array; },
[](NonnullOwnPtr<JsonObject> const&) { return Type::Object; });
}
bool is_null() const { return m_value.has<Empty>(); }
bool is_bool() const { return m_value.has<bool>(); }
bool is_string() const { return m_value.has<ByteString>(); }
bool is_string() const { return m_value.has<String>(); }
bool is_array() const { return m_value.has<NonnullOwnPtr<JsonArray>>(); }
bool is_object() const { return m_value.has<NonnullOwnPtr<JsonObject>>(); }
bool is_number() const

View file

@ -749,7 +749,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, ReadonlySpan<
auto write_completion = [&](auto format, auto& option, auto has_invariant, auto... args) {
JsonObject object;
object.set("completion"sv, ByteString::formatted(StringView { format, strlen(format) }, args...));
object.set("completion"sv, MUST(String::formatted(StringView { format, strlen(format) }, args...)));
object.set("static_offset"sv, 0);
object.set("invariant_offset"sv, has_invariant ? option_to_complete.length() : 0u);
object.set("display_trivia"sv, StringView { option.help_string, strlen(option.help_string) });

View file

@ -11,9 +11,10 @@
namespace DevTools {
// FIXME: Convert `name` to a String.
Actor::Actor(DevToolsServer& devtools, ByteString name)
: m_devtools(devtools)
, m_name(move(name))
, m_name(MUST(String::from_byte_string(name)))
{
}
@ -36,7 +37,7 @@ void Actor::send_missing_parameter_error(StringView parameter)
JsonObject error;
error.set("from"sv, name());
error.set("error"sv, "missingParameter"sv);
error.set("message"sv, ByteString::formatted("Missing parameter: '{}'", parameter));
error.set("message"sv, MUST(String::formatted("Missing parameter: '{}'", parameter)));
send_message(move(error));
}
@ -46,7 +47,7 @@ void Actor::send_unrecognized_packet_type_error(StringView type)
JsonObject error;
error.set("from"sv, name());
error.set("error"sv, "unrecognizedPacketType"sv);
error.set("message"sv, ByteString::formatted("Unrecognized packet type: '{}'", type));
error.set("message"sv, MUST(String::formatted("Unrecognized packet type: '{}'", type)));
send_message(move(error));
}
@ -57,7 +58,7 @@ void Actor::send_unknown_actor_error(StringView actor)
JsonObject error;
error.set("from"sv, name());
error.set("error"sv, "unknownActor"sv);
error.set("message"sv, ByteString::formatted("Unknown actor: '{}'", actor));
error.set("message"sv, MUST(String::formatted("Unknown actor: '{}'", actor)));
send_message(move(error));
}

View file

@ -10,6 +10,7 @@
#include <AK/ByteString.h>
#include <AK/Optional.h>
#include <AK/RefCounted.h>
#include <AK/String.h>
#include <AK/StringView.h>
#include <AK/Vector.h>
#include <AK/WeakPtr.h>
@ -24,7 +25,7 @@ class Actor
public:
virtual ~Actor();
ByteString const& name() const { return m_name; }
String const& name() const { return m_name; }
virtual void handle_message(StringView type, JsonObject const&) = 0;
class [[nodiscard]] BlockToken {
@ -57,7 +58,7 @@ protected:
private:
DevToolsServer& m_devtools;
ByteString m_name;
String m_name;
Vector<JsonValue> m_blocked_responses;
bool m_block_responses { false };

View file

@ -36,7 +36,7 @@ void CSSPropertiesActor::handle_message(StringView type, JsonObject const&)
for (auto const& css_property : css_property_list) {
JsonArray subproperties;
subproperties.must_append(css_property.name);
subproperties.must_append(MUST(String::from_byte_string(css_property.name)));
JsonObject property;
property.set("isInherited"sv, css_property.is_inherited);

View file

@ -27,16 +27,16 @@ DeviceActor::~DeviceActor() = default;
void DeviceActor::handle_message(StringView type, JsonObject const&)
{
if (type == "getDescription"sv) {
auto build_id = Core::Version::read_long_version_string().to_byte_string();
auto build_id = Core::Version::read_long_version_string();
static constexpr auto browser_name = StringView { BROWSER_NAME, __builtin_strlen(BROWSER_NAME) };
static constexpr auto browser_version = StringView { BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) };
static constexpr auto platform_name = StringView { OS_STRING, __builtin_strlen(OS_STRING) };
static constexpr auto arch = StringView { CPU_STRING, __builtin_strlen(CPU_STRING) };
static auto browser_name = String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) });
static auto browser_version = String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) });
static auto platform_name = String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) });
static auto arch = String::from_utf8_without_validation({ CPU_STRING, __builtin_strlen(CPU_STRING) });
// https://github.com/mozilla/gecko-dev/blob/master/devtools/shared/system.js
JsonObject value;
value.set("apptype"sv, browser_name.to_lowercase_string());
value.set("apptype"sv, browser_name.to_ascii_lowercase());
value.set("name"sv, browser_name);
value.set("brandName"sv, browser_name);
value.set("version"sv, browser_version);

View file

@ -50,8 +50,8 @@ void FrameActor::send_frame_update_message()
if (auto tab_actor = m_tab.strong_ref()) {
JsonObject frame;
frame.set("id"sv, tab_actor->description().id);
frame.set("title"sv, tab_actor->description().title);
frame.set("url"sv, tab_actor->description().url);
frame.set("title"sv, MUST(String::from_byte_string(tab_actor->description().title)));
frame.set("url"sv, MUST(String::from_byte_string(tab_actor->description().url)));
frames.must_append(move(frame));
}
@ -76,8 +76,8 @@ JsonObject FrameActor::serialize_target() const
target.set("actor"sv, name());
if (auto tab_actor = m_tab.strong_ref()) {
target.set("title"sv, tab_actor->description().title);
target.set("url"sv, tab_actor->description().url);
target.set("title"sv, MUST(String::from_byte_string(tab_actor->description().title)));
target.set("url"sv, MUST(String::from_byte_string(tab_actor->description().url)));
target.set("browsingContextID"sv, tab_actor->description().id);
target.set("outerWindowID"sv, tab_actor->description().id);
target.set("isTopLevelTarget"sv, true);

View file

@ -57,9 +57,9 @@ void RootActor::handle_message(StringView type, JsonObject const& message)
for (auto const& actor : devtools().actor_registry()) {
if (is<DeviceActor>(*actor.value))
response.set("deviceActor"sv, actor.key);
response.set("deviceActor"sv, MUST(String::from_byte_string(actor.key)));
else if (is<PreferenceActor>(*actor.value))
response.set("preferenceActor"sv, actor.key);
response.set("preferenceActor"sv, MUST(String::from_byte_string(actor.key)));
}
send_message(move(response));

View file

@ -60,8 +60,8 @@ JsonObject TabActor::serialize_description() const
// provide different IDs for browserId, browsingContextID, and outerWindowID.
JsonObject description;
description.set("actor"sv, name());
description.set("title"sv, m_description.title);
description.set("url"sv, m_description.url);
description.set("title"sv, MUST(String::from_byte_string(m_description.title)));
description.set("url"sv, MUST(String::from_byte_string(m_description.url)));
description.set("browserId"sv, m_description.id);
description.set("browsingContextID"sv, m_description.id);
description.set("outerWindowID"sv, m_description.id);

View file

@ -135,12 +135,12 @@ JsonValue WalkerActor::serialize_node(JsonObject const& node) const
if (!tab)
return {};
auto actor = node.get_byte_string("actor"sv);
auto actor = node.get_string("actor"sv);
if (!actor.has_value())
return {};
auto name = node.get_byte_string("name"sv).release_value();
auto type = node.get_byte_string("type"sv).release_value();
auto name = node.get_string("name"sv).release_value();
auto type = node.get_string("type"sv).release_value();
auto dom_type = Web::DOM::NodeType::INVALID;
JsonValue node_value;
@ -157,12 +157,12 @@ JsonValue WalkerActor::serialize_node(JsonObject const& node) const
} else if (type == "text"sv) {
dom_type = Web::DOM::NodeType::TEXT_NODE;
if (auto text = node.get_byte_string("text"sv); text.has_value())
if (auto text = node.get_string("text"sv); text.has_value())
node_value = text.release_value();
} else if (type == "comment"sv) {
dom_type = Web::DOM::NodeType::COMMENT_NODE;
if (auto data = node.get_byte_string("data"sv); data.has_value())
if (auto data = node.get_string("data"sv); data.has_value())
node_value = data.release_value();
} else if (type == "shadow-root"sv) {
is_shadow_root = true;
@ -180,7 +180,7 @@ JsonValue WalkerActor::serialize_node(JsonObject const& node) const
return;
JsonObject attr;
attr.set("name"sv, name.to_byte_string());
attr.set("name"sv, name);
attr.set("value"sv, value.as_string());
attrs.must_append(move(attr));
});
@ -189,10 +189,10 @@ JsonValue WalkerActor::serialize_node(JsonObject const& node) const
JsonObject serialized;
serialized.set("actor"sv, actor.release_value());
serialized.set("attrs"sv, move(attrs));
serialized.set("baseURI"sv, tab->description().url);
serialized.set("baseURI"sv, MUST(String::from_byte_string(tab->description().url)));
serialized.set("causesOverflow"sv, false);
serialized.set("containerType"sv, JsonValue {});
serialized.set("displayName"sv, name.to_lowercase());
serialized.set("displayName"sv, name.to_ascii_lowercase());
serialized.set("displayType"sv, "block"sv);
serialized.set("host"sv, JsonValue {});
serialized.set("isAfterPseudoElement"sv, false);
@ -216,7 +216,7 @@ JsonValue WalkerActor::serialize_node(JsonObject const& node) const
if (!is_top_level_document) {
if (auto parent = m_dom_node_to_parent_map.get(&node); parent.has_value() && parent.value()) {
actor = parent.value()->get_byte_string("actor"sv);
actor = parent.value()->get_string("actor"sv);
if (!actor.has_value())
return {};
@ -255,8 +255,8 @@ void WalkerActor::populate_dom_tree_cache(JsonObject& node, JsonObject const* pa
{
m_dom_node_to_parent_map.set(&node, parent);
auto actor = ByteString::formatted("{}-node{}", name(), m_dom_node_count++);
m_actor_to_dom_node_map.set(actor, &node);
auto actor = MUST(String::formatted("{}-node{}", name(), m_dom_node_count++));
m_actor_to_dom_node_map.set(actor.to_byte_string(), &node);
node.set("actor"sv, actor);
auto children = node.get_array("children"sv);

View file

@ -176,7 +176,7 @@ public:
for (auto& it : m_graph) {
AK::JsonArray edges;
for (auto const& value : it.value.edges) {
edges.must_append(ByteString::formatted("{}", value));
edges.must_append(MUST(String::formatted("{}", value)));
}
auto node = AK::JsonObject();
@ -185,7 +185,7 @@ public:
auto location = it.value.root_origin->location;
switch (type) {
case HeapRoot::Type::Root:
node.set("root"sv, ByteString::formatted("Root {} {}:{}", location->function_name(), location->filename(), location->line_number()));
node.set("root"sv, MUST(String::formatted("Root {} {}:{}", location->function_name(), location->filename(), location->line_number())));
break;
case HeapRoot::Type::RootVector:
node.set("root"sv, "RootVector"sv);

View file

@ -68,7 +68,7 @@ JS::ThrowCompletionOr<JsonWebKey> JsonWebKey::parse(JS::Realm& realm, ReadonlyBy
key.key_ops->ensure_capacity(key_ops->size());
key_ops->for_each([&](auto const& value) {
key.key_ops->append(MUST(String::from_byte_string(value.as_string())));
key.key_ops->append(value.as_string());
});
}

View file

@ -235,9 +235,9 @@ static bool matches_platform_name(StringView requested_platform_name, StringView
// https://w3c.github.io/webdriver/#dfn-matching-capabilities
static JsonValue match_capabilities(JsonObject const& capabilities, SessionFlags flags)
{
static auto browser_name = StringView { BROWSER_NAME, strlen(BROWSER_NAME) }.to_lowercase_string();
static constexpr auto browser_version = StringView { BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) };
static auto platform_name = StringView { OS_STRING, strlen(OS_STRING) }.to_lowercase_string();
static auto browser_name = String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) }).to_ascii_lowercase();
static auto browser_version = String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) });
static auto platform_name = String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) }).to_ascii_lowercase();
// 1. Let matched capabilities be a JSON Object with the following entries:
JsonObject matched_capabilities;
@ -283,7 +283,7 @@ static JsonValue match_capabilities(JsonObject const& capabilities, SessionFlags
// -> "browserName"
if (name == "browserName"sv) {
// If value is not a string equal to the "browserName" entry in matched capabilities, return success with data null.
if (value.as_string() != matched_capabilities.get_byte_string(name).value())
if (value.as_string() != matched_capabilities.get_string(name).value())
return AK::Error::from_string_literal("browserName");
}
// -> "browserVersion"

View file

@ -329,8 +329,8 @@ ErrorOr<void, Client::WrappedError> Client::send_error_response(HTTP::HttpReques
auto reason = HTTP::HttpResponse::reason_phrase_for_code(error.http_status);
JsonObject error_response;
error_response.set("error"sv, error.error);
error_response.set("message"sv, error.message);
error_response.set("error"sv, MUST(String::from_byte_string(error.error)));
error_response.set("message"sv, MUST(String::from_byte_string(error.message)));
error_response.set("stacktrace"sv, ""sv);
if (error.data.has_value())
error_response.set("data"sv, *error.data);

View file

@ -39,7 +39,7 @@ JsonObject window_proxy_reference_object(HTML::WindowProxy const& window)
// identifier
// Associated window handle of the windows browsing context.
object.set(identifier, navigable->traversable_navigable()->window_handle().to_byte_string());
object.set(identifier, navigable->traversable_navigable()->window_handle());
return object;
}

View file

@ -132,7 +132,7 @@ JsonObject web_element_reference_object(HTML::BrowsingContext const& browsing_co
// 3. Return a JSON Object initialized with a property with name identifier and value reference.
JsonObject object;
object.set(identifier, reference);
object.set(identifier, MUST(String::from_byte_string(reference)));
return object;
}
@ -422,7 +422,7 @@ JsonObject shadow_root_reference_object(HTML::BrowsingContext const& browsing_co
// 3. Return a JSON Object initialized with a property with name identifier and value reference.
JsonObject object;
object.set(identifier, reference);
object.set(identifier, MUST(String::from_byte_string(reference)));
return object;
}

View file

@ -40,7 +40,7 @@ static ErrorOr<PropertyType, WebDriver::Error> get_property(JsonObject const& pa
if constexpr (IsSame<PropertyType, ByteString>) {
if (!property->is_string())
return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a String", key));
return property->as_string();
return property->as_string().to_byte_string();
} else if constexpr (IsSame<PropertyType, bool>) {
if (!property->is_bool())
return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a Boolean", key));

View file

@ -655,7 +655,7 @@ String InspectorClient::generate_dom_tree(JsonObject const& dom_tree)
builder.appendff("<span class=\"attribute-value\">\"{}\"</span>", escape_html_entities(value_string));
builder.append("</span>"sv);
dom_node_attributes.empend(name, MUST(String::from_byte_string(value_string)));
dom_node_attributes.empend(name, value_string);
});
}

View file

@ -128,7 +128,7 @@ Optional<@name:titlecase@> keyword_to_@name:snakecase@(Keyword keyword)
auto member_generator = enum_generator.fork();
auto member_name = member.as_string();
if (member_name.contains('=')) {
auto parts = member_name.split_view('=');
auto parts = MUST(member_name.split('='));
member_generator.set("valueid:titlecase", title_casify(parts[0]));
member_generator.set("member:titlecase", title_casify(parts[1]));
} else {

View file

@ -182,7 +182,7 @@ bool media_feature_accepts_type(MediaFeatureID media_feature_id, MediaFeatureVal
VERIFY(type.is_string());
auto type_name = type.as_string();
// Skip keywords.
if (type_name[0] != '<')
if (!type_name.starts_with('<'))
continue;
if (type_name == "<mq-boolean>") {
append_value_type_switch_if_needed();
@ -258,9 +258,9 @@ bool media_feature_accepts_keyword(MediaFeatureID media_feature_id, Keyword keyw
auto& values_array = values.value();
for (auto& keyword : values_array.values()) {
VERIFY(keyword.is_string());
auto keyword_name = keyword.as_string();
auto const& keyword_name = keyword.as_string();
// Skip types.
if (keyword_name[0] == '<')
if (keyword_name.starts_with('<'))
continue;
append_keyword_switch_if_needed();

View file

@ -91,7 +91,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
void replace_logical_aliases(JsonObject& properties)
{
AK::HashMap<String, ByteString> logical_aliases;
AK::HashMap<String, String> logical_aliases;
properties.for_each_member([&](auto& name, auto& value) {
VERIFY(value.is_object());
auto const& value_as_object = value.as_object();
@ -319,7 +319,7 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @
return;
if (auto maybe_valid_types = value.as_object().get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) {
for (auto valid_type : maybe_valid_types->values()) {
auto type_and_range = valid_type.as_string().split_view(' ');
auto type_and_range = MUST(valid_type.as_string().split(' '));
if (type_and_range.first() != css_type_name)
continue;
@ -333,9 +333,9 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @
if (type_and_range.size() > 1) {
auto range = type_and_range[1];
VERIFY(range.starts_with('[') && range.ends_with(']') && range.contains(','));
auto comma_index = range.find(',').value();
StringView min_value_string = range.substring_view(1, comma_index - 1);
StringView max_value_string = range.substring_view(comma_index + 1, range.length() - comma_index - 2);
auto comma_index = range.find_byte_offset(',').value();
StringView min_value_string = range.bytes_as_string_view().substring_view(1, comma_index - 1);
StringView max_value_string = range.bytes_as_string_view().substring_view(comma_index + 1, range.byte_count() - comma_index - 2);
// If the min/max value is infinite, we can just skip that side of the check.
if (min_value_string == "-∞")
@ -782,7 +782,7 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type)
bool did_output_accepted_type = false;
for (auto& type : valid_types.values()) {
VERIFY(type.is_string());
auto type_name = type.as_string().split_view(' ').first();
auto type_name = MUST(type.as_string().split(' ')).first();
if (type_name_is_enum(type_name))
continue;
@ -888,7 +888,7 @@ bool property_accepts_keyword(PropertyID property_id, Keyword keyword)
if (auto maybe_valid_types = object.get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) {
auto& valid_types = maybe_valid_types.value();
for (auto& valid_type : valid_types.values()) {
auto type_name = valid_type.as_string().split_view(' ').first();
auto type_name = MUST(valid_type.as_string().split(' ')).first();
if (!type_name_is_enum(type_name))
continue;

View file

@ -171,7 +171,7 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor
JsonArray const& parameters = value.as_object().get_array("parameters"sv).value();
bool first = true;
parameters.for_each([&](JsonValue const& value) {
GenericLexer lexer { value.as_object().get_byte_string("type"sv).value() };
GenericLexer lexer { value.as_object().get_string("type"sv).value() };
VERIFY(lexer.consume_specific('<'));
auto parameter_type_name = lexer.consume_until('>');
VERIFY(lexer.consume_specific('>'));

View file

@ -83,10 +83,10 @@ namespace WebContent {
static JsonValue serialize_cookie(Web::Cookie::Cookie const& cookie)
{
JsonObject serialized_cookie;
serialized_cookie.set("name"sv, cookie.name.to_byte_string());
serialized_cookie.set("value"sv, cookie.value.to_byte_string());
serialized_cookie.set("path"sv, cookie.path.to_byte_string());
serialized_cookie.set("domain"sv, cookie.domain.to_byte_string());
serialized_cookie.set("name"sv, cookie.name);
serialized_cookie.set("value"sv, cookie.value);
serialized_cookie.set("path"sv, cookie.path);
serialized_cookie.set("domain"sv, cookie.domain);
serialized_cookie.set("secure"sv, cookie.secure);
serialized_cookie.set("httpOnly"sv, cookie.http_only);
serialized_cookie.set("expiry"sv, cookie.expiry_time.seconds_since_epoch());
@ -346,7 +346,7 @@ Messages::WebDriverClient::GetCurrentUrlResponse WebDriverConnection::get_curren
auto url = current_top_level_browsing_context()->active_document()->url();
// 4. Return success with data url.
async_driver_execution_complete({ url.to_byte_string() });
async_driver_execution_complete({ url.to_string() });
});
return JsonValue {};
@ -529,7 +529,7 @@ Messages::WebDriverClient::GetTitleResponse WebDriverConnection::get_title()
auto title = current_top_level_browsing_context()->active_document()->title();
// 4. Return success with data title.
async_driver_execution_complete({ title.to_byte_string() });
async_driver_execution_complete({ move(title) });
});
return JsonValue {};
@ -1323,7 +1323,7 @@ Messages::WebDriverClient::GetElementAttributeResponse WebDriverConnection::get_
}
// 5. Return success with data result.
async_driver_execution_complete({ result.to_byte_string() });
async_driver_execution_complete({ move(result) });
});
return JsonValue {};
@ -1389,7 +1389,7 @@ Messages::WebDriverClient::GetElementCssValueResponse WebDriverConnection::get_e
// "" (empty string)
// 5. Return success with data computed value.
async_driver_execution_complete({ computed_value.to_byte_string() });
async_driver_execution_complete({ move(computed_value) });
});
return JsonValue {};
@ -1411,7 +1411,7 @@ Messages::WebDriverClient::GetElementTextResponse WebDriverConnection::get_eleme
auto rendered_text = Web::WebDriver::element_rendered_text(element);
// 5. Return success with data rendered text.
async_driver_execution_complete({ rendered_text.to_byte_string() });
async_driver_execution_complete({ move(rendered_text) });
});
return JsonValue {};
@ -1434,7 +1434,7 @@ Messages::WebDriverClient::GetElementTagNameResponse WebDriverConnection::get_el
auto qualified_name = element->local_name();
// 5. Return success with data qualified name.
async_driver_execution_complete({ qualified_name.to_string().to_byte_string() });
async_driver_execution_complete({ qualified_name.to_string() });
});
return JsonValue {};
@ -1541,7 +1541,7 @@ Messages::WebDriverClient::GetComputedLabelResponse WebDriverConnection::get_com
auto label = element->accessible_name(element->document()).release_value_but_fixme_should_propagate_errors();
// 5. Return success with data label.
async_driver_execution_complete({ label.to_byte_string() });
async_driver_execution_complete({ move(label) });
});
return JsonValue {};
@ -2047,7 +2047,7 @@ Messages::WebDriverClient::GetSourceResponse WebDriverConnection::get_source()
source = MUST(document->serialize_fragment(Web::DOMParsing::RequireWellFormed::No));
// 5. Return success with data source.
async_driver_execution_complete({ source->to_byte_string() });
async_driver_execution_complete({ source.release_value() });
});
return JsonValue {};
@ -2465,7 +2465,7 @@ Messages::WebDriverClient::GetAlertTextResponse WebDriverConnection::get_alert_t
// 4. Return success with data message.
if (message.has_value())
return message->to_byte_string();
return message.value();
return JsonValue {};
}
@ -2679,7 +2679,7 @@ static Web::WebDriver::Error create_annotated_unexpected_alert_open_error(Option
// The current user prompt's message.
auto data = text.map([&](auto const& text) -> JsonValue {
JsonObject data;
data.set("text"sv, text.to_byte_string());
data.set("text"sv, text);
return data;
});

View file

@ -131,7 +131,7 @@ Web::WebDriver::Response Client::get_status(Web::WebDriver::Parameters, JsonValu
// An implementation-defined string explaining the remote end's readiness state.
JsonObject body;
body.set("ready"sv, readiness_state);
body.set("message"sv, ByteString::formatted("{} to accept a new session", readiness_state ? "Ready"sv : "Not ready"sv));
body.set("message"sv, MUST(String::formatted("{} to accept a new session", readiness_state ? "Ready"sv : "Not ready"sv)));
// 2. Return success with data body.
return JsonValue { body };

View file

@ -221,7 +221,7 @@ ErrorOr<NonnullRefPtr<Core::LocalServer>> Session::create_server(NonnullRefPtr<S
return;
}
auto window_handle = MUST(String::from_byte_string(maybe_window_handle.value().as_string()));
auto const& window_handle = maybe_window_handle.value().as_string();
web_content_connection->on_close = [this, window_handle]() {
dbgln_if(WEBDRIVER_DEBUG, "Window {} was closed remotely.", window_handle);

View file

@ -66,7 +66,7 @@ TEST_CASE(json_string)
{
auto json = JsonValue::from_string("\"A\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().length(), size_t { 1 });
EXPECT_EQ(json.as_string().byte_count(), size_t { 1 });
EXPECT_EQ(json.as_string() == "A", true);
}
@ -74,7 +74,7 @@ TEST_CASE(json_utf8_character)
{
auto json = JsonValue::from_string("\"\\u0041\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().length(), size_t { 1 });
EXPECT_EQ(json.as_string().byte_count(), size_t { 1 });
EXPECT_EQ(json.as_string() == "A", true);
}
@ -83,19 +83,19 @@ TEST_CASE(json_encoded_surrogates)
{
auto json = JsonValue::from_string("\"\\uD83E\\uDD13\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().length(), 4u);
EXPECT_EQ(json.as_string().byte_count(), 4u);
EXPECT_EQ(json.as_string(), "🤓"sv);
}
{
auto json = JsonValue::from_string("\"\\uD83E\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().length(), 3u);
EXPECT_EQ(json.as_string().byte_count(), 3u);
EXPECT_EQ(json.as_string(), "\xED\xA0\xBE"sv);
}
{
auto json = JsonValue::from_string("\"\\uDD13\""sv).value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().length(), 3u);
EXPECT_EQ(json.as_string().byte_count(), 3u);
EXPECT_EQ(json.as_string(), "\xED\xB4\x93"sv);
}
}
@ -110,7 +110,7 @@ TEST_CASE(json_utf8_multibyte)
auto& json = json_or_error.value();
EXPECT_EQ(json.type(), JsonValue::Type::String);
EXPECT_EQ(json.as_string().length(), size_t { 2 });
EXPECT_EQ(json.as_string().byte_count(), size_t { 2 });
EXPECT_EQ(json.as_string() == "š", true);
EXPECT_EQ(json.as_string() == "\xc5\xa1", true);
}

View file

@ -317,8 +317,8 @@ void write_per_file(HashMap<size_t, TestResult> const& result_map, Vector<ByteSt
result_object.set(paths[test], name_for_result(value));
JsonObject complete_results {};
complete_results.set("duration", time_taken_in_ms / 1000.);
complete_results.set("results", result_object);
complete_results.set("duration"sv, time_taken_in_ms / 1000.);
complete_results.set("results"sv, result_object);
if (file->write_until_depleted(complete_results.to_byte_string()).is_error())
warnln("Failed to write per-file");

View file

@ -46,8 +46,8 @@ enum class NegativePhase {
struct TestError {
NegativePhase phase { NegativePhase::ParseOrEarly };
ByteString type;
ByteString details;
String type;
String details;
ByteString harness_file;
};
@ -60,8 +60,8 @@ static ErrorOr<ScriptOrModuleProgram, TestError> parse_program(JS::Realm& realm,
if (script_or_error.is_error()) {
return TestError {
NegativePhase::ParseOrEarly,
"SyntaxError",
script_or_error.error()[0].to_byte_string(),
"SyntaxError"_string,
script_or_error.error()[0].to_string(),
""
};
}
@ -92,22 +92,22 @@ static ErrorOr<void, TestError> run_program(InterpreterT& interpreter, ScriptOrM
auto name = object.get_without_side_effects("name");
if (!name.is_empty() && !name.is_accessor()) {
error.type = name.to_string_without_side_effects().to_byte_string();
error.type = name.to_string_without_side_effects();
} else {
auto constructor = object.get_without_side_effects("constructor");
if (constructor.is_object()) {
name = constructor.as_object().get_without_side_effects("name");
if (!name.is_undefined())
error.type = name.to_string_without_side_effects().to_byte_string();
error.type = name.to_string_without_side_effects();
}
}
auto message = object.get_without_side_effects("message");
if (!message.is_empty() && !message.is_accessor())
error.details = message.to_string_without_side_effects().to_byte_string();
error.details = message.to_string_without_side_effects();
}
if (error.type.is_empty())
error.type = error_value.to_string_without_side_effects().to_byte_string();
error.type = error_value.to_string_without_side_effects();
return error;
}
return {};
@ -136,8 +136,8 @@ static ErrorOr<StringView, TestError> read_harness_file(StringView harness_file)
if (cache.is_error()) {
return TestError {
NegativePhase::Harness,
"filesystem",
ByteString::formatted("Could not read file: {}", harness_file),
"filesystem"_string,
MUST(String::formatted("Could not read file: {}", harness_file)),
harness_file
};
}
@ -202,8 +202,8 @@ static ErrorOr<void, TestError> run_test(StringView source, StringView filepath,
if (parser.has_errors()) {
return TestError {
NegativePhase::ParseOrEarly,
"SyntaxError",
parser.errors()[0].to_byte_string(),
"SyntaxError"_string,
parser.errors()[0].to_string(),
""
};
}
@ -250,14 +250,14 @@ static ErrorOr<void, TestError> run_test(StringView source, StringView filepath,
return run_program(vm->bytecode_interpreter(), program);
}
static ErrorOr<TestMetadata, ByteString> extract_metadata(StringView source)
static ErrorOr<TestMetadata, String> extract_metadata(StringView source)
{
auto lines = source.lines();
TestMetadata metadata;
bool parsing_negative = false;
ByteString failed_message;
String failed_message;
auto parse_list = [&](StringView line) {
auto start = line.find('[');
@ -268,7 +268,7 @@ static ErrorOr<TestMetadata, ByteString> extract_metadata(StringView source)
auto end = line.find_last(']');
if (!end.has_value() || end.value() <= start.value()) {
failed_message = ByteString::formatted("Can't parse list in '{}'", line);
failed_message = MUST(String::formatted("Can't parse list in '{}'", line));
return items;
}
@ -281,7 +281,7 @@ static ErrorOr<TestMetadata, ByteString> extract_metadata(StringView source)
auto second_word = [&](StringView line) {
auto separator = line.find(' ');
if (!separator.has_value() || separator.value() >= (line.length() - 1u)) {
failed_message = ByteString::formatted("Can't parse value after space in '{}'", line);
failed_message = MUST(String::formatted("Can't parse value after space in '{}'", line));
return ""sv;
}
return line.substring_view(separator.value() + 1);
@ -311,7 +311,7 @@ static ErrorOr<TestMetadata, ByteString> extract_metadata(StringView source)
continue;
} else {
if (include_list.is_empty()) {
failed_message = "Supposed to parse a list but found no entries";
failed_message = "Supposed to parse a list but found no entries"_string;
break;
}
@ -335,18 +335,18 @@ static ErrorOr<TestMetadata, ByteString> extract_metadata(StringView source)
metadata.phase = NegativePhase::Runtime;
} else {
has_phase = false;
failed_message = ByteString::formatted("Unknown negative phase: {}", phase);
failed_message = MUST(String::formatted("Unknown negative phase: {}", phase));
break;
}
} else if (line.starts_with("type:"sv)) {
metadata.type = second_word(line);
} else {
if (!has_phase) {
failed_message = "Failed to find phase in negative attributes";
failed_message = "Failed to find phase in negative attributes"_string;
break;
}
if (metadata.type.is_empty()) {
failed_message = "Failed to find type in negative attributes";
failed_message = "Failed to find type in negative attributes"_string;
break;
}
@ -392,7 +392,7 @@ static ErrorOr<TestMetadata, ByteString> extract_metadata(StringView source)
}
if (failed_message.is_empty())
failed_message = ByteString::formatted("Never reached end of comment '---*/'");
failed_message = MUST(String::formatted("Never reached end of comment '---*/'"));
return failed_message;
}
@ -402,13 +402,13 @@ static bool verify_test(ErrorOr<void, TestError>& result, TestMetadata const& me
if (result.is_error()) {
if (result.error().phase == NegativePhase::Harness) {
output.set("harness_error"sv, true);
output.set("harness_file"sv, result.error().harness_file);
output.set("harness_file"sv, String::from_utf8_with_replacement_character(result.error().harness_file));
output.set("result"sv, "harness_error"sv);
} else if (result.error().phase == NegativePhase::Runtime) {
auto& error_type = result.error().type;
auto& error_details = result.error().details;
if ((error_type == "InternalError"sv && error_details.starts_with("TODO("sv))
|| (error_type == "Test262Error"sv && error_details.ends_with(" but got a InternalError"sv))) {
if ((error_type == "InternalError"sv && error_details.starts_with_bytes("TODO("sv))
|| (error_type == "Test262Error"sv && error_details.ends_with_bytes(" but got a InternalError"sv))) {
output.set("todo_error"sv, true);
output.set("result"sv, "todo_error"sv);
}
@ -467,7 +467,7 @@ static bool verify_test(ErrorOr<void, TestError>& result, TestMetadata const& me
JsonObject expected_error_object;
expected_error_object.set("phase"sv, phase_to_string(metadata.phase));
expected_error_object.set("type"sv, metadata.type.to_byte_string());
expected_error_object.set("type"sv, metadata.type);
expected_error = expected_error_object;
@ -528,7 +528,7 @@ static bool g_in_assert = false;
// immediately stop if we are already in a failed assert.
g_in_assert = true;
JsonObject assert_fail_result;
assert_fail_result.set("test"sv, s_current_test);
assert_fail_result.set("test"sv, String::from_utf8_with_replacement_character(s_current_test));
assert_fail_result.set("assert_fail"sv, true);
assert_fail_result.set("result"sv, "assert_fail"sv);
assert_fail_result.set("output"sv, StringView { assert_failed_message, strlen(assert_failed_message) });
@ -741,7 +741,7 @@ int main(int argc, char** argv)
if (metadata_or_error.is_error()) {
result_object.set("result"sv, "metadata_error"sv);
result_object.set("metadata_error"sv, true);
result_object.set("metadata_output"sv, metadata_or_error.error());
result_object.set("metadata_output"sv, metadata_or_error.release_error());
continue;
}
@ -762,7 +762,7 @@ int main(int argc, char** argv)
auto first_output = collect_output();
if (first_output.has_value())
result_object.set("output"sv, *first_output);
result_object.set("output"sv, String::from_utf8_with_replacement_character(*first_output));
passed = verify_test(result, metadata, result_object);
auto output = first_output.value_or("");
@ -786,7 +786,7 @@ int main(int argc, char** argv)
auto first_output = collect_output();
if (first_output.has_value())
result_object.set("strict_output"sv, *first_output);
result_object.set("strict_output"sv, String::from_utf8_with_replacement_character(*first_output));
passed = verify_test(result, metadata, result_object);
auto output = first_output.value_or("");

View file

@ -45,7 +45,7 @@ ErrorOr<Vector<String>> AutoComplete::parse_google_autocomplete(Vector<JsonValue
if (!json[0].is_string())
return Error::from_string_literal("Invalid JSON, expected first element to be a string");
auto query = TRY(String::from_byte_string(json[0].as_string()));
auto query = json[0].as_string();
if (!json[1].is_array())
return Error::from_string_literal("Invalid JSON, expected second element to be an array");
@ -57,7 +57,7 @@ ErrorOr<Vector<String>> AutoComplete::parse_google_autocomplete(Vector<JsonValue
Vector<String> results;
results.ensure_capacity(suggestions_array.size());
for (auto& suggestion : suggestions_array)
results.unchecked_append(MUST(String::from_byte_string(suggestion.as_string())));
results.unchecked_append(suggestion.as_string());
return results;
}
@ -65,11 +65,13 @@ ErrorOr<Vector<String>> AutoComplete::parse_google_autocomplete(Vector<JsonValue
ErrorOr<Vector<String>> AutoComplete::parse_duckduckgo_autocomplete(Vector<JsonValue> const& json)
{
Vector<String> results;
for (auto const& suggestion : json) {
auto maybe_value = suggestion.as_object().get("phrase"sv);
if (!maybe_value.has_value())
continue;
results.append(MUST(String::from_byte_string(maybe_value->as_string())));
if (!suggestion.is_object())
return Error::from_string_literal("Invalid JSON, expected value to be an object");
if (auto value = suggestion.as_object().get_string("phrase"sv); !value.has_value())
results.append(*value);
}
return results;
@ -77,28 +79,28 @@ ErrorOr<Vector<String>> AutoComplete::parse_duckduckgo_autocomplete(Vector<JsonV
ErrorOr<Vector<String>> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
{
if (!json.get("q"sv).has_value() || !json.get("q"sv)->is_string())
auto query = json.get_string("q"sv);
if (!query.has_value())
return Error::from_string_view("Invalid JSON, expected \"q\" to be a string"sv);
auto query = TRY(String::from_byte_string(json.get("q"sv)->as_string()));
if (!json.get("r"sv).has_value() || !json.get("r"sv)->is_array())
return Error::from_string_view("Invalid JSON, expected \"r\" to be an object"sv);
auto suggestions_object = json.get("r"sv)->as_array().values();
if (query != m_query)
return Error::from_string_literal("Invalid JSON, query does not match");
Vector<String> results;
results.ensure_capacity(suggestions_object.size());
for (auto& suggestion_object : suggestions_object) {
if (!suggestion_object.is_object())
return Error::from_string_literal("Invalid JSON, expected value to be an object");
auto suggestion = suggestion_object.as_object();
auto suggestions = json.get_array("r"sv);
if (!suggestions.has_value())
return Error::from_string_view("Invalid JSON, expected \"r\" to be an object"sv);
if (!suggestion.get("k"sv).has_value() || !suggestion.get("k"sv)->is_string())
Vector<String> results;
results.ensure_capacity(suggestions->size());
for (auto const& suggestion : suggestions->values()) {
if (!suggestion.is_object())
return Error::from_string_literal("Invalid JSON, expected value to be an object");
auto result = suggestion.as_object().get_string("k"sv);
if (!result.has_value())
return Error::from_string_view("Invalid JSON, expected \"k\" to be a string"sv);
results.unchecked_append(MUST(String::from_byte_string(suggestion.get("k"sv)->as_string())));
results.unchecked_append(*result);
}
return results;