123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /*
- * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/ByteBuffer.h>
- #include <AK/Debug.h>
- #include <AK/DeprecatedString.h>
- #include <AK/Format.h>
- #include <AK/ScopeGuard.h>
- #include <LibSQL/Forward.h>
- #include <LibSQL/Heap.h>
- #include <string.h>
- namespace SQL {
- class Serializer {
- public:
- Serializer() = default;
- Serializer(RefPtr<Heap> heap)
- : m_heap(heap)
- {
- }
- void get_block(u32 pointer)
- {
- VERIFY(m_heap.ptr() != nullptr);
- auto buffer_or_error = m_heap->read_block(pointer);
- if (buffer_or_error.is_error())
- VERIFY_NOT_REACHED();
- m_buffer = buffer_or_error.value();
- m_current_offset = 0;
- }
- void reset()
- {
- m_buffer.clear();
- m_current_offset = 0;
- }
- void rewind()
- {
- m_current_offset = 0;
- }
- template<typename T, typename... Args>
- T deserialize_block(u32 pointer, Args&&... args)
- {
- get_block(pointer);
- return deserialize<T>(forward<Args>(args)...);
- }
- template<typename T>
- void deserialize_block_to(u32 pointer, T& t)
- {
- get_block(pointer);
- return deserialize_to<T>(t);
- }
- template<typename T>
- void deserialize_to(T& t)
- {
- if constexpr (IsArithmetic<T>)
- memcpy(&t, read(sizeof(T)), sizeof(T));
- else
- t.deserialize(*this);
- }
- void deserialize_to(DeprecatedString& text);
- template<typename T, typename... Args>
- NonnullOwnPtr<T> make_and_deserialize(Args&&... args)
- {
- auto ptr = make<T>(forward<Args>(args)...);
- ptr->deserialize(*this);
- return ptr;
- }
- template<typename T, typename... Args>
- NonnullRefPtr<T> adopt_and_deserialize(Args&&... args)
- {
- auto ptr = adopt_ref(*new T(forward<Args>(args)...));
- ptr->deserialize(*this);
- return ptr;
- }
- template<typename T, typename... Args>
- T deserialize(Args&&... args)
- {
- T t(forward<Args>(args)...);
- deserialize_to(t);
- return t;
- }
- template<typename T>
- void serialize(T const& t)
- {
- if constexpr (IsArithmetic<T>)
- write((u8 const*)(&t), sizeof(T));
- else
- t.serialize(*this);
- }
- void serialize(DeprecatedString const&);
- template<typename T>
- bool serialize_and_write(T const& t)
- {
- VERIFY(m_heap.ptr() != nullptr);
- reset();
- serialize<T>(t);
- m_heap->add_to_wal(t.pointer(), m_buffer);
- return true;
- }
- [[nodiscard]] size_t offset() const { return m_current_offset; }
- u32 new_record_pointer()
- {
- VERIFY(m_heap.ptr() != nullptr);
- return m_heap->new_record_pointer();
- }
- bool has_block(u32 pointer) const
- {
- VERIFY(m_heap.ptr() != nullptr);
- return pointer < m_heap->size();
- }
- Heap& heap()
- {
- VERIFY(m_heap.ptr() != nullptr);
- return *(m_heap.ptr());
- }
- private:
- void write(u8 const* ptr, size_t sz)
- {
- if constexpr (SQL_DEBUG)
- dump(ptr, sz, "(out) =>");
- m_buffer.append(ptr, sz);
- m_current_offset += sz;
- }
- u8 const* read(size_t sz)
- {
- auto buffer_ptr = m_buffer.offset_pointer(m_current_offset);
- if constexpr (SQL_DEBUG)
- dump(buffer_ptr, sz, "<= (in)");
- m_current_offset += sz;
- return buffer_ptr;
- }
- static void dump(u8 const* ptr, size_t sz, DeprecatedString const& prefix)
- {
- StringBuilder builder;
- builder.appendff("{0} {1:04x} | ", prefix, sz);
- Vector<DeprecatedString> bytes;
- for (auto ix = 0u; ix < sz; ++ix) {
- bytes.append(DeprecatedString::formatted("{0:02x}", *(ptr + ix)));
- }
- StringBuilder bytes_builder;
- bytes_builder.join(' ', bytes);
- builder.append(bytes_builder.to_deprecated_string());
- dbgln(builder.to_deprecated_string());
- }
- ByteBuffer m_buffer {};
- size_t m_current_offset { 0 };
- RefPtr<Heap> m_heap { nullptr };
- };
- }
|