SwitchGame/source/Tool/Blob.hpp

138 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <vector>
#include <string>
#include <cstdint>
#include <stdexcept>
#include <algorithm>
class Blob
{
using BYTE = unsigned char;
private:
const std::vector<BYTE> &m_blob;
size_t m_offset;
// 检查是否有足够的剩余字节
void checkSize(size_t required) const
{
if (m_offset + required > m_blob.size())
{
throw std::out_of_range("Insufficient data in blob");
}
}
public:
// 构造函数,接受一个字节向量的引用
Blob(const std::vector<BYTE> &blob) : m_blob(blob), m_offset(0) {}
// 重置解析偏移量
void reset() { m_offset = 0; }
// 获取当前偏移量
size_t getOffset() const { return m_offset; }
// 设置偏移量
void setOffset(size_t offset)
{
if (offset > m_blob.size())
{
throw std::out_of_range("Offset out of range");
}
m_offset = offset;
}
// 获取剩余字节数
size_t remaining() const { return m_blob.size() - m_offset; }
// 读取一个T类型的数据适用于基本类型
template <typename T>
T get()
{
checkSize(sizeof(T));
T value;
std::copy(m_blob.begin() + m_offset,
m_blob.begin() + m_offset + sizeof(T),
reinterpret_cast<BYTE *>(&value));
m_offset += sizeof(T);
return value;
}
// 读取int类型
int32_t getInt() { return get<int32_t>(); }
// 读取无符号int类型
uint32_t getUInt() { return get<uint32_t>(); }
// 读取short类型
int16_t getShort() { return get<int16_t>(); }
// 读取无符号short类型
uint16_t getUShort() { return get<uint16_t>(); }
// 读取float类型
float getFloat() { return get<float>(); }
// 读取double类型
double getDouble() { return get<double>(); }
BYTE getByte() { return get<BYTE>(); }
float get256()
{
BYTE buf = get<BYTE>();
return static_cast<float>(buf);
}
// 读取指定长度的字符串
std::string getString(size_t length)
{
checkSize(length);
std::string str(reinterpret_cast<const char *>(m_blob.data() + m_offset), length);
m_offset += length;
return str;
}
// 读取以null结尾的字符串
std::string getNullTerminatedString()
{
size_t length = 0;
size_t pos = m_offset;
// 查找null终止符
while (pos < m_blob.size() && m_blob[pos] != '\0')
{
pos++;
length++;
}
// 确保找到了终止符
if (pos >= m_blob.size())
{
throw std::runtime_error("Null-terminated string not found");
}
// 读取字符串(不包含终止符)
std::string str(reinterpret_cast<const char *>(m_blob.data() + m_offset), length);
m_offset = pos + 1; // 跳过终止符
return str;
}
// 读取指定数量的字节
std::vector<BYTE> getBytes(size_t count)
{
checkSize(count);
std::vector<BYTE> bytes(m_blob.begin() + m_offset, m_blob.begin() + m_offset + count);
m_offset += count;
return bytes;
}
};