iw4x-client/src/Utils/Stream.hpp

148 lines
3.3 KiB
C++
Raw Normal View History

2016-01-05 19:23:43 -05:00
namespace Utils
{
class Stream
{
private:
int CriticalSectionState;
unsigned int BlockSize[Game::MAX_XFILE_COUNT];
std::vector<Game::XFILE_BLOCK_TYPES> StreamStack;
std::string Buffer;
public:
2016-06-05 15:55:38 -04:00
class Reader
{
public:
Reader(Utils::Memory::Allocator* allocator, std::string& buffer) : Buffer(buffer), Allocator(allocator), Position(0) {}
std::string ReadString();
const char* ReadCString();
char ReadByte();
void* Read(size_t size, size_t count = 1);
template <typename T> T* ReadArray(size_t count = 1)
{
return reinterpret_cast<T*>(Read(sizeof(T), count));
}
bool End();
void Seek(unsigned int position);
private:
unsigned int Position;
std::string Buffer;
Utils::Memory::Allocator* Allocator;
};
2016-01-05 19:23:43 -05:00
enum Alignment
{
ALIGN_2,
ALIGN_4,
ALIGN_8,
ALIGN_16,
ALIGN_32,
ALIGN_64,
ALIGN_128,
ALIGN_256,
ALIGN_512,
ALIGN_1024,
ALIGN_2048,
};
Stream();
Stream(size_t size);
~Stream();
size_t Length();
size_t Capacity();
char* Save(const void * _str, size_t size, size_t count = 1);
char* Save(Game::XFILE_BLOCK_TYPES stream, const void * _str, size_t size, size_t count);
char* Save(Game::XFILE_BLOCK_TYPES stream, int value, size_t count);
2016-01-22 05:59:43 -05:00
template <typename T> char* SaveArray(T* array, size_t count)
{
return Save(array, sizeof(T), count);
}
2016-01-05 19:23:43 -05:00
char* SaveString(std::string string);
char* SaveString(const char* string);
char* SaveString(const char* string, size_t len);
char* SaveByte(unsigned char byte, size_t count = 1);
char* SaveNull(size_t count = 1);
char* SaveMax(size_t count = 1);
char* SaveText(std::string string);
void Align(Alignment align);
bool PushBlock(Game::XFILE_BLOCK_TYPES stream);
bool PopBlock();
bool IsValidBlock(Game::XFILE_BLOCK_TYPES stream);
void IncreaseBlockSize(Game::XFILE_BLOCK_TYPES stream, unsigned int size);
void IncreaseBlockSize(unsigned int size);
Game::XFILE_BLOCK_TYPES GetCurrentBlock();
unsigned int GetBlockSize(Game::XFILE_BLOCK_TYPES stream);
DWORD GetPackedOffset();
char* Data();
char* At();
template <typename T> T* Dest()
{
return reinterpret_cast<T*>(this->At());
}
2016-01-05 19:23:43 -05:00
void ToBuffer(std::string& outBuffer);
std::string ToBuffer();
// Enter/Leave critical sections in which reallocations are not allowed.
// If buffer reallocation is detected, the operation has to be terminated
// and more memory has to be allocated next time. This will have to be done
// by editing the code though.
void EnterCriticalSection();
void LeaveCriticalSection();
bool IsCriticalSection();
// This represents packed offset in streams:
// - lowest 28 bits store the value/offset
// - highest 4 bits store the stream block
class Offset
{
public:
union
{
struct
{
uint32_t offset : 28;
Game::XFILE_BLOCK_TYPES block : 4;
};
uint32_t packed;
void* pointer;
};
Offset() : packed(0) {};
Offset(Game::XFILE_BLOCK_TYPES _block, uint32_t _offset) : offset(_offset), block(_block) {};
// The game needs it to be incremented
uint32_t GetPackedOffset()
{
return this->packed + 1;
};
uint32_t GetUnpackedOffset()
{
Offset lOffset = *this;
lOffset.packed--;
return lOffset.offset;
2016-01-05 19:23:43 -05:00
};
int GetUnpackedBlock()
{
Offset lOffset = *this;
lOffset.packed--;
return lOffset.block;
2016-01-05 19:23:43 -05:00
};
};
};
}