Decoder.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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 == 0)
  33. return ByteString::empty();
  34. return ByteString::create_and_overwrite(length, [&](Bytes bytes) -> ErrorOr<void> {
  35. TRY(decoder.decode_into(bytes));
  36. return {};
  37. });
  38. }
  39. template<>
  40. ErrorOr<ByteBuffer> decode(Decoder& decoder)
  41. {
  42. auto length = TRY(decoder.decode_size());
  43. if (length == 0)
  44. return ByteBuffer {};
  45. auto buffer = TRY(ByteBuffer::create_uninitialized(length));
  46. auto bytes = buffer.bytes();
  47. TRY(decoder.decode_into(bytes));
  48. return buffer;
  49. }
  50. template<>
  51. ErrorOr<JsonValue> decode(Decoder& decoder)
  52. {
  53. auto json = TRY(decoder.decode<ByteString>());
  54. return JsonValue::from_string(json);
  55. }
  56. template<>
  57. ErrorOr<Duration> decode(Decoder& decoder)
  58. {
  59. auto nanoseconds = TRY(decoder.decode<i64>());
  60. return AK::Duration::from_nanoseconds(nanoseconds);
  61. }
  62. template<>
  63. ErrorOr<UnixDateTime> decode(Decoder& decoder)
  64. {
  65. auto nanoseconds = TRY(decoder.decode<i64>());
  66. return AK::UnixDateTime::from_nanoseconds_since_epoch(nanoseconds);
  67. }
  68. template<>
  69. ErrorOr<URL::URL> decode(Decoder& decoder)
  70. {
  71. auto url_string = TRY(decoder.decode<ByteString>());
  72. URL::URL url { url_string };
  73. bool has_blob_url = TRY(decoder.decode<bool>());
  74. if (!has_blob_url)
  75. return url;
  76. url.set_blob_url_entry(URL::BlobURLEntry {
  77. .type = TRY(decoder.decode<String>()),
  78. .byte_buffer = TRY(decoder.decode<ByteBuffer>()),
  79. });
  80. return url;
  81. }
  82. template<>
  83. ErrorOr<File> decode(Decoder& decoder)
  84. {
  85. auto file = TRY(decoder.files().try_dequeue());
  86. auto fd = file.fd();
  87. auto fd_flags = TRY(Core::System::fcntl(fd, F_GETFD));
  88. TRY(Core::System::fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC));
  89. return file;
  90. }
  91. template<>
  92. ErrorOr<Empty> decode(Decoder&)
  93. {
  94. return Empty {};
  95. }
  96. template<>
  97. ErrorOr<Core::AnonymousBuffer> decode(Decoder& decoder)
  98. {
  99. if (auto valid = TRY(decoder.decode<bool>()); !valid)
  100. return Core::AnonymousBuffer {};
  101. auto size = TRY(decoder.decode_size());
  102. auto anon_file = TRY(decoder.decode<IPC::File>());
  103. return Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size);
  104. }
  105. template<>
  106. ErrorOr<Core::DateTime> decode(Decoder& decoder)
  107. {
  108. auto timestamp = TRY(decoder.decode<i64>());
  109. return Core::DateTime::from_timestamp(static_cast<time_t>(timestamp));
  110. }
  111. template<>
  112. ErrorOr<Core::ProxyData> decode(Decoder& decoder)
  113. {
  114. auto type = TRY(decoder.decode<Core::ProxyData::Type>());
  115. auto host_ipv4 = TRY(decoder.decode<u32>());
  116. auto port = TRY(decoder.decode<int>());
  117. return Core::ProxyData { type, host_ipv4, port };
  118. }
  119. }