diff options
31 files changed, 428 insertions, 510 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp b/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp index 61b60ea63e..5c6dabe4f7 100644 --- a/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp @@ -369,8 +369,7 @@ public:)~~~"); parameter_generator.set("parameter.initial_value", "{}"); parameter_generator.appendln(R"~~~( - @parameter.type@ @parameter.name@ = @parameter.initial_value@; - TRY(decoder.decode(@parameter.name@));)~~~"); + auto @parameter.name@ = TRY((decoder.decode<@parameter.type@>()));)~~~"); if (parameter.attributes.contains_slow("UTF8")) { parameter_generator.appendln(R"~~~( diff --git a/Userland/DevTools/HackStudio/AutoCompleteResponse.h b/Userland/DevTools/HackStudio/AutoCompleteResponse.h index bee9dd9045..fb612b294d 100644 --- a/Userland/DevTools/HackStudio/AutoCompleteResponse.h +++ b/Userland/DevTools/HackStudio/AutoCompleteResponse.h @@ -27,14 +27,15 @@ inline bool encode(Encoder& encoder, CodeComprehension::AutocompleteResultEntry } template<> -inline ErrorOr<void> decode(Decoder& decoder, CodeComprehension::AutocompleteResultEntry& response) +inline ErrorOr<CodeComprehension::AutocompleteResultEntry> decode(Decoder& decoder) { - TRY(decoder.decode(response.completion)); - TRY(decoder.decode(response.partial_input_length)); - TRY(decoder.decode(response.language)); - TRY(decoder.decode(response.display_text)); - TRY(decoder.decode(response.hide_autocomplete_after_applying)); - return {}; + auto completion = TRY(decoder.decode<DeprecatedString>()); + auto partial_input_length = TRY(decoder.decode<size_t>()); + auto language = TRY(decoder.decode<CodeComprehension::Language>()); + auto display_text = TRY(decoder.decode<DeprecatedString>()); + auto hide_autocomplete_after_applying = TRY(decoder.decode<CodeComprehension::AutocompleteResultEntry::HideAutocompleteAfterApplying>()); + + return CodeComprehension::AutocompleteResultEntry { move(completion), partial_input_length, language, move(display_text), hide_autocomplete_after_applying }; } template<> @@ -47,12 +48,13 @@ inline bool encode(Encoder& encoder, CodeComprehension::ProjectLocation const& l } template<> -inline ErrorOr<void> decode(Decoder& decoder, CodeComprehension::ProjectLocation& location) +inline ErrorOr<CodeComprehension::ProjectLocation> decode(Decoder& decoder) { - TRY(decoder.decode(location.file)); - TRY(decoder.decode(location.line)); - TRY(decoder.decode(location.column)); - return {}; + auto file = TRY(decoder.decode<DeprecatedString>()); + auto line = TRY(decoder.decode<size_t>()); + auto column = TRY(decoder.decode<size_t>()); + + return CodeComprehension::ProjectLocation { move(file), line, column }; } template<> @@ -67,13 +69,14 @@ inline bool encode(Encoder& encoder, CodeComprehension::Declaration const& decla } template<> -inline ErrorOr<void> decode(Decoder& decoder, CodeComprehension::Declaration& declaration) +inline ErrorOr<CodeComprehension::Declaration> decode(Decoder& decoder) { - TRY(decoder.decode(declaration.name)); - TRY(decoder.decode(declaration.position)); - TRY(decoder.decode(declaration.type)); - TRY(decoder.decode(declaration.scope)); - return {}; + auto name = TRY(decoder.decode<DeprecatedString>()); + auto position = TRY(decoder.decode<CodeComprehension::ProjectLocation>()); + auto type = TRY(decoder.decode<CodeComprehension::DeclarationType>()); + auto scope = TRY(decoder.decode<DeprecatedString>()); + + return CodeComprehension::Declaration { move(name), position, type, move(scope) }; } template<> @@ -87,13 +90,14 @@ inline bool encode(Encoder& encoder, CodeComprehension::TodoEntry const& entry) } template<> -inline ErrorOr<void> decode(Decoder& decoder, CodeComprehension::TodoEntry& entry) +inline ErrorOr<CodeComprehension::TodoEntry> decode(Decoder& decoder) { - TRY(decoder.decode(entry.content)); - TRY(decoder.decode(entry.filename)); - TRY(decoder.decode(entry.line)); - TRY(decoder.decode(entry.column)); - return {}; + auto content = TRY(decoder.decode<DeprecatedString>()); + auto filename = TRY(decoder.decode<DeprecatedString>()); + auto line = TRY(decoder.decode<size_t>()); + auto column = TRY(decoder.decode<size_t>()); + + return CodeComprehension::TodoEntry { move(content), move(filename), line, column }; } template<> @@ -109,18 +113,15 @@ inline bool encode(Encoder& encoder, CodeComprehension::TokenInfo const& locatio } template<> -inline ErrorOr<void> decode(Decoder& decoder, CodeComprehension::TokenInfo& entry) +inline ErrorOr<CodeComprehension::TokenInfo> decode(Decoder& decoder) { - u32 semantic_type { 0 }; - static_assert(sizeof(semantic_type) == sizeof(entry.type)); - - TRY(decoder.decode(semantic_type)); - entry.type = static_cast<CodeComprehension::TokenInfo::SemanticType>(semantic_type); - TRY(decoder.decode(entry.start_line)); - TRY(decoder.decode(entry.start_column)); - TRY(decoder.decode(entry.end_line)); - TRY(decoder.decode(entry.end_column)); - return {}; + auto type = TRY(decoder.decode<CodeComprehension::TokenInfo::SemanticType>()); + auto start_line = TRY(decoder.decode<size_t>()); + auto start_column = TRY(decoder.decode<size_t>()); + auto end_line = TRY(decoder.decode<size_t>()); + auto end_column = TRY(decoder.decode<size_t>()); + + return CodeComprehension::TokenInfo { type, start_line, start_column, end_line, end_column }; } } diff --git a/Userland/Libraries/LibCore/AnonymousBuffer.h b/Userland/Libraries/LibCore/AnonymousBuffer.h index 4855b74078..e4784281f2 100644 --- a/Userland/Libraries/LibCore/AnonymousBuffer.h +++ b/Userland/Libraries/LibCore/AnonymousBuffer.h @@ -78,6 +78,6 @@ template<> bool encode(Encoder&, Core::AnonymousBuffer const&); template<> -ErrorOr<void> decode(Decoder&, Core::AnonymousBuffer&); +ErrorOr<Core::AnonymousBuffer> decode(Decoder&); } diff --git a/Userland/Libraries/LibCore/DateTime.h b/Userland/Libraries/LibCore/DateTime.h index fe050a2df3..e605d1f1d9 100644 --- a/Userland/Libraries/LibCore/DateTime.h +++ b/Userland/Libraries/LibCore/DateTime.h @@ -58,6 +58,6 @@ template<> bool encode(Encoder&, Core::DateTime const&); template<> -ErrorOr<void> decode(Decoder&, Core::DateTime&); +ErrorOr<Core::DateTime> decode(Decoder&); } diff --git a/Userland/Libraries/LibCore/Proxy.h b/Userland/Libraries/LibCore/Proxy.h index 66e1d432b0..780114c3fb 100644 --- a/Userland/Libraries/LibCore/Proxy.h +++ b/Userland/Libraries/LibCore/Proxy.h @@ -57,6 +57,6 @@ template<> bool encode(Encoder&, Core::ProxyData const&); template<> -ErrorOr<void> decode(Decoder&, Core::ProxyData&); +ErrorOr<Core::ProxyData> decode(Decoder&); } diff --git a/Userland/Libraries/LibDNS/Answer.cpp b/Userland/Libraries/LibDNS/Answer.cpp index 35fa89b3aa..c8112755de 100644 --- a/Userland/Libraries/LibDNS/Answer.cpp +++ b/Userland/Libraries/LibDNS/Answer.cpp @@ -108,21 +108,16 @@ bool encode(Encoder& encoder, DNS::Answer const& answer) } template<> -ErrorOr<void> decode(Decoder& decoder, DNS::Answer& answer) +ErrorOr<DNS::Answer> decode(Decoder& decoder) { - DeprecatedString name; - TRY(decoder.decode(name)); - u16 record_type, class_code; - TRY(decoder.decode(record_type)); - TRY(decoder.decode(class_code)); - u32 ttl; - TRY(decoder.decode(ttl)); - DeprecatedString record_data; - TRY(decoder.decode(record_data)); - bool cache_flush; - TRY(decoder.decode(cache_flush)); - answer = { { name }, (DNS::RecordType)record_type, (DNS::RecordClass)class_code, ttl, record_data, cache_flush }; - return {}; + auto name = TRY(decoder.decode<DeprecatedString>()); + auto record_type = TRY(decoder.decode<DNS::RecordType>()); + auto class_code = TRY(decoder.decode<DNS::RecordClass>()); + auto ttl = TRY(decoder.decode<u32>()); + auto record_data = TRY(decoder.decode<DeprecatedString>()); + auto cache_flush = TRY(decoder.decode<bool>()); + + return DNS::Answer { name, record_type, class_code, ttl, record_data, cache_flush }; } } diff --git a/Userland/Libraries/LibDNS/Answer.h b/Userland/Libraries/LibDNS/Answer.h index a064013d00..d666562fb0 100644 --- a/Userland/Libraries/LibDNS/Answer.h +++ b/Userland/Libraries/LibDNS/Answer.h @@ -98,6 +98,6 @@ template<> bool encode(Encoder&, DNS::Answer const&); template<> -ErrorOr<void> decode(Decoder&, DNS::Answer&); +ErrorOr<DNS::Answer> decode(Decoder&); } diff --git a/Userland/Libraries/LibGfx/Color.cpp b/Userland/Libraries/LibGfx/Color.cpp index 2438ae3c7f..b8e8da487b 100644 --- a/Userland/Libraries/LibGfx/Color.cpp +++ b/Userland/Libraries/LibGfx/Color.cpp @@ -374,12 +374,10 @@ bool IPC::encode(Encoder& encoder, Color const& color) } template<> -ErrorOr<void> IPC::decode(Decoder& decoder, Color& color) +ErrorOr<Gfx::Color> IPC::decode(Decoder& decoder) { - u32 rgba; - TRY(decoder.decode(rgba)); - color = Color::from_argb(rgba); - return {}; + auto rgba = TRY(decoder.decode<u32>()); + return Gfx::Color::from_argb(rgba); } ErrorOr<void> AK::Formatter<Gfx::Color>::format(FormatBuilder& builder, Gfx::Color value) diff --git a/Userland/Libraries/LibGfx/Color.h b/Userland/Libraries/LibGfx/Color.h index 9458d97036..9fe5b7e5ab 100644 --- a/Userland/Libraries/LibGfx/Color.h +++ b/Userland/Libraries/LibGfx/Color.h @@ -577,6 +577,6 @@ template<> bool encode(Encoder&, Gfx::Color const&); template<> -ErrorOr<void> decode(Decoder&, Gfx::Color&); +ErrorOr<Gfx::Color> decode(Decoder&); } diff --git a/Userland/Libraries/LibGfx/Point.cpp b/Userland/Libraries/LibGfx/Point.cpp index f5a99bf82e..8dd484ca19 100644 --- a/Userland/Libraries/LibGfx/Point.cpp +++ b/Userland/Libraries/LibGfx/Point.cpp @@ -59,14 +59,11 @@ bool encode(Encoder& encoder, Gfx::IntPoint const& point) } template<> -ErrorOr<void> decode(Decoder& decoder, Gfx::IntPoint& point) +ErrorOr<Gfx::IntPoint> decode(Decoder& decoder) { - int x = 0; - int y = 0; - TRY(decoder.decode(x)); - TRY(decoder.decode(y)); - point = { x, y }; - return {}; + auto x = TRY(decoder.decode<int>()); + auto y = TRY(decoder.decode<int>()); + return Gfx::IntPoint { x, y }; } } diff --git a/Userland/Libraries/LibGfx/Point.h b/Userland/Libraries/LibGfx/Point.h index 452bc605dc..ea601edc5e 100644 --- a/Userland/Libraries/LibGfx/Point.h +++ b/Userland/Libraries/LibGfx/Point.h @@ -295,7 +295,7 @@ template<> bool encode(Encoder&, Gfx::IntPoint const&); template<> -ErrorOr<void> decode(Decoder&, Gfx::IntPoint&); +ErrorOr<Gfx::IntPoint> decode(Decoder&); } diff --git a/Userland/Libraries/LibGfx/Rect.cpp b/Userland/Libraries/LibGfx/Rect.cpp index 6c85b50fac..68bbfd4ead 100644 --- a/Userland/Libraries/LibGfx/Rect.cpp +++ b/Userland/Libraries/LibGfx/Rect.cpp @@ -38,14 +38,11 @@ bool encode(Encoder& encoder, Gfx::IntRect const& rect) } template<> -ErrorOr<void> decode(Decoder& decoder, Gfx::IntRect& rect) +ErrorOr<Gfx::IntRect> decode(Decoder& decoder) { - Gfx::IntPoint point; - Gfx::IntSize size; - TRY(decoder.decode(point)); - TRY(decoder.decode(size)); - rect = { point, size }; - return {}; + auto point = TRY(decoder.decode<Gfx::IntPoint>()); + auto size = TRY(decoder.decode<Gfx::IntSize>()); + return Gfx::IntRect { point, size }; } } diff --git a/Userland/Libraries/LibGfx/Rect.h b/Userland/Libraries/LibGfx/Rect.h index a848b73edc..440f4bb885 100644 --- a/Userland/Libraries/LibGfx/Rect.h +++ b/Userland/Libraries/LibGfx/Rect.h @@ -1036,6 +1036,6 @@ template<> bool encode(Encoder&, Gfx::IntRect const&); template<> -ErrorOr<void> decode(Decoder&, Gfx::IntRect&); +ErrorOr<Gfx::IntRect> decode(Decoder&); } diff --git a/Userland/Libraries/LibGfx/ShareableBitmap.cpp b/Userland/Libraries/LibGfx/ShareableBitmap.cpp index 97bc55fd94..a741c3d7e5 100644 --- a/Userland/Libraries/LibGfx/ShareableBitmap.cpp +++ b/Userland/Libraries/LibGfx/ShareableBitmap.cpp @@ -32,7 +32,7 @@ bool encode(Encoder& encoder, Gfx::ShareableBitmap const& shareable_bitmap) encoder << IPC::File(bitmap.anonymous_buffer().fd()); encoder << bitmap.size(); encoder << static_cast<u32>(bitmap.scale()); - encoder << (u32)bitmap.format(); + encoder << static_cast<u32>(bitmap.format()); if (bitmap.is_indexed()) { auto palette = bitmap.palette_to_vector(); encoder << palette; @@ -41,33 +41,28 @@ bool encode(Encoder& encoder, Gfx::ShareableBitmap const& shareable_bitmap) } template<> -ErrorOr<void> decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap) +ErrorOr<Gfx::ShareableBitmap> decode(Decoder& decoder) { - bool valid = false; - TRY(decoder.decode(valid)); - if (!valid) { - shareable_bitmap = {}; - return {}; - } - IPC::File anon_file; - TRY(decoder.decode(anon_file)); - Gfx::IntSize size; - TRY(decoder.decode(size)); - u32 scale; - TRY(decoder.decode(scale)); - u32 raw_bitmap_format; - TRY(decoder.decode(raw_bitmap_format)); + if (auto valid = TRY(decoder.decode<bool>()); !valid) + return Gfx::ShareableBitmap {}; + + auto anon_file = TRY(decoder.decode<IPC::File>()); + auto size = TRY(decoder.decode<Gfx::IntSize>()); + auto scale = TRY(decoder.decode<u32>()); + auto raw_bitmap_format = TRY(decoder.decode<u32>()); if (!Gfx::is_valid_bitmap_format(raw_bitmap_format)) return Error::from_string_literal("IPC: Invalid Gfx::ShareableBitmap format"); - auto bitmap_format = (Gfx::BitmapFormat)raw_bitmap_format; + + auto bitmap_format = static_cast<Gfx::BitmapFormat>(raw_bitmap_format); + Vector<Gfx::ARGB32> palette; - if (Gfx::Bitmap::is_indexed(bitmap_format)) { - TRY(decoder.decode(palette)); - } + if (Gfx::Bitmap::is_indexed(bitmap_format)) + palette = TRY(decoder.decode<decltype(palette)>()); + auto buffer = TRY(Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width() * scale, bitmap_format), size.height() * scale))); auto bitmap = TRY(Gfx::Bitmap::try_create_with_anonymous_buffer(bitmap_format, move(buffer), size, scale, palette)); - shareable_bitmap = Gfx::ShareableBitmap { move(bitmap), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; - return {}; + + return Gfx::ShareableBitmap { move(bitmap), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; } } diff --git a/Userland/Libraries/LibGfx/ShareableBitmap.h b/Userland/Libraries/LibGfx/ShareableBitmap.h index 26c074a297..16e8df9c13 100644 --- a/Userland/Libraries/LibGfx/ShareableBitmap.h +++ b/Userland/Libraries/LibGfx/ShareableBitmap.h @@ -9,6 +9,7 @@ #include <AK/RefPtr.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Size.h> +#include <LibIPC/Forward.h> namespace Gfx { @@ -38,6 +39,6 @@ template<> bool encode(Encoder&, Gfx::ShareableBitmap const&); template<> -ErrorOr<void> decode(Decoder&, Gfx::ShareableBitmap&); +ErrorOr<Gfx::ShareableBitmap> decode(Decoder&); } diff --git a/Userland/Libraries/LibGfx/Size.cpp b/Userland/Libraries/LibGfx/Size.cpp index 718312d052..b737e7af15 100644 --- a/Userland/Libraries/LibGfx/Size.cpp +++ b/Userland/Libraries/LibGfx/Size.cpp @@ -35,14 +35,11 @@ bool encode(Encoder& encoder, Gfx::IntSize const& size) } template<> -ErrorOr<void> decode(Decoder& decoder, Gfx::IntSize& size) +ErrorOr<Gfx::IntSize> decode(Decoder& decoder) { - int width = 0; - int height = 0; - TRY(decoder.decode(width)); - TRY(decoder.decode(height)); - size = { width, height }; - return {}; + auto width = TRY(decoder.decode<int>()); + auto height = TRY(decoder.decode<int>()); + return Gfx::IntSize { width, height }; } } diff --git a/Userland/Libraries/LibGfx/Size.h b/Userland/Libraries/LibGfx/Size.h index ec461de9c2..ff71e7d16a 100644 --- a/Userland/Libraries/LibGfx/Size.h +++ b/Userland/Libraries/LibGfx/Size.h @@ -218,6 +218,6 @@ template<> bool encode(Encoder&, Gfx::IntSize const&); template<> -ErrorOr<void> decode(Decoder&, Gfx::IntSize&); +ErrorOr<Gfx::IntSize> decode(Decoder&); } diff --git a/Userland/Libraries/LibIPC/Concepts.h b/Userland/Libraries/LibIPC/Concepts.h new file mode 100644 index 0000000000..99746e00c8 --- /dev/null +++ b/Userland/Libraries/LibIPC/Concepts.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/HashMap.h> +#include <AK/Optional.h> +#include <AK/Variant.h> +#include <AK/Vector.h> +#include <LibCore/SharedCircularQueue.h> + +#pragma once + +// These concepts are used to help the compiler distinguish between specializations that would be +// ambiguous otherwise. For example, if the specializations for int and Vector<T> were declared as +// follows: +// +// template<> ErrorOr<int> decode(Decoder& decoder); +// template<typename T> ErrorOr<Vector<T>> decode(Decoder& decoder); +// +// Then decode<int>() would be ambiguous because either declaration could work (the compiler would +// not be able to distinguish if you wanted to decode an int or a Vector of int). +namespace IPC::Concepts { + +namespace Detail { + +template<typename T> +constexpr inline bool IsHashMap = false; +template<typename K, typename V> +constexpr inline bool IsHashMap<HashMap<K, V>> = true; +template<typename K, typename V> +constexpr inline bool IsHashMap<OrderedHashMap<K, V>> = true; + +template<typename T> +constexpr inline bool IsOptional = false; +template<typename T> +constexpr inline bool IsOptional<Optional<T>> = true; + +template<typename T> +constexpr inline bool IsSharedSingleProducerCircularQueue = false; +template<typename T, size_t Size> +constexpr inline bool IsSharedSingleProducerCircularQueue<Core::SharedSingleProducerCircularQueue<T, Size>> = true; + +template<typename T> +constexpr inline bool IsVariant = false; +template<typename... Ts> +constexpr inline bool IsVariant<Variant<Ts...>> = true; + +template<typename T> +constexpr inline bool IsVector = false; +template<typename T> +constexpr inline bool IsVector<Vector<T>> = true; + +} + +template<typename T> +concept HashMap = Detail::IsHashMap<T>; + +template<typename T> +concept Optional = Detail::IsOptional<T>; + +template<typename T> +concept SharedSingleProducerCircularQueue = Detail::IsSharedSingleProducerCircularQueue<T>; + +template<typename T> +concept Variant = Detail::IsVariant<T>; + +template<typename T> +concept Vector = Detail::IsVector<T>; + +} diff --git a/Userland/Libraries/LibIPC/Decoder.cpp b/Userland/Libraries/LibIPC/Decoder.cpp index 04ef566e99..50decffea4 100644 --- a/Userland/Libraries/LibIPC/Decoder.cpp +++ b/Userland/Libraries/LibIPC/Decoder.cpp @@ -5,7 +5,6 @@ */ #include <AK/JsonValue.h> -#include <AK/MemoryStream.h> #include <AK/URL.h> #include <LibCore/AnonymousBuffer.h> #include <LibCore/DateTime.h> @@ -17,201 +16,110 @@ namespace IPC { -ErrorOr<void> Decoder::decode(bool& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(u8& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(u16& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(unsigned& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(unsigned long& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(unsigned long long& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(i8& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(i16& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(i32& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(i64& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(float& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(double& value) -{ - m_stream >> value; - return m_stream.try_handle_any_error(); -} - -ErrorOr<void> Decoder::decode(DeprecatedString& value) +template<> +ErrorOr<DeprecatedString> decode(Decoder& decoder) { - i32 length; - TRY(decode(length)); + auto length = TRY(decoder.decode<i32>()); + if (length < 0) + return DeprecatedString {}; + if (length == 0) + return DeprecatedString::empty(); - if (length < 0) { - value = {}; - return {}; - } - if (length == 0) { - value = DeprecatedString::empty(); - return {}; - } char* text_buffer = nullptr; auto text_impl = StringImpl::create_uninitialized(static_cast<size_t>(length), text_buffer); - m_stream >> Bytes { text_buffer, static_cast<size_t>(length) }; - value = *text_impl; - return m_stream.try_handle_any_error(); + + Bytes bytes { text_buffer, static_cast<size_t>(length) }; + TRY(decoder.decode_into(bytes)); + + return DeprecatedString { *text_impl }; } -ErrorOr<void> Decoder::decode(ByteBuffer& value) +template<> +ErrorOr<ByteBuffer> decode(Decoder& decoder) { - i32 length; - TRY(decode(length)); + auto length = TRY(decoder.decode<i32>()); + if (length <= 0) + return ByteBuffer {}; - if (length < 0) { - value = {}; - return {}; - } - if (length == 0) { - value = {}; - return {}; - } + auto buffer = TRY(ByteBuffer::create_uninitialized(length)); + auto bytes = buffer.bytes(); - value = TRY(ByteBuffer::create_uninitialized(length)); - - m_stream >> value.bytes(); - return m_stream.try_handle_any_error(); + TRY(decoder.decode_into(bytes)); + return buffer; } -ErrorOr<void> Decoder::decode(JsonValue& value) +template<> +ErrorOr<JsonValue> decode(Decoder& decoder) { - DeprecatedString string; - TRY(decode(string)); - value = TRY(JsonValue::from_string(string)); - return {}; + auto json = TRY(decoder.decode<DeprecatedString>()); + return JsonValue::from_string(json); } -ErrorOr<void> Decoder::decode(URL& value) +template<> +ErrorOr<URL> decode(Decoder& decoder) { - DeprecatedString string; - TRY(decode(string)); - value = URL(string); - return {}; + auto url = TRY(decoder.decode<DeprecatedString>()); + return URL { url }; } -ErrorOr<void> Decoder::decode(Dictionary& dictionary) +template<> +ErrorOr<Dictionary> decode(Decoder& decoder) { - u64 size; - TRY(decode(size)); - if (size >= (size_t)NumericLimits<i32>::max()) + auto size = TRY(decoder.decode<u64>()); + if (size >= NumericLimits<i32>::max()) VERIFY_NOT_REACHED(); + Dictionary dictionary {}; + for (size_t i = 0; i < size; ++i) { - DeprecatedString key; - TRY(decode(key)); - DeprecatedString value; - TRY(decode(value)); + auto key = TRY(decoder.decode<DeprecatedString>()); + auto value = TRY(decoder.decode<DeprecatedString>()); dictionary.add(move(key), move(value)); } - return {}; + return dictionary; } -ErrorOr<void> Decoder::decode([[maybe_unused]] File& file) +template<> +ErrorOr<File> decode(Decoder& decoder) { - int fd = TRY(m_socket.receive_fd(O_CLOEXEC)); - file = File(fd, File::ConstructWithReceivedFileDescriptor); - return {}; + int fd = TRY(decoder.socket().receive_fd(O_CLOEXEC)); + return File { fd, File::ConstructWithReceivedFileDescriptor }; } template<> -ErrorOr<void> decode(Decoder& decoder, Core::AnonymousBuffer& buffer) +ErrorOr<Empty> decode(Decoder&) { - bool valid; - TRY(decoder.decode(valid)); - if (!valid) { - buffer = {}; - return {}; - } - u32 size; - TRY(decoder.decode(size)); - IPC::File anon_file; - TRY(decoder.decode(anon_file)); - - buffer = TRY(Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size)); - return {}; + return Empty {}; } template<> -ErrorOr<void> decode(Decoder& decoder, Core::DateTime& datetime) +ErrorOr<Core::AnonymousBuffer> decode(Decoder& decoder) { - i64 timestamp; - TRY(decoder.decode(timestamp)); - datetime = Core::DateTime::from_timestamp(static_cast<time_t>(timestamp)); - return {}; + if (auto valid = TRY(decoder.decode<bool>()); !valid) + return Core::AnonymousBuffer {}; + + auto size = TRY(decoder.decode<u32>()); + auto anon_file = TRY(decoder.decode<IPC::File>()); + + return Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size); } template<> -ErrorOr<void> decode(Decoder& decoder, Core::ProxyData& data) +ErrorOr<Core::DateTime> decode(Decoder& decoder) { - UnderlyingType<decltype(data.type)> type; - TRY(decoder.decode(type)); - data.type = static_cast<Core::ProxyData::Type>(type); - TRY(decoder.decode(data.host_ipv4)); - TRY(decoder.decode(data.port)); - return {}; + auto timestamp = TRY(decoder.decode<i64>()); + return Core::DateTime::from_timestamp(static_cast<time_t>(timestamp)); } -// No-op. -ErrorOr<void> Decoder::decode(AK::Empty&) +template<> +ErrorOr<Core::ProxyData> decode(Decoder& decoder) { - return {}; + auto type = TRY(decoder.decode<Core::ProxyData::Type>()); + auto host_ipv4 = TRY(decoder.decode<u32>()); + auto port = TRY(decoder.decode<int>()); + + return Core::ProxyData { type, host_ipv4, port }; } } diff --git a/Userland/Libraries/LibIPC/Decoder.h b/Userland/Libraries/LibIPC/Decoder.h index 1cc3902a58..ad636f1b8c 100644 --- a/Userland/Libraries/LibIPC/Decoder.h +++ b/Userland/Libraries/LibIPC/Decoder.h @@ -9,6 +9,7 @@ #include <AK/Concepts.h> #include <AK/DeprecatedString.h> #include <AK/Forward.h> +#include <AK/MemoryStream.h> #include <AK/NumericLimits.h> #include <AK/StdLibExtras.h> #include <AK/Try.h> @@ -16,6 +17,7 @@ #include <AK/Variant.h> #include <LibCore/SharedCircularQueue.h> #include <LibCore/Stream.h> +#include <LibIPC/Concepts.h> #include <LibIPC/File.h> #include <LibIPC/Forward.h> #include <LibIPC/Message.h> @@ -23,7 +25,7 @@ namespace IPC { template<typename T> -inline ErrorOr<void> decode(Decoder&, T&) +inline ErrorOr<T> decode(Decoder&) { static_assert(DependentFalse<T>, "Base IPC::decoder() instantiated"); VERIFY_NOT_REACHED(); @@ -37,151 +39,144 @@ public: { } - ErrorOr<void> decode(bool&); - ErrorOr<void> decode(u8&); - ErrorOr<void> decode(u16&); - ErrorOr<void> decode(unsigned&); - ErrorOr<void> decode(unsigned long&); - ErrorOr<void> decode(unsigned long long&); - ErrorOr<void> decode(i8&); - ErrorOr<void> decode(i16&); - ErrorOr<void> decode(i32&); - ErrorOr<void> decode(i64&); - ErrorOr<void> decode(float&); - ErrorOr<void> decode(double&); - ErrorOr<void> decode(DeprecatedString&); - ErrorOr<void> decode(ByteBuffer&); - ErrorOr<void> decode(JsonValue&); - ErrorOr<void> decode(URL&); - ErrorOr<void> decode(Dictionary&); - ErrorOr<void> decode(File&); - ErrorOr<void> decode(AK::Empty&); - template<typename K, typename V> - ErrorOr<void> decode(HashMap<K, V>& hashmap) - { - u32 size; - TRY(decode(size)); - if (size > NumericLimits<i32>::max()) - return Error::from_string_literal("IPC: Invalid HashMap size"); - - for (size_t i = 0; i < size; ++i) { - K key; - TRY(decode(key)); - V value; - TRY(decode(value)); - TRY(hashmap.try_set(move(key), move(value))); - } - return {}; - } + template<typename T> + ErrorOr<T> decode(); - template<typename K, typename V> - ErrorOr<void> decode(OrderedHashMap<K, V>& hashmap) + template<typename T> + ErrorOr<void> decode_into(T& value) { - u32 size; - TRY(decode(size)); - if (size > NumericLimits<i32>::max()) - return Error::from_string_literal("IPC: Invalid HashMap size"); - - for (size_t i = 0; i < size; ++i) { - K key; - TRY(decode(key)); - V value; - TRY(decode(value)); - TRY(hashmap.try_set(move(key), move(value))); - } + m_stream >> value; + TRY(m_stream.try_handle_any_error()); return {}; } - template<Enum T> - ErrorOr<void> decode(T& enum_value) - { - UnderlyingType<T> inner_value; - TRY(decode(inner_value)); - enum_value = T(inner_value); - return {}; - } + Core::Stream::LocalSocket& socket() { return m_socket; } - template<typename T> - ErrorOr<void> decode(T& value) - { - return IPC::decode(*this, value); - } +private: + InputMemoryStream& m_stream; + Core::Stream::LocalSocket& m_socket; +}; - template<typename T> - ErrorOr<void> decode(Vector<T>& vector) - { - u64 size; - TRY(decode(size)); - if (size > NumericLimits<i32>::max()) - return Error::from_string_literal("IPC: Invalid Vector size"); - VERIFY(vector.is_empty()); - TRY(vector.try_ensure_capacity(size)); - for (size_t i = 0; i < size; ++i) { - T value; - TRY(decode(value)); - vector.template unchecked_append(move(value)); - } - return {}; - } +template<Arithmetic T> +ErrorOr<T> decode(Decoder& decoder) +{ + T value { 0 }; + TRY(decoder.decode_into(value)); + return value; +} - template<typename T, size_t Size> - ErrorOr<void> decode(Core::SharedSingleProducerCircularQueue<T, Size>& queue) - { - // FIXME: We don't support decoding into valid queues. - VERIFY(!queue.is_valid()); +template<Enum T> +ErrorOr<T> decode(Decoder& decoder) +{ + auto value = TRY(decoder.decode<UnderlyingType<T>>()); + return static_cast<T>(value); +} - IPC::File anon_file; - TRY(decode(anon_file)); - queue = TRY((Core::SharedSingleProducerCircularQueue<T, Size>::try_create(anon_file.take_fd()))); - return {}; - } +template<> +ErrorOr<DeprecatedString> decode(Decoder&); - template<typename... VariantTypes> - ErrorOr<void> decode(Variant<VariantTypes...>& variant) - { - typename AK::Variant<VariantTypes...>::IndexType type_index; - TRY(decode(type_index)); - if (type_index >= sizeof...(VariantTypes)) - return Error::from_string_literal("IPC: Invalid variant index"); +template<> +ErrorOr<ByteBuffer> decode(Decoder&); - TRY((decode_variant<0, sizeof...(VariantTypes), VariantTypes...>(type_index, variant))); - return {}; +template<> +ErrorOr<JsonValue> decode(Decoder&); + +template<> +ErrorOr<URL> decode(Decoder&); + +template<> +ErrorOr<Dictionary> decode(Decoder&); + +template<> +ErrorOr<File> decode(Decoder&); + +template<> +ErrorOr<Empty> decode(Decoder&); + +template<Concepts::Vector T> +ErrorOr<T> decode(Decoder& decoder) +{ + auto size = TRY(decoder.decode<u64>()); + if (size > NumericLimits<i32>::max()) + return Error::from_string_literal("IPC: Invalid Vector size"); + + T vector; + TRY(vector.try_ensure_capacity(size)); + + for (size_t i = 0; i < size; ++i) { + auto value = TRY(decoder.decode<typename T::ValueType>()); + vector.template unchecked_append(move(value)); } - template<typename T> - ErrorOr<void> decode(Optional<T>& optional) - { - bool has_value; - TRY(decode(has_value)); - if (!has_value) { - optional = {}; - return {}; - } - T value; - TRY(decode(value)); - optional = move(value); - return {}; + return vector; +} + +template<Concepts::HashMap T> +ErrorOr<T> decode(Decoder& decoder) +{ + auto size = TRY(decoder.decode<u32>()); + if (size > NumericLimits<i32>::max()) + return Error::from_string_literal("IPC: Invalid HashMap size"); + + T hashmap; + + for (size_t i = 0; i < size; ++i) { + auto key = TRY(decoder.decode<typename T::KeyType>()); + auto value = TRY(decoder.decode<typename T::ValueType>()); + TRY(hashmap.try_set(move(key), move(value))); } -private: - template<size_t CurrentIndex, size_t Max, typename... VariantTypes> - ErrorOr<void> decode_variant(size_t index, Variant<VariantTypes...>& variant) - { - if constexpr (CurrentIndex < Max) { - if (index == CurrentIndex) { - typename TypeList<VariantTypes...>::template Type<CurrentIndex> element; - TRY(decode(element)); - variant.set(move(element)); - return {}; - } - return decode_variant<CurrentIndex + 1, Max, VariantTypes...>(index, variant); - } else { - VERIFY_NOT_REACHED(); + return hashmap; +} + +template<Concepts::SharedSingleProducerCircularQueue T> +ErrorOr<T> decode(Decoder& decoder) +{ + auto anon_file = TRY(decoder.decode<IPC::File>()); + return T::try_create(anon_file.take_fd()); +} + +template<Concepts::Optional T> +ErrorOr<T> decode(Decoder& decoder) +{ + if (auto has_value = TRY(decoder.decode<bool>()); !has_value) + return T {}; + return T { TRY(decoder.decode<typename T::ValueType>()) }; +} + +namespace Detail { + +template<Concepts::Variant T, size_t Index = 0> +ErrorOr<T> decode_variant(Decoder& decoder, size_t index) +{ + using ElementList = TypeList<T>; + + if constexpr (Index < ElementList::size) { + if (index == Index) { + using ElementType = typename ElementList::template Type<Index>; + return T { TRY(decoder.decode<ElementType>()) }; } + + return decode_variant<T, Index + 1>(decoder, index); + } else { + VERIFY_NOT_REACHED(); } +} - InputMemoryStream& m_stream; - Core::Stream::LocalSocket& m_socket; -}; +} + +template<Concepts::Variant T> +ErrorOr<T> decode(Decoder& decoder) +{ + auto index = TRY(decoder.decode<typename T::IndexType>()); + return Detail::decode_variant<T>(decoder, index); +} + +// This must be last so that it knows about the above specializations. +template<typename T> +ErrorOr<T> Decoder::decode() +{ + return IPC::decode<T>(*this); +} } diff --git a/Userland/Libraries/LibIPC/Forward.h b/Userland/Libraries/LibIPC/Forward.h index c59cca64d3..c16e57a271 100644 --- a/Userland/Libraries/LibIPC/Forward.h +++ b/Userland/Libraries/LibIPC/Forward.h @@ -19,6 +19,6 @@ template<typename T> bool encode(Encoder&, T const&); template<typename T> -ErrorOr<void> decode(Decoder&, T&); +ErrorOr<T> decode(Decoder&); } diff --git a/Userland/Libraries/LibSQL/Value.cpp b/Userland/Libraries/LibSQL/Value.cpp index 884d465cbe..ee85e3e9a4 100644 --- a/Userland/Libraries/LibSQL/Value.cpp +++ b/Userland/Libraries/LibSQL/Value.cpp @@ -847,82 +847,58 @@ bool IPC::encode(Encoder& encoder, SQL::Value const& value) return true; } -template<typename T> -static ErrorOr<void> decode_scalar(IPC::Decoder& decoder, SQL::Value& value) -{ - T decoded {}; - TRY(decoder.decode(decoded)); - value = move(decoded); - return {}; -} - template<> -ErrorOr<void> IPC::decode(Decoder& decoder, SQL::Value& value) +ErrorOr<SQL::Value> IPC::decode(Decoder& decoder) { - u8 type_flags { 0 }; - TRY(decoder.decode(type_flags)); + auto type_flags = TRY(decoder.decode<u8>()); auto type_data = static_cast<SQL::TypeData>(type_flags & 0xf0); auto type = static_cast<SQL::SQLType>(type_flags & 0x0f); - if (type_data == SQL::TypeData::Null) { - value = SQL::Value(type); - return {}; - } + if (type_data == SQL::TypeData::Null) + return SQL::Value { type }; switch (type) { case SQL::SQLType::Null: - break; + return SQL::Value {}; case SQL::SQLType::Text: - TRY(decode_scalar<DeprecatedString>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<DeprecatedString>()) }; case SQL::SQLType::Integer: switch (type_data) { case SQL::TypeData::Int8: - TRY(decode_scalar<i8>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<i8>()) }; case SQL::TypeData::Int16: - TRY(decode_scalar<i16>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<i16>()) }; case SQL::TypeData::Int32: - TRY(decode_scalar<i32>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<i32>()) }; case SQL::TypeData::Int64: - TRY(decode_scalar<i64>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<i64>()) }; case SQL::TypeData::Uint8: - TRY(decode_scalar<u8>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<u8>()) }; case SQL::TypeData::Uint16: - TRY(decode_scalar<u16>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<u16>()) }; case SQL::TypeData::Uint32: - TRY(decode_scalar<u32>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<u32>()) }; case SQL::TypeData::Uint64: - TRY(decode_scalar<u64>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<u64>()) }; default: - VERIFY_NOT_REACHED(); break; } break; case SQL::SQLType::Float: - TRY(decode_scalar<double>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<double>()) }; case SQL::SQLType::Boolean: - TRY(decode_scalar<bool>(decoder, value)); - break; + return SQL::Value { TRY(decoder.decode<bool>()) }; case SQL::SQLType::Tuple: { - Vector<SQL::Value> tuple; - TRY(decoder.decode(tuple)); + auto tuple = TRY(decoder.decode<Vector<SQL::Value>>()); + auto value = SQL::Value::create_tuple(move(tuple)); - if (auto result = value.assign_tuple(move(tuple)); result.is_error()) - return Error::from_errno(to_underlying(result.error().error())); + if (value.is_error()) + return Error::from_errno(to_underlying(value.error().error())); - break; + return value.release_value(); } } - return {}; + VERIFY_NOT_REACHED(); } diff --git a/Userland/Libraries/LibSQL/Value.h b/Userland/Libraries/LibSQL/Value.h index e7568192b6..475e963dc0 100644 --- a/Userland/Libraries/LibSQL/Value.h +++ b/Userland/Libraries/LibSQL/Value.h @@ -194,6 +194,6 @@ template<> bool encode(Encoder&, SQL::Value const&); template<> -ErrorOr<void> decode(Decoder&, SQL::Value&); +ErrorOr<SQL::Value> decode(Decoder&); } diff --git a/Userland/Libraries/LibWeb/Cookie/Cookie.cpp b/Userland/Libraries/LibWeb/Cookie/Cookie.cpp index 2a43385e64..6ddaa79c05 100644 --- a/Userland/Libraries/LibWeb/Cookie/Cookie.cpp +++ b/Userland/Libraries/LibWeb/Cookie/Cookie.cpp @@ -58,19 +58,20 @@ bool IPC::encode(Encoder& encoder, Web::Cookie::Cookie const& cookie) } template<> -ErrorOr<void> IPC::decode(Decoder& decoder, Web::Cookie::Cookie& cookie) +ErrorOr<Web::Cookie::Cookie> IPC::decode(Decoder& decoder) { - TRY(decoder.decode(cookie.name)); - TRY(decoder.decode(cookie.value)); - TRY(decoder.decode(cookie.domain)); - TRY(decoder.decode(cookie.path)); - TRY(decoder.decode(cookie.creation_time)); - TRY(decoder.decode(cookie.expiry_time)); - TRY(decoder.decode(cookie.host_only)); - TRY(decoder.decode(cookie.http_only)); - TRY(decoder.decode(cookie.last_access_time)); - TRY(decoder.decode(cookie.persistent)); - TRY(decoder.decode(cookie.secure)); - TRY(decoder.decode(cookie.same_site)); - return {}; + auto name = TRY(decoder.decode<DeprecatedString>()); + auto value = TRY(decoder.decode<DeprecatedString>()); + auto domain = TRY(decoder.decode<DeprecatedString>()); + auto path = TRY(decoder.decode<DeprecatedString>()); + auto creation_time = TRY(decoder.decode<Core::DateTime>()); + auto expiry_time = TRY(decoder.decode<Core::DateTime>()); + auto host_only = TRY(decoder.decode<bool>()); + auto http_only = TRY(decoder.decode<bool>()); + auto last_access_time = TRY(decoder.decode<Core::DateTime>()); + auto persistent = TRY(decoder.decode<bool>()); + auto secure = TRY(decoder.decode<bool>()); + auto same_site = TRY(decoder.decode<Web::Cookie::SameSite>()); + + return Web::Cookie::Cookie { move(name), move(value), same_site, move(creation_time), move(last_access_time), move(expiry_time), move(domain), move(path), secure, http_only, host_only, persistent }; } diff --git a/Userland/Libraries/LibWeb/Cookie/Cookie.h b/Userland/Libraries/LibWeb/Cookie/Cookie.h index e16352305e..429a90f6d0 100644 --- a/Userland/Libraries/LibWeb/Cookie/Cookie.h +++ b/Userland/Libraries/LibWeb/Cookie/Cookie.h @@ -50,6 +50,6 @@ template<> bool encode(Encoder&, Web::Cookie::Cookie const&); template<> -ErrorOr<void> decode(Decoder&, Web::Cookie::Cookie&); +ErrorOr<Web::Cookie::Cookie> decode(Decoder&); } diff --git a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp index 774240ca73..69ceeb4050 100644 --- a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp +++ b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp @@ -364,16 +364,17 @@ bool IPC::encode(Encoder& encoder, Web::Cookie::ParsedCookie const& cookie) } template<> -ErrorOr<void> IPC::decode(Decoder& decoder, Web::Cookie::ParsedCookie& cookie) +ErrorOr<Web::Cookie::ParsedCookie> IPC::decode(Decoder& decoder) { - TRY(decoder.decode(cookie.name)); - TRY(decoder.decode(cookie.value)); - TRY(decoder.decode(cookie.expiry_time_from_expires_attribute)); - TRY(decoder.decode(cookie.expiry_time_from_max_age_attribute)); - TRY(decoder.decode(cookie.domain)); - TRY(decoder.decode(cookie.path)); - TRY(decoder.decode(cookie.secure_attribute_present)); - TRY(decoder.decode(cookie.http_only_attribute_present)); - TRY(decoder.decode(cookie.same_site_attribute)); - return {}; + auto name = TRY(decoder.decode<DeprecatedString>()); + auto value = TRY(decoder.decode<DeprecatedString>()); + auto expiry_time_from_expires_attribute = TRY(decoder.decode<Optional<Core::DateTime>>()); + auto expiry_time_from_max_age_attribute = TRY(decoder.decode<Optional<Core::DateTime>>()); + auto domain = TRY(decoder.decode<Optional<DeprecatedString>>()); + auto path = TRY(decoder.decode<Optional<DeprecatedString>>()); + auto secure_attribute_present = TRY(decoder.decode<bool>()); + auto http_only_attribute_present = TRY(decoder.decode<bool>()); + auto same_site_attribute = TRY(decoder.decode<Web::Cookie::SameSite>()); + + return Web::Cookie::ParsedCookie { move(name), move(value), same_site_attribute, move(expiry_time_from_expires_attribute), move(expiry_time_from_max_age_attribute), move(domain), move(path), secure_attribute_present, http_only_attribute_present }; } diff --git a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h index ebe38b46ab..31b6b5b15f 100644 --- a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h +++ b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h @@ -36,6 +36,6 @@ template<> bool encode(Encoder&, Web::Cookie::ParsedCookie const&); template<> -ErrorOr<void> decode(Decoder&, Web::Cookie::ParsedCookie&); +ErrorOr<Web::Cookie::ParsedCookie> decode(Decoder&); } diff --git a/Userland/Libraries/LibWeb/WebDriver/Response.cpp b/Userland/Libraries/LibWeb/WebDriver/Response.cpp index a44e17f578..c2ed16cdb4 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Response.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/Response.cpp @@ -48,31 +48,23 @@ bool IPC::encode(Encoder& encoder, Web::WebDriver::Response const& response) } template<> -ErrorOr<void> IPC::decode(Decoder& decoder, Web::WebDriver::Response& response) +ErrorOr<Web::WebDriver::Response> IPC::decode(Decoder& decoder) { - ResponseType type {}; - TRY(decoder.decode(type)); + auto type = TRY(decoder.decode<ResponseType>()); switch (type) { - case ResponseType::Success: { - JsonValue value; - TRY(decoder.decode(value)); - - response = move(value); - break; - } + case ResponseType::Success: + return TRY(decoder.decode<JsonValue>()); case ResponseType::Error: { - Web::WebDriver::Error error {}; - TRY(decoder.decode(error.http_status)); - TRY(decoder.decode(error.error)); - TRY(decoder.decode(error.message)); - TRY(decoder.decode(error.data)); + auto http_status = TRY(decoder.decode<unsigned>()); + auto error = TRY(decoder.decode<DeprecatedString>()); + auto message = TRY(decoder.decode<DeprecatedString>()); + auto data = TRY(decoder.decode<Optional<JsonValue>>()); - response = move(error); - break; + return Web::WebDriver::Error { http_status, move(error), move(message), move(data) }; } } - return {}; + VERIFY_NOT_REACHED(); } diff --git a/Userland/Libraries/LibWeb/WebDriver/Response.h b/Userland/Libraries/LibWeb/WebDriver/Response.h index 1a6663746e..dc8b570441 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Response.h +++ b/Userland/Libraries/LibWeb/WebDriver/Response.h @@ -50,6 +50,6 @@ template<> bool encode(Encoder&, Web::WebDriver::Response const&); template<> -ErrorOr<void> decode(Decoder&, Web::WebDriver::Response&); +ErrorOr<Web::WebDriver::Response> decode(Decoder&); } diff --git a/Userland/Services/WindowServer/ScreenLayout.h b/Userland/Services/WindowServer/ScreenLayout.h index ceb70c88de..6a5c5b0571 100644 --- a/Userland/Services/WindowServer/ScreenLayout.h +++ b/Userland/Services/WindowServer/ScreenLayout.h @@ -77,12 +77,12 @@ template<> bool encode(Encoder&, WindowServer::ScreenLayout::Screen const&); template<> -ErrorOr<void> decode(Decoder&, WindowServer::ScreenLayout::Screen&); +ErrorOr<WindowServer::ScreenLayout::Screen> decode(Decoder&); template<> bool encode(Encoder&, WindowServer::ScreenLayout const&); template<> -ErrorOr<void> decode(Decoder&, WindowServer::ScreenLayout&); +ErrorOr<WindowServer::ScreenLayout> decode(Decoder&); } diff --git a/Userland/Services/WindowServer/ScreenLayout.ipp b/Userland/Services/WindowServer/ScreenLayout.ipp index 592a67cbbf..77b4b04497 100644 --- a/Userland/Services/WindowServer/ScreenLayout.ipp +++ b/Userland/Services/WindowServer/ScreenLayout.ipp @@ -76,7 +76,7 @@ bool ScreenLayout::is_valid(DeprecatedString* error_msg) const *error_msg = "Screen layout has not been normalized"; return false; } - Vector<const Screen*, 16> reachable_screens { &screens[main_screen_index] }; + Vector<Screen const*, 16> reachable_screens { &screens[main_screen_index] }; bool did_reach_another_screen; do { did_reach_another_screen = false; @@ -225,7 +225,7 @@ bool ScreenLayout::normalize() return did_change; } -bool ScreenLayout::load_config(const Core::ConfigFile& config_file, DeprecatedString* error_msg) +bool ScreenLayout::load_config(Core::ConfigFile const& config_file, DeprecatedString* error_msg) { screens.clear_with_capacity(); main_screen_index = config_file.read_num_entry("Screens", "MainScreen", 0); @@ -290,7 +290,7 @@ bool ScreenLayout::save_config(Core::ConfigFile& config_file, bool sync) const return true; } -bool ScreenLayout::operator!=(const ScreenLayout& other) const +bool ScreenLayout::operator!=(ScreenLayout const& other) const { if (this == &other) return false; @@ -400,20 +400,15 @@ bool encode(Encoder& encoder, WindowServer::ScreenLayout::Screen const& screen) } template<> -ErrorOr<void> decode(Decoder& decoder, WindowServer::ScreenLayout::Screen& screen) +ErrorOr<WindowServer::ScreenLayout::Screen> decode(Decoder& decoder) { - WindowServer::ScreenLayout::Screen::Mode mode; - TRY(decoder.decode(mode)); - Optional<DeprecatedString> device; - TRY(decoder.decode(device)); - Gfx::IntPoint location; - TRY(decoder.decode(location)); - Gfx::IntSize resolution; - TRY(decoder.decode(resolution)); - int scale_factor = 0; - TRY(decoder.decode(scale_factor)); - screen = { mode, device, location, resolution, scale_factor }; - return {}; + auto mode = TRY(decoder.decode<WindowServer::ScreenLayout::Screen::Mode>()); + auto device = TRY(decoder.decode<Optional<DeprecatedString>>()); + auto location = TRY(decoder.decode<Gfx::IntPoint>()); + auto resolution = TRY(decoder.decode<Gfx::IntSize>()); + auto scale_factor = TRY(decoder.decode<int>()); + + return WindowServer::ScreenLayout::Screen { mode, device, location, resolution, scale_factor }; } template<> @@ -424,14 +419,12 @@ bool encode(Encoder& encoder, WindowServer::ScreenLayout const& screen_layout) } template<> -ErrorOr<void> decode(Decoder& decoder, WindowServer::ScreenLayout& screen_layout) +ErrorOr<WindowServer::ScreenLayout> decode(Decoder& decoder) { - Vector<WindowServer::ScreenLayout::Screen> screens; - TRY(decoder.decode(screens)); - unsigned main_screen_index = 0; - TRY(decoder.decode(main_screen_index)); - screen_layout = { move(screens), main_screen_index }; - return {}; + auto screens = TRY(decoder.decode<Vector<WindowServer::ScreenLayout::Screen>>()); + auto main_screen_index = TRY(decoder.decode<unsigned>()); + + return WindowServer::ScreenLayout { move(screens), main_screen_index }; } } |