Decoder.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 <AK/URL.h>
  10. #include <LibCore/AnonymousBuffer.h>
  11. #include <LibCore/DateTime.h>
  12. #include <LibCore/Proxy.h>
  13. #include <LibCore/Socket.h>
  14. #include <LibIPC/Decoder.h>
  15. #include <LibIPC/Dictionary.h>
  16. #include <LibIPC/File.h>
  17. #include <fcntl.h>
  18. namespace IPC {
  19. ErrorOr<size_t> Decoder::decode_size()
  20. {
  21. return static_cast<size_t>(TRY(decode<u32>()));
  22. }
  23. template<>
  24. ErrorOr<String> decode(Decoder& decoder)
  25. {
  26. auto length = TRY(decoder.decode_size());
  27. return String::from_stream(decoder.stream(), length);
  28. }
  29. template<>
  30. ErrorOr<DeprecatedString> decode(Decoder& decoder)
  31. {
  32. auto length = TRY(decoder.decode_size());
  33. if (length == NumericLimits<u32>::max())
  34. return DeprecatedString {};
  35. if (length == 0)
  36. return DeprecatedString::empty();
  37. char* text_buffer = nullptr;
  38. auto text_impl = StringImpl::create_uninitialized(length, text_buffer);
  39. Bytes bytes { text_buffer, length };
  40. TRY(decoder.decode_into(bytes));
  41. return DeprecatedString { *text_impl };
  42. }
  43. template<>
  44. ErrorOr<ByteBuffer> decode(Decoder& decoder)
  45. {
  46. auto length = TRY(decoder.decode_size());
  47. if (length == 0)
  48. return ByteBuffer {};
  49. auto buffer = TRY(ByteBuffer::create_uninitialized(length));
  50. auto bytes = buffer.bytes();
  51. TRY(decoder.decode_into(bytes));
  52. return buffer;
  53. }
  54. template<>
  55. ErrorOr<JsonValue> decode(Decoder& decoder)
  56. {
  57. auto json = TRY(decoder.decode<DeprecatedString>());
  58. return JsonValue::from_string(json);
  59. }
  60. template<>
  61. ErrorOr<Time> decode(Decoder& decoder)
  62. {
  63. auto nanoseconds = TRY(decoder.decode<i64>());
  64. return AK::Time::from_nanoseconds(nanoseconds);
  65. }
  66. template<>
  67. ErrorOr<URL> decode(Decoder& decoder)
  68. {
  69. auto url = TRY(decoder.decode<DeprecatedString>());
  70. return URL { url };
  71. }
  72. template<>
  73. ErrorOr<Dictionary> decode(Decoder& decoder)
  74. {
  75. auto size = TRY(decoder.decode_size());
  76. Dictionary dictionary {};
  77. for (size_t i = 0; i < size; ++i) {
  78. auto key = TRY(decoder.decode<DeprecatedString>());
  79. auto value = TRY(decoder.decode<DeprecatedString>());
  80. dictionary.add(move(key), move(value));
  81. }
  82. return dictionary;
  83. }
  84. template<>
  85. ErrorOr<File> decode(Decoder& decoder)
  86. {
  87. int fd = TRY(decoder.socket().receive_fd(O_CLOEXEC));
  88. return File { fd, File::ConstructWithReceivedFileDescriptor };
  89. }
  90. template<>
  91. ErrorOr<Empty> decode(Decoder&)
  92. {
  93. return Empty {};
  94. }
  95. template<>
  96. ErrorOr<Core::AnonymousBuffer> decode(Decoder& decoder)
  97. {
  98. if (auto valid = TRY(decoder.decode<bool>()); !valid)
  99. return Core::AnonymousBuffer {};
  100. auto size = TRY(decoder.decode_size());
  101. auto anon_file = TRY(decoder.decode<IPC::File>());
  102. return Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size);
  103. }
  104. template<>
  105. ErrorOr<Core::DateTime> decode(Decoder& decoder)
  106. {
  107. auto timestamp = TRY(decoder.decode<i64>());
  108. return Core::DateTime::from_timestamp(static_cast<time_t>(timestamp));
  109. }
  110. template<>
  111. ErrorOr<Core::ProxyData> decode(Decoder& decoder)
  112. {
  113. auto type = TRY(decoder.decode<Core::ProxyData::Type>());
  114. auto host_ipv4 = TRY(decoder.decode<u32>());
  115. auto port = TRY(decoder.decode<int>());
  116. return Core::ProxyData { type, host_ipv4, port };
  117. }
  118. }