
3 changed files with 0 additions and 607 deletions
@ -1,396 +0,0 @@ |
|||||
// This file is under GNU General Public License 3.0
|
|
||||
// see LICENSE.txt
|
|
||||
|
|
||||
#include "std_utils.hh" |
|
||||
#include <iostream> |
|
||||
#include <iterator> |
|
||||
#include <fstream> |
|
||||
#include <cstdio> |
|
||||
#include <cerrno> |
|
||||
#include <cmath> |
|
||||
#include <algorithm> |
|
||||
#include <thread> |
|
||||
#include <random> |
|
||||
#include <cassert> |
|
||||
#include <cstring> |
|
||||
#include <iomanip> |
|
||||
#include "pEpLog.hh" |
|
||||
|
|
||||
#ifndef WIN32 |
|
||||
#include <dirent.h> |
|
||||
#include <sys/stat.h> |
|
||||
#include <unistd.h> |
|
||||
#endif |
|
||||
|
|
||||
using namespace std; |
|
||||
using namespace pEp; |
|
||||
|
|
||||
namespace pEp { |
|
||||
namespace Utils { |
|
||||
bool is_c_str_empty(const char *str) |
|
||||
{ |
|
||||
if (str == nullptr) { |
|
||||
return true; |
|
||||
} |
|
||||
string tmp{ str }; |
|
||||
if (tmp.empty()) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
string nested_exception_to_string(const exception &e, int level, string src) |
|
||||
{ |
|
||||
src += string(level, ' ') + "exception: " + e.what() + "\n"; |
|
||||
try { |
|
||||
rethrow_if_nested(e); |
|
||||
} catch (const exception &e) { |
|
||||
src = nested_exception_to_string(e, level + 1, src); |
|
||||
} catch (...) { |
|
||||
} |
|
||||
return src; |
|
||||
} |
|
||||
|
|
||||
// File utils
|
|
||||
bool path_exists(const string &filename) |
|
||||
{ |
|
||||
ifstream ifile(filename.c_str()); |
|
||||
return static_cast<bool>(ifile); |
|
||||
} |
|
||||
|
|
||||
void path_delete(const string &filename) |
|
||||
{ |
|
||||
int status = remove(filename.c_str()); |
|
||||
if (status) { |
|
||||
runtime_error e{ string("path_delete(\"" + filename + "\") - " + strerror(errno)) }; |
|
||||
throw(e); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#ifndef WIN32 |
|
||||
std::string dir_get_cwd() |
|
||||
{ |
|
||||
std::string ret; |
|
||||
char cwd[2048]; |
|
||||
char const *res = getcwd(cwd, sizeof(cwd)); |
|
||||
if (res == nullptr) { |
|
||||
throw std::runtime_error( |
|
||||
"failed to get current working directory: " + std::string(strerror(errno))); |
|
||||
} |
|
||||
ret = std::string(res); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
void dir_set_cwd(const std::string &dir) |
|
||||
{ |
|
||||
int err = chdir(dir.c_str()); |
|
||||
if (err != 0) { |
|
||||
throw std::runtime_error("dir_set_cwd(" + dir + ")" + std::string(strerror(errno))); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
bool path_is_dir(const string &path) |
|
||||
{ |
|
||||
bool ret = false; |
|
||||
struct stat statbuf; |
|
||||
if (stat(path.c_str(), &statbuf) != 0) { |
|
||||
runtime_error e{ "path_is_dir(\"" + path + "\") - " + strerror(errno) }; |
|
||||
throw(e); |
|
||||
} |
|
||||
if (S_ISDIR(statbuf.st_mode)) { |
|
||||
ret = true; |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
void path_delete_all(const string &path) |
|
||||
{ |
|
||||
try { |
|
||||
if (!path_is_dir(path)) { |
|
||||
path_delete(path); |
|
||||
} else { |
|
||||
vector<string> dirlist = dir_list_all(path); |
|
||||
if (dirlist.empty()) { |
|
||||
path_delete(path); |
|
||||
} else { |
|
||||
for (const string &filename : dirlist) { |
|
||||
string newpath = path + "/" + filename; |
|
||||
path_delete_all(newpath); |
|
||||
} |
|
||||
path_delete(path); |
|
||||
} |
|
||||
} |
|
||||
} catch (...) { |
|
||||
runtime_error e{ "path_delete_all(\"" + path + "\")" }; |
|
||||
throw_with_nested(e); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
std::string path_dirname(std::string const &f) |
|
||||
{ |
|
||||
if (f.empty()) |
|
||||
return f; |
|
||||
if (f == "/") |
|
||||
return ""; |
|
||||
|
|
||||
auto len = f.size(); |
|
||||
// if the last character is / or \ ignore it
|
|
||||
if (f[len - 1] == '/' || f[len - 1] == '\\') |
|
||||
--len; |
|
||||
while (len > 0) { |
|
||||
--len; |
|
||||
if (f[len] == '/' || f[len] == '\\') |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
if (f[len] == '/' || f[len] == '\\') |
|
||||
++len; |
|
||||
return std::string(f.c_str(), len); |
|
||||
} |
|
||||
|
|
||||
std::string path_get_abs(const std::string &path) |
|
||||
{ |
|
||||
std::string ret{ path }; |
|
||||
if (path[0] != '/') { |
|
||||
ret = dir_get_cwd() + "/" + path; |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
#endif |
|
||||
|
|
||||
ofstream file_create(const string &filename) |
|
||||
{ |
|
||||
ofstream outfile{ filename }; |
|
||||
return outfile; |
|
||||
} |
|
||||
|
|
||||
std::string file_read(const std::string &filename) |
|
||||
{ |
|
||||
auto ss = ostringstream{}; |
|
||||
ifstream input_file(filename); |
|
||||
if (!input_file.is_open()) { |
|
||||
runtime_error e{ "Could not open the file: " + filename }; |
|
||||
exit(EXIT_FAILURE); |
|
||||
} |
|
||||
ss << input_file.rdbuf(); |
|
||||
return ss.str(); |
|
||||
} |
|
||||
|
|
||||
#ifndef WIN32 |
|
||||
void path_ensure_not_existing(const string &path) |
|
||||
{ |
|
||||
while (path_exists(path)) { |
|
||||
path_delete_all(path); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
void dir_create(const string &dirname, const mode_t mode) |
|
||||
{ |
|
||||
if (mkdir(dirname.c_str(), mode) != 0) { |
|
||||
runtime_error e{ string("dir_create(\"" + dirname + "\") - " + strerror(errno)) }; |
|
||||
throw(e); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void dir_ensure(const std::string &path) |
|
||||
{ |
|
||||
if (!Utils::path_exists(path)) { |
|
||||
Utils::dir_create(path); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void dir_recreate(const std::string &path) |
|
||||
{ |
|
||||
Utils::path_ensure_not_existing(path); |
|
||||
Utils::dir_ensure(path); |
|
||||
} |
|
||||
|
|
||||
vector<string> dir_list_all(const std::string &path, const bool incl_dot_and_dotdot) |
|
||||
{ |
|
||||
vector<string> ret; |
|
||||
if (!path_exists(path)) { |
|
||||
runtime_error e{ "dir_list_all(\"" + path + "\") - Error: does not exist" }; |
|
||||
throw(e); |
|
||||
} |
|
||||
|
|
||||
if (!path_is_dir(path)) { |
|
||||
runtime_error e{ "dir_list_all(\"" + path + "\") - Error: is not a directory" }; |
|
||||
throw(e); |
|
||||
} |
|
||||
|
|
||||
DIR *dirp = opendir(path.c_str()); |
|
||||
if (dirp == nullptr) { |
|
||||
runtime_error e{ "dir_list_all(\"" + path + "\") - Error opening dir" }; |
|
||||
throw e; |
|
||||
} |
|
||||
|
|
||||
struct dirent *dp; |
|
||||
while ((dp = readdir(dirp)) != NULL) { |
|
||||
ret.push_back(string(dp->d_name)); |
|
||||
} |
|
||||
|
|
||||
if (!incl_dot_and_dotdot) { |
|
||||
ret.erase( |
|
||||
remove_if( |
|
||||
ret.begin(), |
|
||||
ret.end(), |
|
||||
[](string elem) { return (elem == "." || elem == ".."); }), |
|
||||
ret.end()); |
|
||||
} |
|
||||
|
|
||||
closedir(dirp); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
vector<string> dir_list_dirs(const string &dirname, const bool incl_dot_and_dotdot) |
|
||||
{ |
|
||||
vector<string> ret = dir_list_all(dirname, incl_dot_and_dotdot); |
|
||||
ret.erase( |
|
||||
remove_if( |
|
||||
ret.begin(), |
|
||||
ret.end(), |
|
||||
[dirname](string elem) { return !path_is_dir(dirname + "/" + elem); }), |
|
||||
ret.end()); |
|
||||
|
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
vector<string> dir_list_files(const string &dirname) |
|
||||
{ |
|
||||
vector<string> ret = dir_list_all(dirname); |
|
||||
ret.erase( |
|
||||
remove_if( |
|
||||
ret.begin(), |
|
||||
ret.end(), |
|
||||
[dirname](string elem) { return path_is_dir(dirname + "/" + elem); }), |
|
||||
ret.end()); |
|
||||
return ret; |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
// Attention, it pads left...
|
|
||||
string padTo(const string &str, const size_t num, const char paddingChar) |
|
||||
{ |
|
||||
string ret{ str }; |
|
||||
if (num > ret.size()) { |
|
||||
ret.insert(0, num - ret.size(), paddingChar); |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
std::string clip(const std::string &str, const size_t len) |
|
||||
{ |
|
||||
std::string ret{ str }; |
|
||||
if (str.length() > len) { |
|
||||
ret = str.substr(0, len) + "..."; |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
// prints the beginning and the end of the string and clips out
|
|
||||
// content in the middle replaced by "... tldr ..."
|
|
||||
std::string tldr(const std::string &str, const size_t len) |
|
||||
{ |
|
||||
std::string decoration = "..."; |
|
||||
int trunclen = len - decoration.length(); |
|
||||
|
|
||||
std::string ret{ str }; |
|
||||
if (str.length() > len) { |
|
||||
ret = "\n" + str.substr(0, (int)floor(trunclen / 2.0)) + "\n... tldr ...\n"; |
|
||||
ret += str.substr(str.length() - (int)floor(trunclen / 2.0), str.length()); |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
std::string to_lower(const std::string &data) |
|
||||
{ |
|
||||
std::string ret{ data }; |
|
||||
std::transform(ret.begin(), ret.end(), ret.begin(), [](unsigned char c) { |
|
||||
return std::tolower(c); |
|
||||
}); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
string to_termcol(const Color &col) |
|
||||
{ |
|
||||
switch (col) { |
|
||||
case Color::RESET: |
|
||||
return "\033[0m"; |
|
||||
case Color::BLACK: |
|
||||
return "\033[30m"; |
|
||||
case Color::RED: |
|
||||
return "\033[31m"; |
|
||||
case Color::GREEN: |
|
||||
return "\033[32m"; |
|
||||
case Color::YELLOW: |
|
||||
return "\033[33m"; |
|
||||
case Color::BLUE: |
|
||||
return "\033[34m"; |
|
||||
case Color::MAGENTA: |
|
||||
return "\033[35m"; |
|
||||
case Color::CYAN: |
|
||||
return "\033[36m"; |
|
||||
case Color::WHITE: |
|
||||
return "\033[37m"; |
|
||||
default: |
|
||||
return "\033[0m"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void sleep_millis(int milis) |
|
||||
{ |
|
||||
std::chrono::milliseconds timespan(milis); |
|
||||
std::this_thread::sleep_for(timespan); |
|
||||
} |
|
||||
|
|
||||
// Random --------------------------------------------------------------------------------
|
|
||||
unsigned g_seed = gen_seed(); |
|
||||
std::mt19937 gen{ g_seed }; |
|
||||
|
|
||||
uint gen_seed() |
|
||||
{ |
|
||||
uint ret{}; |
|
||||
if (std::random_device{}.entropy() > 0) { |
|
||||
ret = std::random_device{}(); |
|
||||
} else { |
|
||||
pEpLog("gen_seed(): No real random device present, falling back to epoch-time"); |
|
||||
ret = std::chrono::system_clock::now().time_since_epoch().count(); |
|
||||
} |
|
||||
assert(ret != 0); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
unsigned int random_fast(int max) |
|
||||
{ |
|
||||
g_seed = (214013 * g_seed + 2531011); |
|
||||
return ((g_seed >> 16) & 0x7FFF) % max + 1; |
|
||||
} |
|
||||
|
|
||||
unsigned char random_char(unsigned char min, unsigned char max) |
|
||||
{ |
|
||||
std::uniform_int_distribution<unsigned char> dis(min, max); |
|
||||
return dis(gen); |
|
||||
} |
|
||||
|
|
||||
std::string random_string(unsigned char min, unsigned char max, int len) |
|
||||
{ |
|
||||
std::stringstream ret; |
|
||||
for (int i = 0; i < len; i++) { |
|
||||
ret << random_char(min, max); |
|
||||
} |
|
||||
return ret.str(); |
|
||||
} |
|
||||
|
|
||||
std::string random_string_fast(unsigned char min, unsigned char max, int len) |
|
||||
{ |
|
||||
int range = std::max(max - min, 0); |
|
||||
std::stringstream ret; |
|
||||
for (int i = 0; i < len; i++) { |
|
||||
ret << static_cast<unsigned char>(random_fast(range) + min); |
|
||||
} |
|
||||
return ret.str(); |
|
||||
} |
|
||||
} // namespace Utils
|
|
||||
} // namespace pEp
|
|
@ -1,114 +0,0 @@ |
|||||
// This file is under GNU General Public License 3.0
|
|
||||
// see LICENSE.txt
|
|
||||
|
|
||||
#ifndef LIBPEPADAPTER_STD_UTILS_HH |
|
||||
#define LIBPEPADAPTER_STD_UTILS_HH |
|
||||
|
|
||||
#include <string> |
|
||||
#include <exception> |
|
||||
#include <vector> |
|
||||
|
|
||||
namespace pEp { |
|
||||
namespace Utils { |
|
||||
// C-types helpers
|
|
||||
bool is_c_str_empty(const char *str); |
|
||||
|
|
||||
// C++/STL data types to string
|
|
||||
template<typename T> |
|
||||
std::string to_string(const std::vector<T> &v); |
|
||||
|
|
||||
// exception utils
|
|
||||
std::string nested_exception_to_string( |
|
||||
const std::exception &e, |
|
||||
int level = 0, |
|
||||
std::string src = ""); |
|
||||
void print_exception(const std::exception &e, int level = 0); |
|
||||
|
|
||||
// File utils
|
|
||||
// ----------
|
|
||||
// path (file & dir)
|
|
||||
bool path_exists(const std::string &filename); |
|
||||
void path_delete(const std::string &filename); |
|
||||
|
|
||||
#ifndef WIN32 |
|
||||
std::string dir_get_cwd(); |
|
||||
void dir_set_cwd(const std::string& dir); |
|
||||
bool path_is_dir(const std::string &path); |
|
||||
void path_delete_all(const std::string &path); |
|
||||
std::string path_dirname(std::string const& f); |
|
||||
std::string path_get_abs(const std::string& path); |
|
||||
#endif |
|
||||
void path_ensure_not_existing(const std::string &path); |
|
||||
|
|
||||
// file
|
|
||||
std::ofstream file_create(const std::string &filename); |
|
||||
std::string file_read(const std::string &filename); |
|
||||
|
|
||||
template<typename T = char> |
|
||||
std::vector<T> file_read_bin(const std::string& filename); |
|
||||
|
|
||||
template<typename T = char> |
|
||||
void file_write_bin(const std::string& filename, std::vector<T>& data); |
|
||||
|
|
||||
// dir
|
|
||||
#ifndef WIN32 |
|
||||
void dir_create(const std::string &dirname, const mode_t mode = 0775); |
|
||||
void dir_ensure(const std::string &path); |
|
||||
void dir_recreate(const std::string &path); |
|
||||
|
|
||||
std::vector<std::string> dir_list_all( |
|
||||
const std::string &path, |
|
||||
const bool incl_dot_and_dotdot = false); |
|
||||
|
|
||||
std::vector<std::string> dir_list_dirs( |
|
||||
const std::string &dirname, |
|
||||
const bool incl_dot_and_dotdot = false); |
|
||||
|
|
||||
std::vector<std::string> dir_list_files(const std::string &dirname); |
|
||||
#endif |
|
||||
|
|
||||
//String tools
|
|
||||
std::string padTo(const std::string &str, const size_t num, const char paddingChar); |
|
||||
std::string clip(const std::string &str, const size_t len); |
|
||||
std::string tldr(const std::string &str, const size_t len); |
|
||||
std::string to_lower(const std::string& data); |
|
||||
|
|
||||
enum class Color |
|
||||
{ |
|
||||
RESET, |
|
||||
BLACK, |
|
||||
RED, |
|
||||
GREEN, |
|
||||
YELLOW, |
|
||||
BLUE, |
|
||||
MAGENTA, |
|
||||
CYAN, |
|
||||
WHITE, |
|
||||
}; |
|
||||
|
|
||||
std::string to_termcol(const Color &col); |
|
||||
|
|
||||
|
|
||||
// Time
|
|
||||
void sleep_millis(int milis); |
|
||||
|
|
||||
// Random
|
|
||||
// Attention: calling gen_seed() often will exhaust your entropy pool.
|
|
||||
// If no random devices present, will return epoch-time.
|
|
||||
unsigned int gen_seed(); |
|
||||
unsigned int random_fast(int max); |
|
||||
unsigned char random_char(unsigned char min, unsigned char max); |
|
||||
std::string random_string(unsigned char min, unsigned char max, int len); |
|
||||
std::string random_string_fast(unsigned char min, unsigned char max, int len); |
|
||||
|
|
||||
// conversion
|
|
||||
template<class T> |
|
||||
std::string bin2hex(const T &bin); |
|
||||
template<class T> |
|
||||
std::vector<T> hex2bin(const std::string &hex_str); |
|
||||
} // namespace Utils
|
|
||||
} // namespace pEp
|
|
||||
|
|
||||
#include "std_utils.hxx" |
|
||||
|
|
||||
#endif // LIBPEPADAPTER_STD_UTILS_HH
|
|
@ -1,97 +0,0 @@ |
|||||
// This file is under GNU General Public License 3.0
|
|
||||
// see LICENSE.txt
|
|
||||
|
|
||||
#ifndef LIBPEPADAPTER_STD_UTILS_HXX |
|
||||
#define LIBPEPADAPTER_STD_UTILS_HXX |
|
||||
|
|
||||
#include <sstream> |
|
||||
#include <fstream> |
|
||||
#include <iomanip> |
|
||||
#include <iterator> |
|
||||
|
|
||||
namespace pEp { |
|
||||
namespace Utils { |
|
||||
template<typename T> |
|
||||
std::string to_string(const std::vector<T>& v) |
|
||||
{ |
|
||||
std::stringstream ss; |
|
||||
for (const T& elem : v) { |
|
||||
ss << elem << std::endl; |
|
||||
} |
|
||||
return ss.str(); |
|
||||
} |
|
||||
|
|
||||
template<typename T> |
|
||||
std::vector<T> file_read_bin(const std::string &filename) |
|
||||
{ |
|
||||
std::vector<T> ret{}; |
|
||||
if (pEp::Utils::path_exists(filename)) { |
|
||||
std::ifstream ifs(filename, std::ios_base::binary); |
|
||||
ifs.unsetf(std::ios_base::skipws); |
|
||||
|
|
||||
if (ifs.bad()) { |
|
||||
throw std::runtime_error("failed to read file: '" + filename + "'"); |
|
||||
} |
|
||||
ret = { std::istream_iterator<T>(ifs), std::istream_iterator<T>() }; |
|
||||
} else { |
|
||||
throw std::runtime_error("File does not exist: '" + filename + "'"); |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
template<typename T> |
|
||||
void file_write_bin(const std::string &filename, std::vector<T> &data) |
|
||||
{ |
|
||||
std::fstream f(filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); |
|
||||
f.write(data.data(), static_cast<std::streamsize>(data.size())); |
|
||||
if (f.bad()) { |
|
||||
throw std::runtime_error("failed to write file: '" + filename + "'"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template<class T> |
|
||||
std::string bin2hex(const T &bin) |
|
||||
{ |
|
||||
std::string ret{}; |
|
||||
std::stringstream ss{}; |
|
||||
for (const auto &i : bin) { |
|
||||
ss << std::hex << std::setfill('0') << std::setw(2) << (int)i; |
|
||||
} |
|
||||
ret = ss.str(); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
template<class T = unsigned char> |
|
||||
std::vector<T> hex2bin(const std::string &hex_str) |
|
||||
{ |
|
||||
std::vector<T> ret{}; |
|
||||
if ((hex_str.size() % 2) != 0) { |
|
||||
throw std::runtime_error("hex2bin: Invalid hex string: must be even length"); |
|
||||
} |
|
||||
for (size_t i = 0; i < hex_str.size(); i += 2) { |
|
||||
std::ostringstream val_hex{}; |
|
||||
val_hex << hex_str.at(i); |
|
||||
val_hex << hex_str.at(i + 1); |
|
||||
|
|
||||
int val_int; |
|
||||
std::istringstream conv_ss{ val_hex.str() }; |
|
||||
conv_ss >> std::hex >> val_int; |
|
||||
if (conv_ss.fail()) { |
|
||||
throw std::runtime_error("hex2bin: invalid hex string" + hex_str); |
|
||||
} |
|
||||
ret.push_back(static_cast<T>(val_int)); |
|
||||
} |
|
||||
return ret; |
|
||||
|
|
||||
// alternative way
|
|
||||
// std::string extract;
|
|
||||
// for (std::string::const_iterator pos = hex_str.begin(); pos < hex_str.end(); pos += 2) {
|
|
||||
// extract.assign(pos, pos + 2);
|
|
||||
// ret.push_back(std::stoi(extract, nullptr, 16));
|
|
||||
// }
|
|
||||
// return ret;
|
|
||||
} |
|
||||
|
|
||||
} // namespace Utils
|
|
||||
} // namespace pEp
|
|
||||
#endif // LIBPEPADAPTER_STD_UTILS_HXX
|
|
Loading…
Reference in new issue