EOS 智能合约源代码解读 (1)name.hpp
2021/10/1 6:13:53
本文主要是介绍EOS 智能合约源代码解读 (1)name.hpp,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
/// Immutable except for fc::from_variant. struct name { private: friend struct fc::reflector<name>; friend void fc::from_variant(const fc::variant& v, tafsys::chain::name& check); void set( std::string_view str ); std::string to_string()const; constexpr uint64_t to_uint64_t()const { return value; } // 构建一个新的name对象,初始化默认为0 constexpr name() : value(0) {} // 使用给定的unit64_t类型的值构建一个新的name对象。 constexpr explicit name( uint64_t v ) :value(v) {} // 使用给定的一个范围的枚举类型,构建一个新的name对象。 constexpr explicit name( name::raw r ) :value(static_cast<uint64_t>(r)) {} // 使用给定的字符串构建一个新的name对象。 constexpr explicit name( std::string_view str ):value(0) { if( str.size() > 13 ) { // 字符串最长不能超过12 eosio::check( false, "string is too long to be a valid name" ); } if( str.empty() ) { return; } // 将字符串转为uint64_t auto n = std::min( (uint32_t)str.size(), (uint32_t)12u ); for( decltype(n) i = 0; i < n; ++i ) { value <<= 5; value |= char_to_value( str[i] ); } value <<= ( 4 + 5*(12 - n) ); if( str.size() == 13 ) { uint64_t v = char_to_value( str[12] ); if( v > 0x0Full ) { eosio::check(false, "thirteenth character in name cannot be a letter that comes after j"); } value |= v; } } // 将一个Base32符号的char转换为它对应的值。 static constexpr uint8_t char_to_value( char c ) { if( c == '.') return 0; else if( c >= '1' && c <= '5' ) return (c - '1') + 1; else if( c >= 'a' && c <= 'z' ) return (c - 'a') + 6; else // 字符中出现了不允许的内容。 eosio::check( false, "character is not in allowed character set for names" ); return 0; // 流程控制将不会到达这里,这一行是为了防止warn信息。 } // 返回一个name对象的长度,运算方法。 constexpr uint8_t length()const { constexpr uint64_t mask = 0xF800000000000000ull; if( value == 0 ) return 0; uint8_t l = 0; uint8_t i = 0; for( auto v = value; i < 13; ++i, v <<= 5 ) { if( (v & mask) > 0 ) { l = i; } } return l + 1; } // 返回一个name对象的后缀,完整的运算方法。 constexpr name suffix()const { uint32_t remaining_bits_after_last_actual_dot = 0; uint32_t tmp = 0; for( int32_t remaining_bits = 59; remaining_bits >= 4; remaining_bits -= 5 ) { // remaining_bits必须有符号整数 // 从左到右依次遍历name中的字符,共12次 auto c = (value >> remaining_bits) & 0x1Full; if( !c ) { // 如果当前字符是点 tmp = static_cast<uint32_t>(remaining_bits); } else { // 如果当前字符不是点 remaining_bits_after_last_actual_dot = tmp; } } uint64_t thirteenth_character = value & 0x0Full; if( thirteenth_character ) { // 如果第13个字符不是点 remaining_bits_after_last_actual_dot = tmp; } if( remaining_bits_after_last_actual_dot == 0 ) // 除了潜在的前导点之外,name中没有实际的点 return name{value}; // 此时,remaining_bits_after_last_actual_dot必须在4到59的范围内(并且限制为5的增量)。 // 除了4个最低有效位(对应于第13个字符)之外,对应于最后一个实际点之后的字符的剩余位的掩码。 uint64_t mask = (1ull << remaining_bits_after_last_actual_dot) - 16; uint32_t shift = 64 - remaining_bits_after_last_actual_dot; return name{ ((value & mask) << shift) + (thirteenth_character << (shift-1)) }; } // 将name类型转为raw枚举类型:基于name对象的值,返回一个raw枚举类型的实例。 constexpr operator raw()const { return raw(value); } // 显式转换一个name的uint64_t值为bool,如果name的值不为0,返回true。 constexpr explicit operator bool()const { return value != 0; } // 根据给定的char缓冲区,以字符串的类型写入name对象。参数begin:char缓冲区的开头,参数end:刚好超过char缓冲区的位置,作为结尾。 char* write_as_string( char* begin, char* end )const { static const char* charmap = ".12345abcdefghijklmnopqrstuvwxyz"; constexpr uint64_t mask = 0xF800000000000000ull; if( (begin + 13) < begin || (begin + 13) > end ) return begin; 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; } return begin; } // 将name对象转为一个字符串返回。 std::string to_string()const { char buffer[13]; auto end = write_as_string( buffer, buffer + sizeof(buffer) ); return {buffer, end}; } // 重载运算符等于号 friend constexpr bool operator == ( const name& a, const name& b ) { return a.value == b.value; } // 重载运算符符不等于 friend constexpr bool operator != ( const name& a, const name& b ) { return a.value != b.value; } // 重载运算符小于号 friend constexpr bool operator < ( const name& a, const name& b ) { return a.value < b.value; } uint64_t value = 0; // 其实name对象只有一个有效属性,就是value,以上都是name对象的构造方式、限制条件、各种转型以及运算符重载。 EOSLIB_SERIALIZE( name, (value) ) }; // Each char of the string is encoded into 5-bit chunk and left-shifted // to its 5-bit slot starting with the highest slot for the first char. // The 13th char, if str is long enough, is encoded into 4-bit chunk // and placed in the lowest 4 bits. 64 = 12 * 5 + 4 static constexpr name string_to_name( std::string_view str ) { return name( string_to_uint64_t( str ) ); }
这篇关于EOS 智能合约源代码解读 (1)name.hpp的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南