2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2023-03-10 23:27:08 +00:00
|
|
|
#pragma once
|
|
|
|
#include <luna/Result.h>
|
|
|
|
#include <luna/Types.h>
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @brief A managed wrapper around a resizable buffer of arbitrary memory.
|
|
|
|
*/
|
2023-03-10 23:27:08 +00:00
|
|
|
class Buffer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Buffer();
|
|
|
|
~Buffer();
|
|
|
|
|
|
|
|
Buffer(Buffer&& other);
|
|
|
|
Buffer(const Buffer& other) = delete; // For now.
|
|
|
|
|
2023-08-04 13:10:33 +00:00
|
|
|
Buffer& operator=(Buffer&&);
|
|
|
|
Buffer& operator=(const Buffer&) = delete;
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:27:08 +00:00
|
|
|
static Result<Buffer> create_sized(usize size);
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:27:08 +00:00
|
|
|
Result<void> try_resize(usize new_size);
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:52:39 +00:00
|
|
|
Result<u8*> slice_at_end(usize size);
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:52:39 +00:00
|
|
|
Result<u8*> slice(usize offset, usize size);
|
2023-03-10 23:27:08 +00:00
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-04-07 09:52:20 +00:00
|
|
|
Result<void> append_data(const u8* data, usize size);
|
2023-03-23 20:20:57 +00:00
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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).
|
|
|
|
*/
|
2023-07-27 14:35:52 +00:00
|
|
|
usize dequeue_data(u8* data, usize size);
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:27:08 +00:00
|
|
|
u8* data()
|
|
|
|
{
|
|
|
|
return m_data;
|
|
|
|
}
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:27:08 +00:00
|
|
|
const u8* data() const
|
|
|
|
{
|
|
|
|
return m_data;
|
|
|
|
}
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-07-02 17:29:04 +00:00
|
|
|
u8* release_data();
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:52:39 +00:00
|
|
|
u8* end()
|
|
|
|
{
|
|
|
|
return m_data + m_size;
|
|
|
|
}
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-10 23:52:39 +00:00
|
|
|
const u8* end() const
|
|
|
|
{
|
|
|
|
return m_data + m_size;
|
|
|
|
}
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @brief Return the size of the buffer in bytes.
|
|
|
|
*
|
|
|
|
* @return usize The buffer's size.
|
|
|
|
*/
|
2023-03-10 23:27:08 +00:00
|
|
|
usize size() const
|
|
|
|
{
|
|
|
|
return m_size;
|
|
|
|
}
|
|
|
|
|
2023-08-28 09:10:04 +00:00
|
|
|
/**
|
|
|
|
* @brief Check whether the buffer is empty.
|
|
|
|
*
|
|
|
|
* @return true The buffer is empty.
|
|
|
|
* @return false The buffer is not empty.
|
|
|
|
*/
|
2023-04-18 14:40:37 +00:00
|
|
|
bool is_empty() const
|
|
|
|
{
|
|
|
|
return m_size == 0;
|
|
|
|
}
|
|
|
|
|
2023-03-10 23:27:08 +00:00
|
|
|
private:
|
|
|
|
Buffer(u8* data, usize size);
|
|
|
|
|
|
|
|
u8* m_data { nullptr };
|
|
|
|
usize m_size { 0 };
|
|
|
|
};
|