diff --git a/libraries/eosiolib/datastream.hpp b/libraries/eosiolib/datastream.hpp index c2d9e786f0b..aa9c797ea40 100644 --- a/libraries/eosiolib/datastream.hpp +++ b/libraries/eosiolib/datastream.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -285,7 +286,7 @@ inline datastream& operator<<(datastream& ds, const std::optiona /** * Deserialize an optional from a stream * - * @brief Deserialize an optional + * @brief Deserialize an optional * @param ds - The stream to read * @param opt - The destination for deserialized value * @tparam Stream - Type of datastream buffer @@ -372,7 +373,7 @@ inline datastream& operator>>(datastream& ds, eosio::symbol& sym /** * Serialize an ignored_wrapper type into a stream * - * @brief Serialize ignored_wrapper's T value + * @brief Serialize ignored_wrapper's T value * @param ds - The stream to write * @param val - The value to serialize * @tparam Stream - Type of datastream buffer diff --git a/libraries/eosiolib/name.hpp b/libraries/eosiolib/name.hpp index 246fb031a61..aecf1b59353 100644 --- a/libraries/eosiolib/name.hpp +++ b/libraries/eosiolib/name.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -131,21 +132,40 @@ namespace eosio { constexpr explicit operator bool()const { return value != 0; } - // keep in sync with name::operator string() in eosio source code definition for name - std::string to_string() const { + /** + * Writes the name as a string to the provided char buffer + * + * + * @brief Writes the name as a string to the provided char buffer + * @pre Appropriate Size Precondition: (begin + 13) <= end and (begin + 13) does not overflow + * @pre Valid Memory Region Precondition: The range [begin, end) must be a valid range of memory to write to. + * @param begin - The start of the char buffer + * @param end - Just past the end of the char buffer + * @return char* - Just past the end of the last character written (returns begin if the Appropriate Size Precondition is not satisfied) + * @post If the Appropriate Size Precondition is satisfied, the range [begin, returned pointer) contains the string representation of the name. + */ + char* write_as_string( char* begin, char* end )const { static const char* charmap = ".12345abcdefghijklmnopqrstuvwxyz"; + constexpr uint64_t mask = 0xF800000000000000ull; - std::string str(13,'.'); + if( (begin + 13) < begin || (begin + 13) > end ) return begin; - uint64_t tmp = value; - for( uint32_t i = 0; i <= 12; ++i ) { - char c = charmap[tmp & (i == 0 ? 0x0f : 0x1f)]; - str[12-i] = c; - tmp >>= (i == 0 ? 4 : 5); + auto v = value; + for( auto i = 0; i < 13; ++i, v <<= 5 ) { + if( v == 0 ) return begin; + + auto indx = (v & mask) >> (i == 12 ? 60 : 59); + *begin = charmap[indx]; + ++begin; } - trim_right_dots( str ); - return str; + return begin; + } + + std::string to_string()const { + char buffer[13]; + auto end = write_as_string( buffer, buffer + sizeof(buffer) ); + return {buffer, end}; } /** @@ -181,13 +201,6 @@ namespace eosio { uint64_t value = 0; EOSLIB_SERIALIZE( name, (value) ) - - private: - static void trim_right_dots(std::string& str ) { - const auto last = str.find_last_not_of('.'); - if (last != std::string::npos) - str = str.substr(0, last + 1); - } }; } /// namespace eosio diff --git a/libraries/eosiolib/print.hpp b/libraries/eosiolib/print.hpp index 20c0405cbf6..52b36af71e9 100644 --- a/libraries/eosiolib/print.hpp +++ b/libraries/eosiolib/print.hpp @@ -5,6 +5,7 @@ #pragma once #include #include +#include #include #include #include @@ -176,6 +177,19 @@ namespace eosio { printn(name.value); } + /** + * Prints a symbol_code + * + * @brief Prints a symbol_code + * @param sym_code symbol code to be printed + */ + inline void print( eosio::symbol_code sym_code ) { + char buffer[7]; + auto end = sym_code.write_as_string( buffer, buffer + sizeof(buffer) ); + if( buffer < end ) + prints_l( buffer, (end-buffer) ); + } + /** * Prints bool * diff --git a/libraries/eosiolib/symbol.hpp b/libraries/eosiolib/symbol.hpp index 65f54afb028..6373a9343f5 100644 --- a/libraries/eosiolib/symbol.hpp +++ b/libraries/eosiolib/symbol.hpp @@ -4,9 +4,10 @@ */ #pragma once -#include -#include #include +#include +#include +#include #include #include #include @@ -94,18 +95,37 @@ namespace eosio { constexpr explicit operator bool()const { return value != 0; } /** - * %Print the symbol code + * Writes the symbol_code as a string to the provided char buffer + * * - * @brief %Print the symbol code + * @brief Writes the symbol_code as a string to the provided char buffer + * @pre Appropriate Size Precondition: (begin + 7) <= end and (begin + 7) does not overflow + * @pre Valid Memory Region Precondition: The range [begin, end) must be a valid range of memory to write to. + * @param begin - The start of the char buffer + * @param end - Just past the end of the char buffer + * @return char* - Just past the end of the last character written (returns begin if the Appropriate Size Precondition is not satisfied) + * @post If the Appropriate Size Precondition is satisfied, the range [begin, returned pointer) contains the string representation of the symbol_code. */ - void print()const { - auto sym = value; - for( int i = 0; i < 7; ++i ) { - char c = (char)(sym & 0xff); - if( !c ) return; - prints_l(&c, 1 ); - sym >>= 8; + char* write_as_string( char* begin, char* end )const { + constexpr uint64_t mask = 0xFFull; + + if( (begin + 7) < begin || (begin + 7) > end ) return begin; + + auto v = value; + for( auto i = 0; i < 7; ++i, v >>= 8 ) { + if( v == 0 ) return begin; + + *begin = static_cast(v & mask); + ++begin; } + + return begin; + } + + std::string to_string()const { + char buffer[7]; + auto end = write_as_string( buffer, buffer + sizeof(buffer) ); + return {buffer, end}; } /** @@ -185,10 +205,13 @@ namespace eosio { */ void print( bool show_precision = true )const { if( show_precision ){ - ::eosio::print( static_cast(precision()) ); + printui( static_cast(precision()) ); prints(","); } - code().print(); + char buffer[7]; + auto end = code().write_as_string( buffer, buffer + sizeof(buffer) ); + if( buffer < end ) + prints_l( buffer, (end-buffer) ); } /** @@ -244,8 +267,8 @@ namespace eosio { * * @brief %Print the extended symbol */ - void print()const { - symbol.print(); + void print( bool show_precision = true )const { + symbol.print( show_precision ); prints("@"); printn( contract.value ); }