libraries/eosiolib/core/eosio/symbol.hpp
Namespaces
Name |
---|
eosio |
Classes
Name | |
---|---|
class | eosio::symbol_code |
class | eosio::symbol |
class | eosio::extended_symbol |
Detailed Description
Copyright: defined in eos/LICENSE
Source code
#pragma once
#include "check.hpp"
#include "name.hpp"
#include "serialize.hpp"
#include "print.hpp"
#include "datastream.hpp"
#include <tuple>
#include <limits>
#include <string_view>
namespace eosio {
class symbol_code {
public:
constexpr symbol_code() : value(0) {}
constexpr explicit symbol_code( uint64_t raw )
:value(raw)
{}
constexpr explicit symbol_code( std::string_view str )
:value(0)
{
if( str.size() > 7 ) {
eosio::check( false, "string is too long to be a valid symbol_code" );
}
for( auto itr = str.rbegin(); itr != str.rend(); ++itr ) {
if( *itr < 'A' || *itr > 'Z') {
eosio::check( false, "only uppercase letters allowed in symbol_code string" );
}
value <<= 8;
value |= *itr;
}
}
constexpr bool is_valid()const {
auto sym = value;
for ( int i=0; i < 7; i++ ) {
char c = (char)(sym & 0xFF);
if ( !('A' <= c && c <= 'Z') ) return false;
sym >>= 8;
if ( !(sym & 0xFF) ) {
do {
sym >>= 8;
if ( (sym & 0xFF) ) return false;
i++;
} while( i < 7 );
}
}
return true;
}
constexpr uint32_t length()const {
auto sym = value;
uint32_t len = 0;
while (sym & 0xFF && len <= 7) {
len++;
sym >>= 8;
}
return len;
}
constexpr uint64_t raw()const { return value; }
constexpr explicit operator bool()const { return value != 0; }
char* write_as_string( char* begin, char* end, bool dry_run = false )const {
constexpr uint64_t mask = 0xFFull;
if( dry_run || (begin + 7 < begin) || (begin + 7 > end) ) {
char* actual_end = begin + length();
if( dry_run || (actual_end < begin) || (actual_end > end) ) return actual_end;
}
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};
}
inline void print()const {
char buffer[7];
auto end = write_as_string( buffer, buffer + sizeof(buffer) );
if( buffer < end )
printl( buffer, (end-buffer) );
}
friend constexpr bool operator == ( const symbol_code& a, const symbol_code& b ) {
return a.value == b.value;
}
friend constexpr bool operator != ( const symbol_code& a, const symbol_code& b ) {
return a.value != b.value;
}
friend constexpr bool operator < ( const symbol_code& a, const symbol_code& b ) {
return a.value < b.value;
}
private:
uint64_t value = 0;
};
template<typename DataStream>
inline DataStream& operator<<(DataStream& ds, const eosio::symbol_code sym_code) {
uint64_t raw = sym_code.raw();
ds.write( (const char*)&raw, sizeof(raw));
return ds;
}
template<typename DataStream>
inline DataStream& operator>>(DataStream& ds, eosio::symbol_code& sym_code) {
uint64_t raw = 0;
ds.read((char*)&raw, sizeof(raw));
sym_code = symbol_code(raw);
return ds;
}
class symbol {
public:
constexpr symbol() : value(0) {}
constexpr explicit symbol( uint64_t raw ) : value(raw) {}
constexpr symbol( symbol_code sc, uint8_t precision )
: value( (sc.raw() << 8) | static_cast<uint64_t>(precision) )
{}
constexpr symbol( std::string_view ss, uint8_t precision )
: value( (symbol_code(ss).raw() << 8) | static_cast<uint64_t>(precision) )
{}
constexpr bool is_valid()const { return code().is_valid(); }
constexpr uint8_t precision()const { return static_cast<uint8_t>( value & 0xFFull ); }
constexpr symbol_code code()const { return symbol_code{value >> 8}; }
constexpr uint64_t raw()const { return value; }
constexpr explicit operator bool()const { return value != 0; }
void print( bool show_precision = true )const {
if( show_precision ){
::eosio::print( static_cast<uint64_t>(precision()), "," );
}
char buffer[7];
auto end = code().write_as_string( buffer, buffer + sizeof(buffer) );
if( buffer < end )
printl( buffer, (end-buffer) );
}
friend constexpr bool operator == ( const symbol& a, const symbol& b ) {
return a.value == b.value;
}
friend constexpr bool operator != ( const symbol& a, const symbol& b ) {
return a.value != b.value;
}
friend constexpr bool operator < ( const symbol& a, const symbol& b ) {
return a.value < b.value;
}
private:
uint64_t value = 0;
};
template<typename DataStream>
inline DataStream& operator<<(DataStream& ds, const eosio::symbol sym) {
uint64_t raw = sym.raw();
ds.write( (const char*)&raw, sizeof(raw));
return ds;
}
template<typename DataStream>
inline DataStream& operator>>(DataStream& ds, eosio::symbol& sym) {
uint64_t raw = 0;
ds.read((char*)&raw, sizeof(raw));
sym = symbol(raw);
return ds;
}
class extended_symbol
{
public:
constexpr extended_symbol() {}
constexpr extended_symbol( symbol s, name con ) : sym(s), contract(con) {}
constexpr symbol get_symbol() const { return sym; }
constexpr name get_contract() const { return contract; }
void print( bool show_precision = true )const {
sym.print( show_precision );
::eosio::print("@", contract);
}
friend constexpr bool operator == ( const extended_symbol& a, const extended_symbol& b ) {
return std::tie( a.sym, a.contract ) == std::tie( b.sym, b.contract );
}
friend constexpr bool operator != ( const extended_symbol& a, const extended_symbol& b ) {
return std::tie( a.sym, a.contract ) != std::tie( b.sym, b.contract );
}
friend constexpr bool operator < ( const extended_symbol& a, const extended_symbol& b ) {
return std::tie( a.sym, a.contract ) < std::tie( b.sym, b.contract );
}
private:
symbol sym;
name contract;
EOSLIB_SERIALIZE( extended_symbol, (sym)(contract) )
};
}
Updated on 2022-12-05 at 15:38:08 +0000