155 lines
3.7 KiB
C++
155 lines
3.7 KiB
C++
/**
|
|
* @file IOStream.h
|
|
* @brief 面向内存缓冲区的二进制流读写工具。
|
|
* @details
|
|
* 定义 reader/writer 两个轻量类,用于在连续内存上顺序序列化:
|
|
* - 支持算术类型按字节写入与读取;
|
|
* - 支持原始块拷贝与位置跳过;
|
|
* - 通过边界断言降低越界读写风险。
|
|
*/
|
|
#pragma once
|
|
#include "CommonHeader.h"
|
|
|
|
namespace XEngine::utl {
|
|
|
|
/**
|
|
* @brief 只读内存二进制流。
|
|
*/
|
|
class blob_stream_reader
|
|
{
|
|
public:
|
|
DISABLE_COPY_AND_MOVE(blob_stream_reader);
|
|
/**
|
|
* @brief 绑定外部只读缓冲区。
|
|
* @param buffer 缓冲区首地址。
|
|
*/
|
|
explicit blob_stream_reader(const u8* buffer)
|
|
:_buffer{buffer}, _position{buffer}
|
|
{
|
|
assert(buffer);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 按类型读取一个值并推进游标。
|
|
* @tparam T 算术类型。
|
|
* @return 读取到的值。
|
|
*/
|
|
template<typename T>
|
|
[[nodiscard]] T reader()
|
|
{
|
|
static_assert(std::is_arithmetic_v<T>, "Template argument should be a primitive type.");
|
|
T value{ *((T*)_position) };
|
|
_position += sizeof(T);
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* @brief 读取原始字节块并推进游标。
|
|
* @param buffer 输出缓冲区。
|
|
* @param length 读取字节数。
|
|
*/
|
|
void read(u8* buffer, size_t length)
|
|
{
|
|
memcpy(buffer, _position, length);
|
|
_position += length;
|
|
}
|
|
|
|
/**
|
|
* @brief 跳过指定字节数。
|
|
* @param offset 偏移字节数。
|
|
*/
|
|
void skip(size_t offset)
|
|
{
|
|
_position += offset;
|
|
}
|
|
|
|
[[nodiscard]] constexpr const u8 *const buffer_start() const { return _buffer; }
|
|
[[nodiscard]] constexpr const u8 *const position() const { return _position; }
|
|
[[nodiscard]] constexpr size_t offset() const { return _position - _buffer; }
|
|
|
|
private:
|
|
const u8 *const _buffer;
|
|
const u8* _position;
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief 可写内存二进制流。
|
|
*/
|
|
class blob_stream_writer
|
|
{
|
|
public:
|
|
DISABLE_COPY_AND_MOVE(blob_stream_writer);
|
|
/**
|
|
* @brief 绑定外部可写缓冲区。
|
|
* @param buffer 缓冲区首地址。
|
|
* @param buffer_size 缓冲区大小。
|
|
*/
|
|
explicit blob_stream_writer(u8* buffer, size_t buffer_size)
|
|
:_buffer{ buffer }, _position{ buffer }, _buffer_size(buffer_size)
|
|
{
|
|
assert(buffer && buffer_size);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 写入一个算术类型值并推进游标。
|
|
* @tparam T 算术类型。
|
|
* @param value 待写入值。
|
|
*/
|
|
template<typename T>
|
|
void write(T value)
|
|
{
|
|
static_assert(std::is_arithmetic_v<T>, "Template argument should be a primitive type.");
|
|
assert(&_position[sizeof(T)] <= &_buffer[_buffer_size]);
|
|
*((T*)_position) = value;
|
|
_position += sizeof(T);
|
|
}
|
|
|
|
/**
|
|
* @brief 写入字符缓冲区。
|
|
* @param buffer 输入缓冲区。
|
|
* @param length 写入字节数。
|
|
*/
|
|
void write(const char* buffer, size_t length)
|
|
{
|
|
assert(&_position[length] <= &_buffer[_buffer_size]);
|
|
memcpy(_position, buffer, length);
|
|
_position += length;
|
|
}
|
|
|
|
/**
|
|
* @brief 写入字节缓冲区。
|
|
* @param buffer 输入缓冲区。
|
|
* @param length 写入字节数。
|
|
*/
|
|
void write(const u8* buffer, size_t length)
|
|
{
|
|
assert(&_position[length] <= &_buffer[_buffer_size]);
|
|
memcpy(_position, buffer, length);
|
|
_position += length;
|
|
}
|
|
|
|
/**
|
|
* @brief 跳过指定字节数。
|
|
* @param offset 偏移字节数。
|
|
*/
|
|
void skip(size_t offset)
|
|
{
|
|
assert(&_position[offset] <= &_buffer[_buffer_size]);
|
|
_position += offset;
|
|
}
|
|
|
|
[[nodiscard]] constexpr const u8 *const buffer_start() const { return _buffer; }
|
|
[[nodiscard]] constexpr const u8 *const buffer_end() const { return &_buffer[_buffer_size]; }
|
|
[[nodiscard]] constexpr const u8 *const position() const { return _position; }
|
|
[[nodiscard]] constexpr size_t offset() const { return _position - _buffer; }
|
|
|
|
private:
|
|
u8 *const _buffer;
|
|
u8* _position;
|
|
size_t _buffer_size;
|
|
};
|
|
}
|