CDT  v4.2.0
инструменты разработчика
symbol.hpp
См. документацию.
1
5#pragma once
6
7#include "check.hpp"
8#include "name.hpp"
9#include "serialize.hpp"
10#include "print.hpp"
11#include "datastream.hpp"
12
13#include <tuple>
14#include <limits>
15#include <string_view>
16
17namespace eosio {
30 public:
31
38 constexpr symbol_code() : value(0) {}
39
47 constexpr explicit symbol_code( uint64_t raw )
48 :value(raw)
49 {}
50
58 constexpr explicit symbol_code( std::string_view str )
59 :value(0)
60 {
61 if( str.size() > 7 ) {
62 eosio::check( false, "string is too long to be a valid symbol_code" );
63 }
64 for( auto itr = str.rbegin(); itr != str.rend(); ++itr ) {
65 if( *itr < 'A' || *itr > 'Z') {
66 eosio::check( false, "only uppercase letters allowed in symbol_code string" );
67 }
68 value <<= 8;
69 value |= *itr;
70 }
71 }
72
77 constexpr bool is_valid()const {
78 auto sym = value;
79 for ( int i=0; i < 7; i++ ) {
80 char c = (char)(sym & 0xFF);
81 if ( !('A' <= c && c <= 'Z') ) return false;
82 sym >>= 8;
83 if ( !(sym & 0xFF) ) {
84 do {
85 sym >>= 8;
86 if ( (sym & 0xFF) ) return false;
87 i++;
88 } while( i < 7 );
89 }
90 }
91 return true;
92 }
93
99 constexpr uint32_t length()const {
100 auto sym = value;
101 uint32_t len = 0;
102 while (sym & 0xFF && len <= 7) {
103 len++;
104 sym >>= 8;
105 }
106 return len;
107 }
108
114 constexpr uint64_t raw()const { return value; }
115
121 constexpr explicit operator bool()const { return value != 0; }
122
136 char* write_as_string( char* begin, char* end, bool dry_run = false )const {
137 constexpr uint64_t mask = 0xFFull;
138
139 if( dry_run || (begin + 7 < begin) || (begin + 7 > end) ) {
140 char* actual_end = begin + length();
141 if( dry_run || (actual_end < begin) || (actual_end > end) ) return actual_end;
142 }
143
144 auto v = value;
145 for( auto i = 0; i < 7; ++i, v >>= 8 ) {
146 if( v == 0 ) return begin;
147
148 *begin = static_cast<char>(v & mask);
149 ++begin;
150 }
151
152 return begin;
153 }
154
158 std::string to_string()const {
159 char buffer[7];
160 auto end = write_as_string( buffer, buffer + sizeof(buffer) );
161 return {buffer, end};
162 }
163
168 inline void print()const {
169 char buffer[7];
170 auto end = write_as_string( buffer, buffer + sizeof(buffer) );
171 if( buffer < end )
172 printl( buffer, (end-buffer) );
173 }
174
180 friend constexpr bool operator == ( const symbol_code& a, const symbol_code& b ) {
181 return a.value == b.value;
182 }
183
189 friend constexpr bool operator != ( const symbol_code& a, const symbol_code& b ) {
190 return a.value != b.value;
191 }
192
198 friend constexpr bool operator < ( const symbol_code& a, const symbol_code& b ) {
199 return a.value < b.value;
200 }
201
202 private:
203 uint64_t value = 0;
204 };
205
214 template<typename DataStream>
215 inline DataStream& operator<<(DataStream& ds, const eosio::symbol_code sym_code) {
216 uint64_t raw = sym_code.raw();
217 ds.write( (const char*)&raw, sizeof(raw));
218 return ds;
219 }
220
229 template<typename DataStream>
230 inline DataStream& operator>>(DataStream& ds, eosio::symbol_code& sym_code) {
231 uint64_t raw = 0;
232 ds.read((char*)&raw, sizeof(raw));
233 sym_code = symbol_code(raw);
234 return ds;
235 }
236
242 class symbol {
243 public:
247 constexpr symbol() : value(0) {}
248
254 constexpr explicit symbol( uint64_t raw ) : value(raw) {}
255
262 constexpr symbol( symbol_code sc, uint8_t precision )
263 : value( (sc.raw() << 8) | static_cast<uint64_t>(precision) )
264 {}
265
272 constexpr symbol( std::string_view ss, uint8_t precision )
273 : value( (symbol_code(ss).raw() << 8) | static_cast<uint64_t>(precision) )
274 {}
275
279 constexpr bool is_valid()const { return code().is_valid(); }
280
284 constexpr uint8_t precision()const { return static_cast<uint8_t>( value & 0xFFull ); }
285
289 constexpr symbol_code code()const { return symbol_code{value >> 8}; }
290
294 constexpr uint64_t raw()const { return value; }
295
296 constexpr explicit operator bool()const { return value != 0; }
297
301 void print( bool show_precision = true )const {
302 if( show_precision ){
303 ::eosio::print( static_cast<uint64_t>(precision()), "," );
304 }
305 char buffer[7];
306 auto end = code().write_as_string( buffer, buffer + sizeof(buffer) );
307 if( buffer < end )
308 printl( buffer, (end-buffer) );
309 }
310
316 friend constexpr bool operator == ( const symbol& a, const symbol& b ) {
317 return a.value == b.value;
318 }
319
325 friend constexpr bool operator != ( const symbol& a, const symbol& b ) {
326 return a.value != b.value;
327 }
328
334 friend constexpr bool operator < ( const symbol& a, const symbol& b ) {
335 return a.value < b.value;
336 }
337
338 private:
339 uint64_t value = 0;
340 };
341
351 template<typename DataStream>
352 inline DataStream& operator<<(DataStream& ds, const eosio::symbol sym) {
353 uint64_t raw = sym.raw();
354 ds.write( (const char*)&raw, sizeof(raw));
355 return ds;
356 }
357
367 template<typename DataStream>
368 inline DataStream& operator>>(DataStream& ds, eosio::symbol& sym) {
369 uint64_t raw = 0;
370 ds.read((char*)&raw, sizeof(raw));
371 sym = symbol(raw);
372 return ds;
373 }
374
381 {
382 public:
383
387 constexpr extended_symbol() {}
388
395 constexpr extended_symbol( symbol s, name con ) : sym(s), contract(con) {}
396
402 constexpr symbol get_symbol() const { return sym; }
403
409 constexpr name get_contract() const { return contract; }
410
416 void print( bool show_precision = true )const {
417 sym.print( show_precision );
419 }
420
426 friend constexpr bool operator == ( const extended_symbol& a, const extended_symbol& b ) {
427 return std::tie( a.sym, a.contract ) == std::tie( b.sym, b.contract );
428 }
429
435 friend constexpr bool operator != ( const extended_symbol& a, const extended_symbol& b ) {
436 return std::tie( a.sym, a.contract ) != std::tie( b.sym, b.contract );
437 }
438
444 friend constexpr bool operator < ( const extended_symbol& a, const extended_symbol& b ) {
445 return std::tie( a.sym, a.contract ) < std::tie( b.sym, b.contract );
446 }
447
448 private:
449 symbol sym;
450 name contract;
451
453 };
454}