annotate 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
rev   line source
ferencd@0 1 #ifndef COMMON_H
ferencd@0 2 #define COMMON_H
ferencd@0 3
ferencd@0 4 #include <string>
ferencd@0 5 #include <vector>
ferencd@0 6 #include <sstream>
ferencd@0 7 #include <iomanip>
ferencd@0 8 #include <functional>
ferencd@0 9 #include <random>
ferencd@0 10 #include <iterator>
ferencd@0 11 #include <algorithm>
ferencd@0 12 #include <stdlib.h>
ferencd@0 13
ferencd@0 14 namespace
ferencd@0 15 {
ferencd@0 16 static const std::string SLASH = "/";
ferencd@0 17 static const std::string HOSTT_WINDOWS = "WINDOWS";
ferencd@0 18 static const std::string HOSTT_LINUX = "LINUX";
ferencd@0 19 static const std::string HOSTT_ANDROID = "ANDROID";
ferencd@0 20 static const std::string HOSTT_AUTHENTICATOR = "AUTHENTICATOR";
ferencd@0 21
ferencd@0 22 static const std::string HOSTT_UNKNOWN = "UNKNOWN";
ferencd@0 23 }
ferencd@0 24 /* Functions and their implementation */
ferencd@0 25 namespace unafrog {
ferencd@0 26
ferencd@0 27 std::string server();
ferencd@0 28
ferencd@0 29 namespace utils {
ferencd@0 30
ferencd@0 31 // trim from start
ferencd@0 32 static inline std::string &sltrim(std::string &s) {
ferencd@0 33 s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
ferencd@0 34 return s;
ferencd@0 35 }
ferencd@0 36
ferencd@0 37 // trim from end
ferencd@0 38 static inline std::string &srtrim(std::string &s) {
ferencd@0 39 s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
ferencd@0 40 return s;
ferencd@0 41 }
ferencd@0 42
ferencd@0 43 // trim from both ends
ferencd@0 44 static inline std::string &trim(std::string &s) {
ferencd@0 45 return sltrim(srtrim(s));
ferencd@0 46 }
ferencd@0 47
ferencd@0 48 /**
ferencd@0 49 * Converts the given hex string to a number
ferencd@0 50 **/
ferencd@0 51 template <class T>
ferencd@0 52 T hex_string_to_nr(const std::string& s)
ferencd@0 53 {
ferencd@0 54 T ret = 0;
ferencd@0 55 for (unsigned int i = 0; i < s.length(); i += 2)
ferencd@0 56 {
ferencd@0 57 ret <<= 8;
ferencd@0 58 std::string byteString = s.substr(i, 2);
ferencd@0 59 uint8_t byte = static_cast<uint8_t>(strtol(byteString.c_str(), NULL, 16));
ferencd@0 60 ret |= byte;
ferencd@0 61 }
ferencd@0 62 return ret;
ferencd@0 63 }
ferencd@0 64
ferencd@0 65 /**
ferencd@0 66 * Converts the parameter to string. Used since android has no std::to_string
ferencd@0 67 **/
ferencd@0 68 template<class T1>
ferencd@0 69 std::string to_string(const T1& v)
ferencd@0 70 {
ferencd@0 71 std::stringstream ss;
ferencd@0 72 ss << v;
ferencd@0 73 return ss.str();
ferencd@0 74 }
ferencd@0 75
ferencd@0 76 /**
ferencd@0 77 * To get a type which can be used in a stringstream to be used as int if type is too small (char)
ferencd@0 78 */
ferencd@0 79 template <class T> struct typefinder { using type = T; };
ferencd@0 80 template<> struct typefinder<char> { using type = int; };
ferencd@0 81 template<> struct typefinder<unsigned char> { using type = int; };
ferencd@0 82
ferencd@0 83 /**
ferencd@0 84 * Converts the given number to a string. The number must be integral type, floating
ferencd@0 85 * point conversion is deleted by default.
ferencd@0 86 **/
ferencd@0 87 template<typename T, class = typename std::enable_if<std::is_integral<T>::value>::type> std::string int_to_hex( T i )
ferencd@0 88 {
ferencd@0 89 std::stringstream stream;
ferencd@0 90 stream << std::setfill ('0') << std::setw(sizeof(T)*2)
ferencd@0 91 << std::hex << static_cast<typename typefinder<T>::type>(i);
ferencd@0 92 return stream.str();
ferencd@0 93 }
ferencd@0 94
ferencd@0 95 /** Converts the given hex string to the vector of bytes */
ferencd@0 96 std::vector<uint8_t> hex_string_to_vector(const std::string& s);
ferencd@0 97
ferencd@0 98 /**
ferencd@0 99 * Convrets the given input string to a hex string.
ferencd@0 100 * Return the hex string, lowercase
ferencd@0 101 **/
ferencd@0 102 std::string hex_to_string(const std::string& input);
ferencd@0 103
ferencd@0 104 /**
ferencd@0 105 * Converts the given hext string (as generated by hex_to_string) to the original string
ferencd@0 106 */
ferencd@0 107 std::string string_to_hex(const std::string& input);
ferencd@0 108
ferencd@0 109 /**
ferencd@0 110 * Makes a URL with the given arguments
ferencd@0 111 **/
ferencd@0 112 template<class Arg>
ferencd@0 113 std::string make_url(Arg arg)
ferencd@0 114 {
ferencd@0 115 return to_string(arg);
ferencd@0 116 }
ferencd@0 117
ferencd@0 118 template<class Arg, class... Args>
ferencd@0 119 std::string make_url(Arg a, Args... args)
ferencd@0 120 {
ferencd@0 121 std::string res = to_string(a) + SLASH + make_url(args...);
ferencd@0 122 return res;
ferencd@0 123 }
ferencd@0 124
ferencd@0 125 /**
ferencd@0 126 * Will remove all HTML tags from the string and transform the HTML special characters into their equivalent
ferencd@0 127 **/
ferencd@0 128 std::string sanitize_user_input(const std::string& s, bool remove_domains = true);
ferencd@0 129
ferencd@0 130 /**
ferencd@0 131 * Will sanitize the hostname, ir. remove the - and . characters and replace them with "_"
ferencd@0 132 */
ferencd@0 133 std::string sanitize_hostname_web(std::string hn);
ferencd@0 134
ferencd@0 135 /**
ferencd@0 136 * consumes the given number of characters from the strings' beginning, throws if out of range
ferencd@0 137 **/
ferencd@0 138 std::string consume(std::string& s, int c);
ferencd@0 139
ferencd@0 140 /**
ferencd@0 141 * Grows the given string to the required length.
ferencd@0 142 */
ferencd@0 143 std::string grow(const std::string& s, std::size_t required_length);
ferencd@0 144
ferencd@0 145 /* The b62 namespace contains functions related to B62 encoding/decoding */
ferencd@0 146 namespace b62 {
ferencd@0 147
ferencd@0 148 /**
ferencd@0 149 * base62 decodes the given string, returns the number
ferencd@0 150 */
ferencd@0 151 uint64_t base62_decode (const std::string &str);
ferencd@0 152
ferencd@0 153 /**
ferencd@0 154 * encodes the given number into base62
ferencd@0 155 **/
ferencd@0 156 std::string base62_encode (uint64_t val);
ferencd@0 157
ferencd@0 158 } //b62
ferencd@0 159
ferencd@0 160 /* The random namespace has function for getting random data */
ferencd@0 161 namespace random {
ferencd@0 162
ferencd@0 163 /* The class for the characters to be used in the string */
ferencd@0 164 enum class random_string_class
ferencd@0 165 {
ferencd@0 166 RSC_HEX = 0,
ferencd@0 167 RSC_B64 = 1,
ferencd@0 168 RSC_FULL = 2,
ferencd@0 169 RSC_ASC_DEC = 3,
ferencd@0 170 RSC_DEC = 4,
ferencd@0 171 };
ferencd@0 172
ferencd@0 173
ferencd@0 174 /**
ferencd@0 175 * Will generate a random string with the given charaters from the class
ferencd@0 176 **/
ferencd@0 177 std::string random_string(size_t length , random_string_class cls = unafrog::utils::random::random_string_class::RSC_ASC_DEC);
ferencd@0 178
ferencd@0 179 template<typename Iter, typename RandomGenerator>
ferencd@0 180 Iter random_element(Iter start, Iter end, RandomGenerator& g)
ferencd@0 181 {
ferencd@0 182 std::uniform_int_distribution<> dis(0, std::distance(start, end) - 1);
ferencd@0 183 std::advance(start, dis(g));
ferencd@0 184 return start;
ferencd@0 185 }
ferencd@0 186
ferencd@0 187 template<typename Iter>
ferencd@0 188 Iter random_element(Iter start, Iter end)
ferencd@0 189 {
ferencd@0 190 static std::random_device rd;
ferencd@0 191 static std::mt19937 gen(rd());
ferencd@0 192 return random_element(start, end, gen);
ferencd@0 193 }
ferencd@0 194
ferencd@0 195 template<typename C>
ferencd@0 196 C random_element(const std::vector<C>& v)
ferencd@0 197 {
ferencd@0 198 return *random_element(v.begin(), v.end());
ferencd@0 199 }
ferencd@0 200
ferencd@0 201 } // random
ferencd@0 202
ferencd@0 203
ferencd@0 204 std::string to_upper(const std::string& s);
ferencd@0 205
ferencd@0 206 template <typename Arg, typename... Args>
ferencd@0 207 void redirect_stream(std::ostream& out, char sep,
ferencd@0 208 Arg&& arg, Args&&... args)
ferencd@0 209 {
ferencd@0 210 out << std::forward<Arg>(arg);
ferencd@0 211 ((out << sep << std::forward<Args>(args)), ...);
ferencd@0 212 }
ferencd@0 213
ferencd@0 214 template <typename... Args>
ferencd@0 215 std::string join_string(char sep, Args&&... args)
ferencd@0 216 {
ferencd@0 217 std::stringstream ss;
ferencd@0 218 redirect_stream(ss, sep, std::forward<Args>(args)...);
ferencd@0 219 return ss.str();
ferencd@0 220 }
ferencd@0 221
ferencd@0 222 }} // unafrog::utils
ferencd@0 223
ferencd@0 224 /**
ferencd@0 225 * Will be used to compare string case insensitively
ferencd@0 226 **/
ferencd@0 227 struct case_insensitive_str_eq
ferencd@0 228 {
ferencd@0 229 case_insensitive_str_eq(std::string key);
ferencd@0 230 bool operator()(const std::string& item) const;
ferencd@0 231 std::string key_;
ferencd@0 232 };
ferencd@0 233
ferencd@0 234 /**
ferencd@0 235 * Converts the given enum class to its base type
ferencd@0 236 */
ferencd@0 237 template <typename E>
ferencd@0 238 constexpr typename std::underlying_type<E>::type basetype(E e) noexcept
ferencd@0 239 {
ferencd@0 240 return static_cast<typename std::underlying_type<E>::type>(e);
ferencd@0 241 }
ferencd@0 242
ferencd@0 243 const std::string platform();
ferencd@0 244
ferencd@0 245 /** will join the strings in the vector with the given delimiter */
ferencd@0 246 std::string join(const std::vector<std::string>& vec, const char* delim);
ferencd@0 247
ferencd@0 248 /** will split the string into substrings, delimited by delim */
ferencd@0 249 std::vector<std::string> split(const std::string&, const char *delim);
ferencd@0 250
ferencd@0 251 /** will run a piece of code when the scope is left */
ferencd@0 252 template<class F>
ferencd@0 253 class scope_exit_runner
ferencd@0 254 {
ferencd@0 255 public:
ferencd@0 256 scope_exit_runner(F f) : m_f(f) {};
ferencd@0 257 scope_exit_runner(F f, bool run) : m_f(f), m_really_run(run) {};
ferencd@0 258 virtual ~scope_exit_runner() { if(m_really_run) m_f(); }
ferencd@0 259 void invalidate() { m_really_run = false; }
ferencd@0 260 void validate() { m_really_run = true; }
ferencd@0 261
ferencd@0 262 template<typename T>
ferencd@0 263 void operator()(T s)
ferencd@0 264 {
ferencd@0 265 m_f(s);
ferencd@0 266 }
ferencd@0 267
ferencd@0 268 private:
ferencd@0 269 F m_f;
ferencd@0 270 bool m_really_run = true;
ferencd@0 271 };
ferencd@0 272
ferencd@0 273 template<class F>
ferencd@0 274 class simple_runner
ferencd@0 275 {
ferencd@0 276 public:
ferencd@0 277 simple_runner(F f) : m_f(f) {}
ferencd@0 278 template<typename T>
ferencd@0 279 simple_runner(F f, T t) : m_f(f)
ferencd@0 280 {
ferencd@0 281 m_f(t);
ferencd@0 282 }
ferencd@0 283
ferencd@0 284 template<typename T>
ferencd@0 285 void operator()(T t)
ferencd@0 286 {
ferencd@0 287 m_f(t);
ferencd@0 288 }
ferencd@0 289
ferencd@0 290 private:
ferencd@0 291 F m_f;
ferencd@0 292
ferencd@0 293 };
ferencd@0 294
ferencd@0 295 /* just to signal an error */
ferencd@0 296 unsigned internalServerError();
ferencd@0 297
ferencd@0 298 /* remove the duplicates from a string */
ferencd@0 299 std::string remove_duplicates(std::string s, char to_remove);
ferencd@0 300
ferencd@0 301 /* removes the quotes from the string */
ferencd@0 302 void remove_quotes(std::string &s);
ferencd@0 303
ferencd@0 304
ferencd@0 305 template<std::size_t I = 0, typename FuncT, typename... Tp>
ferencd@0 306 inline typename std::enable_if< I == sizeof...(Tp), void>::type
ferencd@0 307 for_index(std::size_t, std::tuple<Tp...> &, FuncT)
ferencd@0 308 {}
ferencd@0 309
ferencd@0 310 template<std::size_t I = 0, typename FuncT, typename... Tp>
ferencd@0 311 inline typename std::enable_if< I < sizeof...(Tp), void>::type
ferencd@0 312 for_index(int index, std::tuple<Tp...>& t, FuncT f)
ferencd@0 313 {
ferencd@0 314 if (index == 0) f(std::get<I>(t));
ferencd@0 315 for_index<I + 1, FuncT, Tp...>(index-1, t, f);
ferencd@0 316 }
ferencd@0 317
ferencd@0 318 template <class ...Vals>
ferencd@0 319 std::tuple<Vals...> valset(Vals... v)
ferencd@0 320 {
ferencd@0 321 return std::make_tuple(v...);
ferencd@0 322 }
ferencd@0 323
ferencd@0 324 #endif
ferencd@0 325