Serializer.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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/Debug.h>
  9. #include <AK/DeprecatedString.h>
  10. #include <AK/Format.h>
  11. #include <AK/ScopeGuard.h>
  12. #include <LibSQL/Forward.h>
  13. #include <LibSQL/Heap.h>
  14. #include <string.h>
  15. namespace SQL {
  16. class Serializer {
  17. public:
  18. Serializer() = default;
  19. Serializer(RefPtr<Heap> heap)
  20. : m_heap(heap)
  21. {
  22. }
  23. void get_block(u32 pointer)
  24. {
  25. VERIFY(m_heap.ptr() != nullptr);
  26. auto buffer_or_error = m_heap->read_block(pointer);
  27. if (buffer_or_error.is_error())
  28. VERIFY_NOT_REACHED();
  29. m_buffer = buffer_or_error.value();
  30. m_current_offset = 0;
  31. }
  32. void reset()
  33. {
  34. m_buffer.clear();
  35. m_current_offset = 0;
  36. }
  37. void rewind()
  38. {
  39. m_current_offset = 0;
  40. }
  41. template<typename T, typename... Args>
  42. T deserialize_block(u32 pointer, Args&&... args)
  43. {
  44. get_block(pointer);
  45. return deserialize<T>(forward<Args>(args)...);
  46. }
  47. template<typename T>
  48. void deserialize_block_to(u32 pointer, T& t)
  49. {
  50. get_block(pointer);
  51. return deserialize_to<T>(t);
  52. }
  53. template<typename T>
  54. void deserialize_to(T& t)
  55. {
  56. if constexpr (IsArithmetic<T>)
  57. memcpy(&t, read(sizeof(T)), sizeof(T));
  58. else
  59. t.deserialize(*this);
  60. }
  61. void deserialize_to(DeprecatedString& text);
  62. template<typename T, typename... Args>
  63. NonnullOwnPtr<T> make_and_deserialize(Args&&... args)
  64. {
  65. auto ptr = make<T>(forward<Args>(args)...);
  66. ptr->deserialize(*this);
  67. return ptr;
  68. }
  69. template<typename T, typename... Args>
  70. NonnullRefPtr<T> adopt_and_deserialize(Args&&... args)
  71. {
  72. auto ptr = adopt_ref(*new T(forward<Args>(args)...));
  73. ptr->deserialize(*this);
  74. return ptr;
  75. }
  76. template<typename T, typename... Args>
  77. T deserialize(Args&&... args)
  78. {
  79. T t(forward<Args>(args)...);
  80. deserialize_to(t);
  81. return t;
  82. }
  83. template<typename T>
  84. void serialize(T const& t)
  85. {
  86. if constexpr (IsArithmetic<T>)
  87. write((u8 const*)(&t), sizeof(T));
  88. else
  89. t.serialize(*this);
  90. }
  91. void serialize(DeprecatedString const&);
  92. template<typename T>
  93. bool serialize_and_write(T const& t)
  94. {
  95. VERIFY(m_heap.ptr() != nullptr);
  96. reset();
  97. serialize<T>(t);
  98. m_heap->add_to_wal(t.pointer(), m_buffer);
  99. return true;
  100. }
  101. [[nodiscard]] size_t offset() const { return m_current_offset; }
  102. u32 new_record_pointer()
  103. {
  104. VERIFY(m_heap.ptr() != nullptr);
  105. return m_heap->new_record_pointer();
  106. }
  107. bool has_block(u32 pointer) const
  108. {
  109. VERIFY(m_heap.ptr() != nullptr);
  110. return pointer < m_heap->size();
  111. }
  112. Heap& heap()
  113. {
  114. VERIFY(m_heap.ptr() != nullptr);
  115. return *(m_heap.ptr());
  116. }
  117. private:
  118. void write(u8 const* ptr, size_t sz)
  119. {
  120. if constexpr (SQL_DEBUG)
  121. dump(ptr, sz, "(out) =>");
  122. m_buffer.append(ptr, sz);
  123. m_current_offset += sz;
  124. }
  125. u8 const* read(size_t sz)
  126. {
  127. auto buffer_ptr = m_buffer.offset_pointer(m_current_offset);
  128. if constexpr (SQL_DEBUG)
  129. dump(buffer_ptr, sz, "<= (in)");
  130. m_current_offset += sz;
  131. return buffer_ptr;
  132. }
  133. static void dump(u8 const* ptr, size_t sz, DeprecatedString const& prefix)
  134. {
  135. StringBuilder builder;
  136. builder.appendff("{0} {1:04x} | ", prefix, sz);
  137. Vector<DeprecatedString> bytes;
  138. for (auto ix = 0u; ix < sz; ++ix) {
  139. bytes.append(DeprecatedString::formatted("{0:02x}", *(ptr + ix)));
  140. }
  141. StringBuilder bytes_builder;
  142. bytes_builder.join(' ', bytes);
  143. builder.append(bytes_builder.to_deprecated_string());
  144. dbgln(builder.to_deprecated_string());
  145. }
  146. ByteBuffer m_buffer {};
  147. size_t m_current_offset { 0 };
  148. RefPtr<Heap> m_heap { nullptr };
  149. };
  150. }