aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2019-01-06 20:36:46 +0200
committerRiccardo Spagni <ric@spagni.net>2019-01-06 20:36:46 +0200
commitad1eb3338c071fc3774a0c2599228c8aa953e087 (patch)
tree058efcebcff467ed3370cf86a98b355ebc1b749c
parentMerge pull request #4934 (diff)
parentepee: speed up string matching a bit (diff)
downloadmonero-ad1eb3338c071fc3774a0c2599228c8aa953e087.tar.xz
Merge pull request #4938
a13eb0a1 epee: speed up string matching a bit (moneromooo-monero) 3a3858dc epee: avoid string allocation when parsing a pod from string (moneromooo-monero)
-rw-r--r--contrib/epee/include/storages/parserse_base_utils.h8
-rw-r--r--contrib/epee/include/string_tools.h48
-rw-r--r--src/checkpoints/checkpoints.cpp4
3 files changed, 20 insertions, 40 deletions
diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h
index 31495ae13..d73fbde3a 100644
--- a/contrib/epee/include/storages/parserse_base_utils.h
+++ b/contrib/epee/include/storages/parserse_base_utils.h
@@ -91,11 +91,15 @@ namespace misc_utils
*/
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
- val.clear();
- val.reserve(std::distance(star_end_string, buf_end));
bool escape_mode = false;
std::string::const_iterator it = star_end_string;
++it;
+ std::string::const_iterator fi = it;
+ while (fi != buf_end && *fi != '\\' && *fi != '\"')
+ ++fi;
+ val.assign(it, fi);
+ val.reserve(std::distance(star_end_string, buf_end));
+ it = fi;
for(;it != buf_end;it++)
{
if(escape_mode/*prev_ch == '\\'*/)
diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h
index 6a063cc36..0d8eca727 100644
--- a/contrib/epee/include/string_tools.h
+++ b/contrib/epee/include/string_tools.h
@@ -117,16 +117,12 @@ namespace string_tools
return to_hex::string(to_byte_span(to_span(src)));
}
//----------------------------------------------------------------------------
- template<class CharT>
- bool parse_hexstr_to_binbuff(const std::basic_string<CharT>& s, std::basic_string<CharT>& res)
+ inline bool parse_hexstr_to_binbuff(const epee::span<const char> s, epee::span<char>& res)
{
- res.clear();
- if (s.size() & 1)
- return false;
- try
- {
- res.resize(s.size() / 2);
- unsigned char *dst = (unsigned char *)res.data();
+ if (s.size() != res.size() * 2)
+ return false;
+
+ unsigned char *dst = (unsigned char *)&res[0];
const unsigned char *src = (const unsigned char *)s.data();
for(size_t i = 0; i < s.size(); i += 2)
{
@@ -140,28 +136,15 @@ namespace string_tools
}
return true;
- }
- catch(...)
- {
- return false;
- }
}
//----------------------------------------------------------------------------
- template<class t_pod_type>
- bool parse_tpod_from_hex_string(const std::string& str_hash, t_pod_type& t_pod)
+ inline bool parse_hexstr_to_binbuff(const std::string& s, std::string& res)
{
- static_assert(std::is_pod<t_pod_type>::value, "expected pod type");
- std::string buf;
- bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf);
- if (!res || buf.size() != sizeof(t_pod_type))
- {
+ if (s.size() & 1)
return false;
- }
- else
- {
- buf.copy(reinterpret_cast<char *>(&t_pod), sizeof(t_pod_type));
- return true;
- }
+ res.resize(s.size() / 2);
+ epee::span<char> rspan((char*)&res[0], res.size());
+ return parse_hexstr_to_binbuff(epee::to_span(s), rspan);
}
//----------------------------------------------------------------------------
PUSH_WARNINGS
@@ -360,17 +343,10 @@ POP_WARNINGS
bool hex_to_pod(const std::string& hex_str, t_pod_type& s)
{
static_assert(std::is_pod<t_pod_type>::value, "expected pod type");
- std::string hex_str_tr = trim(hex_str);
if(sizeof(s)*2 != hex_str.size())
return false;
- std::string bin_buff;
- if(!parse_hexstr_to_binbuff(hex_str_tr, bin_buff))
- return false;
- if(bin_buff.size()!=sizeof(s))
- return false;
-
- s = *(t_pod_type*)bin_buff.data();
- return true;
+ epee::span<char> rspan((char*)&s, sizeof(s));
+ return parse_hexstr_to_binbuff(epee::to_span(hex_str), rspan);
}
//----------------------------------------------------------------------------
template<class t_pod_type>
diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp
index 1807d44d9..96f575b2d 100644
--- a/src/checkpoints/checkpoints.cpp
+++ b/src/checkpoints/checkpoints.cpp
@@ -74,7 +74,7 @@ namespace cryptonote
bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str)
{
crypto::hash h = crypto::null_hash;
- bool r = epee::string_tools::parse_tpod_from_hex_string(hash_str, h);
+ bool r = epee::string_tools::hex_to_pod(hash_str, h);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!");
// return false if adding at a height we already have AND the hash is different
@@ -292,7 +292,7 @@ namespace cryptonote
// parse the second part as crypto::hash,
// if this fails move on to the next record
std::string hashStr = record.substr(pos + 1);
- if (!epee::string_tools::parse_tpod_from_hex_string(hashStr, hash))
+ if (!epee::string_tools::hex_to_pod(hashStr, hash))
{
continue;
}