Implement parse_size() function

This commit is contained in:
theoreticalbts 2016-11-07 14:03:47 -05:00
parent 0e5a4fea68
commit 463f242ffa
2 changed files with 87 additions and 0 deletions

View file

@ -29,6 +29,8 @@ namespace fc
fc::string trim( const fc::string& );
fc::string to_lower( const fc::string& );
string trim_and_normalize_spaces( const string& s );
uint64_t parse_size( const string& s );
}
#else

View file

@ -172,6 +172,91 @@ namespace fc {
return result;
}
/**
* Parses a size including an optional multiplicative suffix.
*
* M -> 1024*1024 bytes
* MB -> 1000*1000 bytes
* MiB -> 1024*1024 bytes
*
* The 'M' may be any of KMGTPEZY (upper or lower case)
*/
uint64_t parse_size( const string& s )
{
try
{
size_t i = 0, n = s.size(), suffix_start = n;
for( i=0; i<n; i++ )
{
if( !((s[i] >= '0') && (s[i] <= '9')) )
{
suffix_start = i;
break;
}
}
uint64_t u = to_uint64( s.substr( 0, suffix_start ) );
FC_ASSERT( n - suffix_start <= 3 );
uint64_t m = 1;
uint64_t thousand = 1024;
if( suffix_start == n )
{
return u;
}
else if( suffix_start == n-1 )
{
}
else if( suffix_start == n-2 )
{
FC_ASSERT( (s[suffix_start+1] == 'b') || (s[suffix_start+1] == 'B') );
thousand = 1000;
}
else if( suffix_start == n-3 )
{
FC_ASSERT( (s[suffix_start+1] == 'i') || (s[suffix_start+1] == 'I') );
FC_ASSERT( (s[suffix_start+2] == 'b') || (s[suffix_start+2] == 'B') );
}
switch( s[suffix_start] )
{
case 'y':
case 'Y':
m *= thousand;
case 'z':
case 'Z':
m *= thousand;
case 'e':
case 'E':
m *= thousand;
case 'p':
case 'P':
m *= thousand;
case 't':
case 'T':
m *= thousand;
case 'g':
case 'G':
m *= thousand;
case 'm':
case 'M':
m *= thousand;
case 'k':
case 'K':
m *= thousand;
break;
default:
FC_ASSERT( false );
}
return u*m;
}
catch( const fc::exception& e )
{
FC_THROW_EXCEPTION( parse_error_exception, "Couldn't parse size" );
}
}
} // namespace fc