Electroneum
string_tools.h
Go to the documentation of this file.
1 // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of the Andrey N. Sabelnikov nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 
28 
29 #ifndef _STRING_TOOLS_H_
30 #define _STRING_TOOLS_H_
31 
32 // Previously pulled in by ASIO, further cleanup still required ...
33 #ifdef _WIN32
34 # include <winsock2.h>
35 # include <windows.h>
36 #endif
37 
38 #include <string.h>
39 #include <locale>
40 #include <cstdlib>
41 #include <string>
42 #include <type_traits>
43 #include <boost/lexical_cast.hpp>
44 #include <boost/algorithm/string/predicate.hpp>
45 #include "misc_log_ex.h"
47 #include "hex.h"
48 #include "memwipe.h"
49 #include "mlocker.h"
50 #include "span.h"
51 #include "warnings.h"
52 
53 
54 #ifndef OUT
55  #define OUT
56 #endif
57 
58 #ifdef WINDOWS_PLATFORM
59 #pragma comment (lib, "Rpcrt4.lib")
60 #endif
61 
62 static const constexpr unsigned char isx[256] =
63 {
64  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
68  0xff, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
70  0xff, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
80 };
81 
82 namespace epee
83 {
84 namespace string_tools
85 {
86  //----------------------------------------------------------------------------
88  {
89  return to_hex::string(to_byte_span(to_span(src)));
90  }
91  //----------------------------------------------------------------------------
93  {
94  if (s.size() != res.size() * 2)
95  return false;
96 
97  unsigned char *dst = (unsigned char *)&res[0];
98  const unsigned char *src = (const unsigned char *)s.data();
99  for(size_t i = 0; i < s.size(); i += 2)
100  {
101  int tmp = *src++;
102  tmp = isx[tmp];
103  if (tmp == 0xff) return false;
104  int t2 = *src++;
105  t2 = isx[t2];
106  if (t2 == 0xff) return false;
107  *dst++ = (tmp << 4) | t2;
108  }
109 
110  return true;
111  }
112  //----------------------------------------------------------------------------
114  {
115  if (s.size() & 1)
116  return false;
117  res.resize(s.size() / 2);
118  epee::span<char> rspan((char*)&res[0], res.size());
119  return parse_hexstr_to_binbuff(epee::to_span(s), rspan);
120  }
121  //----------------------------------------------------------------------------
123 DISABLE_GCC_WARNING(maybe-uninitialized)
124  template<class XType>
125  inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
126  {
127  if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
128  {
129  for (char c : str_id)
130  {
132  return false;
133  }
134  }
135 
136  try
137  {
138  val = boost::lexical_cast<XType>(str_id);
139  return true;
140  }
141  catch(const std::exception& /*e*/)
142  {
143  //const char* pmsg = e.what();
144  return false;
145  }
146  catch(...)
147  {
148  return false;
149  }
150 
151  return true;
152  }
154  //----------------------------------------------------------------------------
155  template<class XType>
156  inline bool xtype_to_string(const XType& val, std::string& str)
157  {
158  try
159  {
160  str = boost::lexical_cast<std::string>(val);
161  }
162  catch(...)
163  {
164  return false;
165  }
166 
167  return true;
168  }
169  //----------------------------------------------------------------------------
171  //----------------------------------------------------------------------------
172  bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
173  //----------------------------------------------------------------------------
175  {
176  //parse ip and address
177  std::string::size_type p = addres.find(':');
178  std::string ip_str, port_str;
179  if(p == std::string::npos)
180  {
181  port = 0;
182  ip_str = addres;
183  }
184  else
185  {
186  ip_str = addres.substr(0, p);
187  port_str = addres.substr(p+1, addres.size());
188  }
189 
190  if(!get_ip_int32_from_string(ip, ip_str))
191  {
192  return false;
193  }
194 
195  if(p != std::string::npos && !get_xtype_from_string(port, port_str))
196  {
197  return false;
198  }
199  return true;
200  }
201 
203  {
204  /*
205  char buff[30] = {0};
206  i64toa_s(val, buff, sizeof(buff)-1, 10);
207  return buff;*/
208  return boost::lexical_cast<std::string>(val);
209  }
210  //----------------------------------------------------------------------------
212  {
213  std::stringstream ss;
214  ss << std::hex << val;
215  std::string s;
216  ss >> s;
217  return s;
218  }
219  //----------------------------------------------------------------------------
220 
221  inline bool compare_no_case(const std::string& str1, const std::string& str2)
222  {
223 
224  return !boost::iequals(str1, str2);
225  }
226  //----------------------------------------------------------------------------
228  {
229  static std::string module_name;
230  return module_name;
231  }
232  //----------------------------------------------------------------------------
234  {
235  static std::string module_folder;
236  return module_folder;
237  }
238  //----------------------------------------------------------------------------
239 #ifdef _WIN32
240  inline std::string get_current_module_path()
241  {
242  char pname [5000] = {0};
243  GetModuleFileNameA( NULL, pname, sizeof(pname));
244  pname[sizeof(pname)-1] = 0; //be happy ;)
245  return pname;
246  }
247 #endif
248  //----------------------------------------------------------------------------
249  inline bool set_module_name_and_folder(const std::string& path_to_process_)
250  {
251  std::string path_to_process = path_to_process_;
252 #ifdef _WIN32
253  path_to_process = get_current_module_path();
254 #endif
255  std::string::size_type a = path_to_process.rfind( '\\' );
256  if(a == std::string::npos )
257  {
258  a = path_to_process.rfind( '/' );
259  }
260  if ( a != std::string::npos )
261  {
262  get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
263  get_current_module_folder() = path_to_process.substr(0, a);
264  return true;
265  }else
266  return false;
267 
268  }
269 
270  //----------------------------------------------------------------------------
271  inline bool trim_left(std::string& str)
272  {
273  for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
274  str.erase(str.begin());
275 
276  return true;
277  }
278  //----------------------------------------------------------------------------
279  inline bool trim_right(std::string& str)
280  {
281 
282  for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
283  str.erase( --((it++).base()));
284 
285  return true;
286  }
287  //----------------------------------------------------------------------------
289  {
290 
291  trim_left(str);
292  trim_right(str);
293  return str;
294  }
295  //----------------------------------------------------------------------------
296  inline std::string trim(const std::string& str_)
297  {
298  std::string str = str_;
299  trim_left(str);
300  trim_right(str);
301  return str;
302  }
303  //----------------------------------------------------------------------------
304  inline std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false)
305  {
306  if (s.size() < n)
307  {
308  if (prepend)
309  s = std::string(n - s.size(), c) + s;
310  else
311  s.append(n - s.size(), c);
312  }
313  return s;
314  }
315  //----------------------------------------------------------------------------
316  template<class t_pod_type>
317  std::string pod_to_hex(const t_pod_type& s)
318  {
319  static_assert(std::is_standard_layout<t_pod_type>(), "expected standard layout type");
320  return to_hex::string(as_byte_span(s));
321  }
322  //----------------------------------------------------------------------------
323  template<class t_pod_type>
324  bool hex_to_pod(const std::string& hex_str, t_pod_type& s)
325  {
326  static_assert(std::is_pod<t_pod_type>::value, "expected pod type");
327  if(sizeof(s)*2 != hex_str.size())
328  return false;
329  epee::span<char> rspan((char*)&s, sizeof(s));
330  return parse_hexstr_to_binbuff(epee::to_span(hex_str), rspan);
331  }
332  //----------------------------------------------------------------------------
333  template<class t_pod_type>
334  bool hex_to_pod(const std::string& hex_str, tools::scrubbed<t_pod_type>& s)
335  {
336  return hex_to_pod(hex_str, unwrap(s));
337  }
338  //----------------------------------------------------------------------------
339  template<class t_pod_type>
341  {
342  return hex_to_pod(hex_str, unwrap(s));
343  }
344  //----------------------------------------------------------------------------
345  bool validate_hex(uint64_t length, const std::string& str);
346  //----------------------------------------------------------------------------
348  {
350  std::string::size_type pos = str.rfind('.');
351  if(std::string::npos == pos)
352  return res;
353 
354  res = str.substr(pos+1, str.size()-pos);
355  return res;
356  }
357  //----------------------------------------------------------------------------
359  {
361  std::string::size_type pos = str.rfind('.');
362  if(std::string::npos == pos)
363  return str;
364 
365  res = str.substr(0, pos);
366  return res;
367  }
368  //----------------------------------------------------------------------------
369 #ifdef _WIN32
370  inline std::wstring utf8_to_utf16(const std::string& str)
371  {
372  if (str.empty())
373  return {};
374  int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
375  if (wstr_size == 0)
376  {
377  throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
378  }
379  std::wstring wstr(wstr_size, wchar_t{});
380  if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
381  {
382  throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
383  }
384  return wstr;
385  }
386  inline std::string utf16_to_utf8(const std::wstring& wstr)
387  {
388  if (wstr.empty())
389  return {};
390  int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
391  if (str_size == 0)
392  {
393  throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
394  }
395  std::string str(str_size, char{});
396  if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
397  {
398  throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
399  }
400  return str;
401  }
402 #endif
403 }
404 }
405 #endif //_STRING_TOOLS_H_
const char * res
Definition: hmac_keccak.cpp:41
std::string get_extension(const std::string &str)
Definition: string_tools.h:347
PUSH_WARNINGS
Definition: hash-ops.h:54
bool trim_left(std::string &str)
Definition: string_tools.h:271
#define DISABLE_GCC_WARNING
Definition: warnings.h:24
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition: span.h:153
std::string cut_off_extension(const std::string &str)
Definition: string_tools.h:358
std::string num_to_string_fast(int64_t val)
Definition: string_tools.h:202
bool set_module_name_and_folder(const std::string &path_to_process_)
Definition: string_tools.h:249
::std::string string
Definition: gtest-port.h:1097
unsigned short uint16_t
Definition: stdint.h:125
Non-owning sequence of data. Does not deep copy.
Definition: span.h:56
bool trim_right(std::string &str)
Definition: string_tools.h:279
std::string & trim(std::string &str)
Definition: string_tools.h:288
#define OUT
Definition: string_tools.h:55
std::string pad_string(std::string s, size_t n, char c=' ', bool prepend=false)
Definition: string_tools.h:304
bool validate_hex(uint64_t length, const std::string &str)
constexpr std::size_t size() const noexcept
Definition: span.h:111
std::string get_ip_string_from_int32(uint32_t ip)
POP_WARNINGS bool xtype_to_string(const XType &val, std::string &str)
Definition: string_tools.h:156
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
unsigned int uint32_t
Definition: stdint.h:126
#define POP_WARNINGS
Definition: warnings.h:17
::std::wstring wstring
Definition: gtest-port.h:1103
std::string & get_current_module_name()
Definition: string_tools.h:227
unsigned __int64 uint64_t
Definition: stdint.h:136
bool compare_no_case(const std::string &str1, const std::string &str2)
Definition: string_tools.h:221
bool hex_to_pod(const std::string &hex_str, t_pod_type &s)
Definition: string_tools.h:324
std::string & get_current_module_folder()
Definition: string_tools.h:233
std::string message("Message requiring signing")
boost::endian::big_uint32_t ip
Definition: socks.cpp:61
boost::endian::big_uint16_t port
Definition: socks.cpp:60
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
t2
Definition: pow22523.h:103
std::string to_string_hex(uint32_t val)
Definition: string_tools.h:211
constexpr span< const typename T::value_type > to_span(const T &src)
Definition: span.h:123
std::string buff_to_hex_nodelimer(const std::string &src)
Definition: string_tools.h:87
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
signed __int64 int64_t
Definition: stdint.h:135
T & unwrap(mlocked< T > &src)
Definition: mlocker.h:80
static std::string string(const span< const std::uint8_t > src)
Definition: hex.cpp:68
PUSH_WARNINGS bool get_xtype_from_string(OUT XType &val, const std::string &str_id)
Definition: string_tools.h:125
bool parse_hexstr_to_binbuff(const epee::span< const char > s, epee::span< char > &res)
Definition: string_tools.h:92
bool get_ip_int32_from_string(uint32_t &ip, const std::string &ip_str)
span< const std::uint8_t > to_byte_span(const span< const T > src) noexcept
Definition: span.h:145
constexpr pointer data() const noexcept
Definition: span.h:110
bool parse_peer_from_string(uint32_t &ip, uint16_t &port, const std::string &addres)
Definition: string_tools.h:174