Luna/libluna/src/Buffer.cpp

95 lines
1.7 KiB
C++

/**
* @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 <luna/Buffer.h>
#include <luna/CString.h>
#include <luna/Heap.h>
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> Buffer::create_sized(usize size)
{
u8* data = (u8*)TRY(malloc_impl(size));
return Buffer { data, size };
}
Result<void> Buffer::try_resize(usize new_size)
{
m_data = (u8*)TRY(realloc_impl(m_data, new_size));
m_size = new_size;
return {};
}
Result<u8*> Buffer::slice_at_end(usize size)
{
usize old_size = m_size;
TRY(try_resize(m_size + size));
return m_data + old_size;
}
Result<u8*> Buffer::slice(usize offset, usize size)
{
if (offset + size > m_size) { TRY(try_resize(offset + size)); }
return m_data + offset;
}
Result<void> 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;
}