Encoder.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/ByteBuffer.h>
  7. #include <AK/String.h>
  8. #include <AK/URL.h>
  9. #include <LibCore/AnonymousBuffer.h>
  10. #include <LibCore/DateTime.h>
  11. #include <LibIPC/Dictionary.h>
  12. #include <LibIPC/Encoder.h>
  13. #include <LibIPC/File.h>
  14. namespace IPC {
  15. Encoder& Encoder::operator<<(bool value)
  16. {
  17. return *this << (u8)value;
  18. }
  19. Encoder& Encoder::operator<<(u8 value)
  20. {
  21. m_buffer.data.append(value);
  22. return *this;
  23. }
  24. Encoder& Encoder::operator<<(u16 value)
  25. {
  26. m_buffer.data.ensure_capacity(m_buffer.data.size() + 2);
  27. m_buffer.data.unchecked_append((u8)value);
  28. m_buffer.data.unchecked_append((u8)(value >> 8));
  29. return *this;
  30. }
  31. Encoder& Encoder::operator<<(u32 value)
  32. {
  33. m_buffer.data.ensure_capacity(m_buffer.data.size() + 4);
  34. m_buffer.data.unchecked_append((u8)value);
  35. m_buffer.data.unchecked_append((u8)(value >> 8));
  36. m_buffer.data.unchecked_append((u8)(value >> 16));
  37. m_buffer.data.unchecked_append((u8)(value >> 24));
  38. return *this;
  39. }
  40. Encoder& Encoder::operator<<(u64 value)
  41. {
  42. m_buffer.data.ensure_capacity(m_buffer.data.size() + 8);
  43. m_buffer.data.unchecked_append((u8)value);
  44. m_buffer.data.unchecked_append((u8)(value >> 8));
  45. m_buffer.data.unchecked_append((u8)(value >> 16));
  46. m_buffer.data.unchecked_append((u8)(value >> 24));
  47. m_buffer.data.unchecked_append((u8)(value >> 32));
  48. m_buffer.data.unchecked_append((u8)(value >> 40));
  49. m_buffer.data.unchecked_append((u8)(value >> 48));
  50. m_buffer.data.unchecked_append((u8)(value >> 56));
  51. return *this;
  52. }
  53. Encoder& Encoder::operator<<(i8 value)
  54. {
  55. m_buffer.data.append((u8)value);
  56. return *this;
  57. }
  58. Encoder& Encoder::operator<<(i16 value)
  59. {
  60. m_buffer.data.ensure_capacity(m_buffer.data.size() + 2);
  61. m_buffer.data.unchecked_append((u8)value);
  62. m_buffer.data.unchecked_append((u8)(value >> 8));
  63. return *this;
  64. }
  65. Encoder& Encoder::operator<<(i32 value)
  66. {
  67. m_buffer.data.ensure_capacity(m_buffer.data.size() + 4);
  68. m_buffer.data.unchecked_append((u8)value);
  69. m_buffer.data.unchecked_append((u8)(value >> 8));
  70. m_buffer.data.unchecked_append((u8)(value >> 16));
  71. m_buffer.data.unchecked_append((u8)(value >> 24));
  72. return *this;
  73. }
  74. Encoder& Encoder::operator<<(i64 value)
  75. {
  76. m_buffer.data.ensure_capacity(m_buffer.data.size() + 8);
  77. m_buffer.data.unchecked_append((u8)value);
  78. m_buffer.data.unchecked_append((u8)(value >> 8));
  79. m_buffer.data.unchecked_append((u8)(value >> 16));
  80. m_buffer.data.unchecked_append((u8)(value >> 24));
  81. m_buffer.data.unchecked_append((u8)(value >> 32));
  82. m_buffer.data.unchecked_append((u8)(value >> 40));
  83. m_buffer.data.unchecked_append((u8)(value >> 48));
  84. m_buffer.data.unchecked_append((u8)(value >> 56));
  85. return *this;
  86. }
  87. Encoder& Encoder::operator<<(float value)
  88. {
  89. union bits {
  90. float as_float;
  91. u32 as_u32;
  92. } u;
  93. u.as_float = value;
  94. return *this << u.as_u32;
  95. }
  96. Encoder& Encoder::operator<<(const char* value)
  97. {
  98. return *this << StringView(value);
  99. }
  100. Encoder& Encoder::operator<<(const StringView& value)
  101. {
  102. m_buffer.data.append((const u8*)value.characters_without_null_termination(), value.length());
  103. return *this;
  104. }
  105. Encoder& Encoder::operator<<(const String& value)
  106. {
  107. if (value.is_null())
  108. return *this << (i32)-1;
  109. *this << static_cast<i32>(value.length());
  110. return *this << value.view();
  111. }
  112. Encoder& Encoder::operator<<(const ByteBuffer& value)
  113. {
  114. *this << static_cast<i32>(value.size());
  115. m_buffer.data.append(value.data(), value.size());
  116. return *this;
  117. }
  118. Encoder& Encoder::operator<<(const URL& value)
  119. {
  120. return *this << value.to_string();
  121. }
  122. Encoder& Encoder::operator<<(const Dictionary& dictionary)
  123. {
  124. *this << (u64)dictionary.size();
  125. dictionary.for_each_entry([this](auto& key, auto& value) {
  126. *this << key << value;
  127. });
  128. return *this;
  129. }
  130. Encoder& Encoder::operator<<(const File& file)
  131. {
  132. int fd = file.fd();
  133. if (fd != -1) {
  134. auto result = dup(fd);
  135. if (result < 0) {
  136. perror("dup");
  137. VERIFY_NOT_REACHED();
  138. }
  139. fd = result;
  140. }
  141. m_buffer.fds.append(adopt_ref(*new AutoCloseFileDescriptor(fd)));
  142. return *this;
  143. }
  144. bool encode(Encoder& encoder, const Core::AnonymousBuffer& buffer)
  145. {
  146. encoder << buffer.is_valid();
  147. if (buffer.is_valid()) {
  148. encoder << (u32)buffer.size();
  149. encoder << IPC::File(buffer.fd());
  150. }
  151. return true;
  152. }
  153. bool encode(Encoder& encoder, const Core::DateTime& datetime)
  154. {
  155. encoder << static_cast<i64>(datetime.timestamp());
  156. return true;
  157. }
  158. }