ZoneBuilder stuff.

This commit is contained in:
momo5502 2016-01-12 19:08:26 +01:00
parent 7c411438b1
commit 558112166a
17 changed files with 372 additions and 115 deletions

View File

@ -3,11 +3,29 @@
namespace Components
{
bool AssetHandler::BypassState = false;
std::map<Game::XAssetType, AssetHandler::IAsset*> AssetHandler::AssetInterfaces;
std::map<Game::XAssetType, AssetHandler::Callback> AssetHandler::TypeCallbacks;
std::vector<AssetHandler::RestrictCallback> AssetHandler::RestrictCallbacks;
std::map<void*, void*> AssetHandler::Relocations;
void AssetHandler::RegisterInterface(IAsset* iAsset)
{
if (!iAsset) return;
if (iAsset->GetType() == Game::XAssetType::ASSET_TYPE_INVALID)
{
delete iAsset;
return;
}
if (AssetHandler::AssetInterfaces.find(iAsset->GetType()) != AssetHandler::AssetInterfaces.end())
{
delete AssetHandler::AssetInterfaces[iAsset->GetType()];
}
AssetHandler::AssetInterfaces[iAsset->GetType()] = iAsset;
}
Game::XAssetHeader AssetHandler::FindAsset(Game::XAssetType type, const char* filename)
{
Game::XAssetHeader header = { 0 };
@ -139,6 +157,30 @@ namespace Components
}
}
void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder)
{
if (AssetHandler::AssetInterfaces.find(asset.type) != AssetHandler::AssetInterfaces.end())
{
AssetHandler::AssetInterfaces[asset.type]->Save(asset.header, builder);
}
else
{
Logger::Error("No interface for type '%s'!", Game::DB_GetXAssetTypeName(asset.type));
}
}
void AssetHandler::ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder)
{
if (AssetHandler::AssetInterfaces.find(asset.type) != AssetHandler::AssetInterfaces.end())
{
AssetHandler::AssetInterfaces[asset.type]->Mark(asset.header, builder);
}
else
{
Logger::Error("No interface for type '%s'!", Game::DB_GetXAssetTypeName(asset.type));
}
}
AssetHandler::AssetHandler()
{
// DB_FindXAssetHeader
@ -149,10 +191,20 @@ namespace Components
// DB_AddXAsset
Utils::Hook(0x5BB650, AssetHandler::AddAssetStub, HOOK_JUMP).Install()->Quick();
// Register asset interfaces
AssetHandler::RegisterInterface(new Assets::IRawFile());
AssetHandler::RegisterInterface(new Assets::ILocalizedEntry());
}
AssetHandler::~AssetHandler()
{
for (auto i = AssetHandler::AssetInterfaces.begin(); i != AssetHandler::AssetInterfaces.end(); i++)
{
delete i->second;
}
AssetHandler::AssetInterfaces.clear();
AssetHandler::TypeCallbacks.clear();
}
}

View File

@ -3,6 +3,16 @@ namespace Components
class AssetHandler : public Component
{
public:
class IAsset
{
public:
virtual Game::XAssetType GetType() { return Game::XAssetType::ASSET_TYPE_INVALID; };
virtual void Mark(Game::XAssetHeader header, ZoneBuilder::Zone* builder) { /*ErrorTypeNotSupported(this);*/ };
virtual void Save(Game::XAssetHeader header, ZoneBuilder::Zone* builder) { /*ErrorTypeNotSupported(this);*/ };
virtual void Dump(Game::XAssetHeader header) { /*ErrorTypeNotSupported(this);*/ };
virtual void Load(Game::XAssetHeader* header, std::string name) { /*ErrorTypeNotSupported(this);*/ };
};
typedef Game::XAssetHeader(*Callback)(Game::XAssetType, const char*);
typedef bool(*RestrictCallback)(Game::XAssetType type, Game::XAssetHeader asset, const char* name);
@ -15,9 +25,14 @@ namespace Components
static void Relocate(void* start, void* to, DWORD size = 4);
static void ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder);
static void ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder);
private:
static bool BypassState;
static void RegisterInterface(IAsset* iAsset);
static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename);
static bool IsAssetEligible(Game::XAssetType type, Game::XAssetHeader* asset);
static void FindAssetStub();
@ -25,9 +40,13 @@ namespace Components
static void OffsetToAlias(Utils::Stream::Offset* offset);
static std::map<Game::XAssetType, IAsset*> AssetInterfaces;
static std::map<Game::XAssetType, Callback> TypeCallbacks;
static std::vector<RestrictCallback> RestrictCallbacks;
static std::map<void*, void*> Relocations;
};
}
#include "AssetInterfaces\IRawFile.hpp"
#include "AssetInterfaces\ILocalizedEntry.hpp"

View File

@ -0,0 +1,28 @@
#include <STDInclude.hpp>
namespace Assets
{
void ILocalizedEntry::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Utils::Stream* buffer = builder->GetBuffer();
Game::LocalizedEntry* asset = header.localize;
Game::LocalizedEntry* dest = (Game::LocalizedEntry*)buffer->At();
buffer->Save(asset, sizeof(Game::LocalizedEntry));
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
if (asset->value)
{
buffer->SaveString(asset->value);
dest->value = (char *)-1;
}
if (asset->name)
{
buffer->SaveString(asset->name);
dest->name = (char *)-1;
}
buffer->PopBlock();
}
}

View File

@ -0,0 +1,9 @@
namespace Assets
{
class ILocalizedEntry : public Components::AssetHandler::IAsset
{
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_LOCALIZE; };
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
};
}

View File

@ -0,0 +1,36 @@
#include <STDInclude.hpp>
namespace Assets
{
void IRawFile::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Utils::Stream* buffer = builder->GetBuffer();
Game::RawFile* asset = header.rawfile;
Game::RawFile* dest = (Game::RawFile*)buffer->At();
buffer->Save(asset, sizeof(Game::RawFile));
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
if (asset->name)
{
buffer->SaveString(asset->name);
dest->name = (char *)-1;
}
if (asset->compressedData)
{
if (asset->sizeCompressed)
{
buffer->SaveString(asset->compressedData, asset->sizeCompressed);
}
else
{
buffer->SaveString(asset->compressedData, asset->sizeUnCompressed);
}
dest->compressedData = (char*)-1;
}
buffer->PopBlock();
}
}

View File

@ -0,0 +1,9 @@
namespace Assets
{
class IRawFile : public Components::AssetHandler::IAsset
{
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_RAWFILE; };
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
};
}

View File

@ -3,25 +3,50 @@
namespace Components
{
Dvar::Var Localization::UseLocalization;
std::map<std::string, std::string> Localization::LocalizeMap;
std::map<std::string, Game::LocalizedEntry*> Localization::LocalizeMap;
std::map<std::string, Game::LocalizedEntry*> Localization::TempLocalizeMap;
void Localization::Set(const char* key, const char* value)
{
Localization::LocalizeMap[key] = value;
Game::LocalizedEntry* entry = Utils::Memory::AllocateArray<Game::LocalizedEntry>(1);
if (!entry) return;
entry->name = Utils::Memory::DuplicateString(key);
if (!entry->name)
{
Utils::Memory::Free(entry);
return;
}
entry->value = Utils::Memory::DuplicateString(value);
if (!entry->value)
{
Utils::Memory::Free(entry->name);
Utils::Memory::Free(entry);
return;
}
Localization::LocalizeMap[key] = entry;
}
const char* Localization::Get(const char* key)
{
if (!Localization::UseLocalization.Get<bool>()) return key;
if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
Game::LocalizedEntry* entry = nullptr;
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
{
return Localization::LocalizeMap[key].data();
entry = Localization::TempLocalizeMap[key];
}
else if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
{
entry = Localization::LocalizeMap[key];
}
Game::localizedEntry_s* entry = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_LOCALIZE, key).localize;
if (!entry || !entry->value) entry = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_LOCALIZE, key).localize;
if (entry)
if (entry && entry->value)
{
return entry->value;
}
@ -29,6 +54,53 @@ namespace Components
return key;
}
void Localization::SetTemp(std::string key, std::string value)
{
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
{
Game::LocalizedEntry* entry = Localization::TempLocalizeMap[key];
if(entry->value) Utils::Memory::Free(entry->value);
entry->value = Utils::Memory::DuplicateString(value);
}
else
{
Game::LocalizedEntry* entry = Utils::Memory::AllocateArray<Game::LocalizedEntry>(1);
if (!entry) return;
entry->name = Utils::Memory::DuplicateString(key);
if (!entry->name)
{
Utils::Memory::Free(entry);
return;
}
entry->value = Utils::Memory::DuplicateString(value);
if (!entry->value)
{
Utils::Memory::Free(entry->name);
Utils::Memory::Free(entry);
return;
}
Localization::TempLocalizeMap[key] = entry;
}
}
void Localization::ClearTemp()
{
for (auto i = Localization::TempLocalizeMap.begin(); i != Localization::TempLocalizeMap.end(); i++)
{
if (i->second)
{
if (i->second->name) Utils::Memory::Free(i->second->name);
if (i->second->value) Utils::Memory::Free(i->second->value);
Utils::Memory::Free(i->second);
}
}
Localization::TempLocalizeMap.clear();
}
void __stdcall Localization::SetStringStub(const char* key, const char* value, bool isEnglish)
{
Localization::Set(key, value);
@ -44,6 +116,22 @@ namespace Components
Localization::Localization()
{
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE, [] (Game::XAssetType, const char* filename)
{
Game::XAssetHeader header = { 0 };
if (Localization::TempLocalizeMap.find(filename) != Localization::TempLocalizeMap.end())
{
header.localize = Localization::TempLocalizeMap[filename];
}
else if (Localization::LocalizeMap.find(filename) != Localization::LocalizeMap.end())
{
header.localize = Localization::LocalizeMap[filename];
}
return header;
});
// Resolving hook
Utils::Hook(0x629B90, Localization::Get, HOOK_JUMP).Install()->Quick();
@ -85,6 +173,18 @@ namespace Components
Localization::~Localization()
{
Localization::ClearTemp();
for (auto i = Localization::LocalizeMap.begin(); i != Localization::LocalizeMap.end(); i++)
{
if (i->second)
{
if (i->second->name) Utils::Memory::Free(i->second->name);
if (i->second->value) Utils::Memory::Free(i->second->value);
Utils::Memory::Free(i->second);
}
}
Localization::LocalizeMap.clear();
}
}

View File

@ -10,8 +10,12 @@ namespace Components
static void Set(const char* key, const char* value);
static const char* Get(const char* key);
static void SetTemp(std::string key, std::string value);
static void ClearTemp();
private:
static std::map<std::string, std::string> LocalizeMap;
static std::map<std::string, Game::LocalizedEntry*> LocalizeMap;
static std::map<std::string, Game::LocalizedEntry*> TempLocalizeMap;
static Dvar::Var UseLocalization;
static void __stdcall SetStringStub(const char* key, const char* value, bool isEnglish);

View File

@ -68,7 +68,7 @@ namespace Components
script->next = NULL;
source = (Game::source_t *)calloc(1, sizeof(Game::source_t));
source = Utils::Memory::AllocateArray<Game::source_t>(1);
if (!source)
{
Game::FreeMemory(script);
@ -81,7 +81,7 @@ namespace Components
source->defines = NULL;
source->indentstack = NULL;
source->skip = 0;
source->definehash = (Game::define_t**)calloc(1, 4096);
source->definehash = (Game::define_t**)Utils::Memory::Allocate(4096);
Game::sourceFiles[handle] = source;
@ -115,13 +115,13 @@ namespace Components
Game::menuDef_t* Menus::ParseMenu(int handle)
{
Game::menuDef_t* menu = (Game::menuDef_t*)calloc(1, sizeof(Game::menuDef_t));
Game::menuDef_t* menu = Utils::Memory::AllocateArray<Game::menuDef_t>(1);
if (!menu) return nullptr;
menu->items = (Game::itemDef_t**)calloc(512, sizeof(Game::itemDef_t*));
menu->items = Utils::Memory::AllocateArray<Game::itemDef_t*>(512);
if (!menu->items)
{
free(menu);
Utils::Memory::Free(menu);
return nullptr;
}
@ -230,17 +230,17 @@ namespace Components
if (!menus.size()) return nullptr;
// Allocate new menu list
Game::MenuList* newList = (Game::MenuList*)calloc(1, sizeof(Game::MenuList));
Game::MenuList* newList = Utils::Memory::AllocateArray<Game::MenuList>(1);
if (!newList) return nullptr;
newList->menus = (Game::menuDef_t **)calloc(menus.size(), sizeof(Game::menuDef_t *));
newList->menus = Utils::Memory::AllocateArray<Game::menuDef_t*>(menus.size());
if (!newList->menus)
{
free(newList);
Utils::Memory::Free(newList);
return nullptr;
}
newList->name = _strdup(menu);
newList->name = Utils::Memory::DuplicateString(menu);
newList->menuCount = menus.size();
// Copy new menus
@ -275,17 +275,17 @@ namespace Components
}
// Allocate new menu list
Game::MenuList* newList = (Game::MenuList*)calloc(1, sizeof(Game::MenuList));
Game::MenuList* newList = Utils::Memory::AllocateArray<Game::MenuList>(1);
if (!newList) return menuList;
newList->menus = (Game::menuDef_t **)calloc(menus.size(), sizeof(Game::menuDef_t *));
newList->menus = Utils::Memory::AllocateArray<Game::menuDef_t*>(menus.size());
if (!newList->menus)
{
free(newList);
Utils::Memory::Free(newList);
return menuList;
}
newList->name = _strdup(menuList->name);
newList->name = Utils::Memory::DuplicateString(menuList->name);
newList->menuCount = menus.size();
// Copy new menus
@ -331,12 +331,12 @@ namespace Components
{
indent = source->indentstack;
source->indentstack = source->indentstack->next;
free(indent);
Utils::Memory::Free(indent);
}
if (source->definehash) free(source->definehash);
if (source->definehash) Utils::Memory::Free(source->definehash);
free(source);
Utils::Memory::Free(source);
Game::sourceFiles[handle] = nullptr;
}
@ -357,10 +357,10 @@ namespace Components
// Game::Menu_FreeItemMemory(menudef->items[i]);
//}
free(menudef->items);
Utils::Memory::Free(menudef->items);
}
free(menudef);
Utils::Memory::Free(menudef);
}
void Menus::FreeMenuList(Game::MenuList* menuList)
@ -372,15 +372,15 @@ namespace Components
if (list.name)
{
free(list.name);
Utils::Memory::Free(list.name);
}
if (list.menus)
{
free(list.menus);
Utils::Memory::Free(list.menus);
}
free(menuList);
Utils::Memory::Free(menuList);
}
void Menus::RemoveMenu(Game::menuDef_t* menudef)

View File

@ -4,7 +4,7 @@ namespace Components
{
Game::XAssetHeader Weapon::WeaponFileLoad(Game::XAssetType type, const char* filename)
{
Game::XAssetHeader header = { nullptr };
Game::XAssetHeader header = { 0 };
// Try loading raw weapon
if (FileSystem::File(Utils::VA("weapons/mp/%s", filename)).Exists())

View File

@ -15,7 +15,7 @@ namespace Components
ZoneBuilder::Zone::~Zone()
{
//Assets::Patches::DeleteTemporaryLocalizeEntries();
Localization::ClearTemp();
ZoneBuilder::Zone::Assets.clear();
ZoneBuilder::Zone::ScriptStrings.clear();
@ -34,14 +34,6 @@ namespace Components
Logger::Print("link...");
if (!ZoneBuilder::Zone::LoadAssets()) return;
Game::RawFile* rawFile = new Game::RawFile;
rawFile->name = "zob.cfg";
rawFile->compressedData = "map mp_rust";
rawFile->sizeUnCompressed = strlen(rawFile->compressedData) + 1;
rawFile->sizeCompressed = 0;
Assets.push_back({ Game::XAssetType::ASSET_TYPE_RAWFILE, rawFile });
ZoneBuilder::Zone::AddBranding();
Logger::Print("save...");
@ -89,11 +81,11 @@ namespace Components
{
if (DataMap.GetColumns(i) > 2)
{
// if (DataMap.GetElementAt(i, 0) == "localize")
// {
// Assets::Patches::AddTemporaryLocalizeEntry(DataMap.GetElementAt(i, 1), DataMap.GetElementAt(i, 2));
// }
// else
if (DataMap.GetElementAt(i, 0) == "localize")
{
Localization::SetTemp(DataMap.GetElementAt(i, 1), DataMap.GetElementAt(i, 2));
}
else
{
ZoneBuilder::Zone::RenameAsset(Game::DB_GetXAssetNameType(DataMap.GetElementAt(i, 0).data()), DataMap.GetElementAt(i, 1), DataMap.GetElementAt(i, 2));
}
@ -139,7 +131,7 @@ namespace Components
asset.header = assetHeader;
// Handle script strings and referenced assets
//Assets::Mark(&asset, this);
AssetHandler::ZoneMark(asset, this);
ZoneBuilder::Zone::Assets.push_back(asset);
return true;
@ -248,7 +240,7 @@ namespace Components
// So scriptString loading for NULL scriptStrings from fastfile results in a NULL scriptString.
// That's the reason why the count is incremented by 1, if scriptStrings are available.
// Write ScriptString pointer table
// Write ScriptString pointer table
for (size_t i = 0; i < ZoneBuilder::Zone::ScriptStrings.size(); i++)
{
ZoneBuilder::Zone::Buffer.SaveMax(4);
@ -266,7 +258,8 @@ namespace Components
// Align buffer (4 bytes) to get correct offsets for pointers
ZoneBuilder::Zone::Buffer.Align(Utils::Stream::ALIGN_4);
ZoneBuilder::Zone::IndexStart = ZoneBuilder::Zone::Buffer.GetBlockSize(Game::XFILE_BLOCK_VIRTUAL); // Mark AssetTable offset
// AssetTable
// AssetTable
for (auto asset : Assets)
{
Game::XAsset entry;
@ -280,44 +273,9 @@ namespace Components
for (auto asset : Assets)
{
ZoneBuilder::Zone::Buffer.PushBlock(Game::XFILE_BLOCK_TEMP);
if (asset.type == Game::XAssetType::ASSET_TYPE_RAWFILE)
{
Game::RawFile* _asset = asset.header.rawfile;
Game::RawFile* dest = (Game::RawFile*)ZoneBuilder::Zone::Buffer.At();
ZoneBuilder::Zone::Buffer.Save(_asset, sizeof(Game::RawFile));
ZoneBuilder::Zone::Buffer.PushBlock(Game::XFILE_BLOCK_VIRTUAL);
AssetHandler::ZoneSave(asset, this);
if (_asset->name)
{
ZoneBuilder::Zone::Buffer.SaveString(_asset->name);
dest->name = (char *)-1;
}
if (_asset->compressedData)
{
if (_asset->sizeCompressed)
{
ZoneBuilder::Zone::Buffer.SaveString(_asset->compressedData, _asset->sizeCompressed);
}
else
{
ZoneBuilder::Zone::Buffer.SaveString(_asset->compressedData, _asset->sizeUnCompressed);
}
dest->compressedData = (char*)-1;
}
ZoneBuilder::Zone::Buffer.PopBlock();
}
else
{
Logger::Error("Wat?");
}
//Assets::Save(asset, this);
ZoneBuilder::Zone::Buffer.PopBlock();
}
@ -327,7 +285,7 @@ namespace Components
header->size = ZoneBuilder::Zone::Buffer.Length() - sizeof(Game::XFile); // Write correct data size
header->externalSize = 0; // ?
// Write stream sizes
// Write stream sizes
for (int i = 0; i < Game::MAX_XFILE_COUNT; i++)
{
header->blockSize[i] = ZoneBuilder::Zone::Buffer.GetBlockSize((Game::XFILE_BLOCK_TYPES)i);
@ -463,6 +421,16 @@ namespace Components
static_assert(sizeof(Game::XFile) == 40, "Invalid XFile structure!");
static_assert(Game::MAX_XFILE_COUNT == 8, "XFile block enum is invalid!");
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, const char* name)
{
if (FastFiles::Current() == "penis")
{
OutputDebugStringA(name);
}
return true;
});
if (ZoneBuilder::IsEnabled())
{
Command::Add("build", [] (Command::Params params)
@ -476,6 +444,6 @@ namespace Components
});
}
//Utils::Hook(0x60B4AC, TestZoneLoading, HOOK_CALL).Install()->Quick();
Utils::Hook(0x4546DF, TestZoneLoading, HOOK_CALL).Install()->Quick();
}
}

View File

@ -164,7 +164,7 @@ namespace Game
void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
{
int elSize = DB_GetXAssetSizeHandlers[type]();
void* poolEntry = new char[newSize * elSize];
void* poolEntry = Utils::Memory::Allocate(newSize * elSize);
DB_XAssetPool[type] = poolEntry;
g_poolSize[type] = newSize;
return poolEntry;

View File

@ -890,7 +890,7 @@ namespace Game
UILocalVarContext localVars;
};
struct localizedEntry_s
struct LocalizedEntry
{
const char* value;
const char* name;
@ -931,7 +931,7 @@ namespace Game
menuDef_t *menu;
Material *material;
snd_alias_list_t *aliasList;
localizedEntry_s *localize;
LocalizedEntry *localize;
StringTable *stringTable;
MapEnts* mapEnts;
RawFile* rawfile;

View File

@ -39,6 +39,7 @@
#include "Utils\CSV.hpp"
#include "Utils\Utils.hpp"
#include "Utils\WebIO.hpp"
#include "Utils\Memory.hpp"
#include "Utils\Hooking.hpp"
#include "Utils\Compression.hpp"

View File

@ -6,38 +6,19 @@ namespace Utils
{
std::string ZLib::Compress(std::string data)
{
z_stream stream;
ZeroMemory(&stream, sizeof(stream));
unsigned long length = (data.size() * 2);
char* buffer = Utils::Memory::AllocateArray<char>(length);
char* buffer = new char[data.size() * 2];
if (deflateInit(&stream, Z_BEST_COMPRESSION) != Z_OK)
{
delete[] buffer;
return "";
}
stream.next_out = reinterpret_cast<uint8_t*>(buffer);
stream.next_in = reinterpret_cast<const uint8_t*>(data.data());
stream.avail_out = data.size() * 2;
stream.avail_in = data.size();
if (deflate(&stream, Z_FINISH) != Z_STREAM_END)
{
delete[] buffer;
return "";
}
if (deflateEnd(&stream) != Z_OK)
if (compress2((Bytef*)buffer, &length, (Bytef*)data.data(), data.size(), Z_BEST_COMPRESSION) != Z_OK)
{
delete[] buffer;
Utils::Memory::Free(buffer);
return "";
}
data.clear();
data.append(buffer, stream.total_out);
data.append(buffer, length);
delete[] buffer;
Utils::Memory::Free(buffer);
return data;
}
@ -54,7 +35,7 @@ namespace Utils
}
int ret = 0;
uint8_t* dest = new uint8_t[CHUNK];
uint8_t* dest = Utils::Memory::AllocateArray<uint8_t>(CHUNK);
const char* dataPtr = data.data();
do
@ -71,7 +52,7 @@ namespace Utils
if (ret == Z_STREAM_ERROR)
{
inflateEnd(&stream);
delete[] dest;
Utils::Memory::Free(dest);
return "";
}
@ -83,7 +64,7 @@ namespace Utils
inflateEnd(&stream);
delete[] dest;
Utils::Memory::Free(dest);
return buffer;
}

33
src/Utils/Memory.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "STDInclude.hpp"
namespace Utils
{
void* Memory::Allocate(size_t length)
{
void* data = new char[length];
if (data)
{
ZeroMemory(data, length);
}
return data;
}
char* Memory::DuplicateString(std::string string)
{
char* newString = Memory::AllocateArray<char>(string.size() + 1);
memcpy(newString, string.data(), string.size());
return newString;
}
void Memory::Free(void* data)
{
delete[] data;
}
void Memory::Free(const void* data)
{
Memory::Free((void*)data);
}
}

17
src/Utils/Memory.hpp Normal file
View File

@ -0,0 +1,17 @@
namespace Utils
{
class Memory
{
public:
static void* Allocate(size_t length);
template <typename T> static T* AllocateArray(size_t count)
{
return (T*)Allocate(count * sizeof(T));
}
static char* DuplicateString(std::string string);
static void Free(void* data);
static void Free(const void* data);
};
}