Encoder.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/BitCast.h>
  8. #include <AK/ByteBuffer.h>
  9. #include <AK/DeprecatedString.h>
  10. #include <AK/JsonObject.h>
  11. #include <AK/JsonValue.h>
  12. #include <AK/URL.h>
  13. #include <LibCore/AnonymousBuffer.h>
  14. #include <LibCore/DateTime.h>
  15. #include <LibCore/Proxy.h>
  16. #include <LibCore/System.h>
  17. #include <LibIPC/Dictionary.h>
  18. #include <LibIPC/Encoder.h>
  19. #include <LibIPC/File.h>
  20. namespace IPC {
  21. template<>
  22. ErrorOr<void> encode(Encoder& encoder, float const& value)
  23. {
  24. return encoder.encode(bit_cast<u32>(value));
  25. }
  26. template<>
  27. ErrorOr<void> encode(Encoder& encoder, double const& value)
  28. {
  29. return encoder.encode(bit_cast<u64>(value));
  30. }
  31. template<>
  32. ErrorOr<void> encode(Encoder& encoder, StringView const& value)
  33. {
  34. TRY(encoder.append(reinterpret_cast<u8 const*>(value.characters_without_null_termination()), value.length()));
  35. return {};
  36. }
  37. template<>
  38. ErrorOr<void> encode(Encoder& encoder, DeprecatedString const& value)
  39. {
  40. if (value.is_null())
  41. return encoder.encode(-1);
  42. TRY(encoder.encode(static_cast<i32>(value.length())));
  43. TRY(encoder.encode(value.view()));
  44. return {};
  45. }
  46. template<>
  47. ErrorOr<void> encode(Encoder& encoder, ByteBuffer const& value)
  48. {
  49. TRY(encoder.encode(static_cast<i32>(value.size())));
  50. TRY(encoder.append(value.data(), value.size()));
  51. return {};
  52. }
  53. template<>
  54. ErrorOr<void> encode(Encoder& encoder, JsonValue const& value)
  55. {
  56. return encoder.encode(value.serialized<StringBuilder>());
  57. }
  58. template<>
  59. ErrorOr<void> encode(Encoder& encoder, URL const& value)
  60. {
  61. return encoder.encode(value.to_deprecated_string());
  62. }
  63. template<>
  64. ErrorOr<void> encode(Encoder& encoder, Dictionary const& dictionary)
  65. {
  66. TRY(encoder.encode(static_cast<u64>(dictionary.size())));
  67. TRY(dictionary.try_for_each_entry([&](auto const& key, auto const& value) -> ErrorOr<void> {
  68. TRY(encoder.encode(key));
  69. TRY(encoder.encode(value));
  70. return {};
  71. }));
  72. return {};
  73. }
  74. template<>
  75. ErrorOr<void> encode(Encoder& encoder, File const& file)
  76. {
  77. int fd = file.fd();
  78. if (fd != -1)
  79. fd = TRY(Core::System::dup(fd));
  80. TRY(encoder.append_file_descriptor(fd));
  81. return {};
  82. }
  83. template<>
  84. ErrorOr<void> encode(Encoder&, Empty const&)
  85. {
  86. return {};
  87. }
  88. template<>
  89. ErrorOr<void> encode(Encoder& encoder, Core::AnonymousBuffer const& buffer)
  90. {
  91. TRY(encoder.encode(buffer.is_valid()));
  92. if (buffer.is_valid()) {
  93. TRY(encoder.encode(static_cast<u32>(buffer.size())));
  94. TRY(encoder.encode(IPC::File { buffer.fd() }));
  95. }
  96. return {};
  97. }
  98. template<>
  99. ErrorOr<void> encode(Encoder& encoder, Core::DateTime const& datetime)
  100. {
  101. return encoder.encode(static_cast<i64>(datetime.timestamp()));
  102. }
  103. template<>
  104. ErrorOr<void> encode(Encoder& encoder, Core::ProxyData const& proxy)
  105. {
  106. TRY(encoder.encode(proxy.type));
  107. TRY(encoder.encode(proxy.host_ipv4));
  108. TRY(encoder.encode(proxy.port));
  109. return {};
  110. }
  111. }