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; | |||
|  |     } | |||
|  | }; |