Skip to content

Commit

Permalink
Merge pull request EOSIO#144 from EOSIO/efficient-name-symbol-asset-p…
Browse files Browse the repository at this point in the history
…rinting

Efficient name and symbol_code printing (and to_string)
  • Loading branch information
arhag authored Oct 10, 2018
2 parents e4ab5e0 + 6e66479 commit 5ffc39d
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 34 deletions.
5 changes: 3 additions & 2 deletions libraries/eosiolib/datastream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <eosiolib/system.h>
#include <eosiolib/memory.h>
#include <eosiolib/symbol.hpp>
#include <eosiolib/fixed_key.hpp>
#include <eosiolib/ignore.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
Expand Down Expand Up @@ -285,7 +286,7 @@ inline datastream<Stream>& operator<<(datastream<Stream>& 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
Expand Down Expand Up @@ -372,7 +373,7 @@ inline datastream<Stream>& operator>>(datastream<Stream>& ds, eosio::symbol& sym
/**
* Serialize an ignored_wrapper type into a stream
*
* @brief Serialize ignored_wrapper<T>'s T value
* @brief Serialize ignored_wrapper<T>'s T value
* @param ds - The stream to write
* @param val - The value to serialize
* @tparam Stream - Type of datastream buffer
Expand Down
47 changes: 30 additions & 17 deletions libraries/eosiolib/name.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <eosiolib/system.h>
#include <eosiolib/serialize.hpp>
#include <string>
#include <string_view>

Expand Down Expand Up @@ -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};
}

/**
Expand Down Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions libraries/eosiolib/print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once
#include <eosiolib/print.h>
#include <eosiolib/name.hpp>
#include <eosiolib/symbol.hpp>
#include <eosiolib/fixed_key.hpp>
#include <utility>
#include <string>
Expand Down Expand Up @@ -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
*
Expand Down
53 changes: 38 additions & 15 deletions libraries/eosiolib/symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/
#pragma once

#include <eosiolib/serialize.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/system.h>
#include <eosiolib/print.h>
#include <eosiolib/name.hpp>
#include <eosiolib/serialize.hpp>
#include <tuple>
#include <limits>
#include <string_view>
Expand Down Expand Up @@ -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<char>(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};
}

/**
Expand Down Expand Up @@ -185,10 +205,13 @@ namespace eosio {
*/
void print( bool show_precision = true )const {
if( show_precision ){
::eosio::print( static_cast<uint64_t>(precision()) );
printui( static_cast<uint64_t>(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) );
}

/**
Expand Down Expand Up @@ -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 );
}
Expand Down

0 comments on commit 5ffc39d

Please sign in to comment.