Skip to main content

libraries/eosiolib/core/eosio/symbol.hpp

More...

Namespaces

Name
eosio

Classes

Name
classeosio::symbol_code
classeosio::symbol
classeosio::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