view common/common.h @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
line wrap: on
line source
#ifndef COMMON_H
#define COMMON_H

#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <functional>
#include <random>
#include <iterator>
#include <algorithm>
#include <stdlib.h>

namespace
{
    static const std::string SLASH = "/";
    static const std::string HOSTT_WINDOWS          = "WINDOWS";
    static const std::string HOSTT_LINUX            = "LINUX";
    static const std::string HOSTT_ANDROID          = "ANDROID";
    static const std::string HOSTT_AUTHENTICATOR    = "AUTHENTICATOR";

    static const std::string HOSTT_UNKNOWN    = "UNKNOWN";
}
/* Functions and their implementation */
namespace unafrog {

std::string server();

namespace utils {

// trim from start
static inline std::string &sltrim(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
static inline std::string &srtrim(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
static inline std::string &trim(std::string &s) {
        return sltrim(srtrim(s));
}

/**
 * Converts the given hex string to a number
 **/
template <class T>
T hex_string_to_nr(const std::string& s)
{
    T ret = 0;
    for (unsigned int i = 0; i < s.length(); i += 2)
    {
        ret <<= 8;
        std::string byteString = s.substr(i, 2);
        uint8_t byte = static_cast<uint8_t>(strtol(byteString.c_str(), NULL, 16));
        ret |= byte;
    }
    return ret;
}

/**
 * Converts the parameter to string. Used since android has no std::to_string
 **/
template<class T1>
std::string to_string(const T1& v)
{
    std::stringstream ss;
    ss << v;
    return ss.str();
}

/**
 * To get a type which can be used in a stringstream to be used as int if type is too small (char)
 */
template <class T> struct typefinder { using type = T; };
template<> struct typefinder<char> { using type = int; };
template<> struct typefinder<unsigned char> { using type = int; };

/**
 * Converts the given number to a string. The number must be integral type, floating
 * point conversion is deleted by default.
 **/
template<typename T, class = typename std::enable_if<std::is_integral<T>::value>::type> std::string int_to_hex( T i )
{
    std::stringstream stream;
    stream << std::setfill ('0') << std::setw(sizeof(T)*2)
           << std::hex << static_cast<typename typefinder<T>::type>(i);
    return stream.str();
}

/** Converts the given hex string to the vector of bytes */
std::vector<uint8_t> hex_string_to_vector(const std::string& s);

/**
 * Convrets the given input string to a hex string.
 * Return the hex string, lowercase
 **/
std::string hex_to_string(const std::string& input);

/**
 * Converts the given hext string (as generated by hex_to_string) to the original string
 */
std::string string_to_hex(const std::string& input);

/**
 * Makes a URL with the given arguments
 **/
template<class Arg>
std::string make_url(Arg arg)
{
    return to_string(arg);
}

template<class Arg, class... Args>
std::string make_url(Arg a, Args... args)
{
    std::string res = to_string(a) + SLASH + make_url(args...);
    return res;
}

/**
 * Will remove all HTML tags from the string and transform the HTML special characters into their equivalent
 **/
std::string sanitize_user_input(const std::string& s, bool remove_domains = true);

/**
 * Will sanitize the hostname, ir. remove the - and . characters and replace them with "_"
 */
std::string sanitize_hostname_web(std::string hn);

/**
 * consumes the given number of characters from the strings' beginning, throws if out of range
 **/
std::string consume(std::string& s, int c);

/**
 * Grows the given string to the required length.
 */
std::string grow(const std::string& s, std::size_t required_length);

/* The b62 namespace contains functions related to B62 encoding/decoding */
namespace b62 {

/**
 * base62 decodes the given string, returns the number
 */
uint64_t base62_decode (const std::string &str);

/**
 * encodes the given number into base62
 **/
std::string base62_encode (uint64_t val);

} //b62

/* The random namespace has function for getting random data */
namespace random {

/* The class for the characters to be used in the string */
enum class random_string_class
{
    RSC_HEX     = 0,
    RSC_B64     = 1,
    RSC_FULL    = 2,
    RSC_ASC_DEC = 3,
    RSC_DEC     = 4,
};


/**
 * Will generate a random string with the given charaters from the class
 **/
std::string random_string(size_t length , random_string_class cls = unafrog::utils::random::random_string_class::RSC_ASC_DEC);

template<typename Iter, typename RandomGenerator>
Iter random_element(Iter start, Iter end, RandomGenerator& g)
{
    std::uniform_int_distribution<> dis(0, std::distance(start, end) - 1);
    std::advance(start, dis(g));
    return start;
}

template<typename Iter>
Iter random_element(Iter start, Iter end)
{
    static std::random_device rd;
    static std::mt19937 gen(rd());
    return random_element(start, end, gen);
}

template<typename C>
C random_element(const std::vector<C>& v)
{
    return *random_element(v.begin(), v.end());
}

} // random


std::string to_upper(const std::string& s);

template <typename Arg, typename... Args>
void redirect_stream(std::ostream& out, char sep,
               Arg&& arg, Args&&... args)
{
    out << std::forward<Arg>(arg);
    ((out << sep << std::forward<Args>(args)), ...);
}

template <typename... Args>
std::string join_string(char sep, Args&&... args)
{
    std::stringstream ss;
    redirect_stream(ss, sep, std::forward<Args>(args)...);
    return ss.str();
}

}} // unafrog::utils

/**
 * Will be used to compare string case insensitively
 **/
struct case_insensitive_str_eq
{
    case_insensitive_str_eq(std::string key);
    bool operator()(const std::string& item) const;
    std::string key_;
};

/**
 * Converts the given enum class to its base type
 */
template <typename E>
constexpr typename std::underlying_type<E>::type basetype(E e) noexcept
{
    return static_cast<typename std::underlying_type<E>::type>(e);
}

const std::string platform();

/** will join the strings in the vector with the given delimiter */
std::string join(const std::vector<std::string>& vec, const char* delim);

/** will split the string into substrings, delimited by delim */
std::vector<std::string> split(const std::string&, const char *delim);

/** will run a piece of code when the scope is left */
template<class F>
class scope_exit_runner
{
public:
    scope_exit_runner(F f) : m_f(f) {};
    scope_exit_runner(F f, bool run) : m_f(f), m_really_run(run) {};
    virtual ~scope_exit_runner() { if(m_really_run) m_f(); }
    void invalidate() { m_really_run = false; }
    void validate() { m_really_run = true; }

    template<typename T>
    void operator()(T s)
    {
        m_f(s);
    }

private:
    F m_f;
    bool m_really_run = true;
};

template<class F>
class simple_runner
{
public:
    simple_runner(F f) : m_f(f) {}
    template<typename T>
    simple_runner(F f, T t) : m_f(f)
    {
        m_f(t);
    }

    template<typename T>
    void operator()(T t)
    {
        m_f(t);
    }

private:
    F m_f;

};

/* just to signal an error */
unsigned internalServerError();

/* remove the duplicates from a string */
std::string remove_duplicates(std::string s, char to_remove);

/* removes the quotes from the string */
void remove_quotes(std::string &s);


template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if< I == sizeof...(Tp), void>::type
for_index(std::size_t, std::tuple<Tp...> &, FuncT)
{}

template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if< I < sizeof...(Tp), void>::type
for_index(int index, std::tuple<Tp...>& t, FuncT f)
{
    if (index == 0) f(std::get<I>(t));
    for_index<I + 1, FuncT, Tp...>(index-1, t, f);
}

template <class ...Vals>
std::tuple<Vals...> valset(Vals... v)
{
    return std::make_tuple(v...);
}

#endif