Files
2025-08-03 18:39:13 +02:00

220 lines
4.7 KiB
C++

#pragma once
/**
* \file DataBuffer.h
* \brief File containing the sp::DataBuffer class
*/
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <list>
#include <map>
#include <memory>
#include <sp/common/ByteSwapping.h>
#include <sp/common/VarInt.h>
#include <string>
#include <vector>
namespace sp {
/**
* \class DataBuffer
* \brief Class used to manipulate memory
*/
class DataBuffer {
private:
using Data = std::vector<std::uint8_t>;
private:
Data m_Buffer;
std::size_t m_ReadOffset;
public:
using iterator = Data::iterator;
using const_iterator = Data::const_iterator;
using reference = Data::reference;
using const_reference = Data::const_reference;
using difference_type = Data::difference_type;
DataBuffer();
DataBuffer(std::size_t a_InitialSize);
DataBuffer(const DataBuffer& other);
DataBuffer(const DataBuffer& other, difference_type offset);
DataBuffer(DataBuffer&& other);
DataBuffer(const std::string& str);
DataBuffer& operator=(const DataBuffer& other);
DataBuffer& operator=(DataBuffer&& other);
/**
* \brief Append data to the buffer
* \warning No endian checks
*/
template <typename T>
void Append(const T& a_Data) {
std::size_t size = sizeof(a_Data);
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + size);
std::memcpy(&m_Buffer[end_pos], &a_Data, size);
}
/**
* \brief Read data into a_Data
* \warning No endian checks
*/
template <typename T>
void Read(T& a_Data) {
assert(m_ReadOffset + sizeof(T) <= GetSize());
std::memcpy(&a_Data, m_Buffer.data() + m_ReadOffset, sizeof(T));
m_ReadOffset += sizeof(T);
}
/**
* \brief Write some data to the buffer
* \param buffer The buffer to write
* \param amount The amount of data to write
*/
void WriteSome(const char* buffer, std::size_t amount);
/**
* \brief Write some data to the buffer
* \param buffer The buffer to write
* \param amount The amount of data to write
*/
void WriteSome(const std::uint8_t* buffer, std::size_t amount);
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(char* buffer, std::size_t amount);
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(std::uint8_t* buffer, std::size_t amount);
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(DataBuffer& buffer, std::size_t amount);
/**
* \brief Resize the buffer
* \param size The new size of the buffer
*/
void Resize(std::size_t size) {
m_Buffer.resize(size);
}
/**
* \brief Reserve some space in the buffer
* \param amount The amount of space to reserve
*/
void Reserve(std::size_t amount) {
m_Buffer.reserve(amount);
}
/**
* \brief Clear the buffer
*/
void Clear() {
m_Buffer.clear();
m_ReadOffset = 0;
}
/**
* \brief When the buffer has been read entirely
*/
bool IsFinished() const {
return m_ReadOffset >= m_Buffer.size();
}
/**
* \brief Get the buffer data
*/
std::uint8_t* data() {
return m_Buffer.data();
}
/**
* \brief Get the buffer data
*/
const std::uint8_t* data() const {
return m_Buffer.data();
}
/**
* \brief Get the read offset
*/
std::size_t GetReadOffset() const {
return m_ReadOffset;
}
/**
* \brief Set the read offset
* \param pos The new read offset
*/
void SetReadOffset(std::size_t pos);
/**
* \brief Get the size of the buffer
*/
std::size_t GetSize() const;
/**
* \brief Get the remaining size of the buffer
*/
std::size_t GetRemaining() const;
/**
* \brief Read a file into the buffer
* \param fileName The name of the file to read
*/
void ReadFile(const std::string& fileName);
/**
* \brief Write a file into the buffer
* \param fileName The name of the file to write to
*/
void WriteFile(const std::string& fileName) const;
/**
* \brief Allocate the buffer on the heap
* \warning Don't forget to free the data !
*/
std::uint8_t* HeapAllocatedData() const {
std::uint8_t* newBuffer = new std::uint8_t[GetSize()];
std::memcpy(newBuffer, data(), GetSize());
return newBuffer;
}
/**
* \brief Operator == to compare two DataBuffer
*/
bool operator==(const DataBuffer& other) const {
return m_Buffer == other.m_Buffer;
}
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
};
/**
* \brief Append data to the buffer from another const buffer
* \param data The buffer to append
*/
DataBuffer& operator<<(DataBuffer& a_Buffer, const DataBuffer& data);
} // namespace sp