Split epee/string_tools.h and encapsulate boost::lexical_cast

This commit is contained in:
mj-xmr 2020-11-12 19:14:32 +01:00
parent e45619e61e
commit dc81e23e60
29 changed files with 733 additions and 496 deletions

View file

@ -32,6 +32,7 @@
#ifdef __cplusplus
#include <array>
#include <cstddef>
extern "C" {
#endif

View file

@ -47,7 +47,7 @@
#endif
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <ctime>
#pragma once
namespace epee
@ -115,15 +115,7 @@ namespace misc_utils
}
inline std::string get_thread_string_id()
{
#if defined(_WIN32)
return boost::lexical_cast<std::string>(GetCurrentThreadId());
#elif defined(__GNUC__)
return boost::lexical_cast<std::string>(pthread_self());
#endif
}
std::string get_thread_string_id();
inline bool get_gmt_time(time_t t, struct tm &tm)
{

View file

@ -42,7 +42,7 @@
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include "warnings.h"
#include "string_tools.h"
#include "string_tools_lexical.h"
#include "misc_language.h"
#include "net/local_ip.h"
#include "pragma_comp_defs.h"

View file

@ -27,14 +27,13 @@
#pragma once
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include "memwipe.h"
#include <boost/utility/string_ref.hpp>
#include <string>
#include <utility>
#include "memwipe.h"
#include "string_tools.h"
#include <list>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
@ -66,34 +65,9 @@ namespace net_utils
typedef std::list<std::pair<std::string, std::string> > fields_list;
inline
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
{
fields_list::const_iterator it = fields.begin();
for(; it != fields.end(); it++)
if(!string_tools::compare_no_case(param_name, it->first))
break;
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields);
if(it==fields.end())
return std::string();
return it->second;
}
inline
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri)
{
std::string buff = "([\\?|&])";
buff += param_name + "=([^&]*)";
boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched)
{
return result[2];
}
return std::string();
}
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri);
static inline void add_field(std::string& out, const boost::string_ref name, const boost::string_ref value)
{

View file

@ -30,7 +30,6 @@
#include <ctype.h>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/string_ref.hpp>
//#include <mbstring.h>
@ -46,6 +45,7 @@
#endif
#include "string_tools.h"
#include "string_tools_lexical.h"
#include "reg_exp_definer.h"
#include "abstract_http_client.h"
#include "http_base.h"

View file

@ -24,12 +24,9 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "http_base.h"
#include "reg_exp_definer.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
@ -38,173 +35,8 @@ namespace epee
{
namespace net_utils
{
inline bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params)
{
enum state
{
st_param_name,
st_param_val
};
state st = st_param_name;
std::string::const_iterator start_it = query.begin();
std::pair<std::string, std::string> e;
for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
{
switch(st)
{
case st_param_name:
if(*it == '=')
{
e.first.assign(start_it, it);
start_it = it;++start_it;
st = st_param_val;
}
break;
case st_param_val:
if(*it == '&')
{
e.second.assign(start_it, it);
start_it = it;++start_it;
params.push_back(e);
e.first.clear();e.second.clear();
st = st_param_name;
}
break;
default:
LOG_ERROR("Unknown state " << (int)st);
return false;
}
}
if(st == st_param_name)
{
if(start_it != query.end())
{
e.first.assign(start_it, query.end());
params.push_back(e);
}
}else
{
if(start_it != query.end())
e.second.assign(start_it, query.end());
if(e.first.size())
params.push_back(e);
}
return true;
}
inline
bool parse_uri(const std::string uri, http::uri_content& content)
{
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
content.m_query_params.clear();
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
content.m_path = uri;
return true;
}
if(result[1].matched)
{
content.m_path = result[1];
}
if(result[3].matched)
{
content.m_query = result[3];
}
if(result[5].matched)
{
content.m_fragment = result[5];
}
if(content.m_query.size())
{
parse_uri_query(content.m_query, content.m_query_params);
}
return true;
}
inline
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
{
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 3 4 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return false;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
else // if host not matched, matching should be considered failed
{
return false;
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
inline
bool parse_url(const std::string url_str, http::url_content& content)
{
if (parse_url_ipv6(url_str, content)) return true;
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 34 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return true;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
bool parse_uri(const std::string uri, http::uri_content& content);
bool parse_url_ipv6(const std::string url_str, http::url_content& content);
bool parse_url(const std::string url_str, http::url_content& content);
}
}

View file

@ -29,6 +29,7 @@
#define _REG_EXP_DEFINER_H_
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/regex.hpp>
#include "syncobj.h"
namespace epee

View file

@ -24,33 +24,16 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _STRING_TOOLS_H_
#define _STRING_TOOLS_H_
// Previously pulled in by ASIO, further cleanup still required ...
#ifdef _WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <string.h>
#include <locale>
#include <cstdlib>
#include <string>
#include <type_traits>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/utility/string_ref.hpp>
#include "misc_log_ex.h"
#include "storages/parserse_base_utils.h"
#include "hex.h"
#include "memwipe.h"
#include "mlocker.h"
#include "span.h"
#include "warnings.h"
#include <boost/utility/string_ref.hpp>
#include <sstream>
#include <string>
#include <cstdint>
#ifndef OUT
#define OUT
@ -74,182 +57,28 @@ namespace string_tools
{
return from_hex::to_string(res, s);
}
//----------------------------------------------------------------------------
PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class XType>
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
{
if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
{
for (char c : str_id)
{
if (!epee::misc_utils::parse::isdigit(c))
return false;
}
}
try
{
val = boost::lexical_cast<XType>(str_id);
return true;
}
catch(const std::exception& /*e*/)
{
//const char* pmsg = e.what();
return false;
}
catch(...)
{
return false;
}
return true;
}
POP_WARNINGS
//----------------------------------------------------------------------------
template<class XType>
inline bool xtype_to_string(const XType& val, std::string& str)
{
try
{
str = boost::lexical_cast<std::string>(val);
}
catch(...)
{
return false;
}
return true;
}
//----------------------------------------------------------------------------
std::string get_ip_string_from_int32(uint32_t ip);
//----------------------------------------------------------------------------
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
//----------------------------------------------------------------------------
inline bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
{
//parse ip and address
std::string::size_type p = addres.find(':');
std::string ip_str, port_str;
if(p == std::string::npos)
{
port = 0;
ip_str = addres;
}
else
{
ip_str = addres.substr(0, p);
port_str = addres.substr(p+1, addres.size());
}
if(!get_ip_int32_from_string(ip, ip_str))
{
return false;
}
if(p != std::string::npos && !get_xtype_from_string(port, port_str))
{
return false;
}
return true;
}
inline std::string num_to_string_fast(int64_t val)
{
/*
char buff[30] = {0};
i64toa_s(val, buff, sizeof(buff)-1, 10);
return buff;*/
return boost::lexical_cast<std::string>(val);
}
//----------------------------------------------------------------------------
template<typename T>
inline std::string to_string_hex(const T &val)
{
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
std::stringstream ss;
ss << std::hex << val;
std::string s;
ss >> s;
return s;
}
//----------------------------------------------------------------------------
std::string get_ip_string_from_int32(uint32_t ip);
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres);
std::string num_to_string_fast(int64_t val);
inline bool compare_no_case(const std::string& str1, const std::string& str2)
{
return !boost::iequals(str1, str2);
}
//----------------------------------------------------------------------------
inline std::string& get_current_module_name()
{
static std::string module_name;
return module_name;
}
//----------------------------------------------------------------------------
inline std::string& get_current_module_folder()
{
static std::string module_folder;
return module_folder;
}
//----------------------------------------------------------------------------
bool compare_no_case(const std::string& str1, const std::string& str2);
std::string& get_current_module_name();
std::string& get_current_module_folder();
#ifdef _WIN32
inline std::string get_current_module_path()
{
char pname [5000] = {0};
GetModuleFileNameA( NULL, pname, sizeof(pname));
pname[sizeof(pname)-1] = 0; //be happy ;)
return pname;
}
std::string get_current_module_path();
#endif
//----------------------------------------------------------------------------
inline bool set_module_name_and_folder(const std::string& path_to_process_)
{
std::string path_to_process = path_to_process_;
#ifdef _WIN32
path_to_process = get_current_module_path();
#endif
std::string::size_type a = path_to_process.rfind( '\\' );
if(a == std::string::npos )
{
a = path_to_process.rfind( '/' );
}
if ( a != std::string::npos )
{
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
get_current_module_folder() = path_to_process.substr(0, a);
return true;
}else
return false;
}
//----------------------------------------------------------------------------
inline bool trim_left(std::string& str)
{
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
str.erase(str.begin());
return true;
}
//----------------------------------------------------------------------------
inline bool trim_right(std::string& str)
{
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
str.erase( --((it++).base()));
return true;
}
//----------------------------------------------------------------------------
inline std::string& trim(std::string& str)
{
trim_left(str);
trim_right(str);
return str;
}
bool set_module_name_and_folder(const std::string& path_to_process_);
bool trim_left(std::string& str);
bool trim_right(std::string& str);
//----------------------------------------------------------------------------
inline std::string& trim(std::string& str)
{
trim_left(str);
trim_right(str);
return str;
}
//----------------------------------------------------------------------------
inline std::string trim(const std::string& str_)
{
@ -258,18 +87,8 @@ POP_WARNINGS
trim_right(str);
return str;
}
//----------------------------------------------------------------------------
inline std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false)
{
if (s.size() < n)
{
if (prepend)
s = std::string(n - s.size(), c) + s;
else
s.append(n - s.size(), c);
}
return s;
}
std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false);
//----------------------------------------------------------------------------
template<class t_pod_type>
std::string pod_to_hex(const t_pod_type& s)
@ -296,64 +115,25 @@ POP_WARNINGS
{
return hex_to_pod(hex_str, unwrap(s));
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
template<typename T>
inline std::string to_string_hex(const T &val)
{
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
std::stringstream ss;
ss << std::hex << val;
std::string s;
ss >> s;
return s;
}
bool validate_hex(uint64_t length, const std::string& str);
//----------------------------------------------------------------------------
inline std::string get_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return res;
res = str.substr(pos+1, str.size()-pos);
return res;
}
//----------------------------------------------------------------------------
inline std::string cut_off_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return str;
res = str.substr(0, pos);
return res;
}
//----------------------------------------------------------------------------
std::string get_extension(const std::string& str);
std::string cut_off_extension(const std::string& str);
#ifdef _WIN32
inline std::wstring utf8_to_utf16(const std::string& str)
{
if (str.empty())
return {};
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
if (wstr_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::wstring wstr(wstr_size, wchar_t{});
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return wstr;
}
inline std::string utf16_to_utf8(const std::wstring& wstr)
{
if (wstr.empty())
return {};
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
if (str_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::string str(str_size, char{});
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return str;
}
std::wstring utf8_to_utf16(const std::string& str);
std::string utf16_to_utf8(const std::wstring& wstr);
#endif
}
}

View file

@ -0,0 +1,91 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _STRING_TOOLS_LEXICAL_H_
#define _STRING_TOOLS_LEXICAL_H_
#include "warnings.h"
#include "storages/parserse_base_utils.h"
#include <boost/lexical_cast.hpp> // A heavy header, that was extracted from the rest
#ifndef OUT
#define OUT
#endif
namespace epee
{
namespace string_tools
{
PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class XType>
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
{
if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
{
for (char c : str_id)
{
if (!epee::misc_utils::parse::isdigit(c))
return false;
}
}
try
{
val = boost::lexical_cast<XType>(str_id);
return true;
}
catch(const std::exception& /*e*/)
{
//const char* pmsg = e.what();
return false;
}
catch(...)
{
return false;
}
return true;
}
POP_WARNINGS
template<class XType>
inline bool xtype_to_string(const XType& val, std::string& str)
{
try
{
str = boost::lexical_cast<std::string>(val);
}
catch(...)
{
return false;
}
return true;
}
}
}
#endif //_STRING_TOOLS_LEXICAL_H_

View file

@ -28,8 +28,6 @@
#ifndef _TINY_INI_H_
#define _TINY_INI_H_
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include "string_tools.h"
namespace epee
@ -37,20 +35,8 @@ namespace epee
namespace tiny_ini
{
inline
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
{
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
return false;
res = result[2];
string_tools::trim(res);
return true;
}
inline
std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res);
inline std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
{
std::string buff;
get_param_value(param_name, ini_entry, buff);

View file

@ -38,7 +38,11 @@ add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_cli
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
int-util.cpp portable_storage.cpp
misc_language.cpp
misc_os_dependent.cpp
file_io_utils.cpp
net_parse_helpers.cpp
http_base.cpp
tiny_ini.cpp
${EPEE_HEADERS_PUBLIC}
)

View file

@ -1,6 +1,7 @@
#include "net/abstract_http_client.h"
#include "net/http_base.h"
#include "net/net_parse_helpers.h"
#include "misc_log_ex.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"

View file

@ -0,0 +1,71 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "net/http_base.h"
#include "memwipe.h"
#include "string_tools.h"
#include <boost/regex.hpp>
#include <string>
#include <utility>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
namespace epee
{
namespace net_utils
{
namespace http
{
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
{
fields_list::const_iterator it = fields.begin();
for(; it != fields.end(); it++)
if(!string_tools::compare_no_case(param_name, it->first))
break;
if(it==fields.end())
return std::string();
return it->second;
}
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri)
{
std::string buff = "([\\?|&])";
buff += param_name + "=([^&]*)";
boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched)
{
return result[2];
}
return std::string();
}
}
}
}

View file

@ -0,0 +1,44 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "misc_os_dependent.h"
#include <boost/lexical_cast.hpp>
namespace epee
{
namespace misc_utils
{
// TODO: (vtnerd) This function is weird since boost::this_thread::get_id() exists but returns a different value.
std::string get_thread_string_id()
{
#if defined(_WIN32)
return boost::lexical_cast<std::string>(GetCurrentThreadId());
#elif defined(__GNUC__)
return boost::lexical_cast<std::string>(pthread_self());
#endif
}
}
}

View file

@ -0,0 +1,206 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "net/net_parse_helpers.h"
#include "net/http_base.h"
#include "misc_log_ex.h"
#include "reg_exp_definer.h"
#include <boost/lexical_cast.hpp>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace net_utils
{
static bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params)
{
enum state
{
st_param_name,
st_param_val
};
state st = st_param_name;
std::string::const_iterator start_it = query.begin();
std::pair<std::string, std::string> e;
for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
{
switch(st)
{
case st_param_name:
if(*it == '=')
{
e.first.assign(start_it, it);
start_it = it;++start_it;
st = st_param_val;
}
break;
case st_param_val:
if(*it == '&')
{
e.second.assign(start_it, it);
start_it = it;++start_it;
params.push_back(e);
e.first.clear();e.second.clear();
st = st_param_name;
}
break;
default:
LOG_ERROR("Unknown state " << (int)st);
return false;
}
}
if(st == st_param_name)
{
if(start_it != query.end())
{
e.first.assign(start_it, query.end());
params.push_back(e);
}
}else
{
if(start_it != query.end())
e.second.assign(start_it, query.end());
if(e.first.size())
params.push_back(e);
}
return true;
}
bool parse_uri(const std::string uri, http::uri_content& content)
{
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
content.m_query_params.clear();
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
content.m_path = uri;
return true;
}
if(result[1].matched)
{
content.m_path = result[1];
}
if(result[3].matched)
{
content.m_query = result[3];
}
if(result[5].matched)
{
content.m_fragment = result[5];
}
if(content.m_query.size())
{
parse_uri_query(content.m_query, content.m_query_params);
}
return true;
}
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
{
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 3 4 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return false;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
else // if host not matched, matching should be considered failed
{
return false;
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
bool parse_url(const std::string url_str, http::url_content& content)
{
if (parse_url_ipv6(url_str, content)) return true;
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 34 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return true;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
}
}

View file

@ -25,6 +25,29 @@
//
#include "string_tools.h"
#include "string_tools_lexical.h"
// Previously pulled in by ASIO, further cleanup still required ...
#ifdef _WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <locale>
#include <cstdlib>
#include <string>
#include <type_traits>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/utility/string_ref.hpp>
#include "misc_log_ex.h"
#include "storages/parserse_base_utils.h"
#include "hex.h"
#include "memwipe.h"
#include "mlocker.h"
#include "span.h"
#include "warnings.h"
#include <ctype.h>
@ -68,6 +91,180 @@ namespace string_tools
return false;
return true;
}
//----------------------------------------------------------------------------
bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
{
//parse ip and address
std::string::size_type p = addres.find(':');
std::string ip_str, port_str;
if(p == std::string::npos)
{
port = 0;
ip_str = addres;
}
else
{
ip_str = addres.substr(0, p);
port_str = addres.substr(p+1, addres.size());
}
if(!get_ip_int32_from_string(ip, ip_str))
{
return false;
}
if(p != std::string::npos && !get_xtype_from_string(port, port_str))
{
return false;
}
return true;
}
std::string num_to_string_fast(int64_t val)
{
/*
char buff[30] = {0};
i64toa_s(val, buff, sizeof(buff)-1, 10);
return buff;*/
return boost::lexical_cast<std::string>(val);
}
bool compare_no_case(const std::string& str1, const std::string& str2)
{
return !boost::iequals(str1, str2);
}
//----------------------------------------------------------------------------
std::string& get_current_module_name()
{
static std::string module_name;
return module_name;
}
//----------------------------------------------------------------------------
std::string& get_current_module_folder()
{
static std::string module_folder;
return module_folder;
}
#ifdef _WIN32
std::string get_current_module_path()
{
char pname [5000] = {0};
GetModuleFileNameA( NULL, pname, sizeof(pname));
pname[sizeof(pname)-1] = 0; //be happy ;)
return pname;
}
#endif
bool set_module_name_and_folder(const std::string& path_to_process_)
{
std::string path_to_process = path_to_process_;
#ifdef _WIN32
path_to_process = get_current_module_path();
#endif
std::string::size_type a = path_to_process.rfind( '\\' );
if(a == std::string::npos )
{
a = path_to_process.rfind( '/' );
}
if ( a != std::string::npos )
{
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
get_current_module_folder() = path_to_process.substr(0, a);
return true;
}else
return false;
}
//----------------------------------------------------------------------------
bool trim_left(std::string& str)
{
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
str.erase(str.begin());
return true;
}
//----------------------------------------------------------------------------
bool trim_right(std::string& str)
{
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
str.erase( --((it++).base()));
return true;
}
//----------------------------------------------------------------------------
std::string pad_string(std::string s, size_t n, char c, bool prepend)
{
if (s.size() < n)
{
if (prepend)
s = std::string(n - s.size(), c) + s;
else
s.append(n - s.size(), c);
}
return s;
}
std::string get_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return res;
res = str.substr(pos+1, str.size()-pos);
return res;
}
//----------------------------------------------------------------------------
std::string cut_off_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return str;
res = str.substr(0, pos);
return res;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
std::wstring utf8_to_utf16(const std::string& str)
{
if (str.empty())
return {};
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
if (wstr_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::wstring wstr(wstr_size, wchar_t{});
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return wstr;
}
std::string utf16_to_utf8(const std::wstring& wstr)
{
if (wstr.empty())
return {};
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
if (str_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::string str(str_size, char{});
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return str;
}
#endif
}
}

View file

@ -0,0 +1,46 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "string_tools.h"
#include <boost/regex.hpp>
namespace epee
{
namespace tiny_ini
{
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
{
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
return false;
res = result[2];
string_tools::trim(res);
return true;
}
}
}

View file

@ -32,6 +32,7 @@
#include <boost/algorithm/string.hpp>
#include "wipeable_string.h"
#include "string_tools.h"
#include "string_tools_lexical.h"
#include "serialization/string.h"
#include "cryptonote_format_utils.h"
#include "cryptonote_config.h"

View file

@ -31,6 +31,7 @@
#include "net/parse.h"
#include "daemon/command_parser_executor.h"
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/predicate.hpp>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "daemon"

View file

@ -28,6 +28,8 @@
//
#include "device_trezor.hpp"
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/predicate.hpp>
namespace hw {
namespace trezor {

View file

@ -31,6 +31,7 @@
#include "memwipe.h"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/regex.hpp>
namespace hw {

View file

@ -38,6 +38,7 @@
#include <boost/asio/ip/udp.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "common/apply_permutation.h"
#include "transport.hpp"
#include "messages/messages-common.pb.h"

View file

@ -38,7 +38,7 @@
#include "net/error.h"
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage.h"
#include "string_tools.h"
#include "string_tools_lexical.h"
namespace net
{

View file

@ -31,6 +31,7 @@
#include "net/tor_address.h"
#include "net/i2p_address.h"
#include "string_tools.h"
#include "string_tools_lexical.h"
namespace net
{

View file

@ -38,6 +38,7 @@
#include "net/net_utils_base.h"
#include "net/socks.h"
#include "string_tools.h"
#include "string_tools_lexical.h"
namespace net
{

View file

@ -38,7 +38,7 @@
#include "net/error.h"
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage.h"
#include "string_tools.h"
#include "string_tools_lexical.h"
namespace net
{

View file

@ -37,6 +37,7 @@
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/preprocessor/stringize.hpp>

View file

@ -28,6 +28,7 @@
#include <stdio.h>
#include "misc_language.h"
#include "misc_log_ex.h"
#include "string_tools.h"
#include "rpc/rpc_payment_signature.h"

View file

@ -31,6 +31,7 @@
#include "gtest/gtest.h"
#include <string_tools.h>
#include <string_tools_lexical.h>
using namespace epee::string_tools;