Files
DX12/Engine/Utilities/IOStream.h
2026-03-19 18:27:49 +08:00

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;
};
}