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