164 lines
3.5 KiB
C++
164 lines
3.5 KiB
C++
#pragma once
|
||
|
||
#include <vector>
|
||
#include <cstdint>
|
||
#include <cstring>
|
||
|
||
/**
|
||
* @brief 自定义字节数组容器类
|
||
* @details 提供类似QByteArray的功能,用于处理二进制数据
|
||
*/
|
||
class XNByteArray
|
||
{
|
||
public:
|
||
XNByteArray() = default;
|
||
explicit XNByteArray(size_t size) : data_(size) {}
|
||
|
||
/**
|
||
* @brief 从原始数据构造
|
||
* @param buffer 原始数据缓冲区
|
||
* @param size 数据大小
|
||
*/
|
||
XNByteArray(const uint8_t *buffer, size_t size) : data_(buffer, buffer + size) {}
|
||
|
||
/**
|
||
* @brief 获取数据指针
|
||
* @return 数据指针
|
||
*/
|
||
uint8_t *data() { return data_.data(); }
|
||
|
||
/**
|
||
* @brief 获取常量数据指针
|
||
* @return 常量数据指针
|
||
*/
|
||
const uint8_t *data() const { return data_.data(); }
|
||
|
||
/**
|
||
* @brief 获取数据大小
|
||
* @return 数据大小
|
||
*/
|
||
size_t size() const { return data_.size(); }
|
||
|
||
/**
|
||
* @brief 调整大小
|
||
* @param size 新大小
|
||
*/
|
||
void resize(size_t size) { data_.resize(size); }
|
||
|
||
/**
|
||
* @brief 清空数据
|
||
*/
|
||
void clear() { data_.clear(); }
|
||
|
||
/**
|
||
* @brief 追加数据
|
||
* @param buffer 要追加的数据
|
||
* @param size 数据大小
|
||
*/
|
||
void append(const uint8_t *buffer, size_t size)
|
||
{
|
||
size_t oldSize = data_.size();
|
||
data_.resize(oldSize + size);
|
||
std::memcpy(data_.data() + oldSize, buffer, size);
|
||
}
|
||
|
||
/**
|
||
* @brief 追加另一个XNByteArray
|
||
* @param other 要追加的XNByteArray
|
||
*/
|
||
void append(const XNByteArray &other) { append(other.data(), other.size()); }
|
||
|
||
/**
|
||
* @brief 获取指定位置的字节
|
||
* @param index 索引
|
||
* @return 字节值
|
||
*/
|
||
uint8_t &operator[](size_t index) { return data_[index]; }
|
||
|
||
/**
|
||
* @brief 获取指定位置的字节(常量版本)
|
||
* @param index 索引
|
||
* @return 字节值
|
||
*/
|
||
const uint8_t &operator[](size_t index) const { return data_[index]; }
|
||
|
||
/**
|
||
* @brief 检查是否为空
|
||
* @return 是否为空
|
||
*/
|
||
bool isEmpty() const { return data_.empty(); }
|
||
|
||
/**
|
||
* @brief 预分配空间
|
||
* @param size 要预分配的大小
|
||
*/
|
||
void reserve(size_t size) { data_.reserve(size); }
|
||
|
||
/**
|
||
* @brief 按指定大小分段
|
||
* @param segmentSize 每段的大小
|
||
* @return 分段后的XNByteArray向量,如果不能整除则返回空向量
|
||
*/
|
||
std::vector<XNByteArray> segment(size_t segmentSize) const
|
||
{
|
||
if (segmentSize == 0) {
|
||
return {};
|
||
}
|
||
|
||
size_t totalSize = data_.size();
|
||
|
||
// 检查是否能够整除
|
||
if (totalSize % segmentSize != 0) {
|
||
return {};
|
||
}
|
||
|
||
std::vector<XNByteArray> segments;
|
||
size_t numSegments = totalSize / segmentSize;
|
||
segments.reserve(numSegments);
|
||
|
||
for (size_t i = 0; i < totalSize; i += segmentSize) {
|
||
segments.emplace_back(data_.data() + i, segmentSize);
|
||
}
|
||
|
||
return segments;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取指定范围的子数组
|
||
* @param start 起始位置
|
||
* @param length 长度
|
||
* @return 子数组
|
||
*/
|
||
XNByteArray mid(size_t start, size_t length = SIZE_MAX) const
|
||
{
|
||
if (start >= data_.size()) {
|
||
return XNByteArray{};
|
||
}
|
||
|
||
size_t actualLength = std::min(length, data_.size() - start);
|
||
return XNByteArray(data_.data() + start, actualLength);
|
||
}
|
||
|
||
/**
|
||
* @brief 获取左侧子数组
|
||
* @param length 长度
|
||
* @return 左侧子数组
|
||
*/
|
||
XNByteArray left(size_t length) const { return mid(0, length); }
|
||
|
||
/**
|
||
* @brief 获取右侧子数组
|
||
* @param length 长度
|
||
* @return 右侧子数组
|
||
*/
|
||
XNByteArray right(size_t length) const
|
||
{
|
||
if (length >= data_.size()) {
|
||
return *this;
|
||
}
|
||
return mid(data_.size() - length, length);
|
||
}
|
||
|
||
private:
|
||
std::vector<uint8_t> data_;
|
||
}; |