From 463f242ffa4132d22a5006d653bc67b5b703851f Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Mon, 7 Nov 2016 14:03:47 -0500 Subject: [PATCH] Implement parse_size() function --- include/fc/string.hpp | 2 + src/string.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/include/fc/string.hpp b/include/fc/string.hpp index 0ae999b..dc942b9 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -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 diff --git a/src/string.cpp b/src/string.cpp index 0b7cb9f..84edb88 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -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= '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