/* * 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 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, DeprecatedString 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, 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 const& value) { return encoder.encode(value.to_deprecated_string()); } template<> ErrorOr encode(Encoder& encoder, File const& file) { int fd = file.fd(); if (fd != -1) fd = TRY(Core::System::dup(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(IPC::File { 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 {}; } }