Browse Source

Moved: module 'std_utils' to libpEpCxx11

pull/15/head
heck 3 years ago
parent
commit
e9bd989020
  1. 396
      src/std_utils.cc
  2. 114
      src/std_utils.hh
  3. 97
      src/std_utils.hxx

396
src/std_utils.cc

@ -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

114
src/std_utils.hh

@ -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

97
src/std_utils.hxx

@ -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…
Cancel
Save