/** * @file Buffer.cpp * @author apio (cloudapio.eu) * @brief A managed wrapper around a resizable buffer of arbitrary memory. * * @copyright Copyright (c) 2023, the Luna authors. * */ #include #include #include Buffer::Buffer() { } Buffer::Buffer(u8* data, usize size) : m_data(data), m_size(size) { } Buffer::Buffer(Buffer&& other) : m_data(other.data()), m_size(other.size()) { other.m_data = nullptr; } Buffer& Buffer::operator=(Buffer&& other) { if (&other == this) return *this; if (m_data) free_impl(m_data); m_data = other.m_data; m_size = other.m_size; other.m_data = nullptr; return *this; } Buffer::~Buffer() { if (m_data) free_impl(m_data); } Result Buffer::create_sized(usize size) { u8* data = (u8*)TRY(malloc_impl(size)); return Buffer { data, size }; } Result Buffer::try_resize(usize new_size) { m_data = (u8*)TRY(realloc_impl(m_data, new_size)); m_size = new_size; return {}; } Result Buffer::slice_at_end(usize size) { usize old_size = m_size; TRY(try_resize(m_size + size)); return m_data + old_size; } Result Buffer::slice(usize offset, usize size) { if (offset + size > m_size) { TRY(try_resize(offset + size)); } return m_data + offset; } Result Buffer::append_data(const u8* data, usize size) { memcpy(TRY(slice_at_end(size)), data, size); return {}; } usize Buffer::dequeue_data(u8* data, usize size) { if (size > m_size) size = m_size; if (!size) return 0; memcpy(data, m_data, size); memmove(m_data, m_data + size, m_size - size); m_size -= size; return size; } u8* Buffer::release_data() { u8* data = m_data; m_data = nullptr; return data; }