|
|
|
@ -29,6 +29,7 @@
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <boost/utility/string_ref.hpp>
|
|
|
|
|
|
|
|
|
|
namespace epee
|
|
|
|
|
{
|
|
|
|
@ -36,6 +37,40 @@ namespace misc_utils
|
|
|
|
|
{
|
|
|
|
|
namespace parse
|
|
|
|
|
{
|
|
|
|
|
// 1: digit
|
|
|
|
|
// 2: .eE (floating point)
|
|
|
|
|
// 4: alpha
|
|
|
|
|
// 8: whitespace
|
|
|
|
|
// 16: allowed in float but doesn't necessarily mean it's a float
|
|
|
|
|
static const constexpr uint8_t lut[256]={
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 0, 0, // 16
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32
|
|
|
|
|
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 18, 0, // 48
|
|
|
|
|
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, // 64
|
|
|
|
|
0, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 80
|
|
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 96
|
|
|
|
|
0, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 112
|
|
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 128
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline bool isspace(char c)
|
|
|
|
|
{
|
|
|
|
|
return lut[(uint8_t)c] & 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool isdigit(char c)
|
|
|
|
|
{
|
|
|
|
|
return lut[(uint8_t)c] & 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline std::string transform_to_escape_sequence(const std::string& src)
|
|
|
|
|
{
|
|
|
|
|
static const char escaped[] = "\b\f\n\r\t\v\"\\/";
|
|
|
|
@ -159,25 +194,34 @@ namespace misc_utils
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
inline void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val, bool& is_float_val, bool& is_signed_val)
|
|
|
|
|
inline void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val)
|
|
|
|
|
{
|
|
|
|
|
val.clear();
|
|
|
|
|
is_float_val = false;
|
|
|
|
|
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
|
|
|
|
uint8_t float_flag = 0;
|
|
|
|
|
is_signed_val = false;
|
|
|
|
|
size_t chars = 0;
|
|
|
|
|
std::string::const_iterator it = star_end_string;
|
|
|
|
|
if (it != buf_end && *it == '-')
|
|
|
|
|
{
|
|
|
|
|
is_signed_val = true;
|
|
|
|
|
++chars;
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
for(;it != buf_end;it++)
|
|
|
|
|
{
|
|
|
|
|
if(isdigit(*it) || (it == star_end_string && *it == '-') || (val.size() && *it == '.' ) || (is_float_val && (*it == 'e' || *it == 'E' || *it == '-' || *it == '+' )) )
|
|
|
|
|
const uint8_t flags = lut[(uint8_t)*it];
|
|
|
|
|
if (flags & 16)
|
|
|
|
|
{
|
|
|
|
|
if(!val.size() && *it == '-')
|
|
|
|
|
is_signed_val = true;
|
|
|
|
|
if(*it == '.' )
|
|
|
|
|
is_float_val = true;
|
|
|
|
|
val.push_back(*it);
|
|
|
|
|
float_flag |= flags;
|
|
|
|
|
++chars;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
val = boost::string_ref(&*star_end_string, chars);
|
|
|
|
|
if(val.size())
|
|
|
|
|
{
|
|
|
|
|
star_end_string = --it;
|
|
|
|
|
is_float_val = !!(float_flag & 2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -186,7 +230,7 @@ namespace misc_utils
|
|
|
|
|
}
|
|
|
|
|
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
|
|
|
|
}
|
|
|
|
|
inline bool match_number(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
|
|
|
|
inline bool match_number(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
@ -199,15 +243,15 @@ namespace misc_utils
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
inline void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
|
|
|
|
inline void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
|
|
|
|
{
|
|
|
|
|
val.clear();
|
|
|
|
|
|
|
|
|
|
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
|
|
|
|
{
|
|
|
|
|
if(!isalpha(*it))
|
|
|
|
|
if (!(lut[(uint8_t)*it] & 4))
|
|
|
|
|
{
|
|
|
|
|
val.assign(star_end_string, it);
|
|
|
|
|
val = boost::string_ref(&*star_end_string, std::distance(star_end_string, it));
|
|
|
|
|
if(val.size())
|
|
|
|
|
{
|
|
|
|
|
star_end_string = --it;
|
|
|
|
@ -218,7 +262,7 @@ namespace misc_utils
|
|
|
|
|
}
|
|
|
|
|
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
|
|
|
|
}
|
|
|
|
|
inline bool match_word(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
|
|
|
|
inline bool match_word(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|