diff --git a/AK/JsonObject.h b/AK/JsonObject.h index 5b95005495bec6..aa177da18dbd78 100644 --- a/AK/JsonObject.h +++ b/AK/JsonObject.h @@ -41,26 +41,32 @@ class JsonObject { ~JsonObject() {} JsonObject(const JsonObject& other) - : m_members(other.m_members) + : m_order(other.m_order) + , m_members(other.m_members) { } JsonObject(JsonObject&& other) - : m_members(move(other.m_members)) + : m_order(move(other.m_order)) + , m_members(move(other.m_members)) { } JsonObject& operator=(const JsonObject& other) { - if (this != &other) + if (this != &other) { m_members = other.m_members; + m_order = other.m_order; + } return *this; } JsonObject& operator=(JsonObject&& other) { - if (this != &other) + if (this != &other) { m_members = move(other.m_members); + m_order = move(other.m_order); + } return *this; } @@ -70,7 +76,7 @@ class JsonObject { JsonValue get(const String& key) const { auto* value = get_ptr(key); - return value ? *value : JsonValue(JsonValue::Type::Undefined); + return value ? *value : JsonValue(JsonValue::Type::Null); } JsonValue get_or(const String& key, JsonValue alternative) const @@ -94,14 +100,17 @@ class JsonObject { void set(const String& key, JsonValue value) { + m_order.append(key); m_members.set(key, move(value)); } template void for_each_member(Callback callback) const { - for (auto& it : m_members) - callback(it.key, it.value); + for (size_t i = 0; i < m_order.size(); ++i) { + auto property = m_order[i]; + callback(property, m_members.get(property).value()); + } } template @@ -113,6 +122,7 @@ class JsonObject { String to_string() const { return serialized(); } private: + Vector m_order; HashMap m_members; }; @@ -193,9 +203,6 @@ inline void JsonValue::serialize(Builder& builder) const case Type::UnsignedInt64: builder.appendf("%llu", as_u64()); break; - case Type::Undefined: - builder.append("undefined"); - break; case Type::Null: builder.append("null"); break; diff --git a/AK/JsonParser.cpp b/AK/JsonParser.cpp index 7a883a8b3adb85..142c797a4792cc 100644 --- a/AK/JsonParser.cpp +++ b/AK/JsonParser.cpp @@ -62,15 +62,16 @@ void JsonParser::consume_whitespace() consume_while([](char ch) { return is_whitespace(ch); }); } -void JsonParser::consume_specific(char expected_ch) +bool JsonParser::consume_specific(char expected_ch) { char consumed_ch = consume(); - ASSERT(consumed_ch == expected_ch); + return consumed_ch == expected_ch; } String JsonParser::consume_quoted_string() { - consume_specific('"'); + if (!consume_specific('"')) + return {}; Vector buffer; for (;;) { @@ -136,7 +137,8 @@ String JsonParser::consume_quoted_string() break; } } - consume_specific('"'); + if (!consume_specific('"')) + return {}; if (buffer.is_empty()) return String::empty(); @@ -151,55 +153,78 @@ String JsonParser::consume_quoted_string() return last_string_starting_with_character; } -JsonObject JsonParser::parse_object() +Optional JsonParser::parse_object() { JsonObject object; - consume_specific('{'); + if (!consume_specific('{')) + return {}; for (;;) { consume_whitespace(); if (peek() == '}') break; consume_whitespace(); auto name = consume_quoted_string(); + if (name.is_null()) + return {}; consume_whitespace(); - consume_specific(':'); + if (!consume_specific(':')) + return {}; consume_whitespace(); - auto value = parse(); - object.set(name, move(value)); + auto value = parse_helper(); + if (!value.has_value()) + return {}; + object.set(name, move(value.value())); consume_whitespace(); if (peek() == '}') break; - consume_specific(','); + if (!consume_specific(',')) + return {}; + consume_whitespace(); + if (peek() == '}') + return {}; } - consume_specific('}'); + if (!consume_specific('}')) + return {}; return object; } -JsonArray JsonParser::parse_array() +Optional JsonParser::parse_array() { JsonArray array; - consume_specific('['); + if (!consume_specific('[')) + return {}; for (;;) { consume_whitespace(); if (peek() == ']') break; - array.append(parse()); + auto element = parse_helper(); + if (!element.has_value()) + return {}; + array.append(element.value()); consume_whitespace(); if (peek() == ']') break; - consume_specific(','); + if (!consume_specific(',')) + return {}; + consume_whitespace(); + if (peek() == ']') + return {}; } consume_whitespace(); - consume_specific(']'); + if (!consume_specific(']')) + return {}; return array; } -JsonValue JsonParser::parse_string() +Optional JsonParser::parse_string() { - return consume_quoted_string(); + auto result = consume_quoted_string(); + if (result.is_null()) + return {}; + return JsonValue(result); } -JsonValue JsonParser::parse_number() +Optional JsonParser::parse_number() { JsonValue value; Vector number_buffer; @@ -235,7 +260,10 @@ JsonValue JsonParser::parse_number() if (to_signed_result.has_value()) { whole = to_signed_result.value(); } else { - whole = number_string.to_int().value(); + auto number = number_string.to_int(); + if (!number.has_value()) + return {}; + whole = number.value(); } int fraction = fraction_string.to_uint().value(); @@ -252,7 +280,10 @@ JsonValue JsonParser::parse_number() if (to_unsigned_result.has_value()) { value = JsonValue(to_unsigned_result.value()); } else { - value = JsonValue(number_string.to_int().value()); + auto number = number_string.to_int(); + if (!number.has_value()) + return {}; + value = JsonValue(number.value()); } #ifndef KERNEL } @@ -261,37 +292,37 @@ JsonValue JsonParser::parse_number() return value; } -void JsonParser::consume_string(const char* str) +bool JsonParser::consume_string(const char* str) { - for (size_t i = 0, length = strlen(str); i < length; ++i) - consume_specific(str[i]); + for (size_t i = 0, length = strlen(str); i < length; ++i) { + if (!consume_specific(str[i])) + return false; + } + return true; } -JsonValue JsonParser::parse_true() +Optional JsonParser::parse_true() { - consume_string("true"); + if (!consume_string("true")) + return {}; return JsonValue(true); } -JsonValue JsonParser::parse_false() +Optional JsonParser::parse_false() { - consume_string("false"); + if (!consume_string("false")) + return {}; return JsonValue(false); } -JsonValue JsonParser::parse_null() +Optional JsonParser::parse_null() { - consume_string("null"); + if (!consume_string("null")) + return {}; return JsonValue(JsonValue::Type::Null); } -JsonValue JsonParser::parse_undefined() -{ - consume_string("undefined"); - return JsonValue(JsonValue::Type::Undefined); -} - -JsonValue JsonParser::parse() +Optional JsonParser::parse_helper() { consume_whitespace(); auto type_hint = peek(); @@ -320,10 +351,19 @@ JsonValue JsonParser::parse() return parse_true(); case 'n': return parse_null(); - case 'u': - return parse_undefined(); } - return JsonValue(); + return {}; +} + +Optional JsonParser::parse() { + auto result = parse_helper(); + if (!result.has_value()) + return {}; + consume_whitespace(); + if (m_index != m_input.length()) + return {}; + return result; } + } diff --git a/AK/JsonParser.h b/AK/JsonParser.h index 3ff321424ca38f..607bab8a6fc879 100644 --- a/AK/JsonParser.h +++ b/AK/JsonParser.h @@ -40,23 +40,24 @@ class JsonParser { { } - JsonValue parse(); + Optional parse(); private: + Optional parse_helper(); + char peek() const; char consume(); void consume_whitespace(); - void consume_specific(char expected_ch); - void consume_string(const char*); + bool consume_specific(char expected_ch); + bool consume_string(const char*); String consume_quoted_string(); - JsonArray parse_array(); - JsonObject parse_object(); - JsonValue parse_number(); - JsonValue parse_string(); - JsonValue parse_false(); - JsonValue parse_true(); - JsonValue parse_null(); - JsonValue parse_undefined(); + Optional parse_array(); + Optional parse_object(); + Optional parse_number(); + Optional parse_string(); + Optional parse_false(); + Optional parse_true(); + Optional parse_null(); template void consume_while(C); diff --git a/AK/JsonValue.cpp b/AK/JsonValue.cpp index 76e65f3f15eac4..8a1bc99f04e2b9 100644 --- a/AK/JsonValue.cpp +++ b/AK/JsonValue.cpp @@ -75,7 +75,7 @@ void JsonValue::copy_from(const JsonValue& other) JsonValue::JsonValue(JsonValue&& other) { - m_type = exchange(other.m_type, Type::Undefined); + m_type = exchange(other.m_type, Type::Null); m_value.as_string = exchange(other.m_value.as_string, nullptr); } @@ -83,7 +83,7 @@ JsonValue& JsonValue::operator=(JsonValue&& other) { if (this != &other) { clear(); - m_type = exchange(other.m_type, Type::Undefined); + m_type = exchange(other.m_type, Type::Null); m_value.as_string = exchange(other.m_value.as_string, nullptr); } return *this; @@ -247,11 +247,11 @@ void JsonValue::clear() default: break; } - m_type = Type::Undefined; + m_type = Type::Null; m_value.as_string = nullptr; } -JsonValue JsonValue::from_string(const StringView& input) +Optional JsonValue::from_string(const StringView& input) { return JsonParser(input).parse(); } diff --git a/AK/JsonValue.h b/AK/JsonValue.h index 5ff6b4be997248..7d3eef87f997bd 100644 --- a/AK/JsonValue.h +++ b/AK/JsonValue.h @@ -37,7 +37,6 @@ namespace AK { class JsonValue { public: enum class Type { - Undefined, Null, Int32, UnsignedInt32, @@ -52,7 +51,7 @@ class JsonValue { Object, }; - static JsonValue from_string(const StringView&); + static Optional from_string(const StringView&); explicit JsonValue(Type = Type::Null); ~JsonValue() { clear(); } @@ -188,7 +187,6 @@ class JsonValue { } bool is_null() const { return m_type == Type::Null; } - bool is_undefined() const { return m_type == Type::Undefined; } bool is_bool() const { return m_type == Type::Bool; } bool is_string() const { return m_type == Type::String; } bool is_i32() const { return m_type == Type::Int32; } @@ -246,7 +244,7 @@ class JsonValue { void clear(); void copy_from(const JsonValue&); - Type m_type { Type::Undefined }; + Type m_type { Type::Null }; union { StringImpl* as_string { nullptr }; diff --git a/AK/Tests/TestJSON.cpp b/AK/Tests/TestJSON.cpp index c8e787d4d47223..87dca328794c1e 100644 --- a/AK/Tests/TestJSON.cpp +++ b/AK/Tests/TestJSON.cpp @@ -48,7 +48,7 @@ TEST_CASE(load_form) fclose(fp); - JsonValue form_json = JsonValue::from_string(builder.to_string()); + JsonValue form_json = JsonValue::from_string(builder.to_string()).value(); EXPECT(form_json.is_object()); @@ -87,14 +87,14 @@ BENCHMARK_CASE(load_4chan_catalog) auto json_string = builder.to_string(); for (int i = 0; i < 10; ++i) { - JsonValue form_json = JsonValue::from_string(json_string); + JsonValue form_json = JsonValue::from_string(json_string).value(); EXPECT(form_json.is_array()); } } TEST_CASE(json_empty_string) { - auto json = JsonValue::from_string("\"\""); + auto json = JsonValue::from_string("\"\"").value(); EXPECT_EQ(json.type(), JsonValue::Type::String); EXPECT_EQ(json.as_string().is_null(), false); EXPECT_EQ(json.as_string().is_empty(), true); @@ -102,7 +102,7 @@ TEST_CASE(json_empty_string) TEST_CASE(json_utf8_character) { - auto json = JsonValue::from_string("\"\xc3\x84\""); + auto json = JsonValue::from_string("\"\xc3\x84\"").value(); EXPECT_EQ(json.type(), JsonValue::Type::String); EXPECT_EQ(json.as_string().is_null(), false); EXPECT_EQ(json.as_string().length(), size_t { 2 }); diff --git a/Applications/SystemMonitor/DevicesModel.cpp b/Applications/SystemMonitor/DevicesModel.cpp index 69091402cc686f..5777d0f601b8c5 100644 --- a/Applications/SystemMonitor/DevicesModel.cpp +++ b/Applications/SystemMonitor/DevicesModel.cpp @@ -127,10 +127,11 @@ void DevicesModel::update() if (!proc_devices->open(Core::IODevice::OpenMode::ReadOnly)) ASSERT_NOT_REACHED(); - auto json = JsonValue::from_string(proc_devices->read_all()).as_array(); + auto json = JsonValue::from_string(proc_devices->read_all()); + ASSERT(json.has_value()); m_devices.clear(); - json.for_each([this](auto& value) { + json.value().as_array().for_each([this](auto& value) { JsonObject device = value.as_object(); DeviceInfo device_info; diff --git a/Applications/SystemMonitor/MemoryStatsWidget.cpp b/Applications/SystemMonitor/MemoryStatsWidget.cpp index c9ebacc2687f97..89bd77fdc49709 100644 --- a/Applications/SystemMonitor/MemoryStatsWidget.cpp +++ b/Applications/SystemMonitor/MemoryStatsWidget.cpp @@ -98,7 +98,9 @@ void MemoryStatsWidget::refresh() ASSERT_NOT_REACHED(); auto file_contents = proc_memstat->read_all(); - auto json = JsonValue::from_string(file_contents).as_object(); + auto json_result = JsonValue::from_string(file_contents); + ASSERT(json_result.has_value()); + auto json = json_result.value().as_object(); unsigned kmalloc_eternal_allocated = json.get("kmalloc_eternal_allocated").to_u32(); (void)kmalloc_eternal_allocated; diff --git a/DevTools/FormCompiler/main.cpp b/DevTools/FormCompiler/main.cpp index 0ccafa31ce8929..7113f510fc709b 100644 --- a/DevTools/FormCompiler/main.cpp +++ b/DevTools/FormCompiler/main.cpp @@ -46,7 +46,9 @@ int main(int argc, char** argv) } auto file_contents = file->read_all(); - auto json = JsonValue::from_string(file_contents); + auto json_result = JsonValue::from_string(file_contents); + ASSERT(json_result.has_value()); + auto json = json_result.value(); if (!json.is_object()) { fprintf(stderr, "Malformed input\n"); diff --git a/DevTools/Inspector/RemoteProcess.cpp b/DevTools/Inspector/RemoteProcess.cpp index d1ceb61c3dfd79..6e8dce589497ae 100644 --- a/DevTools/Inspector/RemoteProcess.cpp +++ b/DevTools/Inspector/RemoteProcess.cpp @@ -167,11 +167,12 @@ void RemoteProcess::update() dbg() << "Got data size " << length << " and read that many bytes"; auto json_value = JsonValue::from_string(data); - ASSERT(json_value.is_object()); + ASSERT(json_value.has_value()); + ASSERT(json_value.value().is_object()); - dbg() << "Got JSON response " << json_value.to_string(); + dbg() << "Got JSON response " << json_value.value().to_string(); - auto& response = json_value.as_object(); + auto& response = json_value.value().as_object(); auto response_type = response.get("type").as_string_or({}); if (response_type.is_null()) diff --git a/DevTools/ProfileViewer/Profile.cpp b/DevTools/ProfileViewer/Profile.cpp index 435bfd28105314..32c966bbb5c63c 100644 --- a/DevTools/ProfileViewer/Profile.cpp +++ b/DevTools/ProfileViewer/Profile.cpp @@ -172,12 +172,13 @@ OwnPtr Profile::load_from_perfcore_file(const StringView& path) } auto json = JsonValue::from_string(file->read_all()); - if (!json.is_object()) { + ASSERT(json.has_value()); + if (!json.value().is_object()) { fprintf(stderr, "Invalid perfcore format (not a JSON object)\n"); return nullptr; } - auto& object = json.as_object(); + auto& object = json.value().as_object(); auto executable_path = object.get("executable").to_string(); MappedFile elf_file(executable_path); diff --git a/DevTools/VisualBuilder/VBForm.cpp b/DevTools/VisualBuilder/VBForm.cpp index 7bd247c1882830..6f813a4e5554c8 100644 --- a/DevTools/VisualBuilder/VBForm.cpp +++ b/DevTools/VisualBuilder/VBForm.cpp @@ -389,14 +389,15 @@ void VBForm::load_from_file(const String& path) auto file_contents = file->read_all(); auto form_json = JsonValue::from_string(file_contents); + ASSERT(form_json.has_value()); - if (!form_json.is_object()) { + if (!form_json.value().is_object()) { GUI::MessageBox::show(String::format("Could not parse '%s'", path.characters()), "Error", GUI::MessageBox::Type::Error, GUI::MessageBox::InputType::OK, window()); return; } - m_name = form_json.as_object().get("name").to_string(); - auto widgets = form_json.as_object().get("widgets").as_array(); + m_name = form_json.value().as_object().get("name").to_string(); + auto widgets = form_json.value().as_object().get("widgets").as_array(); widgets.for_each([&](const JsonValue& widget_value) { auto& widget_object = widget_value.as_object(); diff --git a/Libraries/LibCore/EventLoop.cpp b/Libraries/LibCore/EventLoop.cpp index ebf457a3b87c65..a35da46b8b8015 100644 --- a/Libraries/LibCore/EventLoop.cpp +++ b/Libraries/LibCore/EventLoop.cpp @@ -105,13 +105,13 @@ class RPCClient : public Object { auto request = m_socket->read(length); auto request_json = JsonValue::from_string(request); - if (!request_json.is_object()) { + if (!request_json.has_value() || !request_json.value().is_object()) { dbg() << "RPC client sent invalid request"; shutdown(); return; } - handle_request(request_json.as_object()); + handle_request(request_json.value().as_object()); }; } virtual ~RPCClient() override diff --git a/Libraries/LibCore/ProcessStatisticsReader.cpp b/Libraries/LibCore/ProcessStatisticsReader.cpp index 13936b9f15b484..b9a55eb0c33fa1 100644 --- a/Libraries/LibCore/ProcessStatisticsReader.cpp +++ b/Libraries/LibCore/ProcessStatisticsReader.cpp @@ -48,7 +48,8 @@ HashMap ProcessStatisticsReader::get_all() auto file_contents = file->read_all(); auto json = JsonValue::from_string(file_contents); - json.as_array().for_each([&](auto& value) { + ASSERT(json.has_value()); + json.value().as_array().for_each([&](auto& value) { const JsonObject& process_object = value.as_object(); Core::ProcessStatistics process; diff --git a/Libraries/LibGUI/JsonArrayModel.cpp b/Libraries/LibGUI/JsonArrayModel.cpp index fee86003ea3e50..e845602c145fb1 100644 --- a/Libraries/LibGUI/JsonArrayModel.cpp +++ b/Libraries/LibGUI/JsonArrayModel.cpp @@ -42,8 +42,9 @@ void JsonArrayModel::update() auto json = JsonValue::from_string(file->read_all()); - ASSERT(json.is_array()); - m_array = json.as_array(); + ASSERT(json.has_value()); + ASSERT(json.value().is_array()); + m_array = json.value().as_array(); did_update(); } diff --git a/Libraries/LibKeyboard/CharacterMapFile.cpp b/Libraries/LibKeyboard/CharacterMapFile.cpp index c1ee2fa5b6bbd9..eb50e7f876629a 100644 --- a/Libraries/LibKeyboard/CharacterMapFile.cpp +++ b/Libraries/LibKeyboard/CharacterMapFile.cpp @@ -48,7 +48,9 @@ Optional CharacterMapFile::load_from_file(const String& file_n } auto file_contents = file->read_all(); - auto json = JsonValue::from_string(file_contents).as_object(); + auto json_result = JsonValue::from_string(file_contents); + ASSERT(json_result.has_value()); + auto json = json_result.value().as_object(); ByteBuffer map = read_map(json, "map"); ByteBuffer shift_map = read_map(json, "shift_map"); diff --git a/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_cpp.cpp b/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_cpp.cpp index 9891d6bae43c99..7fab48f81d8b42 100644 --- a/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_cpp.cpp +++ b/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_cpp.cpp @@ -56,7 +56,8 @@ int main(int argc, char** argv) return 1; auto json = JsonValue::from_string(file->read_all()); - ASSERT(json.is_object()); + ASSERT(json.has_value()); + ASSERT(json.value().is_object()); out() << "#include "; out() << "#include "; @@ -65,7 +66,7 @@ int main(int argc, char** argv) out() << "PropertyID property_id_from_string(const StringView& string) {"; - json.as_object().for_each_member([&](auto& name, auto& value) { + json.value().as_object().for_each_member([&](auto& name, auto& value) { ASSERT(value.is_object()); out() << " if (string.equals_ignoring_case(\"" << name << "\"))"; out() << " return PropertyID::" << title_casify(name) << ";"; @@ -77,7 +78,7 @@ int main(int argc, char** argv) out() << "const char* string_from_property_id(PropertyID property_id) {"; out() << " switch (property_id) {"; - json.as_object().for_each_member([&](auto& name, auto& value) { + json.value().as_object().for_each_member([&](auto& name, auto& value) { ASSERT(value.is_object()); out() << " case PropertyID::" << title_casify(name) << ":"; out() << " return \"" << name << "\";"; diff --git a/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_h.cpp b/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_h.cpp index 04cd3d9278c693..1dbf80d9a30e75 100644 --- a/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_h.cpp +++ b/Libraries/LibWeb/CodeGenerators/Generate_CSS_PropertyID_h.cpp @@ -56,7 +56,8 @@ int main(int argc, char** argv) return 1; auto json = JsonValue::from_string(file->read_all()); - ASSERT(json.is_object()); + ASSERT(json.has_value()); + ASSERT(json.value().is_object()); out() << "#pragma once"; out() << "#include "; @@ -67,7 +68,7 @@ int main(int argc, char** argv) out() << "enum class PropertyID {"; out() << " Invalid,"; - json.as_object().for_each_member([&](auto& name, auto& value) { + json.value().as_object().for_each_member([&](auto& name, auto& value) { ASSERT(value.is_object()); out() << " " << title_casify(name) << ","; }); diff --git a/MenuApplets/ResourceGraph/main.cpp b/MenuApplets/ResourceGraph/main.cpp index d982d9f9e9e20f..2bea1acabc0351 100644 --- a/MenuApplets/ResourceGraph/main.cpp +++ b/MenuApplets/ResourceGraph/main.cpp @@ -140,9 +140,10 @@ class GraphWidget final : public GUI::Frame { ASSERT_NOT_REACHED(); auto file_contents = proc_memstat->read_all(); - auto json = JsonValue::from_string(file_contents).as_object(); - unsigned user_physical_allocated = json.get("user_physical_allocated").to_u32(); - unsigned user_physical_available = json.get("user_physical_available").to_u32(); + auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); + unsigned user_physical_allocated = json.value().as_object().get("user_physical_allocated").to_u32(); + unsigned user_physical_available = json.value().as_object().get("user_physical_available").to_u32(); allocated = (user_physical_allocated * 4096) / 1024; available = (user_physical_available * 4096) / 1024; } diff --git a/Meta/Lagom/TestJson.cpp b/Meta/Lagom/TestJson.cpp index 4c8891f0d9911f..e149daddf62e66 100644 --- a/Meta/Lagom/TestJson.cpp +++ b/Meta/Lagom/TestJson.cpp @@ -31,7 +31,8 @@ int main(int, char**) { auto value = JsonValue::from_string("{\"property\": \"value\"}"); - printf("parsed: _%s_\n", value.to_string().characters()); - printf("object.property = '%s'\n", value.as_object().get("property").to_string().characters()); + ASSERT(value.has_value()); + printf("parsed: _%s_\n", value.value().to_string().characters()); + printf("object.property = '%s'\n", value.value().as_object().get("property").to_string().characters()); return 0; } diff --git a/Services/DHCPClient/main.cpp b/Services/DHCPClient/main.cpp index b65b63eb469f4b..33e7d7e2e8baac 100644 --- a/Services/DHCPClient/main.cpp +++ b/Services/DHCPClient/main.cpp @@ -77,9 +77,10 @@ int main(int argc, char** argv) } auto file_contents = file->read_all(); - auto json = JsonValue::from_string(file_contents).as_array(); + auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); Vector ifnames; - json.for_each([&ifnames](auto& value) { + json.value().as_array().for_each([&ifnames](auto& value) { auto if_object = value.as_object(); if (if_object.get("class_name").to_string() == "LoopbackAdapter") diff --git a/Userland/arp.cpp b/Userland/arp.cpp index 700302f73e8e7e..9f3149409a94bf 100644 --- a/Userland/arp.cpp +++ b/Userland/arp.cpp @@ -39,8 +39,9 @@ int main() printf("Address HWaddress\n"); auto file_contents = file->read_all(); - auto json = JsonValue::from_string(file_contents).as_array(); - json.for_each([](auto& value) { + auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); + json.value().as_array().for_each([](auto& value) { auto if_object = value.as_object(); auto ip_address = if_object.get("ip_address").to_string(); diff --git a/Userland/df.cpp b/Userland/df.cpp index 9cf1def128855d..a8a65958679190 100644 --- a/Userland/df.cpp +++ b/Userland/df.cpp @@ -86,7 +86,9 @@ int main(int argc, char** argv) } auto file_contents = file->read_all(); - auto json = JsonValue::from_string(file_contents).as_array(); + auto json_result = JsonValue::from_string(file_contents); + ASSERT(json_result.has_value()); + auto json = json_result.value().as_array(); json.for_each([](auto& value) { auto fs_object = value.as_object(); auto fs = fs_object.get("class_name").to_string(); diff --git a/Userland/gron.cpp b/Userland/gron.cpp index 877327d417c9ed..f473fabbbc1f68 100644 --- a/Userland/gron.cpp +++ b/Userland/gron.cpp @@ -74,6 +74,7 @@ int main(int argc, char** argv) auto file_contents = file->read_all(); auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); if (use_color) { color_name = "\033[33;1m"; @@ -86,7 +87,7 @@ int main(int argc, char** argv) } Vector trail; - print("json", json, trail); + print("json", json.value(), trail); return 0; } @@ -116,7 +117,6 @@ static void print(const String& name, const JsonValue& value, Vector& tr } switch (value.type()) { case JsonValue::Type::Null: - case JsonValue::Type::Undefined: printf("%s", color_null); break; case JsonValue::Type::Bool: diff --git a/Userland/ifconfig.cpp b/Userland/ifconfig.cpp index 65fc7f5a985896..9711fa8ccb21be 100644 --- a/Userland/ifconfig.cpp +++ b/Userland/ifconfig.cpp @@ -72,8 +72,9 @@ int main(int argc, char** argv) } auto file_contents = file->read_all(); - auto json = JsonValue::from_string(file_contents).as_array(); - json.for_each([](auto& value) { + auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); + json.value().as_array().for_each([](auto& value) { auto if_object = value.as_object(); auto name = if_object.get("name").to_string(); diff --git a/Userland/jp.cpp b/Userland/jp.cpp index 75f8df2ab531a2..436eb97d2befa8 100644 --- a/Userland/jp.cpp +++ b/Userland/jp.cpp @@ -63,8 +63,9 @@ int main(int argc, char** argv) auto file_contents = file->read_all(); auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); - print(json); + print(json.value()); printf("\n"); return 0; @@ -101,7 +102,7 @@ void print(const JsonValue& value, int indent) printf("\033[35;1m"); else if (value.is_bool()) printf("\033[32;1m"); - else if (value.is_null() || value.is_undefined()) + else if (value.is_null()) printf("\033[34;1m"); if (value.is_string()) putchar('"'); diff --git a/Userland/lsirq.cpp b/Userland/lsirq.cpp index 51a670c551a01b..5273142363e55a 100644 --- a/Userland/lsirq.cpp +++ b/Userland/lsirq.cpp @@ -60,8 +60,9 @@ int main(int argc, char** argv) printf("%4s %-10s\n", " ", "CPU0"); auto file_contents = proc_interrupts->read_all(); - auto json = JsonValue::from_string(file_contents).as_array(); - json.for_each([](auto& value) { + auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); + json.value().as_array().for_each([](auto& value) { auto handler = value.as_object(); auto purpose = handler.get("purpose").to_string(); auto interrupt = handler.get("interrupt_line").to_string(); diff --git a/Userland/lspci.cpp b/Userland/lspci.cpp index 8b80be2a548b5c..fefbf95085f3ed 100644 --- a/Userland/lspci.cpp +++ b/Userland/lspci.cpp @@ -69,8 +69,9 @@ int main(int argc, char** argv) } auto file_contents = proc_pci->read_all(); - auto json = JsonValue::from_string(file_contents).as_array(); - json.for_each([db](auto& value) { + auto json = JsonValue::from_string(file_contents); + ASSERT(json.has_value()); + json.value().as_array().for_each([db](auto& value) { auto dev = value.as_object(); auto seg = dev.get("seg").to_u32(); auto bus = dev.get("bus").to_u32(); diff --git a/Userland/mount.cpp b/Userland/mount.cpp index da75ea5e9ac763..697c37768679e6 100644 --- a/Userland/mount.cpp +++ b/Userland/mount.cpp @@ -149,9 +149,10 @@ bool print_mounts() } auto content = df->read_all(); - auto json = JsonValue::from_string(content).as_array(); + auto json = JsonValue::from_string(content); + ASSERT(json.has_value()); - json.for_each([](auto& value) { + json.value().as_array().for_each([](auto& value) { auto fs_object = value.as_object(); auto class_name = fs_object.get("class_name").to_string(); auto mount_point = fs_object.get("mount_point").to_string();