From d1711f1cefc2940b96f995334b7859605fa349f0 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 14 Jan 2023 21:13:29 +0100 Subject: [PATCH] AK: Define our own concept of "trivially serializable" While at it, rename the `read_trivial_value` and `write_trivial_value` functions to `read_value` and `write_value` respectively, since we'll add compatibility for non-trivial types down the line. --- AK/Traits.h | 4 ++++ Userland/Libraries/LibCore/Stream.h | 8 ++++---- Userland/Libraries/LibDNS/Name.cpp | 4 ++-- Userland/Libraries/LibDNS/Packet.cpp | 16 ++++++++-------- Userland/Libraries/LibDNS/PacketHeader.h | 5 +++++ 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/AK/Traits.h b/AK/Traits.h index 27efd35446a..cdcb9a85f76 100644 --- a/AK/Traits.h +++ b/AK/Traits.h @@ -20,6 +20,7 @@ struct GenericTraits { using PeekType = T&; using ConstPeekType = T const&; static constexpr bool is_trivial() { return false; } + static constexpr bool is_trivially_serializable() { return false; } static constexpr bool equals(T const& a, T const& b) { return a == b; } template U> static bool equals(U const& a, T const& b) { return a == b; } @@ -32,6 +33,7 @@ struct Traits : public GenericTraits { template struct Traits : public GenericTraits { static constexpr bool is_trivial() { return true; } + static constexpr bool is_trivially_serializable() { return true; } static constexpr unsigned hash(T value) { if constexpr (sizeof(T) < 8) @@ -45,6 +47,7 @@ struct Traits : public GenericTraits { template struct Traits : public GenericTraits { static constexpr bool is_trivial() { return true; } + static constexpr bool is_trivially_serializable() { return true; } static constexpr unsigned hash(T value) { if constexpr (sizeof(T) < 8) @@ -65,6 +68,7 @@ template struct Traits : public GenericTraits { static unsigned hash(T value) { return Traits>::hash(to_underlying(value)); } static constexpr bool is_trivial() { return Traits>::is_trivial(); } + static constexpr bool is_trivially_serializable() { return Traits>::is_trivially_serializable(); } }; template diff --git a/Userland/Libraries/LibCore/Stream.h b/Userland/Libraries/LibCore/Stream.h index 3f75850f1bc..4ed9ce5c21f 100644 --- a/Userland/Libraries/LibCore/Stream.h +++ b/Userland/Libraries/LibCore/Stream.h @@ -109,8 +109,8 @@ public: } template - requires(IsTriviallyDestructible) - ErrorOr read_trivial_value() + requires(Traits::is_trivially_serializable()) + ErrorOr read_value() { alignas(T) u8 buffer[sizeof(T)] = {}; TRY(read_entire_buffer({ &buffer, sizeof(buffer) })); @@ -118,8 +118,8 @@ public: } template - requires(IsTriviallyDestructible) - ErrorOr write_trivial_value(T const& value) + requires(Traits::is_trivially_serializable()) + ErrorOr write_value(T const& value) { return write_entire_buffer({ &value, sizeof(value) }); } diff --git a/Userland/Libraries/LibDNS/Name.cpp b/Userland/Libraries/LibDNS/Name.cpp index 3d351a28c35..39ee9ae0cc0 100644 --- a/Userland/Libraries/LibDNS/Name.cpp +++ b/Userland/Libraries/LibDNS/Name.cpp @@ -79,10 +79,10 @@ ErrorOr Name::write_to_stream(Core::Stream::Stream& stream) const { auto parts = as_string().split_view('.'); for (auto& part : parts) { - TRY(stream.write_trivial_value(part.length())); + TRY(stream.write_value(part.length())); TRY(stream.write_entire_buffer(part.bytes())); } - TRY(stream.write_trivial_value('\0')); + TRY(stream.write_value('\0')); return {}; } diff --git a/Userland/Libraries/LibDNS/Packet.cpp b/Userland/Libraries/LibDNS/Packet.cpp index 58a8f81feff..6289ae974e6 100644 --- a/Userland/Libraries/LibDNS/Packet.cpp +++ b/Userland/Libraries/LibDNS/Packet.cpp @@ -51,23 +51,23 @@ ErrorOr Packet::to_byte_buffer() const Core::Stream::AllocatingMemoryStream stream; - TRY(stream.write_trivial_value(header)); + TRY(stream.write_value(header)); for (auto& question : m_questions) { TRY(question.name().write_to_stream(stream)); - TRY(stream.write_trivial_value(htons((u16)question.record_type()))); - TRY(stream.write_trivial_value(htons(question.raw_class_code()))); + TRY(stream.write_value(htons((u16)question.record_type()))); + TRY(stream.write_value(htons(question.raw_class_code()))); } for (auto& answer : m_answers) { TRY(answer.name().write_to_stream(stream)); - TRY(stream.write_trivial_value(htons((u16)answer.type()))); - TRY(stream.write_trivial_value(htons(answer.raw_class_code()))); - TRY(stream.write_trivial_value(htonl(answer.ttl()))); + TRY(stream.write_value(htons((u16)answer.type()))); + TRY(stream.write_value(htons(answer.raw_class_code()))); + TRY(stream.write_value(htonl(answer.ttl()))); if (answer.type() == RecordType::PTR) { Name name { answer.record_data() }; - TRY(stream.write_trivial_value(htons(name.serialized_size()))); + TRY(stream.write_value(htons(name.serialized_size()))); TRY(name.write_to_stream(stream)); } else { - TRY(stream.write_trivial_value(htons(answer.record_data().length()))); + TRY(stream.write_value(htons(answer.record_data().length()))); TRY(stream.write_entire_buffer(answer.record_data().bytes())); } } diff --git a/Userland/Libraries/LibDNS/PacketHeader.h b/Userland/Libraries/LibDNS/PacketHeader.h index 166e061f616..300286f0ed4 100644 --- a/Userland/Libraries/LibDNS/PacketHeader.h +++ b/Userland/Libraries/LibDNS/PacketHeader.h @@ -97,3 +97,8 @@ private: static_assert(sizeof(PacketHeader) == 12); } + +template<> +struct AK::Traits : public AK::GenericTraits { + static constexpr bool is_trivially_serializable() { return true; } +};