1 /* 2 * Utils.h 3 * 4 * Created on: Jul 30, 2015 5 * Author: dpayne 6 */ 7 8 #ifndef _VIS_UTILS_H 9 #define _VIS_UTILS_H 10 11 #include "Domain/VisConstants.h" 12 #include "Domain/VisTypes.h" 13 14 #include <algorithm> 15 #include <cctype> 16 #include <cstdlib> 17 #include <iostream> 18 #include <locale> 19 #include <sstream> 20 #include <string> 21 #include <unordered_map> 22 #include <vector> 23 24 #include <pwd.h> 25 #include <sys/types.h> 26 #include <unistd.h> 27 28 namespace vis 29 { 30 31 class Utils 32 { 33 34 public: 35 /** 36 * Returns true if the given string is an integer. Supports signed and 37 * unsigned numbers between MIN_LONG and MAX_LONG 38 */ is_numeric(const std::string & s)39 static inline bool is_numeric(const std::string &s) 40 { 41 char *p = nullptr; 42 auto cstr = s.c_str(); 43 44 std::strtol(cstr, &p, 10); 45 46 return p != cstr; 47 } 48 49 /** 50 * lowercase and ascii string. 51 * Note: this will not work on multi-byte unicode strings 52 */ lowercase(const std::string & str)53 static inline std::string lowercase(const std::string &str) 54 { 55 std::string result = str; 56 std::transform(result.begin(), result.end(), result.begin(), ::tolower); 57 return result; 58 } 59 60 /** 61 * 62 * Converts strings to bool's. "1" and "true" are true where "true" can be 63 * mixed case, otherwise false is returned. 64 * 65 */ to_bool(const std::string & s)66 static inline bool to_bool(const std::string &s) 67 { 68 return (s == "1" || lowercase(s) == VisConstants::k_true); 69 } 70 wstring_to_string(const std::wstring & s)71 static inline const std::string wstring_to_string(const std::wstring &s) 72 { 73 return std::string(s.begin(), s.end()); 74 } 75 76 /** 77 * Helper method for getting a value from a unordered map with a default. 78 */ 79 template <class E, class V> get(const std::unordered_map<E,V> & map,const E & key,const V & default_value)80 static inline const V &get(const std::unordered_map<E, V> &map, 81 const E &key, const V &default_value) 82 { 83 auto iter = map.find(key); 84 if (iter != map.end()) 85 { 86 return iter->second; 87 } 88 89 return default_value; 90 } 91 92 /** 93 * Helper method for getting a value from a unordered map with a default. 94 */ 95 template <class E> 96 static inline const std::string get(const std::unordered_map<E,std::wstring> & map,const E & key,const std::string & default_value)97 get(const std::unordered_map<E, std::wstring> &map, const E &key, 98 const std::string &default_value) 99 { 100 auto iter = map.find(key); 101 if (iter != map.end()) 102 { 103 return wstring_to_string(iter->second); 104 } 105 106 return default_value; 107 } 108 109 /** 110 * Helper method for getting a wchar_t value from a unordered map with a 111 * default. 112 */ 113 template <class E> get(const std::unordered_map<E,std::wstring> & map,const E & key,const wchar_t default_value)114 static inline wchar_t get(const std::unordered_map<E, std::wstring> &map, 115 const E &key, const wchar_t default_value) 116 { 117 auto iter = map.find(key); 118 if (iter != map.end()) 119 { 120 if (iter->second.empty()) 121 { 122 return '\0'; 123 } 124 125 return iter->second.at(0); 126 } 127 128 return default_value; 129 } 130 131 /** 132 * Helper method for getting a bool value from a unordered map with a 133 * default. 134 */ 135 template <class E> get(const std::unordered_map<E,std::wstring> & map,const E & key,const bool default_value)136 static inline bool get(const std::unordered_map<E, std::wstring> &map, 137 const E &key, const bool default_value) 138 { 139 auto iter = map.find(key); 140 if (iter != map.end()) 141 { 142 return to_bool(wstring_to_string(iter->second)); 143 } 144 145 return default_value; 146 } 147 148 /** 149 * Helper method for getting a double value from a unordered map with a 150 * default. 151 */ 152 template <class E> get(const std::unordered_map<E,std::wstring> & map,const E & key,const double default_value)153 static inline double get(const std::unordered_map<E, std::wstring> &map, 154 const E &key, const double default_value) 155 { 156 auto iter = map.find(key); 157 if (iter != map.end()) 158 { 159 return std::stod(wstring_to_string(iter->second)); 160 } 161 162 return default_value; 163 } 164 165 /** 166 * Helper method for getting a uint32_t from a unordered map with a default. 167 */ 168 template <class E> get(const std::unordered_map<E,std::wstring> & map,const E & key,const uint32_t default_value)169 static inline uint32_t get(const std::unordered_map<E, std::wstring> &map, 170 const E &key, const uint32_t default_value) 171 { 172 auto iter = map.find(key); 173 if (iter != map.end()) 174 { 175 const auto num = to_int(wstring_to_string(iter->second)); 176 if (num < 0) 177 { 178 return default_value; 179 } 180 return static_cast<uint32_t>(num); 181 } 182 183 return default_value; 184 } 185 186 /** 187 * Helper method for getting a int32_t from a unordered map with a default. 188 */ 189 template <class E> get(const std::unordered_map<E,std::wstring> & map,const E & key,const int32_t default_value)190 static inline int32_t get(const std::unordered_map<E, std::wstring> &map, 191 const E &key, const int32_t default_value) 192 { 193 auto iter = map.find(key); 194 if (iter != map.end()) 195 { 196 return to_int(wstring_to_string(iter->second)); 197 } 198 199 return default_value; 200 } 201 202 /** 203 * Helper method for getting a int64_t from a unordered map with a default. 204 */ 205 template <class E> get(const std::unordered_map<E,std::wstring> & map,const E & key,const int64_t default_value)206 static inline int64_t get(const std::unordered_map<E, std::wstring> &map, 207 const E &key, const int64_t default_value) 208 { 209 auto iter = map.find(key); 210 if (iter != map.end()) 211 { 212 return to_long(wstring_to_string(iter->second)); 213 } 214 215 return default_value; 216 } 217 218 /** 219 * Split a string by the first delimiter. Note, the delimiter will not be 220 * included in either the first or second string in the pair. 221 */ split_first(const std::string & s,char delim,std::pair<std::string,std::string> * elems)222 static inline void split_first(const std::string &s, char delim, 223 std::pair<std::string, std::string> *elems) 224 { 225 auto index_of_first_elem = s.find_first_of(delim); 226 227 // delimiter not found 228 if (index_of_first_elem == std::string::npos) 229 { 230 elems->first = s; 231 elems->second.clear(); 232 return; 233 } 234 235 elems->first = s.substr(0, index_of_first_elem); 236 237 // nothing after the delimiter 238 if (index_of_first_elem == (s.size() - 1)) 239 { 240 elems->second.clear(); 241 } 242 else 243 { 244 elems->second = 245 s.substr(index_of_first_elem + 1, std::string::npos); 246 } 247 } 248 249 /** 250 * Split a string by the first delimiter. Note, the delimiter will not be 251 * included in either the first or second string in the pair. 252 */ split_first(const std::wstring & s,char delim,std::pair<std::wstring,std::wstring> * elems)253 static inline void split_first(const std::wstring &s, char delim, 254 std::pair<std::wstring, std::wstring> *elems) 255 { 256 auto index_of_first_elem = s.find_first_of(delim); 257 258 // delimiter not found 259 if (index_of_first_elem == std::wstring::npos) 260 { 261 elems->first = s; 262 elems->second.clear(); 263 return; 264 } 265 266 elems->first = s.substr(0, index_of_first_elem); 267 268 // nothing after the delimiter 269 if (index_of_first_elem == (s.size() - 1)) 270 { 271 elems->second.clear(); 272 } 273 else 274 { 275 elems->second = 276 s.substr(index_of_first_elem + 1, std::wstring::npos); 277 } 278 } 279 280 /** 281 * Helper method to convert string to long. If string is empty, 0 is 282 * returned. 283 */ to_long(const std::string & str)284 static inline int64_t to_long(const std::string &str) 285 { 286 if (str.empty()) 287 { 288 return 0L; 289 } 290 291 return std::atoi(str.c_str()); 292 } 293 294 /** 295 * Helper method to convert string to int. If string is empty, 0 is 296 * returned. 297 */ to_int(const std::string & str)298 static inline int32_t to_int(const std::string &str) 299 { 300 if (str.empty()) 301 { 302 return 0; 303 } 304 305 return std::atoi(str.c_str()); 306 } 307 308 /** 309 * Helper method to split a string by the delimiter "delim" 310 */ split(const std::string & s,char delim)311 static inline std::vector<std::string> split(const std::string &s, 312 char delim) 313 { 314 std::vector<std::string> result; 315 split(s, delim, &result); 316 return result; 317 } 318 319 /** 320 * Helper method to split a string by the delimiter "delim", contents are 321 * put input the vector "elems" 322 */ split(const std::string & s,char delim,std::vector<std::string> * elems)323 static inline void split(const std::string &s, char delim, 324 std::vector<std::string> *elems) 325 { 326 std::stringstream ss(s); 327 std::string item; 328 329 elems->clear(); 330 331 while (std::getline(ss, item, delim)) 332 { 333 elems->push_back(item); 334 } 335 } 336 337 /** 338 * Helper method to split a wstring by the delimiter "delim" 339 */ split(const std::wstring & s,wchar_t delim)340 static inline std::vector<std::wstring> split(const std::wstring &s, 341 wchar_t delim) 342 { 343 std::vector<std::wstring> result; 344 split(s, delim, &result); 345 return result; 346 } 347 348 /** 349 * Helper method to split a wstring by the delimiter "delim", contents are 350 * put input the vector "elems" 351 */ split(const std::wstring & s,wchar_t delim,std::vector<std::wstring> * elems)352 static inline void split(const std::wstring &s, wchar_t delim, 353 std::vector<std::wstring> *elems) 354 { 355 std::wstringstream ss(s); 356 std::wstring item; 357 358 elems->clear(); 359 360 while (std::getline(ss, item, delim)) 361 { 362 elems->push_back(item); 363 } 364 } 365 366 /** 367 * Helper method to convert a single hex character to the equivalent integer 368 * representation. 369 */ hex_to_int(char c)370 static inline int64_t hex_to_int(char c) 371 { 372 int64_t hex_number; 373 if (c >= '0' && c <= '9') 374 { 375 hex_number = static_cast<int64_t>(c - '0'); 376 } 377 else 378 { 379 if (c >= 'a' && c <= 'z') 380 { 381 c -= 32; 382 } 383 384 if (c >= 'A' && c <= 'F') 385 { 386 hex_number = 10 + static_cast<int64_t>(c - 'A'); 387 } 388 else 389 { 390 hex_number = 0; 391 } 392 } 393 394 return hex_number; 395 } 396 397 /** 398 * Helper method to convert a hex string to the equivalent integer 399 * representation. 400 */ hex_to_int(const std::string & hex)401 static inline int64_t hex_to_int(const std::string &hex) 402 { 403 auto decimalValue = 0l; 404 for (const auto &elem : hex) 405 { 406 decimalValue = decimalValue * 16 + hex_to_int(elem); 407 } 408 409 return decimalValue; 410 } 411 }; 412 } // namespace vis 413 414 #endif 415