@ -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 , boo st: : 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 , boo st: : 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 , boo st: : 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 , boo st: : string _ref & val )
{
try
{