ladybird/Userland/Libraries/LibSQL/Serializer.h
Linus Groh 57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.

One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
2022-12-06 08:54:33 +01:00

177 lines
4.0 KiB
C++

/*
* 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 };
};
}