Luna/libluna/include/luna/Buffer.h
apio ffdcc843eb
All checks were successful
continuous-integration/drone/push Build is passing
kernel+terminal: Move pseudoterminal input processing to kernel-space
2023-09-22 22:45:35 +02:00

177 lines
4.7 KiB
C++

/**
* @file Buffer.h
* @author apio (cloudapio.eu)
* @brief A managed wrapper around a resizable buffer of arbitrary memory.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Result.h>
#include <luna/Types.h>
/**
* @brief A managed wrapper around a resizable buffer of arbitrary memory.
*/
class Buffer
{
public:
Buffer();
~Buffer();
/**
* @brief Create a new Buffer object, adopting existing data.
*
* The data provided will be owned by the buffer.
*
* @param data The data to use.
* @param size The amount of bytes in the data.
*/
Buffer(u8* data, usize size);
Buffer(Buffer&& other);
Buffer(const Buffer& other) = delete; // For now.
Buffer& operator=(Buffer&&);
Buffer& operator=(const Buffer&) = delete;
/**
* @brief Create a Buffer object, allocating a specific amount of memory for it.
*
* @param size The number of bytes to allocate.
* @return Result<Buffer> An error, or the newly created buffer.
*/
static Result<Buffer> create_sized(usize size);
/**
* @brief Resize the buffer.
*
* The existing data is kept, unless the new size is smaller than the old size, in which case only the first
* new_size bytes are kept.
*
* @param new_size The new size of the buffer, in bytes.
* @return Result<void> Whether the operation succeeded.
*/
Result<void> try_resize(usize new_size);
/**
* @brief Expand the buffer and return a pointer to the beginning of this new expanded area.
*
* @param size The amount of bytes to expand the buffer by.
* @return Result<u8*> An error, or a pointer to the new area of the buffer.
*/
Result<u8*> slice_at_end(usize size);
/**
* @brief Return a pointer to an area of the buffer, expanding it if necessary.
*
* @param offset The offset inside the buffer to start at.
* @param size The amount of bytes to reserve.
* @return Result<u8*> An error, or a pointer to the requested area.
*/
Result<u8*> slice(usize offset, usize size);
/**
* @brief Add data to the end of the buffer.
*
* @param data A pointer to the data to add.
* @param size The amount of bytes to add.
* @return Result<void> Whether the operation succeeded.
*/
Result<void> append_data(const u8* data, usize size);
/**
* @brief Remove data from the beginning of the buffer and return it.
*
* @param data A pointer to store the removed data in.
* @param size The amount of bytes to remove.
* @return usize The amount of bytes actually removed (may be less if the buffer was smaller than the requested
* size).
*/
usize dequeue_data(u8* data, usize size);
/**
* @brief Return a pointer to the data contained in the buffer.
*
* This pointer may be invalid after the buffer is resized.
*
* @return u8* The contained data.
*/
u8* data()
{
return m_data;
}
/**
* @brief Return a pointer to the data contained in the buffer.
*
* This pointer may be invalid after the buffer is resized.
*
* @return const u8* The contained data.
*/
const u8* data() const
{
return m_data;
}
/**
* @brief Return a pointer to the data contained in the buffer, moving the data out of the buffer.
*
* This call will empty the buffer, making it the caller's responsibility to manage the data, including freeing it
* when no longer used.
*
* @return u8* The released data.
*/
u8* release_data();
/**
* @brief Return a pointer to the end of the data contained in the buffer.
*
* This pointer points past the data; as such, dereferencing it directly is undefined behavior.
*
* @return u8* The end of the data.
*/
u8* end()
{
return m_data + m_size;
}
/**
* @brief Return a pointer to the end of the data contained in the buffer.
*
* This pointer points past the data; as such, dereferencing it directly is undefined behavior.
*
* @return const u8* The end of the data.
*/
const u8* end() const
{
return m_data + m_size;
}
/**
* @brief Return the size of the buffer in bytes.
*
* @return usize The buffer's size.
*/
usize size() const
{
return m_size;
}
/**
* @brief Check whether the buffer is empty.
*
* @return true The buffer is empty.
* @return false The buffer is not empty.
*/
bool is_empty() const
{
return m_size == 0;
}
private:
u8* m_data { nullptr };
usize m_size { 0 };
};