/* * Copyright (c) 2020, Andreas Kling * Copyright (c) 2021, kleines Filmröllchen * Copyright (c) 2023, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace IPC { ErrorOr Encoder::encode_size(size_t size) { if (static_cast(size) > static_cast(NumericLimits::max())) return Error::from_string_literal("Container exceeds the maximum allowed size"); return encode(static_cast(size)); } template<> ErrorOr encode(Encoder& encoder, float const& value) { return encoder.encode(bit_cast(value)); } template<> ErrorOr encode(Encoder& encoder, double const& value) { return encoder.encode(bit_cast(value)); } template<> ErrorOr encode(Encoder& encoder, String const& value) { auto bytes = value.bytes(); TRY(encoder.encode_size(bytes.size())); TRY(encoder.append(bytes.data(), bytes.size())); return {}; } template<> ErrorOr encode(Encoder& encoder, StringView const& value) { // NOTE: Do not change this encoding without also updating LibC/netdb.cpp. if (value.is_null()) return encoder.encode(NumericLimits::max()); TRY(encoder.encode_size(value.length())); TRY(encoder.append(reinterpret_cast(value.characters_without_null_termination()), value.length())); return {}; } template<> ErrorOr encode(Encoder& encoder, ByteString const& value) { return encoder.encode(value.view()); } template<> ErrorOr encode(Encoder& encoder, ByteBuffer const& value) { TRY(encoder.encode_size(value.size())); TRY(encoder.append(value.data(), value.size())); return {}; } template<> ErrorOr encode(Encoder& encoder, JsonValue const& value) { return encoder.encode(value.serialized()); } template<> ErrorOr encode(Encoder& encoder, AK::Duration const& value) { return encoder.encode(value.to_nanoseconds()); } template<> ErrorOr encode(Encoder& encoder, UnixDateTime const& value) { return encoder.encode(value.nanoseconds_since_epoch()); } template<> ErrorOr encode(Encoder& encoder, URL::URL const& value) { TRY(encoder.encode(value.serialize())); if (!value.blob_url_entry().has_value()) return encoder.encode(false); TRY(encoder.encode(true)); auto const& blob = value.blob_url_entry().value(); TRY(encoder.encode(blob.type)); TRY(encoder.encode(blob.byte_buffer)); TRY(encoder.encode(blob.environment_origin)); return {}; } template<> ErrorOr encode(Encoder& encoder, URL::Origin const& origin) { TRY(encoder.encode(origin.scheme())); TRY(encoder.encode(origin.host())); TRY(encoder.encode(origin.port())); return {}; } template<> ErrorOr encode(Encoder& encoder, File const& file) { int fd = file.take_fd(); TRY(encoder.append_file_descriptor(fd)); return {}; } template<> ErrorOr encode(Encoder&, Empty const&) { return {}; } template<> ErrorOr encode(Encoder& encoder, Core::AnonymousBuffer const& buffer) { TRY(encoder.encode(buffer.is_valid())); if (buffer.is_valid()) { TRY(encoder.encode_size(buffer.size())); TRY(encoder.encode(TRY(IPC::File::clone_fd(buffer.fd())))); } return {}; } template<> ErrorOr encode(Encoder& encoder, Core::DateTime const& datetime) { return encoder.encode(static_cast(datetime.timestamp())); } template<> ErrorOr encode(Encoder& encoder, Core::ProxyData const& proxy) { TRY(encoder.encode(proxy.type)); TRY(encoder.encode(proxy.host_ipv4)); TRY(encoder.encode(proxy.port)); return {}; } }