Use new format library and sort utils

This commit is contained in:
momo5502
2016-07-11 17:14:58 +02:00
parent 766fd631b1
commit 9562285ed7
59 changed files with 13009 additions and 12950 deletions

View File

@ -1,144 +1,144 @@
#include "STDInclude.hpp"
namespace Utils
{
CSV::CSV(std::string file, bool isFile, bool allowComments)
{
CSV::Parse(file, isFile, allowComments);
}
CSV::~CSV()
{
for (auto row : CSV::DataMap)
{
for (auto entry : row)
{
entry.clear();
}
row.clear();
}
CSV::DataMap.clear();
}
int CSV::GetRows()
{
return CSV::DataMap.size();
}
int CSV::GetColumns(size_t row)
{
if (CSV::DataMap.size() > row)
{
return CSV::DataMap[row].size();
}
return 0;
}
int CSV::GetColumns()
{
int count = 0;
for (int i = 0; i < CSV::GetRows(); ++i)
{
count = std::max(CSV::GetColumns(i), count);
}
return count;
}
std::string CSV::GetElementAt(size_t row, size_t column)
{
if (CSV::DataMap.size() > row)
{
auto _row = CSV::DataMap[row];
if (_row.size() > column)
{
return _row[column];
}
}
return "";
}
void CSV::Parse(std::string file, bool isFile, bool allowComments)
{
std::string buffer;
if (isFile)
{
if (!Utils::FileExists(file)) return;
buffer = Utils::ReadFile(file);
}
else
{
buffer = file;
}
if (!buffer.empty())
{
auto rows = Utils::Explode(buffer, '\n');
for (auto row : rows)
{
CSV::ParseRow(row, allowComments);
}
}
}
void CSV::ParseRow(std::string row, bool allowComments)
{
bool isString = false;
std::string element;
std::vector<std::string> _row;
char tempStr = 0;
for (unsigned int i = 0; i < row.size(); ++i)
{
if (row[i] == ',' && !isString) // FLush entry
{
_row.push_back(element);
element.clear();
continue;
}
else if (row[i] == '"') // Start/Terminate string
{
isString = !isString;
continue;
}
else if (i < (row.size() - 1) && row[i] == '\\' &&row[i + 1] == '"' && isString) // Handle quotes in strings as \"
{
tempStr = '"';
++i;
}
else if (!isString && (row[i] == '\n' || row[i] == '\x0D' || row[i] == '\x0A' || row[i] == '\t'))
{
//++i;
continue;
}
else if (!isString && row[i] == '#' && allowComments) // Skip comments. I know CSVs usually don't have comments, but in this case it's useful
{
return;
}
else
{
tempStr = row[i];
}
element.append(&tempStr, 1);
}
// Push last element
_row.push_back(element);
if (_row.size() == 0 || (_row.size() == 1 && !_row[0].size())) // Skip empty rows
{
return;
}
DataMap.push_back(_row);
}
}
#include "STDInclude.hpp"
namespace Utils
{
CSV::CSV(std::string file, bool isFile, bool allowComments)
{
CSV::Parse(file, isFile, allowComments);
}
CSV::~CSV()
{
for (auto row : CSV::DataMap)
{
for (auto entry : row)
{
entry.clear();
}
row.clear();
}
CSV::DataMap.clear();
}
int CSV::GetRows()
{
return CSV::DataMap.size();
}
int CSV::GetColumns(size_t row)
{
if (CSV::DataMap.size() > row)
{
return CSV::DataMap[row].size();
}
return 0;
}
int CSV::GetColumns()
{
int count = 0;
for (int i = 0; i < CSV::GetRows(); ++i)
{
count = std::max(CSV::GetColumns(i), count);
}
return count;
}
std::string CSV::GetElementAt(size_t row, size_t column)
{
if (CSV::DataMap.size() > row)
{
auto _row = CSV::DataMap[row];
if (_row.size() > column)
{
return _row[column];
}
}
return "";
}
void CSV::Parse(std::string file, bool isFile, bool allowComments)
{
std::string buffer;
if (isFile)
{
if (!Utils::IO::FileExists(file)) return;
buffer = Utils::IO::ReadFile(file);
}
else
{
buffer = file;
}
if (!buffer.empty())
{
auto rows = Utils::String::Explode(buffer, '\n');
for (auto row : rows)
{
CSV::ParseRow(row, allowComments);
}
}
}
void CSV::ParseRow(std::string row, bool allowComments)
{
bool isString = false;
std::string element;
std::vector<std::string> _row;
char tempStr = 0;
for (unsigned int i = 0; i < row.size(); ++i)
{
if (row[i] == ',' && !isString) // FLush entry
{
_row.push_back(element);
element.clear();
continue;
}
else if (row[i] == '"') // Start/Terminate string
{
isString = !isString;
continue;
}
else if (i < (row.size() - 1) && row[i] == '\\' &&row[i + 1] == '"' && isString) // Handle quotes in strings as \"
{
tempStr = '"';
++i;
}
else if (!isString && (row[i] == '\n' || row[i] == '\x0D' || row[i] == '\x0A' || row[i] == '\t'))
{
//++i;
continue;
}
else if (!isString && row[i] == '#' && allowComments) // Skip comments. I know CSVs usually don't have comments, but in this case it's useful
{
return;
}
else
{
tempStr = row[i];
}
element.append(&tempStr, 1);
}
// Push last element
_row.push_back(element);
if (_row.size() == 0 || (_row.size() == 1 && !_row[0].size())) // Skip empty rows
{
return;
}
DataMap.push_back(_row);
}
}

View File

@ -1,72 +1,72 @@
#include "STDInclude.hpp"
namespace Utils
{
namespace Compression
{
std::string ZLib::Compress(std::string data)
{
unsigned long length = (data.size() * 2);
char* buffer = Utils::Memory::AllocateArray<char>(length);
if (compress2(reinterpret_cast<Bytef*>(buffer), &length, reinterpret_cast<Bytef*>(const_cast<char*>(data.data())), data.size(), Z_BEST_COMPRESSION) != Z_OK)
{
Utils::Memory::Free(buffer);
return "";
}
data.clear();
data.append(buffer, length);
Utils::Memory::Free(buffer);
return data;
}
std::string ZLib::Decompress(std::string data)
{
z_stream stream;
ZeroMemory(&stream, sizeof(stream));
std::string buffer;
if (inflateInit(&stream) != Z_OK)
{
return "";
}
int ret = 0;
uint8_t* dest = Utils::Memory::AllocateArray<uint8_t>(CHUNK);
const char* dataPtr = data.data();
do
{
stream.avail_in = min(CHUNK, data.size() - (dataPtr - data.data()));
stream.next_in = reinterpret_cast<const uint8_t*>(dataPtr);
do
{
stream.avail_out = CHUNK;
stream.next_out = dest;
ret = inflate(&stream, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR)
{
inflateEnd(&stream);
Utils::Memory::Free(dest);
return "";
}
buffer.append(reinterpret_cast<const char*>(dest), CHUNK - stream.avail_out);
} while (stream.avail_out == 0);
} while (ret != Z_STREAM_END);
inflateEnd(&stream);
Utils::Memory::Free(dest);
return buffer;
}
};
}
#include "STDInclude.hpp"
namespace Utils
{
namespace Compression
{
std::string ZLib::Compress(std::string data)
{
unsigned long length = (data.size() * 2);
char* buffer = Utils::Memory::AllocateArray<char>(length);
if (compress2(reinterpret_cast<Bytef*>(buffer), &length, reinterpret_cast<Bytef*>(const_cast<char*>(data.data())), data.size(), Z_BEST_COMPRESSION) != Z_OK)
{
Utils::Memory::Free(buffer);
return "";
}
data.clear();
data.append(buffer, length);
Utils::Memory::Free(buffer);
return data;
}
std::string ZLib::Decompress(std::string data)
{
z_stream stream;
ZeroMemory(&stream, sizeof(stream));
std::string buffer;
if (inflateInit(&stream) != Z_OK)
{
return "";
}
int ret = 0;
uint8_t* dest = Utils::Memory::AllocateArray<uint8_t>(CHUNK);
const char* dataPtr = data.data();
do
{
stream.avail_in = std::min(static_cast<size_t>(CHUNK), data.size() - (dataPtr - data.data()));
stream.next_in = reinterpret_cast<const uint8_t*>(dataPtr);
do
{
stream.avail_out = CHUNK;
stream.next_out = dest;
ret = inflate(&stream, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR)
{
inflateEnd(&stream);
Utils::Memory::Free(dest);
return "";
}
buffer.append(reinterpret_cast<const char*>(dest), CHUNK - stream.avail_out);
} while (stream.avail_out == 0);
} while (ret != Z_STREAM_END);
inflateEnd(&stream);
Utils::Memory::Free(dest);
return buffer;
}
};
}

View File

@ -1,261 +1,261 @@
#include "STDInclude.hpp"
/// http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-55010/Source/libtomcrypt/doc/libTomCryptDoc.pdf
namespace Utils
{
namespace Cryptography
{
void Initialize()
{
TDES::Initialize();
Rand::Initialize();
}
#pragma region Rand
prng_state Rand::State;
uint32_t Rand::GenerateInt()
{
uint32_t number = 0;
fortuna_read(reinterpret_cast<uint8_t*>(&number), sizeof(number), &Rand::State);
return number;
}
void Rand::Initialize()
{
ltc_mp = ltm_desc;
register_prng(&fortuna_desc);
rng_make_prng(128, find_prng("fortuna"), &Rand::State, NULL);
}
#pragma endregion
#pragma region ECC
ECC::Key ECC::GenerateKey(int bits)
{
ECC::Key key;
register_prng(&sprng_desc);
ltc_mp = ltm_desc;
ecc_make_key(NULL, find_prng("sprng"), bits / 8, key.GetKeyPtr());
return key;
}
std::string ECC::SignMessage(Key key, std::string message)
{
if (!key.IsValid()) return "";
uint8_t buffer[512];
DWORD length = sizeof(buffer);
register_prng(&sprng_desc);
ltc_mp = ltm_desc;
ecc_sign_hash(reinterpret_cast<const uint8_t*>(message.data()), message.size(), buffer, &length, NULL, find_prng("sprng"), key.GetKeyPtr());
return std::string(reinterpret_cast<char*>(buffer), length);
}
bool ECC::VerifyMessage(Key key, std::string message, std::string signature)
{
if (!key.IsValid()) return false;
ltc_mp = ltm_desc;
int result = 0;
return (ecc_verify_hash(reinterpret_cast<const uint8_t*>(signature.data()), signature.size(), reinterpret_cast<const uint8_t*>(message.data()), message.size(), &result, key.GetKeyPtr()) == CRYPT_OK && result != 0);
}
#pragma endregion
#pragma region RSA
RSA::Key RSA::GenerateKey(int bits)
{
RSA::Key key;
register_prng(&sprng_desc);
register_hash(&sha1_desc);
ltc_mp = ltm_desc;
rsa_make_key(NULL, find_prng("sprng"), bits / 8, 65537, key.GetKeyPtr());
return key;
}
std::string RSA::SignMessage(RSA::Key key, std::string message)
{
if (!key.IsValid()) return "";
uint8_t buffer[512];
DWORD length = sizeof(buffer);
register_prng(&sprng_desc);
register_hash(&sha1_desc);
ltc_mp = ltm_desc;
rsa_sign_hash(reinterpret_cast<const uint8_t*>(message.data()), message.size(), buffer, &length, NULL, find_prng("sprng"), find_hash("sha1"), 0, key.GetKeyPtr());
return std::string(reinterpret_cast<char*>(buffer), length);
}
bool RSA::VerifyMessage(Key key, std::string message, std::string signature)
{
if (!key.IsValid()) return false;
register_hash(&sha1_desc);
ltc_mp = ltm_desc;
int result = 0;
return (rsa_verify_hash(reinterpret_cast<const uint8_t*>(signature.data()), signature.size(), reinterpret_cast<const uint8_t*>(message.data()), message.size(), find_hash("sha1"), 0, &result, key.GetKeyPtr()) == CRYPT_OK && result != 0);
}
#pragma endregion
#pragma region TDES
void TDES::Initialize()
{
register_cipher(&des3_desc);
}
std::string TDES::Encrypt(std::string text, std::string iv, std::string key)
{
std::string encData;
encData.resize(text.size());
symmetric_CBC cbc;
int des3 = find_cipher("3des");
cbc_start(des3, reinterpret_cast<const uint8_t*>(iv.data()), reinterpret_cast<const uint8_t*>(key.data()), key.size(), 0, &cbc);
cbc_encrypt(reinterpret_cast<const uint8_t*>(text.data()), reinterpret_cast<uint8_t*>(const_cast<char*>(encData.data())), text.size(), &cbc);
cbc_done(&cbc);
return encData;
}
std::string TDES::Decrpyt(std::string data, std::string iv, std::string key)
{
std::string decData;
decData.resize(data.size());
symmetric_CBC cbc;
int des3 = find_cipher("3des");
cbc_start(des3, reinterpret_cast<const uint8_t*>(iv.data()), reinterpret_cast<const uint8_t*>(key.data()), key.size(), 0, &cbc);
cbc_decrypt(reinterpret_cast<const uint8_t*>(data.data()), reinterpret_cast<uint8_t*>(const_cast<char*>(decData.data())), data.size(), &cbc);
cbc_done(&cbc);
return decData;
}
#pragma endregion
#pragma region Tiger
std::string Tiger::Compute(std::string data, bool hex)
{
return Tiger::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string Tiger::Compute(const uint8_t* data, size_t length, bool hex)
{
uint8_t buffer[24] = { 0 };
hash_state state;
tiger_init(&state);
tiger_process(&state, data, length);
tiger_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
if (!hex) return hash;
return Utils::DumpHex(hash, "");
}
#pragma endregion
#pragma region SHA256
std::string SHA256::Compute(std::string data, bool hex)
{
return SHA256::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string SHA256::Compute(const uint8_t* data, size_t length, bool hex)
{
uint8_t buffer[32] = { 0 };
hash_state state;
sha256_init(&state);
sha256_process(&state, data, length);
sha256_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
if (!hex) return hash;
return Utils::DumpHex(hash, "");
}
#pragma endregion
#pragma region SHA512
std::string SHA512::Compute(std::string data, bool hex)
{
return SHA512::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string SHA512::Compute(const uint8_t* data, size_t length, bool hex)
{
uint8_t buffer[64] = { 0 };
hash_state state;
sha512_init(&state);
sha512_process(&state, data, length);
sha512_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
if (!hex) return hash;
return Utils::DumpHex(hash, "");
}
#pragma endregion
#pragma region JenkinsOneAtATime
unsigned int JenkinsOneAtATime::Compute(std::string data)
{
return JenkinsOneAtATime::Compute(data.data(), data.size());
}
unsigned int JenkinsOneAtATime::Compute(const char *key, size_t len)
{
unsigned int hash, i;
for (hash = i = 0; i < len; ++i)
{
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
#pragma endregion
}
}
#include "STDInclude.hpp"
/// http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-55010/Source/libtomcrypt/doc/libTomCryptDoc.pdf
namespace Utils
{
namespace Cryptography
{
void Initialize()
{
TDES::Initialize();
Rand::Initialize();
}
#pragma region Rand
prng_state Rand::State;
uint32_t Rand::GenerateInt()
{
uint32_t number = 0;
fortuna_read(reinterpret_cast<uint8_t*>(&number), sizeof(number), &Rand::State);
return number;
}
void Rand::Initialize()
{
ltc_mp = ltm_desc;
register_prng(&fortuna_desc);
rng_make_prng(128, find_prng("fortuna"), &Rand::State, NULL);
}
#pragma endregion
#pragma region ECC
ECC::Key ECC::GenerateKey(int bits)
{
ECC::Key key;
register_prng(&sprng_desc);
ltc_mp = ltm_desc;
ecc_make_key(NULL, find_prng("sprng"), bits / 8, key.GetKeyPtr());
return key;
}
std::string ECC::SignMessage(Key key, std::string message)
{
if (!key.IsValid()) return "";
uint8_t buffer[512];
DWORD length = sizeof(buffer);
register_prng(&sprng_desc);
ltc_mp = ltm_desc;
ecc_sign_hash(reinterpret_cast<const uint8_t*>(message.data()), message.size(), buffer, &length, NULL, find_prng("sprng"), key.GetKeyPtr());
return std::string(reinterpret_cast<char*>(buffer), length);
}
bool ECC::VerifyMessage(Key key, std::string message, std::string signature)
{
if (!key.IsValid()) return false;
ltc_mp = ltm_desc;
int result = 0;
return (ecc_verify_hash(reinterpret_cast<const uint8_t*>(signature.data()), signature.size(), reinterpret_cast<const uint8_t*>(message.data()), message.size(), &result, key.GetKeyPtr()) == CRYPT_OK && result != 0);
}
#pragma endregion
#pragma region RSA
RSA::Key RSA::GenerateKey(int bits)
{
RSA::Key key;
register_prng(&sprng_desc);
register_hash(&sha1_desc);
ltc_mp = ltm_desc;
rsa_make_key(NULL, find_prng("sprng"), bits / 8, 65537, key.GetKeyPtr());
return key;
}
std::string RSA::SignMessage(RSA::Key key, std::string message)
{
if (!key.IsValid()) return "";
uint8_t buffer[512];
DWORD length = sizeof(buffer);
register_prng(&sprng_desc);
register_hash(&sha1_desc);
ltc_mp = ltm_desc;
rsa_sign_hash(reinterpret_cast<const uint8_t*>(message.data()), message.size(), buffer, &length, NULL, find_prng("sprng"), find_hash("sha1"), 0, key.GetKeyPtr());
return std::string(reinterpret_cast<char*>(buffer), length);
}
bool RSA::VerifyMessage(Key key, std::string message, std::string signature)
{
if (!key.IsValid()) return false;
register_hash(&sha1_desc);
ltc_mp = ltm_desc;
int result = 0;
return (rsa_verify_hash(reinterpret_cast<const uint8_t*>(signature.data()), signature.size(), reinterpret_cast<const uint8_t*>(message.data()), message.size(), find_hash("sha1"), 0, &result, key.GetKeyPtr()) == CRYPT_OK && result != 0);
}
#pragma endregion
#pragma region TDES
void TDES::Initialize()
{
register_cipher(&des3_desc);
}
std::string TDES::Encrypt(std::string text, std::string iv, std::string key)
{
std::string encData;
encData.resize(text.size());
symmetric_CBC cbc;
int des3 = find_cipher("3des");
cbc_start(des3, reinterpret_cast<const uint8_t*>(iv.data()), reinterpret_cast<const uint8_t*>(key.data()), key.size(), 0, &cbc);
cbc_encrypt(reinterpret_cast<const uint8_t*>(text.data()), reinterpret_cast<uint8_t*>(const_cast<char*>(encData.data())), text.size(), &cbc);
cbc_done(&cbc);
return encData;
}
std::string TDES::Decrpyt(std::string data, std::string iv, std::string key)
{
std::string decData;
decData.resize(data.size());
symmetric_CBC cbc;
int des3 = find_cipher("3des");
cbc_start(des3, reinterpret_cast<const uint8_t*>(iv.data()), reinterpret_cast<const uint8_t*>(key.data()), key.size(), 0, &cbc);
cbc_decrypt(reinterpret_cast<const uint8_t*>(data.data()), reinterpret_cast<uint8_t*>(const_cast<char*>(decData.data())), data.size(), &cbc);
cbc_done(&cbc);
return decData;
}
#pragma endregion
#pragma region Tiger
std::string Tiger::Compute(std::string data, bool hex)
{
return Tiger::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string Tiger::Compute(const uint8_t* data, size_t length, bool hex)
{
uint8_t buffer[24] = { 0 };
hash_state state;
tiger_init(&state);
tiger_process(&state, data, length);
tiger_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
if (!hex) return hash;
return Utils::String::DumpHex(hash, "");
}
#pragma endregion
#pragma region SHA256
std::string SHA256::Compute(std::string data, bool hex)
{
return SHA256::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string SHA256::Compute(const uint8_t* data, size_t length, bool hex)
{
uint8_t buffer[32] = { 0 };
hash_state state;
sha256_init(&state);
sha256_process(&state, data, length);
sha256_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
if (!hex) return hash;
return Utils::String::DumpHex(hash, "");
}
#pragma endregion
#pragma region SHA512
std::string SHA512::Compute(std::string data, bool hex)
{
return SHA512::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string SHA512::Compute(const uint8_t* data, size_t length, bool hex)
{
uint8_t buffer[64] = { 0 };
hash_state state;
sha512_init(&state);
sha512_process(&state, data, length);
sha512_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
if (!hex) return hash;
return Utils::String::DumpHex(hash, "");
}
#pragma endregion
#pragma region JenkinsOneAtATime
unsigned int JenkinsOneAtATime::Compute(std::string data)
{
return JenkinsOneAtATime::Compute(data.data(), data.size());
}
unsigned int JenkinsOneAtATime::Compute(const char *key, size_t len)
{
unsigned int hash, i;
for (hash = i = 0; i < len; ++i)
{
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
#pragma endregion
}
}

51
src/Utils/IO.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "STDInclude.hpp"
namespace Utils
{
namespace IO
{
bool FileExists(std::string file)
{
return std::ifstream(file).good();
}
void WriteFile(std::string file, std::string data)
{
std::ofstream stream(file, std::ios::binary);
if (stream.is_open())
{
stream.write(data.data(), data.size());
stream.close();
}
}
std::string ReadFile(std::string file)
{
std::string buffer;
if (FileExists(file))
{
std::streamsize size = 0;
std::ifstream stream(file, std::ios::binary);
if (!stream.is_open()) return buffer;
stream.seekg(0, std::ios::end);
size = stream.tellg();
stream.seekg(0, std::ios::beg);
if (size > -1)
{
buffer.clear();
buffer.resize((uint32_t)size);
stream.read(const_cast<char*>(buffer.data()), size);
}
stream.close();
}
return buffer;
}
}
}

9
src/Utils/IO.hpp Normal file
View File

@ -0,0 +1,9 @@
namespace Utils
{
namespace IO
{
bool FileExists(std::string file);
void WriteFile(std::string file, std::string data);
std::string ReadFile(std::string file);
}
}

67
src/Utils/InfoString.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "STDInclude.hpp"
namespace Utils
{
// Infostring class
void InfoString::Set(std::string key, std::string value)
{
this->KeyValuePairs[key] = value;
}
std::string InfoString::Get(std::string key)
{
if (this->KeyValuePairs.find(key) != this->KeyValuePairs.end())
{
return this->KeyValuePairs[key];
}
return "";
}
void InfoString::Parse(std::string buffer)
{
if (buffer[0] == '\\')
{
buffer = buffer.substr(1);
}
std::vector<std::string> KeyValues = Utils::String::Explode(buffer, '\\');
for (unsigned int i = 0; i < (KeyValues.size() - 1); i += 2)
{
this->KeyValuePairs[KeyValues[i]] = KeyValues[i + 1];
}
}
std::string InfoString::Build()
{
std::string infoString;
bool first = true;
for (auto i = this->KeyValuePairs.begin(); i != this->KeyValuePairs.end(); ++i)
{
if (first) first = false;
else infoString.append("\\");
infoString.append(i->first); // Key
infoString.append("\\");
infoString.append(i->second); // Value
}
return infoString;
}
void InfoString::Dump()
{
for (auto i = this->KeyValuePairs.begin(); i != this->KeyValuePairs.end(); ++i)
{
OutputDebugStringA(Utils::String::VA("%s: %s", i->first.data(), i->second.data()));
}
}
json11::Json InfoString::to_json()
{
return this->KeyValuePairs;
}
}

25
src/Utils/InfoString.hpp Normal file
View File

@ -0,0 +1,25 @@
#define ARR_SIZE(x) (sizeof(x) / sizeof(x[0]))
namespace Utils
{
class InfoString
{
public:
InfoString() {};
InfoString(std::string buffer) : InfoString() { this->Parse(buffer); };
InfoString(const InfoString &obj) : KeyValuePairs(obj.KeyValuePairs) {};
void Set(std::string key, std::string value);
std::string Get(std::string key);
std::string Build();
void Dump();
json11::Json to_json();
private:
std::map<std::string, std::string> KeyValuePairs;
void Parse(std::string buffer);
};
}

View File

@ -1,306 +1,306 @@
#include "STDInclude.hpp"
namespace Utils
{
std::string Stream::Reader::ReadString()
{
std::string str;
while (char byte = Stream::Reader::ReadByte())
{
str.append(&byte, 1);
}
return str;
}
const char* Stream::Reader::ReadCString()
{
return Stream::Reader::Allocator->DuplicateString(Stream::Reader::ReadString());
}
char Stream::Reader::ReadByte()
{
if ((Stream::Reader::Position + 1) <= Stream::Reader::Buffer.size())
{
return Stream::Reader::Buffer[Stream::Reader::Position++];
}
return 0;
}
void* Stream::Reader::Read(size_t size, size_t count)
{
size_t bytes = size * count;
if ((Stream::Reader::Position + bytes) <= Stream::Reader::Buffer.size())
{
void* buffer = Stream::Reader::Allocator->Allocate(bytes);
std::memcpy(buffer, Stream::Reader::Buffer.data() + Stream::Reader::Position, bytes);
Stream::Reader::Position += bytes;
return buffer;
}
return nullptr;
}
bool Stream::Reader::End()
{
return (Stream::Reader::Buffer.size() == Stream::Reader::Position);
}
void Stream::Reader::Seek(unsigned int position)
{
if (Stream::Reader::Buffer.size() >= position)
{
Stream::Reader::Position = position;
}
}
Stream::Stream() : CriticalSectionState(0)
{
memset(Stream::BlockSize, 0, sizeof(Stream::BlockSize));
}
Stream::Stream(size_t size) : Stream()
{
Stream::Buffer.reserve(size);
}
Stream::~Stream()
{
Stream::Buffer.clear();
if (Stream::CriticalSectionState != 0)
{
MessageBoxA(0, Utils::VA("Invalid critical section state '%i' for stream destruction!", Stream::CriticalSectionState), "WARNING", MB_ICONEXCLAMATION);
}
};
size_t Stream::Length()
{
return Stream::Buffer.length();
}
size_t Stream::Capacity()
{
return Stream::Buffer.capacity();
}
char* Stream::Save(const void* _str, size_t size, size_t count)
{
return Stream::Save(Stream::GetCurrentBlock(), _str, size, count);
}
char* Stream::Save(Game::XFILE_BLOCK_TYPES stream, const void * _str, size_t size, size_t count)
{
//if (stream == XFILE_BLOCK_TEMP || stream == XFILE_BLOCK_VIRTUAL || stream == XFILE_BLOCK_PHYSICAL) // Only those seem to actually write data.
// As I'm not sure though, I'll still write the data
// Use IncreaseBlockSize to fill virtual streams
auto data = Stream::Data();
if (Stream::IsCriticalSection() && Stream::Length() + (size * count) > Stream::Capacity())
{
MessageBoxA(0, Utils::VA("Potential stream reallocation during critical operation detected! Writing data of the length 0x%X exceeds the allocated stream size of 0x%X\n", (size * count), Stream::Capacity()), "ERROR", MB_ICONERROR);
__debugbreak();
}
Stream::Buffer.append(static_cast<const char*>(_str), size * count);
if (Stream::Data() != data && Stream::IsCriticalSection())
{
MessageBoxA(0, "Stream reallocation during critical operations not permitted!\nPlease increase the initial memory size or reallocate memory during non-critical sections!", "ERROR", MB_ICONERROR);
__debugbreak();
}
Stream::IncreaseBlockSize(stream, size * count);
return Stream::At() - (size * count);
}
char* Stream::Save(Game::XFILE_BLOCK_TYPES stream, int value, size_t count)
{
auto ret = Stream::Length();
for (size_t i = 0; i < count; ++i)
{
Stream::Save(stream, &value, 4, 1);
}
return Stream::Data() + ret;
}
char* Stream::SaveString(std::string string)
{
return Stream::SaveString(string.data()/*, string.size()*/);
}
char* Stream::SaveString(const char* string)
{
return Stream::SaveString(string, strlen(string));
}
char* Stream::SaveString(const char* string, size_t len)
{
auto ret = Stream::Length();
if (string)
{
Stream::Save(string, len);
}
Stream::SaveNull();
return Stream::Data() + ret;
}
char* Stream::SaveText(std::string string)
{
return Stream::Save(string.data(), string.length());
}
char* Stream::SaveByte(unsigned char byte, size_t count)
{
auto ret = Stream::Length();
for (size_t i = 0; i < count; ++i)
{
Stream::Save(&byte, 1);
}
return Stream::Data() + ret;
}
char* Stream::SaveNull(size_t count)
{
return Stream::SaveByte(0, count);
}
char* Stream::SaveMax(size_t count)
{
return Stream::SaveByte(static_cast<unsigned char>(-1), count);
}
void Stream::Align(Stream::Alignment align)
{
uint32_t size = 2 << align;
// Not power of 2!
if (!size || (size & (size - 1))) return;
--size;
Game::XFILE_BLOCK_TYPES stream = Stream::GetCurrentBlock();
Stream::BlockSize[stream] = ~size & (Stream::GetBlockSize(stream) + size);
}
bool Stream::PushBlock(Game::XFILE_BLOCK_TYPES stream)
{
Stream::StreamStack.push_back(stream);
return Stream::IsValidBlock(stream);
}
bool Stream::PopBlock()
{
if (!Stream::StreamStack.empty())
{
Stream::StreamStack.pop_back();
return true;
}
return false;
}
bool Stream::IsValidBlock(Game::XFILE_BLOCK_TYPES stream)
{
return (stream < Game::MAX_XFILE_COUNT && stream >= Game::XFILE_BLOCK_TEMP);
}
void Stream::IncreaseBlockSize(Game::XFILE_BLOCK_TYPES stream, unsigned int size)
{
if (Stream::IsValidBlock(stream))
{
Stream::BlockSize[stream] += size;
}
}
void Stream::IncreaseBlockSize(unsigned int size)
{
return IncreaseBlockSize(Stream::GetCurrentBlock(), size);
}
Game::XFILE_BLOCK_TYPES Stream::GetCurrentBlock()
{
if (!Stream::StreamStack.empty())
{
return Stream::StreamStack.back();
}
return Game::XFILE_BLOCK_INVALID;
}
char* Stream::At()
{
return reinterpret_cast<char*>(Stream::Data() + Stream::Length());
}
char* Stream::Data()
{
return const_cast<char*>(Stream::Buffer.data());
}
unsigned int Stream::GetBlockSize(Game::XFILE_BLOCK_TYPES stream)
{
if (Stream::IsValidBlock(stream))
{
return Stream::BlockSize[stream];
}
return 0;
}
DWORD Stream::GetPackedOffset()
{
Game::XFILE_BLOCK_TYPES block = Stream::GetCurrentBlock();
Stream::Offset offset;
offset.block = block;
offset.offset = Stream::GetBlockSize(block);
return offset.GetPackedOffset();
}
void Stream::ToBuffer(std::string& outBuffer)
{
outBuffer.clear();
outBuffer.append(Stream::Data(), Stream::Length());
}
std::string Stream::ToBuffer()
{
std::string buffer;
Stream::ToBuffer(buffer);
return buffer;
}
void Stream::EnterCriticalSection()
{
++Stream::CriticalSectionState;
}
void Stream::LeaveCriticalSection()
{
--Stream::CriticalSectionState;
}
bool Stream::IsCriticalSection()
{
if (Stream::CriticalSectionState < 0)
{
MessageBoxA(0, "CriticalSectionState in stream has been overrun!", "ERROR", MB_ICONERROR);
__debugbreak();
}
return (Stream::CriticalSectionState != 0);
}
}
#include "STDInclude.hpp"
namespace Utils
{
std::string Stream::Reader::ReadString()
{
std::string str;
while (char byte = Stream::Reader::ReadByte())
{
str.append(&byte, 1);
}
return str;
}
const char* Stream::Reader::ReadCString()
{
return Stream::Reader::Allocator->DuplicateString(Stream::Reader::ReadString());
}
char Stream::Reader::ReadByte()
{
if ((Stream::Reader::Position + 1) <= Stream::Reader::Buffer.size())
{
return Stream::Reader::Buffer[Stream::Reader::Position++];
}
return 0;
}
void* Stream::Reader::Read(size_t size, size_t count)
{
size_t bytes = size * count;
if ((Stream::Reader::Position + bytes) <= Stream::Reader::Buffer.size())
{
void* buffer = Stream::Reader::Allocator->Allocate(bytes);
std::memcpy(buffer, Stream::Reader::Buffer.data() + Stream::Reader::Position, bytes);
Stream::Reader::Position += bytes;
return buffer;
}
return nullptr;
}
bool Stream::Reader::End()
{
return (Stream::Reader::Buffer.size() == Stream::Reader::Position);
}
void Stream::Reader::Seek(unsigned int position)
{
if (Stream::Reader::Buffer.size() >= position)
{
Stream::Reader::Position = position;
}
}
Stream::Stream() : CriticalSectionState(0)
{
memset(Stream::BlockSize, 0, sizeof(Stream::BlockSize));
}
Stream::Stream(size_t size) : Stream()
{
Stream::Buffer.reserve(size);
}
Stream::~Stream()
{
Stream::Buffer.clear();
if (Stream::CriticalSectionState != 0)
{
MessageBoxA(0, Utils::String::VA("Invalid critical section state '%i' for stream destruction!", Stream::CriticalSectionState), "WARNING", MB_ICONEXCLAMATION);
}
};
size_t Stream::Length()
{
return Stream::Buffer.length();
}
size_t Stream::Capacity()
{
return Stream::Buffer.capacity();
}
char* Stream::Save(const void* _str, size_t size, size_t count)
{
return Stream::Save(Stream::GetCurrentBlock(), _str, size, count);
}
char* Stream::Save(Game::XFILE_BLOCK_TYPES stream, const void * _str, size_t size, size_t count)
{
//if (stream == XFILE_BLOCK_TEMP || stream == XFILE_BLOCK_VIRTUAL || stream == XFILE_BLOCK_PHYSICAL) // Only those seem to actually write data.
// As I'm not sure though, I'll still write the data
// Use IncreaseBlockSize to fill virtual streams
auto data = Stream::Data();
if (Stream::IsCriticalSection() && Stream::Length() + (size * count) > Stream::Capacity())
{
MessageBoxA(0, Utils::String::VA("Potential stream reallocation during critical operation detected! Writing data of the length 0x%X exceeds the allocated stream size of 0x%X\n", (size * count), Stream::Capacity()), "ERROR", MB_ICONERROR);
__debugbreak();
}
Stream::Buffer.append(static_cast<const char*>(_str), size * count);
if (Stream::Data() != data && Stream::IsCriticalSection())
{
MessageBoxA(0, "Stream reallocation during critical operations not permitted!\nPlease increase the initial memory size or reallocate memory during non-critical sections!", "ERROR", MB_ICONERROR);
__debugbreak();
}
Stream::IncreaseBlockSize(stream, size * count);
return Stream::At() - (size * count);
}
char* Stream::Save(Game::XFILE_BLOCK_TYPES stream, int value, size_t count)
{
auto ret = Stream::Length();
for (size_t i = 0; i < count; ++i)
{
Stream::Save(stream, &value, 4, 1);
}
return Stream::Data() + ret;
}
char* Stream::SaveString(std::string string)
{
return Stream::SaveString(string.data()/*, string.size()*/);
}
char* Stream::SaveString(const char* string)
{
return Stream::SaveString(string, strlen(string));
}
char* Stream::SaveString(const char* string, size_t len)
{
auto ret = Stream::Length();
if (string)
{
Stream::Save(string, len);
}
Stream::SaveNull();
return Stream::Data() + ret;
}
char* Stream::SaveText(std::string string)
{
return Stream::Save(string.data(), string.length());
}
char* Stream::SaveByte(unsigned char byte, size_t count)
{
auto ret = Stream::Length();
for (size_t i = 0; i < count; ++i)
{
Stream::Save(&byte, 1);
}
return Stream::Data() + ret;
}
char* Stream::SaveNull(size_t count)
{
return Stream::SaveByte(0, count);
}
char* Stream::SaveMax(size_t count)
{
return Stream::SaveByte(static_cast<unsigned char>(-1), count);
}
void Stream::Align(Stream::Alignment align)
{
uint32_t size = 2 << align;
// Not power of 2!
if (!size || (size & (size - 1))) return;
--size;
Game::XFILE_BLOCK_TYPES stream = Stream::GetCurrentBlock();
Stream::BlockSize[stream] = ~size & (Stream::GetBlockSize(stream) + size);
}
bool Stream::PushBlock(Game::XFILE_BLOCK_TYPES stream)
{
Stream::StreamStack.push_back(stream);
return Stream::IsValidBlock(stream);
}
bool Stream::PopBlock()
{
if (!Stream::StreamStack.empty())
{
Stream::StreamStack.pop_back();
return true;
}
return false;
}
bool Stream::IsValidBlock(Game::XFILE_BLOCK_TYPES stream)
{
return (stream < Game::MAX_XFILE_COUNT && stream >= Game::XFILE_BLOCK_TEMP);
}
void Stream::IncreaseBlockSize(Game::XFILE_BLOCK_TYPES stream, unsigned int size)
{
if (Stream::IsValidBlock(stream))
{
Stream::BlockSize[stream] += size;
}
}
void Stream::IncreaseBlockSize(unsigned int size)
{
return IncreaseBlockSize(Stream::GetCurrentBlock(), size);
}
Game::XFILE_BLOCK_TYPES Stream::GetCurrentBlock()
{
if (!Stream::StreamStack.empty())
{
return Stream::StreamStack.back();
}
return Game::XFILE_BLOCK_INVALID;
}
char* Stream::At()
{
return reinterpret_cast<char*>(Stream::Data() + Stream::Length());
}
char* Stream::Data()
{
return const_cast<char*>(Stream::Buffer.data());
}
unsigned int Stream::GetBlockSize(Game::XFILE_BLOCK_TYPES stream)
{
if (Stream::IsValidBlock(stream))
{
return Stream::BlockSize[stream];
}
return 0;
}
DWORD Stream::GetPackedOffset()
{
Game::XFILE_BLOCK_TYPES block = Stream::GetCurrentBlock();
Stream::Offset offset;
offset.block = block;
offset.offset = Stream::GetBlockSize(block);
return offset.GetPackedOffset();
}
void Stream::ToBuffer(std::string& outBuffer)
{
outBuffer.clear();
outBuffer.append(Stream::Data(), Stream::Length());
}
std::string Stream::ToBuffer()
{
std::string buffer;
Stream::ToBuffer(buffer);
return buffer;
}
void Stream::EnterCriticalSection()
{
++Stream::CriticalSectionState;
}
void Stream::LeaveCriticalSection()
{
--Stream::CriticalSectionState;
}
bool Stream::IsCriticalSection()
{
if (Stream::CriticalSectionState < 0)
{
MessageBoxA(0, "CriticalSectionState in stream has been overrun!", "ERROR", MB_ICONERROR);
__debugbreak();
}
return (Stream::CriticalSectionState != 0);
}
}

119
src/Utils/String.cpp Normal file
View File

@ -0,0 +1,119 @@
#include "STDInclude.hpp"
namespace Utils
{
namespace String
{
std::string StrToLower(std::string input)
{
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
return input;
}
std::string StrToUpper(std::string input)
{
std::transform(input.begin(), input.end(), input.begin(), ::toupper);
return input;
}
bool EndsWith(std::string haystack, std::string needle)
{
return (strstr(haystack.data(), needle.data()) == (haystack.data() + haystack.size() - needle.size()));
}
std::string DumpHex(std::string data, std::string separator)
{
std::string result;
for (unsigned int i = 0; i < data.size(); ++i)
{
if (i > 0)
{
result.append(separator);
}
result.append(fmt::sprintf("%02X", data[i] & 0xFF));
}
return result;
}
std::string XORString(std::string str, char value)
{
for (unsigned int i = 0; i < str.size(); ++i)
{
str[i] ^= value;
}
return str;
}
std::vector<std::string> Explode(const std::string& str, char delim)
{
std::vector<std::string> result;
std::istringstream iss(str);
for (std::string token; std::getline(iss, token, delim);)
{
std::string _entry = std::move(token);
// Remove trailing 0x0 bytes
while (_entry.size() && !_entry[_entry.size() - 1])
{
_entry = _entry.substr(0, _entry.size() - 1);
}
result.push_back(_entry);
}
return result;
}
void Replace(std::string &string, std::string find, std::string replace)
{
size_t nPos = 0;
while ((nPos = string.find(find, nPos)) != std::string::npos)
{
string = string.replace(nPos, find.length(), replace);
nPos += replace.length();
}
}
bool StartsWith(std::string haystack, std::string needle)
{
return (haystack.size() >= needle.size() && !strncmp(needle.data(), haystack.data(), needle.size()));
}
// trim from start
std::string &LTrim(std::string &s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
std::string &RTrim(std::string &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
// trim from both ends
std::string &Trim(std::string &s)
{
return LTrim(RTrim(s));
}
std::string FormatTimeSpan(int milliseconds)
{
int secondsTotal = milliseconds / 1000;
int seconds = secondsTotal % 60;
int minutesTotal = secondsTotal / 60;
int minutes = minutesTotal % 60;
int hoursTotal = minutesTotal / 60;
return fmt::sprintf("%02d:%02d:%02d", hoursTotal, minutes, seconds);
}
}
}

38
src/Utils/String.hpp Normal file
View File

@ -0,0 +1,38 @@
namespace Utils
{
namespace String
{
template <typename ...Args>
const char* VA(std::string message, Args && ...args)
{
#define VA_BUFFER_COUNT 4
#define VA_BUFFER_SIZE 65536
static char g_vaBuffer[VA_BUFFER_COUNT][VA_BUFFER_SIZE];
static int g_vaNextBufferIndex = 0;
char* buffer = g_vaBuffer[g_vaNextBufferIndex];
std::string str = fmt::sprintf(message, std::forward<Args>(args)...);
strncpy_s(g_vaBuffer[g_vaNextBufferIndex], str.data(), VA_BUFFER_SIZE);
g_vaNextBufferIndex = (g_vaNextBufferIndex + 1) % VA_BUFFER_COUNT;
return buffer;
}
std::string StrToLower(std::string input);
std::string StrToUpper(std::string input);
bool EndsWith(std::string haystack, std::string needle);
std::vector<std::string> Explode(const std::string& str, char delim);
void Replace(std::string &string, std::string find, std::string replace);
bool StartsWith(std::string haystack, std::string needle);
std::string &LTrim(std::string &s);
std::string &RTrim(std::string &s);
std::string &Trim(std::string &s);
std::string FormatTimeSpan(int milliseconds);
std::string DumpHex(std::string data, std::string separator = " ");
std::string XORString(std::string str, char value);
}
}

View File

@ -1,287 +1,41 @@
#include "STDInclude.hpp"
#define VA_BUFFER_COUNT 4
#define VA_BUFFER_SIZE 65536
namespace Utils
{
std::string GetMimeType(std::string url)
{
wchar_t* mimeType = nullptr;
FindMimeFromData(NULL, std::wstring(url.begin(), url.end()).data(), NULL, 0, NULL, 0, &mimeType, 0);
if (mimeType)
{
std::wstring wMimeType(mimeType);
return std::string(wMimeType.begin(), wMimeType.end());
}
return "application/octet-stream";
}
const char *VA(const char *fmt, ...)
{
static char g_vaBuffer[VA_BUFFER_COUNT][VA_BUFFER_SIZE];
static int g_vaNextBufferIndex = 0;
va_list ap;
va_start(ap, fmt);
char* dest = g_vaBuffer[g_vaNextBufferIndex];
vsnprintf(g_vaBuffer[g_vaNextBufferIndex], VA_BUFFER_SIZE, fmt, ap);
g_vaNextBufferIndex = (g_vaNextBufferIndex + 1) % VA_BUFFER_COUNT;
va_end(ap);
return dest;
}
std::string StrToLower(std::string input)
{
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
return input;
}
std::string StrToUpper(std::string input)
{
std::transform(input.begin(), input.end(), input.begin(), ::toupper);
return input;
}
bool EndsWith(std::string haystack, std::string needle)
{
return (strstr(haystack.data(), needle.data()) == (haystack.data() + haystack.size() - needle.size()));
}
std::string DumpHex(std::string data, std::string separator)
{
std::string result;
for (unsigned int i = 0; i < data.size(); ++i)
{
if (i > 0)
{
result.append(separator);
}
result.append(Utils::VA("%02X", data[i] & 0xFF));
}
return result;
}
std::string XORString(std::string str, char value)
{
for (unsigned int i = 0; i < str.size(); ++i)
{
str[i] ^= value;
}
return str;
}
// Complementary function for memset, which checks if a memory is set
bool MemIsSet(void* mem, char chr, size_t length)
{
char* memArr = reinterpret_cast<char*>(mem);
for (size_t i = 0; i < length; ++i)
{
if (memArr[i] != chr)
{
return false;
}
}
return true;
}
std::vector<std::string> Explode(const std::string& str, char delim)
{
std::vector<std::string> result;
std::istringstream iss(str);
for (std::string token; std::getline(iss, token, delim);)
{
std::string _entry = std::move(token);
// Remove trailing 0x0 bytes
while (_entry.size() && !_entry[_entry.size() - 1])
{
_entry = _entry.substr(0, _entry.size() - 1);
}
result.push_back(_entry);
}
return result;
}
void Replace(std::string &string, std::string find, std::string replace)
{
size_t nPos = 0;
while ((nPos = string.find(find, nPos)) != std::string::npos)
{
string = string.replace(nPos, find.length(), replace);
nPos += replace.length();
}
}
bool StartsWith(std::string haystack, std::string needle)
{
return (haystack.size() >= needle.size() && !strncmp(needle.data(), haystack.data(), needle.size()));
}
// trim from start
std::string &LTrim(std::string &s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
std::string &RTrim(std::string &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
// trim from both ends
std::string &Trim(std::string &s)
{
return LTrim(RTrim(s));
}
std::string FormatTimeSpan(int milliseconds)
{
int secondsTotal = milliseconds / 1000;
int seconds = secondsTotal % 60;
int minutesTotal = secondsTotal / 60;
int minutes = minutesTotal % 60;
int hoursTotal = minutesTotal / 60;
return Utils::VA("%02d:%02d:%02d", hoursTotal, minutes, seconds);
}
std::string ParseChallenge(std::string data)
{
auto pos = data.find_first_of("\n ");
if (pos == std::string::npos) return data;
return data.substr(0, pos).data();
}
// TODO: Use modern file reading methods
bool FileExists(std::string file)
{
FILE* fp;
fopen_s(&fp, file.data(), "r");
if (fp)
{
fclose(fp);
return true;
}
return false;
}
void WriteFile(std::string file, std::string data)
{
std::ofstream stream(file, std::ios::binary);
if (stream.is_open())
{
stream.write(data.data(), data.size());
stream.close();
}
}
std::string ReadFile(std::string file)
{
std::string buffer;
if (FileExists(file))
{
std::streamsize size = 0;
std::ifstream stream(file, std::ios::binary);
if (!stream.is_open()) return buffer;
stream.seekg(0, std::ios::end);
size = stream.tellg();
stream.seekg(0, std::ios::beg);
if (size > -1)
{
buffer.clear();
buffer.resize((uint32_t)size);
stream.read(const_cast<char*>(buffer.data()), size);
}
stream.close();
}
return buffer;
}
// Infostring class
void InfoString::Set(std::string key, std::string value)
{
this->KeyValuePairs[key] = value;
}
std::string InfoString::Get(std::string key)
{
if (this->KeyValuePairs.find(key) != this->KeyValuePairs.end())
{
return this->KeyValuePairs[key];
}
return "";
}
std::string InfoString::Build()
{
std::string infoString;
bool first = true;
for (auto i = this->KeyValuePairs.begin(); i != this->KeyValuePairs.end(); ++i)
{
if (first) first = false;
else infoString.append("\\");
infoString.append(i->first); // Key
infoString.append("\\");
infoString.append(i->second); // Value
}
return infoString;
}
void InfoString::Dump()
{
for (auto i = this->KeyValuePairs.begin(); i != this->KeyValuePairs.end(); ++i)
{
OutputDebugStringA(Utils::VA("%s: %s", i->first.data(), i->second.data()));
}
}
json11::Json InfoString::to_json()
{
return this->KeyValuePairs;
}
void InfoString::Parse(std::string buffer)
{
if (buffer[0] == '\\')
{
buffer = buffer.substr(1);
}
std::vector<std::string> KeyValues = Utils::Explode(buffer, '\\');
for (unsigned int i = 0; i < (KeyValues.size() - 1); i+=2)
{
this->KeyValuePairs[KeyValues[i]] = KeyValues[i + 1];
}
}
}
#include "STDInclude.hpp"
namespace Utils
{
std::string GetMimeType(std::string url)
{
wchar_t* mimeType = nullptr;
FindMimeFromData(NULL, std::wstring(url.begin(), url.end()).data(), NULL, 0, NULL, 0, &mimeType, 0);
if (mimeType)
{
std::wstring wMimeType(mimeType);
return std::string(wMimeType.begin(), wMimeType.end());
}
return "application/octet-stream";
}
// Complementary function for memset, which checks if a memory is set
bool MemIsSet(void* mem, char chr, size_t length)
{
char* memArr = reinterpret_cast<char*>(mem);
for (size_t i = 0; i < length; ++i)
{
if (memArr[i] != chr)
{
return false;
}
}
return true;
}
std::string ParseChallenge(std::string data)
{
auto pos = data.find_first_of("\n ");
if (pos == std::string::npos) return data;
return data.substr(0, pos).data();
}
}

View File

@ -1,69 +1,25 @@
#define ARR_SIZE(x) (sizeof(x) / sizeof(x[0]))
namespace Utils
{
std::string GetMimeType(std::string url);
const char *VA(const char *fmt, ...);
std::string StrToLower(std::string input);
std::string StrToUpper(std::string input);
bool EndsWith(std::string haystack, std::string needle);
std::vector<std::string> Explode(const std::string& str, char delim);
void Replace(std::string &string, std::string find, std::string replace);
bool StartsWith(std::string haystack, std::string needle);
std::string &LTrim(std::string &s);
std::string &RTrim(std::string &s);
std::string &Trim(std::string &s);
std::string FormatTimeSpan(int milliseconds);
std::string ParseChallenge(std::string data);
bool FileExists(std::string file);
void WriteFile(std::string file, std::string data);
std::string ReadFile(std::string file);
std::string DumpHex(std::string data, std::string separator = " ");
std::string XORString(std::string str, char value);
bool MemIsSet(void* mem, char chr, size_t length);
class InfoString
{
public:
InfoString() {};
InfoString(std::string buffer) : InfoString() { this->Parse(buffer); };
InfoString(const InfoString &obj) : KeyValuePairs(obj.KeyValuePairs) {};
void Set(std::string key, std::string value);
std::string Get(std::string key);
std::string Build();
void Dump();
json11::Json to_json();
private:
std::map<std::string, std::string> KeyValuePairs;
void Parse(std::string buffer);
};
template <typename T> void Merge(std::vector<T>* target, T* source, size_t length)
{
if (source)
{
for (size_t i = 0; i < length; ++i)
{
target->push_back(source[i]);
}
}
}
template <typename T> void Merge(std::vector<T>* target, std::vector<T> source)
{
for (auto &entry : source)
{
target->push_back(entry);
}
}
}
namespace Utils
{
std::string GetMimeType(std::string url);
std::string ParseChallenge(std::string data);
bool MemIsSet(void* mem, char chr, size_t length);
template <typename T> void Merge(std::vector<T>* target, T* source, size_t length)
{
if (source)
{
for (size_t i = 0; i < length; ++i)
{
target->push_back(source[i]);
}
}
}
template <typename T> void Merge(std::vector<T>* target, std::vector<T> source)
{
for (auto &entry : source)
{
target->push_back(entry);
}
}
}