SwitchGame/source/Tool/Ifstream_PVF.h

170 lines
4.6 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 <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <SDL.h>
#include <algorithm>
typedef unsigned char BYTE;
// 定义宏用于注册获取不同类型值的函数
#define REGISTER_GET_FUNCTION(Type, FunctionName) \
Type Get##FunctionName() \
{ \
char buffer[sizeof(Type)]; \
read(buffer, sizeof(Type)); \
Type result; \
std::memcpy(&result, buffer, sizeof(Type)); \
return result; \
}
class Ifstream_PVF
{
public:
// 使用vector存储数据替代char*
std::vector<char> _Data;
// 当前位置
int _CurPos = 0;
// 上一次读取的实际大小
int _LastReadSize = 0;
public:
Ifstream_PVF(std::string fileName);
~Ifstream_PVF();
public:
int tellg()
{
return _CurPos;
}
// 获取数据大小
int size() const
{
return static_cast<int>(_Data.size());
}
void read(char *ptr, int size)
{
// 使用vector的size()作为最大长度
if ((size + _CurPos) > static_cast<int>(_Data.size()))
{
size = static_cast<int>(_Data.size()) - _CurPos;
}
memcpy(ptr, _Data.data() + _CurPos, size);
_CurPos += size;
_LastReadSize = size;
}
int gcount()
{
return _LastReadSize;
}
void seek(int _jidx)
{
// 确保不会越界
_CurPos = std::clamp(_jidx, 0, static_cast<int>(_Data.size()));
}
public:
unsigned int charPtrToInt(const char *bytes)
{
unsigned int result;
std::memcpy(&result, bytes, sizeof(int));
return result;
}
void CrcDecode(const int Length, const int crc32)
{
int num = 0x81A79011;
int originalPos = tellg(); // 保存初始位置
for (int i = 0; i < Length; i += 4)
{
int Pos = tellg();
char buffer[4];
read(buffer, 4);
unsigned int anInt = charPtrToInt(buffer);
unsigned int val = (anInt ^ num ^ crc32);
unsigned int jiemi = (val >> 6) | ((val << (32 - 6)) & 0xFFFFFFFF);
// 使用vector的data()获取数据指针
if (Pos + 3 < static_cast<int>(_Data.size()))
{
_Data[Pos] = ((jiemi >> 0) & 0xFF);
_Data[Pos + 1] = ((jiemi >> 8) & 0xFF);
_Data[Pos + 2] = ((jiemi >> 16) & 0xFF);
_Data[Pos + 3] = ((jiemi >> 24) & 0xFF);
}
}
// 重置读取位置,因为解码过程中移动了指针
seek(originalPos + Length); // 移动到解码后的位置
}
std::string tolower(std::string str)
{
for (size_t i = 0; i < str.length(); ++i)
{
str[i] = std::tolower(str[i]);
}
return str;
}
std::vector<std::string> split(const std::string &str, const std::string &delimiter)
{
std::vector<std::string> tokens;
size_t pos = 0;
size_t found;
while ((found = str.find(delimiter, pos)) != std::string::npos)
{
tokens.push_back(str.substr(pos, found - pos));
pos = found + delimiter.length();
}
tokens.push_back(str.substr(pos));
return tokens;
}
public:
REGISTER_GET_FUNCTION(int, Int);
REGISTER_GET_FUNCTION(short, Short);
REGISTER_GET_FUNCTION(unsigned short, UShort);
std::string GetString(const int size)
{
if (size <= 0)
return "";
// 确保不会读取超出范围的数据
int readSize = std::min(size, static_cast<int>(_Data.size()) - _CurPos);
std::string result(_Data.data() + _CurPos, readSize);
_CurPos += readSize;
_LastReadSize = readSize;
if (readSize != size)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "未能成功读取指定字节数的数据!");
}
return result;
}
std::string GetStringNormal(const int size)
{
// 与GetString实现相同可根据实际需求区分
if (size <= 0)
return "";
int readSize = std::min(size, static_cast<int>(_Data.size()) - _CurPos);
std::string result(_Data.data() + _CurPos, readSize);
_CurPos += readSize;
_LastReadSize = readSize;
if (readSize != size)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "未能成功读取指定字节数的数据!");
}
return result;
}
};