Branch data Line data Source code
1 : : /* 2 : : ** Copyright (C) 2020 Sylvain Fargier 3 : : ** 4 : : ** This software is provided 'as-is', without any express or implied 5 : : ** warranty. In no event will the authors be held liable for any damages 6 : : ** arising from the use of this software. 7 : : ** 8 : : ** Permission is granted to anyone to use this software for any purpose, 9 : : ** including commercial applications, and to alter it and redistribute it 10 : : ** freely, subject to the following restrictions: 11 : : ** 12 : : ** 1. The origin of this software must not be misrepresented; you must not 13 : : ** claim that you wrote the original software. If you use this software 14 : : ** in a product, an acknowledgment in the product documentation would be 15 : : ** appreciated but is not required. 16 : : ** 2. Altered source versions must be plainly marked as such, and must not be 17 : : ** misrepresented as being the original software. 18 : : ** 3. This notice may not be removed or altered from any source distribution. 19 : : ** 20 : : ** Created on: 2022-02-14T16:52:00+01:00 21 : : ** Author: Sylvain Fargier <fargie_s> <fargier.sylvain@free.fr> 22 : : ** 23 : : */ 24 : : 25 : : #include "utils.hpp" 26 : : 27 : : #include <algorithm> 28 : : #include <cstdint> 29 : : #include <sstream> 30 : : 31 : : #include <endian.h> 32 : : #include <logger/Logger.hpp> 33 : : 34 : : #include "local-config.h" 35 : : 36 : : namespace ccut { 37 : : 38 : 52 : static inline char to_hexdigit(int8_t num) 39 : : { 40 : 52 : if (num >= 10) 41 : 15 : return num - 10 + 'A'; 42 : 37 : return num + '0'; 43 : : } 44 : : 45 : 58 : static inline uint8_t from_hexdigit(char c) 46 : : { 47 : 58 : if (c >= 'A' && c <= 'Z') 48 : 19 : return c + 10 - 'A'; 49 : 39 : else if (c >= 'a' && c <= 'z') 50 : 0 : return c + 10 - 'a'; 51 : 39 : else if (c >= '0' && c <= '9') 52 : 39 : return c - '0'; 53 : 0 : return 0xFF; 54 : : } 55 : : 56 : 0 : std::string ccutVersion(bool extraLong, bool log) 57 : : { 58 : 0 : std::string ret{PROJECT_VERSION}; 59 : 0 : if (extraLong) 60 : : { 61 : 0 : ret += "-"; 62 : 0 : ret += GIT_SHORT; 63 : 0 : ret += GIT_DIRTY; 64 : : } 65 : 0 : if (log) 66 : 0 : logger::info("ccut") << "libccut: " << ret; 67 : 0 : return ret; 68 : 0 : } 69 : : 70 : 4 : std::vector<std::string> &split(const std::string &str, 71 : : char separator, 72 : : std::vector<std::string> &out) 73 : : { 74 : 15 : for (std::string::size_type pos = 0; pos != std::string::npos;) 75 : : { 76 : 11 : std::string::size_type end = str.find(separator, pos); 77 : 11 : if (end == std::string::npos) 78 : : { 79 : 4 : out.emplace_back(str, pos); 80 : 4 : pos = end; 81 : : } 82 : : else 83 : : { 84 : 7 : out.emplace_back(str, pos, end - pos); 85 : 7 : pos = end + 1; 86 : : } 87 : : } 88 : 4 : return out; 89 : : } 90 : : 91 : 5 : std::vector<std::string> &split(const std::string::const_iterator &begin, 92 : : const std::string::const_iterator &end, 93 : : char separator, 94 : : std::vector<std::string> &out) 95 : : { 96 : 5 : if (end < begin) 97 : 1 : return out; 98 : : 99 : 4 : std::string::const_iterator pos = begin; 100 : : do 101 : : { 102 : 6 : std::string::const_iterator it = std::find(pos, end, separator); 103 : 6 : if (it == end) 104 : : { 105 : 2 : out.emplace_back(pos, end); 106 : 2 : pos = end; 107 : : } 108 : : else 109 : : { 110 : 4 : out.emplace_back(pos, it); 111 : 4 : pos = ++it; 112 : 4 : if (pos == end) 113 : 2 : out.push_back(std::string()); 114 : : } 115 : 6 : } while (pos != end); 116 : 4 : return out; 117 : : } 118 : : 119 : 11 : std::string trim(const std::string &str) 120 : : { 121 : 11 : const std::string::size_type begin = str.find_first_not_of(" \t\r\n"); 122 : 11 : if (begin == std::string::npos) 123 : 2 : return std::string(); 124 : : 125 : 9 : const std::string::size_type end = str.find_last_not_of(" \t\r\n"); 126 : : 127 : : return str.substr(begin, 128 : : (end == std::string::npos) ? std::string::npos : 129 : 9 : (end - begin + 1)); 130 : : } 131 : : 132 : 4 : std::string urlencode(const std::string &str) 133 : : { 134 : 4 : std::ostringstream oss; 135 : 46 : for (char c : str) 136 : : { 137 : 42 : if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || 138 : 27 : (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || 139 : : (c == '~')) 140 : 16 : oss << c; 141 : : else 142 : 26 : oss << '%' << to_hexdigit((c >> 4) & 0x0F) << to_hexdigit(c & 0x0F); 143 : : } 144 : 8 : return oss.str(); 145 : 4 : } 146 : : 147 : 7 : std::string urldecode(const std::string &str) 148 : : { 149 : 7 : std::ostringstream oss; 150 : 59 : for (std::size_t i = 0; i < str.size(); ++i) 151 : : { 152 : 52 : char c = str[i]; 153 : 52 : if (c == '%' && (i + 2 < str.size())) 154 : : { 155 : 29 : int decoded = from_hexdigit(str[i + 1]) << 4; 156 : 29 : decoded += from_hexdigit(str[i + 2]); 157 : 29 : if (decoded <= 0x7F) 158 : : { 159 : 26 : i += 2; 160 : 26 : c = static_cast<char>(decoded); 161 : : } 162 : : } 163 : 52 : oss << c; 164 : : } 165 : 14 : return oss.str(); 166 : 7 : } 167 : : 168 : : } // namespace ccut