/** * @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 [[nodiscard]] T reader() { static_assert(std::is_arithmetic_v, "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 void write(T value) { static_assert(std::is_arithmetic_v, "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; }; }