Use new format library and sort utils
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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
51
src/Utils/IO.cpp
Normal 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
9
src/Utils/IO.hpp
Normal 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
67
src/Utils/InfoString.cpp
Normal 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
25
src/Utils/InfoString.hpp
Normal 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);
|
||||
};
|
||||
}
|
@ -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
119
src/Utils/String.cpp
Normal 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 <rim(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
38
src/Utils/String.hpp
Normal 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 <rim(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);
|
||||
}
|
||||
}
|
@ -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 <rim(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();
|
||||
}
|
||||
}
|
||||
|
@ -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 <rim(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user