maint: downgrade to c++14 to expand portability

This commit is contained in:
6arelyFuture 2022-11-25 19:44:46 +00:00
parent 3ce730df44
commit 7c2870bbee
No known key found for this signature in database
GPG Key ID: 22F9079C86CFAB31
10 changed files with 887 additions and 920 deletions

View File

@ -57,11 +57,11 @@ filter "platforms:arm64"
filter {} filter {}
filter {"language:C++", "toolset:not msc*"} filter {"language:C++", "toolset:not msc*"}
buildoptions "-std=c++17" buildoptions "-std=c++14"
filter {} filter {}
filter "toolset:msc*" filter "toolset:msc*"
buildoptions "/std:c++17" buildoptions "/std:c++14"
filter {} filter {}
filter {"system:windows"} filter {"system:windows"}

View File

@ -11,15 +11,15 @@ namespace network
void set_ipv4(in_addr addr); void set_ipv4(in_addr addr);
void set_port(unsigned short port); void set_port(unsigned short port);
[[nodiscard]] unsigned short get_port() const; GSL_NODISCARD unsigned short get_port() const;
[[nodiscard]] sockaddr& get_addr(); GSL_NODISCARD sockaddr& get_addr();
[[nodiscard]] const sockaddr& get_addr() const; GSL_NODISCARD const sockaddr& get_addr() const;
[[nodiscard]] sockaddr_in& get_in_addr(); GSL_NODISCARD sockaddr_in& get_in_addr();
[[nodiscard]] const sockaddr_in& get_in_addr() const; GSL_NODISCARD const sockaddr_in& get_in_addr() const;
[[nodiscard]] bool is_local() const; GSL_NODISCARD bool is_local() const;
[[nodiscard]] std::string to_string(bool with_port = true) const; GSL_NODISCARD std::string to_string(bool with_port = true) const;
bool operator==(const address& obj) const; bool operator==(const address& obj) const;

File diff suppressed because it is too large Load Diff

View File

@ -3,116 +3,119 @@
#include <string> #include <string>
#include <tomcrypt.h> #include <tomcrypt.h>
namespace utils::cryptography namespace utils
{ {
namespace ecc namespace cryptography
{ {
class key final namespace ecc
{ {
public: class key final
key(); {
~key(); public:
key();
~key();
key(key&& obj) noexcept; key(key&& obj) noexcept;
key(const key& obj); key(const key& obj);
key& operator=(key&& obj) noexcept; key& operator=(key&& obj) noexcept;
key& operator=(const key& obj); key& operator=(const key& obj);
[[nodiscard]] bool is_valid() const; GSL_NODISCARD bool is_valid() const;
ecc_key& get(); ecc_key& get();
[[nodiscard]] const ecc_key& get() const; GSL_NODISCARD const ecc_key& get() const;
[[nodiscard]] std::string get_public_key() const; GSL_NODISCARD std::string get_public_key() const;
void set(const std::string& pub_key_buffer); void set(const std::string& pub_key_buffer);
void deserialize(const std::string& key); void deserialize(const std::string& key);
[[nodiscard]] std::string serialize(int type = PK_PRIVATE) const; GSL_NODISCARD std::string serialize(int type = PK_PRIVATE) const;
void free(); void free();
bool operator==(key& key) const; bool operator==(key& key) const;
[[nodiscard]] std::uint64_t get_hash() const; GSL_NODISCARD std::uint64_t get_hash() const;
private: private:
ecc_key key_storage_{}; ecc_key key_storage_{};
};
key generate_key(int bits);
key generate_key(int bits, const std::string& entropy);
std::string sign_message(const key& key, const std::string& message);
bool verify_message(const key& key, const std::string& message, const std::string& signature);
bool encrypt(const key& key, std::string& data);
bool decrypt(const key& key, std::string& data);
}
namespace rsa
{
std::string encrypt(const std::string& data, const std::string& hash, const std::string& key);
}
namespace des3
{
std::string encrypt(const std::string& data, const std::string& iv, const std::string& key);
std::string decrypt(const std::string& data, const std::string& iv, const std::string& key);
}
namespace tiger
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace aes
{
std::string encrypt(const std::string& data, const std::string& iv, const std::string& key);
std::string decrypt(const std::string& data, const std::string& iv, const std::string& key);
}
namespace hmac_sha1
{
std::string compute(const std::string& data, const std::string& key);
}
namespace sha1
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace sha256
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace sha512
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace base64
{
std::string encode(const std::uint8_t* data, std::size_t len);
std::string encode(const std::string& data);
std::string decode(const std::string& data);
}
namespace jenkins_one_at_a_time
{
std::uint32_t compute(const std::string& data);
std::uint32_t compute(const char* key, std::size_t len);
}; };
key generate_key(int bits); namespace random
key generate_key(int bits, const std::string& entropy); {
std::string sign_message(const key& key, const std::string& message); std::uint32_t get_integer();
bool verify_message(const key& key, const std::string& message, const std::string& signature); std::string get_challenge();
void get_data(void* data, std::size_t size);
bool encrypt(const key& key, std::string& data); }
bool decrypt(const key& key, std::string& data);
}
namespace rsa
{
std::string encrypt(const std::string& data, const std::string& hash, const std::string& key);
}
namespace des3
{
std::string encrypt(const std::string& data, const std::string& iv, const std::string& key);
std::string decrypt(const std::string& data, const std::string& iv, const std::string& key);
}
namespace tiger
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace aes
{
std::string encrypt(const std::string& data, const std::string& iv, const std::string& key);
std::string decrypt(const std::string& data, const std::string& iv, const std::string& key);
}
namespace hmac_sha1
{
std::string compute(const std::string& data, const std::string& key);
}
namespace sha1
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace sha256
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace sha512
{
std::string compute(const std::string& data, bool hex = false);
std::string compute(const std::uint8_t* data, std::size_t length, bool hex = false);
}
namespace base64
{
std::string encode(const std::uint8_t* data, std::size_t len);
std::string encode(const std::string& data);
std::string decode(const std::string& data);
}
namespace jenkins_one_at_a_time
{
std::uint32_t compute(const std::string& data);
std::uint32_t compute(const char* key, std::size_t len);
};
namespace random
{
std::uint32_t get_integer();
std::string get_challenge();
void get_data(void* data, std::size_t size);
} }
} }

View File

@ -1,128 +1,92 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "io.hpp" #include "io.hpp"
namespace utils::io namespace utils
{ {
bool remove_file(const std::string& file) namespace io
{ {
return remove(file.data()) == 0; bool remove_file(const std::string& file)
}
bool move_file(const std::string& src, const std::string& target)
{
return rename(src.data(), target.data()) == 0;
}
bool file_exists(const std::string& file)
{
return std::ifstream(file).good();
}
bool write_file(const std::string& file, const std::string& data, const bool append)
{
const auto pos = file.find_last_of("/\\");
if (pos != std::string::npos)
{ {
create_directory(file.substr(0, pos)); return remove(file.data()) == 0;
} }
auto mode = std::ios::binary | std::ofstream::out; bool move_file(const std::string& src, const std::string& target)
if (append)
{ {
mode |= std::ofstream::app; return rename(src.data(), target.data()) == 0;
} }
std::ofstream stream(file, mode); bool file_exists(const std::string& file)
if (stream.is_open())
{ {
stream.write(data.data(), static_cast<std::streamsize>(data.size())); return std::ifstream(file).good();
stream.close();
return true;
} }
return false; bool write_file(const std::string& file, const std::string& data, const bool append)
}
std::string read_file(const std::string& file)
{
std::string data;
read_file(file, &data);
return data;
}
bool read_file(const std::string& file, std::string* data)
{
if (!data) return false;
data->clear();
if (file_exists(file))
{ {
std::ifstream stream(file, std::ios::binary); auto mode = std::ios::binary | std::ofstream::out;
if (!stream.is_open()) return false; if (append)
stream.seekg(0, std::ios::end);
const std::streamsize size = stream.tellg();
stream.seekg(0, std::ios::beg);
if (size > -1)
{ {
data->resize(static_cast<std::uint32_t>(size)); mode |= std::ofstream::app;
stream.read(const_cast<char*>(data->data()), size); }
std::ofstream stream(file, mode);
if (stream.is_open())
{
stream.write(data.data(), static_cast<std::streamsize>(data.size()));
stream.close(); stream.close();
return true; return true;
} }
return false;
} }
return false; std::string read_file(const std::string& file)
}
std::size_t file_size(const std::string& file)
{
if (file_exists(file))
{ {
std::ifstream stream(file, std::ios::binary); std::string data;
read_file(file, &data);
return data;
}
if (stream.good()) bool read_file(const std::string& file, std::string* data)
{
if (!data) return false;
data->clear();
if (file_exists(file))
{ {
std::ifstream stream(file, std::ios::binary);
if (!stream.is_open()) return false;
stream.seekg(0, std::ios::end); stream.seekg(0, std::ios::end);
return static_cast<std::size_t>(stream.tellg()); const std::streamsize size = stream.tellg();
stream.seekg(0, std::ios::beg);
if (size > -1)
{
data->resize(static_cast<std::uint32_t>(size));
stream.read(const_cast<char*>(data->data()), size);
stream.close();
return true;
}
} }
return false;
} }
return 0; std::size_t file_size(const std::string& file)
}
bool create_directory(const std::string& directory)
{
return std::filesystem::create_directories(directory);
}
bool directory_exists(const std::string& directory)
{
return std::filesystem::is_directory(directory);
}
bool directory_is_empty(const std::string& directory)
{
return std::filesystem::is_empty(directory);
}
std::vector<std::string> list_files(const std::string& directory)
{
std::vector<std::string> files;
for (auto& file : std::filesystem::directory_iterator(directory))
{ {
files.push_back(file.path().generic_string()); if (file_exists(file))
{
std::ifstream stream(file, std::ios::binary);
if (stream.good())
{
stream.seekg(0, std::ios::end);
return static_cast<std::size_t>(stream.tellg());
}
}
return 0;
} }
return files;
}
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target)
{
std::filesystem::copy(src, target, std::filesystem::copy_options::overwrite_existing |
std::filesystem::copy_options::recursive);
} }
} }

View File

@ -1,20 +1,17 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
namespace utils::io namespace utils
{ {
bool remove_file(const std::string& file); namespace io
bool move_file(const std::string& src, const std::string& target); {
bool file_exists(const std::string& file); bool remove_file(const std::string& file);
bool write_file(const std::string& file, const std::string& data, bool append = false); bool move_file(const std::string& src, const std::string& target);
bool read_file(const std::string& file, std::string* data); bool file_exists(const std::string& file);
std::string read_file(const std::string& file); bool write_file(const std::string& file, const std::string& data, bool append = false);
std::size_t file_size(const std::string& file); bool read_file(const std::string& file, std::string* data);
bool create_directory(const std::string& directory); std::string read_file(const std::string& file);
bool directory_exists(const std::string& directory); std::size_t file_size(const std::string& file);
bool directory_is_empty(const std::string& directory); }
std::vector<std::string> list_files(const std::string& directory);
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target);
} }

View File

@ -13,7 +13,7 @@ namespace utils
void memory::allocator::clear() void memory::allocator::clear()
{ {
std::lock_guard _(this->mutex_); std::lock_guard<std::mutex> _(this->mutex_);
for (auto& data : this->pool_) for (auto& data : this->pool_)
{ {
@ -25,7 +25,7 @@ namespace utils
void memory::allocator::free(void* data) void memory::allocator::free(void* data)
{ {
std::lock_guard _(this->mutex_); std::lock_guard<std::mutex> _(this->mutex_);
const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); const auto j = std::find(this->pool_.begin(), this->pool_.end(), data);
if (j != this->pool_.end()) if (j != this->pool_.end())
@ -42,7 +42,7 @@ namespace utils
void* memory::allocator::allocate(const size_t length) void* memory::allocator::allocate(const size_t length)
{ {
std::lock_guard _(this->mutex_); std::lock_guard<std::mutex> _(this->mutex_);
const auto data = memory::allocate(length); const auto data = memory::allocate(length);
this->pool_.push_back(data); this->pool_.push_back(data);
@ -56,7 +56,7 @@ namespace utils
char* memory::allocator::duplicate_string(const std::string& string) char* memory::allocator::duplicate_string(const std::string& string)
{ {
std::lock_guard _(this->mutex_); std::lock_guard<std::mutex> _(this->mutex_);
const auto data = memory::duplicate_string(string); const auto data = memory::duplicate_string(string);
this->pool_.push_back(data); this->pool_.push_back(data);

View File

@ -22,13 +22,13 @@ namespace utils
void* allocate(size_t length); void* allocate(size_t length);
template <typename T> template <typename T>
inline T* allocate() T* allocate()
{ {
return this->allocate_array<T>(1); return this->allocate_array<T>(1);
} }
template <typename T> template <typename T>
inline T* allocate_array(const size_t count = 1) T* allocate_array(const size_t count = 1)
{ {
return static_cast<T*>(this->allocate(count * sizeof(T))); return static_cast<T*>(this->allocate(count * sizeof(T)));
} }
@ -45,13 +45,13 @@ namespace utils
static void* allocate(size_t length); static void* allocate(size_t length);
template <typename T> template <typename T>
static inline T* allocate() static T* allocate()
{ {
return allocate_array<T>(1); return allocate_array<T>(1);
} }
template <typename T> template <typename T>
static inline T* allocate_array(const size_t count = 1) static T* allocate_array(const size_t count = 1)
{ {
return static_cast<T*>(allocate(count * sizeof(T))); return static_cast<T*>(allocate(count * sizeof(T)));
} }

View File

@ -5,98 +5,101 @@
#include <cstdarg> #include <cstdarg>
#include <algorithm> #include <algorithm>
namespace utils::string namespace utils
{ {
const char* va(const char* fmt, ...) namespace string
{ {
static thread_local va_provider<8, 256> provider; const char* va(const char* fmt, ...)
va_list ap;
va_start(ap, fmt);
const char* result = provider.get(fmt, ap);
va_end(ap);
return result;
}
std::vector<std::string> split(const std::string& s, const char delim)
{
std::stringstream ss(s);
std::string item;
std::vector<std::string> elems;
while (std::getline(ss, item, delim))
{ {
elems.push_back(item); static thread_local va_provider<8, 256> provider;
item = std::string();
va_list ap;
va_start(ap, fmt);
const char* result = provider.get(fmt, ap);
va_end(ap);
return result;
} }
return elems; std::vector<std::string> split(const std::string& s, const char delim)
}
std::string to_lower(std::string text)
{
std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input)
{ {
return static_cast<char>(std::tolower(input)); std::stringstream ss(s);
}); std::string item;
std::vector<std::string> elems;
return text; while (std::getline(ss, item, delim))
} {
elems.push_back(item);
item = std::string();
}
std::string to_upper(std::string text) return elems;
{ }
std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input)
std::string to_lower(std::string text)
{ {
return static_cast<char>(std::toupper(input)); std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input)
}); {
return static_cast<char>(std::tolower(input));
});
return text; return text;
} }
bool starts_with(const std::string& text, const std::string& substring) std::string to_upper(std::string text)
{
return text.find(substring) == 0;
}
bool ends_with(const std::string& text, const std::string& substring)
{
if (substring.size() > text.size()) return false;
return std::equal(substring.rbegin(), substring.rend(), text.rbegin());
}
std::string replace(std::string str, const std::string& from, const std::string& to)
{
if (from.empty())
{ {
std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input)
{
return static_cast<char>(std::toupper(input));
});
return text;
}
bool starts_with(const std::string& text, const std::string& substring)
{
return text.find(substring) == 0;
}
bool ends_with(const std::string& text, const std::string& substring)
{
if (substring.size() > text.size()) return false;
return std::equal(substring.rbegin(), substring.rend(), text.rbegin());
}
std::string replace(std::string str, const std::string& from, const std::string& to)
{
if (from.empty())
{
return str;
}
std::size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
return str; return str;
} }
std::size_t start_pos = 0; std::string dump_hex(const std::string& data, const std::string& separator)
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{ {
str.replace(start_pos, from.length(), to); std::string result;
start_pos += to.length();
}
return str; for (unsigned int i = 0; i < data.size(); ++i)
}
std::string dump_hex(const std::string& data, const std::string& separator)
{
std::string result;
for (unsigned int i = 0; i < data.size(); ++i)
{
if (i > 0)
{ {
result.append(separator); if (i > 0)
{
result.append(separator);
}
result.append(va("%02X", data[i] & 0xFF));
} }
result.append(va("%02X", data[i] & 0xFF)); return result;
} }
return result;
} }
} }

View File

@ -2,96 +2,99 @@
#include "memory.hpp" #include "memory.hpp"
#ifndef ARRAYSIZE #ifndef ARRAYSIZE
template <class Type, size_t n> template <class Type, std::size_t n>
size_t ARRAYSIZE(Type (&)[n]) { return n; } std::size_t ARRAYSIZE(Type (&)[n]) { return n; }
#endif #endif
namespace utils::string namespace utils
{ {
template <std::size_t Buffers, std::size_t MinBufferSize> namespace string
class va_provider final
{ {
public: template <std::size_t Buffers, std::size_t MinBufferSize>
static_assert(Buffers != 0 && MinBufferSize != 0, "Buffers and MinBufferSize mustn't be 0"); class va_provider final
va_provider() : current_buffer_(0)
{
}
char* get(const char* format, va_list ap)
{
++this->current_buffer_ %= ARRAYSIZE(this->string_pool_);
auto entry = &this->string_pool_[this->current_buffer_];
if (!entry->size || !entry->buffer)
{
throw std::runtime_error("String pool not initialized");
}
while (true)
{
#ifdef _WIN32
const int res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap);
#else
const int res = vsnprintf(entry->buffer, entry->size, format, ap);
#endif
if (res > 0) break; // Success
if (res == 0) return nullptr; // Error
entry->double_size();
}
return entry->buffer;
}
private:
class entry final
{ {
public: public:
explicit entry(const std::size_t _size = MinBufferSize) : size(_size), buffer(nullptr) static_assert(Buffers != 0 && MinBufferSize != 0, "Buffers and MinBufferSize mustn't be 0");
va_provider() : current_buffer_(0)
{ {
if (this->size < MinBufferSize) this->size = MinBufferSize;
this->allocate();
} }
~entry() char* get(const char* format, va_list ap)
{ {
if (this->buffer) memory::get_allocator()->free(this->buffer); ++this->current_buffer_ %= ARRAYSIZE(this->string_pool_);
this->size = 0; auto entry = &this->string_pool_[this->current_buffer_];
this->buffer = nullptr;
if (!entry->size || !entry->buffer)
{
throw std::runtime_error("String pool not initialized");
}
while (true)
{
#ifdef _WIN32
const int res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap);
#else
const int res = vsnprintf(entry->buffer, entry->size, format, ap);
#endif
if (res > 0) break; // Success
if (res == 0) return nullptr; // Error
entry->double_size();
}
return entry->buffer;
} }
void allocate() private:
class entry final
{ {
if (this->buffer) memory::get_allocator()->free(this->buffer); public:
this->buffer = memory::get_allocator()->allocate_array<char>(this->size + 1); explicit entry(const std::size_t _size = MinBufferSize) : size(_size), buffer(nullptr)
} {
if (this->size < MinBufferSize) this->size = MinBufferSize;
this->allocate();
}
void double_size() ~entry()
{ {
this->size *= 2; if (this->buffer) memory::get_allocator()->free(this->buffer);
this->allocate(); this->size = 0;
} this->buffer = nullptr;
}
std::size_t size; void allocate()
char* buffer; {
if (this->buffer) memory::get_allocator()->free(this->buffer);
this->buffer = memory::get_allocator()->allocate_array<char>(this->size + 1);
}
void double_size()
{
this->size *= 2;
this->allocate();
}
std::size_t size;
char* buffer;
};
std::size_t current_buffer_;
entry string_pool_[Buffers];
}; };
std::size_t current_buffer_; const char* va(const char* fmt, ...);
entry string_pool_[Buffers];
};
const char* va(const char* fmt, ...); std::vector<std::string> split(const std::string& s, char delim);
std::vector<std::string> split(const std::string& s, char delim); std::string to_lower(std::string text);
std::string to_upper(std::string text);
bool starts_with(const std::string& text, const std::string& substring);
bool ends_with(const std::string& text, const std::string& substring);
std::string to_lower(std::string text); std::string replace(std::string str, const std::string& from, const std::string& to);
std::string to_upper(std::string text);
bool starts_with(const std::string& text, const std::string& substring);
bool ends_with(const std::string& text, const std::string& substring);
std::string replace(std::string str, const std::string& from, const std::string& to); std::string dump_hex(const std::string& data, const std::string& separator = " ");
}
std::string dump_hex(const std::string& data, const std::string& separator = " ");
} }