170 lines
4.6 KiB
C++
170 lines
4.6 KiB
C++
#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;
|
||
}
|
||
};
|