Serializer.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/ByteString.h>
  9. #include <AK/Debug.h>
  10. #include <AK/Format.h>
  11. #include <LibSQL/Forward.h>
  12. #include <LibSQL/Heap.h>
  13. namespace SQL {
  14. class Serializer {
  15. public:
  16. Serializer() = default;
  17. Serializer(RefPtr<Heap> heap)
  18. : m_heap(heap)
  19. {
  20. }
  21. void read_storage(Block::Index block_index)
  22. {
  23. m_buffer = m_heap->read_storage(block_index).release_value_but_fixme_should_propagate_errors();
  24. m_current_offset = 0;
  25. }
  26. void reset()
  27. {
  28. m_buffer.clear();
  29. m_current_offset = 0;
  30. }
  31. void rewind()
  32. {
  33. m_current_offset = 0;
  34. }
  35. template<typename T, typename... Args>
  36. T deserialize_block(Block::Index block_index, Args&&... args)
  37. {
  38. read_storage(block_index);
  39. return deserialize<T>(forward<Args>(args)...);
  40. }
  41. template<typename T>
  42. void deserialize_block_to(Block::Index block_index, T& t)
  43. {
  44. read_storage(block_index);
  45. return deserialize_to<T>(t);
  46. }
  47. template<typename T>
  48. void deserialize_to(T& t)
  49. {
  50. if constexpr (IsArithmetic<T>)
  51. memcpy(&t, read(sizeof(T)), sizeof(T));
  52. else
  53. t.deserialize(*this);
  54. }
  55. void deserialize_to(ByteString& text);
  56. template<typename T, typename... Args>
  57. NonnullOwnPtr<T> make_and_deserialize(Args&&... args)
  58. {
  59. auto ptr = make<T>(forward<Args>(args)...);
  60. ptr->deserialize(*this);
  61. return ptr;
  62. }
  63. template<typename T, typename... Args>
  64. NonnullRefPtr<T> adopt_and_deserialize(Args&&... args)
  65. {
  66. auto ptr = adopt_ref(*new T(forward<Args>(args)...));
  67. ptr->deserialize(*this);
  68. return ptr;
  69. }
  70. template<typename T, typename... Args>
  71. T deserialize(Args&&... args)
  72. {
  73. T t(forward<Args>(args)...);
  74. deserialize_to(t);
  75. return t;
  76. }
  77. template<typename T>
  78. void serialize(T const& t)
  79. {
  80. if constexpr (IsArithmetic<T>)
  81. write((u8 const*)(&t), sizeof(T));
  82. else
  83. t.serialize(*this);
  84. }
  85. void serialize(ByteString const&);
  86. template<typename T>
  87. bool serialize_and_write(T const& t)
  88. {
  89. VERIFY(!m_heap.is_null());
  90. reset();
  91. serialize<T>(t);
  92. m_heap->write_storage(t.block_index(), m_buffer).release_value_but_fixme_should_propagate_errors();
  93. return true;
  94. }
  95. [[nodiscard]] size_t offset() const { return m_current_offset; }
  96. u32 request_new_block_index()
  97. {
  98. return m_heap->request_new_block_index();
  99. }
  100. bool has_block(u32 pointer) const
  101. {
  102. return m_heap->has_block(pointer);
  103. }
  104. Heap& heap()
  105. {
  106. return *m_heap;
  107. }
  108. private:
  109. void write(u8 const* ptr, size_t sz)
  110. {
  111. if constexpr (SQL_DEBUG)
  112. dump(ptr, sz, "(out) =>");
  113. m_buffer.append(ptr, sz);
  114. m_current_offset += sz;
  115. }
  116. u8 const* read(size_t sz)
  117. {
  118. auto buffer_ptr = m_buffer.offset_pointer(m_current_offset);
  119. if constexpr (SQL_DEBUG)
  120. dump(buffer_ptr, sz, "<= (in)");
  121. m_current_offset += sz;
  122. return buffer_ptr;
  123. }
  124. static void dump(u8 const* ptr, size_t sz, ByteString const& prefix)
  125. {
  126. StringBuilder builder;
  127. builder.appendff("{0} {1:04x} | ", prefix, sz);
  128. Vector<ByteString> bytes;
  129. for (auto ix = 0u; ix < sz; ++ix)
  130. bytes.append(ByteString::formatted("{0:02x}", *(ptr + ix)));
  131. StringBuilder bytes_builder;
  132. bytes_builder.join(' ', bytes);
  133. builder.append(bytes_builder.to_byte_string());
  134. dbgln(builder.to_byte_string());
  135. }
  136. ByteBuffer m_buffer {};
  137. size_t m_current_offset { 0 };
  138. // FIXME: make this a NonnullRefPtr<Heap> so we can get rid of the null checks
  139. RefPtr<Heap> m_heap { nullptr };
  140. };
  141. }