Decoder.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/JsonValue.h>
  8. #include <AK/NumericLimits.h>
  9. #include <LibCore/AnonymousBuffer.h>
  10. #include <LibCore/DateTime.h>
  11. #include <LibCore/Proxy.h>
  12. #include <LibCore/Socket.h>
  13. #include <LibIPC/Decoder.h>
  14. #include <LibIPC/File.h>
  15. #include <LibURL/URL.h>
  16. #include <fcntl.h>
  17. namespace IPC {
  18. ErrorOr<size_t> Decoder::decode_size()
  19. {
  20. return static_cast<size_t>(TRY(decode<u32>()));
  21. }
  22. template<>
  23. ErrorOr<String> decode(Decoder& decoder)
  24. {
  25. auto length = TRY(decoder.decode_size());
  26. return String::from_stream(decoder.stream(), length);
  27. }
  28. template<>
  29. ErrorOr<ByteString> decode(Decoder& decoder)
  30. {
  31. auto length = TRY(decoder.decode_size());
  32. if (length == NumericLimits<u32>::max())
  33. return ByteString {};
  34. if (length == 0)
  35. return ByteString::empty();
  36. return ByteString::create_and_overwrite(length, [&](Bytes bytes) -> ErrorOr<void> {
  37. TRY(decoder.decode_into(bytes));
  38. return {};
  39. });
  40. }
  41. template<>
  42. ErrorOr<ByteBuffer> decode(Decoder& decoder)
  43. {
  44. auto length = TRY(decoder.decode_size());
  45. if (length == 0)
  46. return ByteBuffer {};
  47. auto buffer = TRY(ByteBuffer::create_uninitialized(length));
  48. auto bytes = buffer.bytes();
  49. TRY(decoder.decode_into(bytes));
  50. return buffer;
  51. }
  52. template<>
  53. ErrorOr<JsonValue> decode(Decoder& decoder)
  54. {
  55. auto json = TRY(decoder.decode<ByteString>());
  56. return JsonValue::from_string(json);
  57. }
  58. template<>
  59. ErrorOr<Duration> decode(Decoder& decoder)
  60. {
  61. auto nanoseconds = TRY(decoder.decode<i64>());
  62. return AK::Duration::from_nanoseconds(nanoseconds);
  63. }
  64. template<>
  65. ErrorOr<UnixDateTime> decode(Decoder& decoder)
  66. {
  67. auto nanoseconds = TRY(decoder.decode<i64>());
  68. return AK::UnixDateTime::from_nanoseconds_since_epoch(nanoseconds);
  69. }
  70. template<>
  71. ErrorOr<URL::URL> decode(Decoder& decoder)
  72. {
  73. auto url_string = TRY(decoder.decode<ByteString>());
  74. URL::URL url { url_string };
  75. bool has_blob_url = TRY(decoder.decode<bool>());
  76. if (!has_blob_url)
  77. return url;
  78. url.set_blob_url_entry(URL::BlobURLEntry {
  79. .type = TRY(decoder.decode<String>()),
  80. .byte_buffer = TRY(decoder.decode<ByteBuffer>()),
  81. });
  82. return url;
  83. }
  84. template<>
  85. ErrorOr<File> decode(Decoder& decoder)
  86. {
  87. auto file = TRY(decoder.files().try_dequeue());
  88. auto fd = file.fd();
  89. auto fd_flags = TRY(Core::System::fcntl(fd, F_GETFD));
  90. TRY(Core::System::fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC));
  91. return file;
  92. }
  93. template<>
  94. ErrorOr<Empty> decode(Decoder&)
  95. {
  96. return Empty {};
  97. }
  98. template<>
  99. ErrorOr<Core::AnonymousBuffer> decode(Decoder& decoder)
  100. {
  101. if (auto valid = TRY(decoder.decode<bool>()); !valid)
  102. return Core::AnonymousBuffer {};
  103. auto size = TRY(decoder.decode_size());
  104. auto anon_file = TRY(decoder.decode<IPC::File>());
  105. return Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size);
  106. }
  107. template<>
  108. ErrorOr<Core::DateTime> decode(Decoder& decoder)
  109. {
  110. auto timestamp = TRY(decoder.decode<i64>());
  111. return Core::DateTime::from_timestamp(static_cast<time_t>(timestamp));
  112. }
  113. template<>
  114. ErrorOr<Core::ProxyData> decode(Decoder& decoder)
  115. {
  116. auto type = TRY(decoder.decode<Core::ProxyData::Type>());
  117. auto host_ipv4 = TRY(decoder.decode<u32>());
  118. auto port = TRY(decoder.decode<int>());
  119. return Core::ProxyData { type, host_ipv4, port };
  120. }
  121. }