symbol.hpp 5.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
#pragma once
#include <eosiolib/core_symbol.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/system.h>
#include <tuple>
#include <limits>

namespace eosio {

D
dskvr 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
  /**
   *  @defgroup symbolapi Symbol API
   *  @brief Defines API for managing symbols
   *  @ingroup contractdev
   */

  /**
   *  @defgroup symbolcppapi Symbol CPP API
   *  @brief Defines %CPP API for managing symbols
   *  @ingroup symbolapi
   *  @{
   */

   /**
    * Converts string to uint64_t representation of symbol
    *
    * @param precision - precision of symbol
    * @param str - the string representation of the symbol
    */
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   static constexpr uint64_t string_to_symbol( uint8_t precision, const char* str ) {
      uint32_t len = 0;
      while( str[len] ) ++len;

      uint64_t result = 0;
      for( uint32_t i = 0; i < len; ++i ) {
         if( str[i] < 'A' || str[i] > 'Z' ) {
            /// ERRORS?
         } else {
            result |= (uint64_t(str[i]) << (8*(1+i)));
         }
      }

      result |= uint64_t(precision);
      return result;
   }

D
dskvr 已提交
47 48 49 50 51 52
   /**
    * Macro for converting string to char representation of symbol
    *
    * @param precision - precision of symbol
    * @param str - the string representation of the symbol
    */
53 54
   #define S(P,X) ::eosio::string_to_symbol(P,#X)

D
dskvr 已提交
55 56 57
   /**
    * uint64_t representation of a symbol name
    */
58 59
   typedef uint64_t symbol_name;

D
dskvr 已提交
60 61 62 63 64 65
   /**
    * Checks if provided symbol name is valid.
    *
    * @param sym - symbol name of type symbol_name
    * @return true - if symbol is valid
    */
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
   static constexpr bool is_valid_symbol( symbol_name sym ) {
      sym >>= 8;
      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;
   }

D
dskvr 已提交
83 84 85 86 87 88 89 90
   /**
    * Returns the character length of the provided symbol
    *
    * @param sym - symbol to retrieve length for (uint64_t)
    * @return length - character length of the provided symbol
    */
   static constexpr uint32_t symbol_name_length( symbol_name sym ) {
      sym >>= 8; /// skip precision
91
      uint32_t length = 0;
D
dskvr 已提交
92
      while( sym & 0xff && length <= 7) {
93
         ++length;
D
dskvr 已提交
94
         sym >>= 8;
95 96 97 98 99
      }

      return length;
   }

D
dskvr 已提交
100 101 102 103 104
   /**
    * \struct Stores information about a symbol
    *
    * @brief Stores information about a symbol
    */
105
   struct symbol_type {
D
dskvr 已提交
106 107 108
     /**
      * The symbol name
      */
109 110 111
      symbol_name value;

      symbol_type() { }
D
dskvr 已提交
112 113 114 115

      /**
       * What is the type of the symbol
       */
116
      symbol_type(symbol_name s): value(s) { }
D
dskvr 已提交
117 118 119 120

      /**
       * Is this symbol valid
       */
121
      bool     is_valid()const  { return is_valid_symbol( value ); }
D
dskvr 已提交
122 123 124 125

      /**
       * This symbol's precision
       */
126
      uint64_t precision()const { return value & 0xff; }
D
dskvr 已提交
127 128 129 130

      /**
       * Returns uint64_t representation of symbol name
       */
131
      uint64_t name()const      { return value >> 8;   }
D
dskvr 已提交
132 133 134 135

      /**
       * The length of this symbol
       */
136 137
      uint32_t name_length()const { return symbol_name_length( value ); }

D
dskvr 已提交
138 139 140
      /**
       *
       */
141 142
      operator symbol_name()const { return value; }

D
dskvr 已提交
143 144 145 146 147
      /**
       * %Print the symbol
       *
       * @brief %Print the symbol
       */
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
      void print(bool show_precision=true)const {
         if( show_precision ){
            ::eosio::print(precision());
            prints(",");
         }

         auto sym = value;
         sym >>= 8;
         for( int i = 0; i < 7; ++i ) {
            char c = (char)(sym & 0xff);
            if( !c ) return;
            prints_l(&c, 1 );
            sym >>= 8;
         }
      }

      EOSLIB_SERIALIZE( symbol_type, (value) )
   };

D
dskvr 已提交
167 168 169 170
   /**
    * \struct Extended asset which stores the information of the owner of the symbol
    *
    */
171 172
   struct extended_symbol : public symbol_type
   {
D
dskvr 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186
     /**
      * The owner of the symbol
      *
      * @brief The owner of the symbol
      */
     account_name contract;

     extended_symbol( symbol_name sym = 0, account_name acc = 0 ):symbol_type{sym},contract(acc){}

      /**
       * %Print the extended symbol
       *
       * @brief %Print the extended symbol
       */
187 188 189 190 191 192
      void print()const {
         symbol_type::print();
         prints("@");
         printn( contract );
      }

D
dskvr 已提交
193 194 195 196 197 198 199 200 201

      /**
       * Equivalency operator. Returns true if a == b (are the same)
       *
       * @brief Subtraction operator
       * @param a - The extended asset to be subtracted
       * @param b - The extended asset used to subtract
       * @return boolean - true if both provided symbols are the same
       */
202 203 204
      friend bool operator == ( const extended_symbol& a, const extended_symbol& b ) {
        return std::tie( a.value, a.contract ) == std::tie( b.value, b.contract );
      }
D
dskvr 已提交
205 206 207 208 209 210 211 212 213

      /**
       * Inverted equivalency operator. Returns true if a != b (are different)
       *
       * @brief Subtraction operator
       * @param a - The extended asset to be subtracted
       * @param b - The extended asset used to subtract
       * @return boolean - true if both provided symbols are the same
       */
214 215 216
      friend bool operator != ( const extended_symbol& a, const extended_symbol& b ) {
        return std::tie( a.value, a.contract ) != std::tie( b.value, b.contract );
      }
D
dskvr 已提交
217

T
Todd Fleming 已提交
218 219 220 221
      friend bool operator < ( const extended_symbol& a, const extended_symbol& b ) {
        return std::tie( a.value, a.contract ) < std::tie( b.value, b.contract );
      }

222 223 224
      EOSLIB_SERIALIZE( extended_symbol, (value)(contract) )
   };

D
dskvr 已提交
225 226
   // }@ symbolapi

227
} /// namespace eosio