diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 2b3a4b2591a8214d3d422e3a2c3d5ac19d303fa3..13657cdee493c24bb5406c4d097e9aea0796e563 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -545,7 +545,7 @@ void database::validate_referenced_accounts(const signed_transaction& trx)const for(const auto& msg : trx.messages) { get_account(msg.sender); get_account(msg.recipient); - const account_name* previous_notify_account = nullptr; + const AccountName* previous_notify_account = nullptr; for(const auto& current_notify_account : msg.notify) { get_account(current_notify_account); if(previous_notify_account) { @@ -798,10 +798,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) create([&](account_object& a) { a.name = "sys"; }); - register_type("sys"); - register_type("sys"); - register_type("sys"); - register_type("sys"); + register_type("sys"); + register_type("sys"); + register_type("sys"); + register_type("sys"); // Create initial accounts for (const auto& acct : genesis_state.initial_accounts) { @@ -1129,17 +1129,17 @@ void database::update_producer_schedule() { } -void database::set_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, message_validate_handler v ) { +void database::set_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, message_validate_handler v ) { message_validate_handlers[contract][std::make_pair(scope,action)] = v; } -void database::set_precondition_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, precondition_validate_handler v ) { +void database::set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, precondition_validate_handler v ) { precondition_validate_handlers[contract][std::make_pair(scope,action)] = v; } -void database::set_apply_handler( const account_name& contract, const account_name& scope, const message_type& action, apply_handler v ) { +void database::set_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v ) { apply_handlers[contract][std::make_pair(scope,action)] = v; } -const account_object& database::get_account( const account_name& name )const { +const account_object& database::get_account( const AccountName& name )const { try { return get(name); } FC_CAPTURE_AND_RETHROW( (name) ) } diff --git a/libraries/chain/include/eos/chain/account_object.hpp b/libraries/chain/include/eos/chain/account_object.hpp index a2e4a963c72136405693374327aa0711b49389b4..f987dee31a251a6e627e3170f9feb6b048257dca 100644 --- a/libraries/chain/include/eos/chain/account_object.hpp +++ b/libraries/chain/include/eos/chain/account_object.hpp @@ -51,9 +51,9 @@ namespace eos { namespace chain { return *this; } - UInt32 threshold = 0; - shared_vector accounts; - shared_vector keys; + UInt32 threshold = 0; + shared_vector accounts; + shared_vector keys; }; class account_object : public chainbase::object @@ -84,7 +84,7 @@ namespace eos { namespace chain { id_type id; account_id_type owner; ///< the account this permission belongs to id_type parent; ///< parent permission - permission_name name; + PermissionName name; shared_authority auth; ///< TODO }; @@ -105,11 +105,11 @@ namespace eos { namespace chain { ordered_unique, composite_key< permission_object, member, - member, + member, member > >, - ordered_unique, member > + ordered_unique, member > > >; diff --git a/libraries/chain/include/eos/chain/authority.hpp b/libraries/chain/include/eos/chain/authority.hpp index 0a6ac6799f0e52e20038ec0d660645fd7bb28480..06f5f90ec507fb9455376bf107ea4ec555498baa 100644 --- a/libraries/chain/include/eos/chain/authority.hpp +++ b/libraries/chain/include/eos/chain/authority.hpp @@ -3,20 +3,20 @@ #include namespace eos { - inline bool operator < ( const AccountPermission& a, const AccountPermission& b ) { + inline bool operator < ( const types::AccountPermission& a, const types::AccountPermission& b ) { return std::tie( a.account, a.permission ) < std::tie( b.account, b.permission ); } /** * Makes sure all keys are unique and sorted and all account permissions are unique and sorted */ - inline bool validate( eos::Authority& auth ) { - const KeyPermissionWeight* prev = nullptr; + inline bool validate( types::Authority& auth ) { + const types::KeyPermissionWeight* prev = nullptr; for( const auto& k : auth.keys ) { if( !prev ) prev = &k; else if( prev->key < k.key ) return false; } - const AccountPermissionWeight* pa = nullptr; + const types::AccountPermissionWeight* pa = nullptr; for( const auto& a : auth.accounts ) { if( !pa ) pa = &a; else if( pa->permission < a.permission ) return false; diff --git a/libraries/chain/include/eos/chain/database.hpp b/libraries/chain/include/eos/chain/database.hpp index d9642ff98e847b8ebd17a6a8734e3291b7db1959..e501389164f5e343dffd7f6f6f49d81ff1274cb6 100644 --- a/libraries/chain/include/eos/chain/database.hpp +++ b/libraries/chain/include/eos/chain/database.hpp @@ -56,17 +56,17 @@ namespace eos { namespace chain { class precondition_validate_context : public message_validate_context { public: - precondition_validate_context( const database& d, const transaction& t, const message& m, const account_name& r ) + precondition_validate_context( const database& d, const transaction& t, const message& m, const AccountName& r ) :message_validate_context(t,m),recipient(r),db(d){} - const account_name& recipient; + const AccountName& recipient; const database& db; }; class apply_context : public precondition_validate_context { public: - apply_context( database& d, const transaction& t, const message& m, const account_name& recipient ) + apply_context( database& d, const transaction& t, const message& m, const AccountName& recipient ) :precondition_validate_context(d,t,m,recipient),mutable_db(d){} String get( String key )const; @@ -108,8 +108,8 @@ namespace eos { namespace chain { fc::signal on_pending_transaction; template - void register_type( account_name scope ) { - auto stru = eos::GetStruct::type(); + void register_type( AccountName scope ) { + auto stru = eos::types::GetStruct::type(); create([&](type_object& o) { o.scope = scope; o.name = stru.name; @@ -126,9 +126,9 @@ namespace eos { namespace chain { * The database can override any script handler with native code. */ ///@{ - void set_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, message_validate_handler v ); - void set_precondition_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, precondition_validate_handler v ); - void set_apply_handler( const account_name& contract, const account_name& scope, const message_type& action, apply_handler v ); + void set_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, message_validate_handler v ); + void set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, precondition_validate_handler v ); + void set_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v ); //@} enum validation_steps @@ -193,7 +193,7 @@ namespace eos { namespace chain { const signed_transaction& get_recent_transaction( const transaction_id_type& trx_id )const; std::vector get_block_ids_on_fork(block_id_type head_of_fork) const; - const account_object& get_account( const account_name& name )const; + const account_object& get_account( const AccountName& name )const; /** * Calculate the percent of block production slots that were missed in the @@ -383,10 +383,10 @@ namespace eos { namespace chain { node_property_object _node_property_object; - typedef pair handler_key; - map< account_name, map > message_validate_handlers; - map< account_name, map > precondition_validate_handlers; - map< account_name, map > apply_handlers; + typedef pair handler_key; + map< AccountName, map > message_validate_handlers; + map< AccountName, map > precondition_validate_handlers; + map< AccountName, map > apply_handlers; }; } } diff --git a/libraries/chain/include/eos/chain/exceptions.hpp b/libraries/chain/include/eos/chain/exceptions.hpp index ff99673edb17b68e66013b704162368f6f94a5e6..70f4770499e1f0f27829e0a7f8e6d131ce1e8424 100644 --- a/libraries/chain/include/eos/chain/exceptions.hpp +++ b/libraries/chain/include/eos/chain/exceptions.hpp @@ -25,45 +25,7 @@ #include #include - -#define EOS_ASSERT( expr, exc_type, FORMAT, ... ) \ - FC_MULTILINE_MACRO_BEGIN \ - if( !(expr) ) \ - FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \ - FC_MULTILINE_MACRO_END - - -#define EOS_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \ - FC_DECLARE_DERIVED_EXCEPTION( \ - op_name ## _validate_exception, \ - eos::chain::message_validate_exception, \ - 3040000 + 100 * operation::tag< op_name ## _operation >::value, \ - #op_name "_operation validation exception" \ - ) \ - FC_DECLARE_DERIVED_EXCEPTION( \ - op_name ## _evaluate_exception, \ - eos::chain::message_evaluate_exception, \ - 3050000 + 100 * operation::tag< op_name ## _operation >::value, \ - #op_name "_operation evaluation exception" \ - ) - -#define EOS_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ - FC_DECLARE_DERIVED_EXCEPTION( \ - op_name ## _ ## exc_name, \ - eos::chain::op_name ## _validate_exception, \ - 3040000 + 100 * operation::tag< op_name ## _operation >::value \ - + seqnum, \ - msg \ - ) - -#define EOS_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ - FC_DECLARE_DERIVED_EXCEPTION( \ - op_name ## _ ## exc_name, \ - eos::chain::op_name ## _evaluate_exception, \ - 3050000 + 100 * operation::tag< op_name ## _operation >::value \ - + seqnum, \ - msg \ - ) +#include namespace eos { namespace chain { diff --git a/libraries/chain/include/eos/chain/key_value_object.hpp b/libraries/chain/include/eos/chain/key_value_object.hpp index a2b3d7f8528ad96abb1738251319418c5a9d3ec4..cb28b0cdf40533532fc6940e33cd5e43bfa61f43 100644 --- a/libraries/chain/include/eos/chain/key_value_object.hpp +++ b/libraries/chain/include/eos/chain/key_value_object.hpp @@ -32,7 +32,7 @@ namespace eos { namespace chain { OBJECT_CTOR(key_value_object, (key)(value)) id_type id; - account_name scope; + AccountName scope; shared_string key; shared_string value; }; @@ -44,10 +44,10 @@ namespace eos { namespace chain { ordered_unique, member>, ordered_unique, composite_key< key_value_object, - member, + member, member >, - composite_key_compare< std::less, chainbase::strcmp_less > + composite_key_compare< std::less, chainbase::strcmp_less > > > >; diff --git a/libraries/chain/include/eos/chain/message.hpp b/libraries/chain/include/eos/chain/message.hpp index d216d9216527f84fbf1b63aef6a3dce31c8f1ad8..9128670a859a1357af839ec44fefd9aa5f0c26a5 100644 --- a/libraries/chain/include/eos/chain/message.hpp +++ b/libraries/chain/include/eos/chain/message.hpp @@ -20,26 +20,26 @@ namespace eos { namespace chain { */ struct message { /// The account which sent the message - account_name sender; + AccountName sender; /// The account to receive the message - account_name recipient; + AccountName recipient; /// Other accounts to notify about this message - vector notify; + vector notify; /** * Every contract defines the set of types that it accepts, these types are * scoped according to the recipient. This means two contracts can can define * two different types with the same name. */ - TypeName type; + types::TypeName type; /// The message contents vector data; template - void set( const message_type& t, const T& value ) { + void set( const TypeName& t, const T& value ) { type = t; data = fc::raw::pack( value ); } @@ -47,7 +47,7 @@ struct message { T as()const { return fc::raw::unpack(data); } - bool has_notify( const account_name& n )const { + bool has_notify( const AccountName& n )const { for( const auto& no : notify ) if( no == n ) return true; return false; diff --git a/libraries/chain/include/eos/chain/transaction.hpp b/libraries/chain/include/eos/chain/transaction.hpp index f5ee106a801912197f6524980a5324c53b529e88..b8da1118b6853c3bf195ab4bb53f5563b9a20d07 100644 --- a/libraries/chain/include/eos/chain/transaction.hpp +++ b/libraries/chain/include/eos/chain/transaction.hpp @@ -133,9 +133,9 @@ namespace eos { namespace chain { */ struct authorization { /// The account authorizing the transaction - account_name authorizing_account; + AccountName authorizing_account; /// The privileges being invoked to authorize the transaction - permission_name privileges; + PermissionName privileges; }; /** diff --git a/libraries/chain/include/eos/chain/type_object.hpp b/libraries/chain/include/eos/chain/type_object.hpp index 845710abfa771fe85e2baccd9b18e1547f6bf493..476736495678cdb760439cf78bdaafed3eb796b1 100644 --- a/libraries/chain/include/eos/chain/type_object.hpp +++ b/libraries/chain/include/eos/chain/type_object.hpp @@ -32,9 +32,9 @@ namespace eos { namespace chain { OBJECT_CTOR(type_object, (fields)) id_type id; - account_name scope; + AccountName scope; TypeName name; - account_name base_scope; + AccountName base_scope; TypeName base; shared_vector fields; }; @@ -46,8 +46,8 @@ namespace eos { namespace chain { ordered_unique, member>, ordered_unique, composite_key< type_object, - member, - member + member, + member > > > diff --git a/libraries/chain/include/eos/chain/types.hpp b/libraries/chain/include/eos/chain/types.hpp index 556cc318e59aceb7a26a58c93b115e3e6fe1d84c..de42fc6a3ede8514630bfac65c43f73c1400bb21 100644 --- a/libraries/chain/include/eos/chain/types.hpp +++ b/libraries/chain/include/eos/chain/types.hpp @@ -107,13 +107,27 @@ namespace eos { namespace chain { using chain_id_type = fc::sha256; - using eos::AccountName; - using account_name = eos::AccountName; - using eos::PermissionName; - using permission_name = eos::PermissionName; - using message_name = eos::TypeName; - using message_type = message_name; - + using eos::types::AccountName; + using eos::types::PermissionName; + using eos::types::Asset; + using eos::types::Authority; + using eos::types::PermissionName; + using eos::types::TypeName; + using eos::types::Time; + using eos::types::Field; + using eos::types::String; + using eos::types::UInt8; + using eos::types::UInt16; + using eos::types::UInt32; + using eos::types::UInt64; + using eos::types::UInt128; + using eos::types::UInt256; + using eos::types::Int8; + using eos::types::Int16; + using eos::types::Int32; + using eos::types::Int64; + using eos::types::Int128; + using eos::types::Int256; /** * List all object types from all namespaces here so they can @@ -154,7 +168,7 @@ namespace eos { namespace chain { using signature_type = fc::ecc::compact_signature; using weight_type = uint16_t; - using public_key_type = eos::PublicKey; + using public_key_type = eos::types::PublicKey; } } // eos::chain diff --git a/libraries/types/Asset.cpp b/libraries/types/Asset.cpp index 5216f9be941e905aac570a10dcca950805a9ab14..18f2d4d696fd57c9d224be6559ecf9f924832004 100644 --- a/libraries/types/Asset.cpp +++ b/libraries/types/Asset.cpp @@ -3,7 +3,7 @@ #include #include -namespace eos { +namespace eos { namespace types { typedef boost::multiprecision::int128_t int128_t; uint8_t Asset::decimals()const { @@ -159,4 +159,4 @@ namespace eos { } FC_CAPTURE_AND_RETHROW( (base)(quote) ) } -} // eos +}} // eos::types diff --git a/libraries/types/CMakeLists.txt b/libraries/types/CMakeLists.txt index 8b48c1becdc6366ca92ced5d39ae7928026bb6b1..1c133aa380e34ca102e0a8845b528c41f86a558e 100644 --- a/libraries/types/CMakeLists.txt +++ b/libraries/types/CMakeLists.txt @@ -8,14 +8,14 @@ add_library( eos_types ${HEADERS} ) target_include_directories( eos_types PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) -target_link_libraries( eos_types fc ) +target_link_libraries( eos_types eos_utilities fc ) add_executable( type_generator type_generator.cpp ) target_link_libraries( type_generator fc eos_types ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) add_custom_command( OUTPUT include/eos/types/generated.hpp COMMAND ${CMAKE_CURRENT_BINARY_DIR}/type_generator ${CMAKE_CURRENT_SOURCE_DIR}/types.eos ${CMAKE_CURRENT_SOURCE_DIR}/include/eos/types/generated.hpp - DEPENDS types.eos type_generator ) + DEPENDS types.eos type_generator type_generator.cpp ) add_executable( types_test test.cpp include/eos/types/generated.hpp ) target_link_libraries( types_test eos_types fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) diff --git a/libraries/types/PublicKey.cpp b/libraries/types/PublicKey.cpp index cd65a038b506f9412ca18391b7791f085d448d1e..f61ad932b20f79956850c6a3b397bc1b538a9cda 100644 --- a/libraries/types/PublicKey.cpp +++ b/libraries/types/PublicKey.cpp @@ -6,7 +6,7 @@ #define KEY_PREFIX "EOS" -namespace eos { +namespace eos { namespace types { PublicKey::PublicKey():key_data(){}; @@ -70,19 +70,19 @@ namespace eos { return p1.key_data < p2.key_data; }; -} // eos +}} // eos::types namespace fc { using namespace std; - void to_variant(const eos::PublicKey& var, fc::variant& vo) + void to_variant(const eos::types::PublicKey& var, fc::variant& vo) { vo = std::string(var); } - void from_variant(const fc::variant& var, eos::PublicKey& vo) + void from_variant(const fc::variant& var, eos::types::PublicKey& vo) { - vo = eos::PublicKey(var.as_string()); + vo = eos::types::PublicKey(var.as_string()); } } // fc diff --git a/libraries/types/TypeParser.cpp b/libraries/types/TypeParser.cpp index b2f20ba9ab3b6e2027ca2cd43fd4ad3aa0701f3e..bf894f78c4a55b4fb90886d2a6a0923cd1b876d0 100644 --- a/libraries/types/TypeParser.cpp +++ b/libraries/types/TypeParser.cpp @@ -1,60 +1,136 @@ #include #include +#include +#include + +#include #include -namespace eos { - void AbstractSymbolTable::parse( std::istream& in ) { - vector line_tokens; - - bool in_struct = false; - Struct current; - - auto finishStruct = [&](){ - FC_ASSERT( current.fields.size() > 0, "A struct must specify at least one field" ); - this->addType( current ); - current.fields.clear(); - current.base = TypeName(); - in_struct = false; - }; - - int linenum = -1; - for( string line; std::getline(in, line); ) { - ++linenum; - if( !line.size() ) continue; - line = line.substr( 0, line.find( '#' ) ); - line = fc::trim(line); - if( !line.size() ) continue; - std::cerr << line << "\n"; - - line_tokens.clear(); - split( line_tokens, line, boost::is_any_of( " \t" ), boost::token_compress_on ); - - if( !line_tokens.size() ) continue; - if( line_tokens[0] == "struct" ) { - if( in_struct ) finishStruct(); - in_struct = true; - FC_ASSERT( line_tokens.size() >= 2, "Expected a struct name" ); - current.name = line_tokens[1]; - if( line_tokens.size() > 2 ) { - FC_ASSERT( line_tokens.size() == 4, "Expected a struct name" ); - FC_ASSERT( line_tokens[2] == "inherits" ); - current.base = line_tokens[3]; - } - } else if( line_tokens[0] == "typedef" ) { - if( in_struct ) finishStruct(); - FC_ASSERT( line_tokens.size() == 3, "Expected a struct name" ); - this->addTypeDef( line_tokens[1], line_tokens[2] ); - } else if( in_struct ) { // parse field - idump((line_tokens)); - FC_ASSERT( line_tokens.size() == 2, "a field must be two tokens long" ); - const auto& name = line_tokens[0]; - const auto& type = line_tokens[1]; - FC_ASSERT( name.size() > 0 ); - current.fields.emplace_back( Field{name,type} ); +namespace eos { namespace types { +namespace alg = boost::algorithm; + +bool AbstractSymbolTable::isValidTypeName(const TypeName& name, bool allowArray) { + std::string mutable_name = name; + if (name.size() == 0 || !std::isupper(mutable_name[0])) return false; + + // If appropriate, remove trailing [] + if (allowArray && alg::ends_with(mutable_name, "[]")) + mutable_name.resize(mutable_name.size() - 2); + + return alg::all_of(mutable_name, alg::is_alnum()); +} + +void AbstractSymbolTable::parse(std::istream& in) { + vector line_tokens; + + bool in_struct = false; + Struct current; + + auto finishStruct = [&](){ + FC_ASSERT(current.fields.size() > 0, "A struct must specify at least one field"); + this->addType(current); + current.fields.clear(); + current.base = TypeName(); + in_struct = false; + }; + + int linenum = -1; + for(string line; std::getline(in, line);) { + ++linenum; + if(!line.size()) continue; + line = line.substr(0, line.find('#')); + line = fc::trim(line); + if(!line.size()) continue; + std::cerr << line << "\n"; + + line_tokens.clear(); + split(line_tokens, line, boost::is_any_of(" \t"), boost::token_compress_on); + + if(!line_tokens.size()) continue; + if(line_tokens[0] == "struct") { + if(in_struct) finishStruct(); + in_struct = true; + FC_ASSERT(line_tokens.size() >= 2, "Expected a struct name"); + current.name = line_tokens[1]; + if(line_tokens.size() > 2) { + FC_ASSERT(line_tokens.size() == 4, "Expected a struct name"); + FC_ASSERT(line_tokens[2] == "inherits"); + current.base = line_tokens[3]; } - else - FC_ASSERT( false, "Invalid token ${t} on line ${n}", ("t",line_tokens[0])("n",linenum) ); + } else if(line_tokens[0] == "typedef") { + if(in_struct) finishStruct(); + FC_ASSERT(line_tokens.size() == 3, "Expected a struct name"); + this->addTypeDef(line_tokens[1], line_tokens[2]); + } else if(in_struct) { // parse field + idump((line_tokens)); + FC_ASSERT(line_tokens.size() == 2, "a field must be two tokens long"); + const auto& name = line_tokens[0]; + const auto& type = line_tokens[1]; + FC_ASSERT(name.size() > 0); + current.fields.emplace_back(Field{name,type}); } + else + FC_ASSERT(false, "Invalid token ${t} on line ${n}", ("t",line_tokens[0])("n",linenum)); + } +} + +void SimpleSymbolTable::addType(const Struct& s) { try { + EOS_ASSERT(isValidTypeName(s.name), invalid_type_name_exception, + "Invalid type name: ${name}", ("name", s.name)); + EOS_ASSERT(!isKnownType(s.name), duplicate_type_exception, + "Duplicate type name: ${name}", ("name", s.name)); + EOS_ASSERT(s.base.size() == 0 || isKnownType(s.base), unknown_type_exception, + "Unknown base type name: ${name}", ("name", s.base)); + for(const auto& f : s.fields) { + EOS_ASSERT(isKnownType(f.type), unknown_type_exception, + "No such type found: ${type}", ("type",f.type)); + } + structs[s.name] = s; + order.push_back(s.name); +} FC_CAPTURE_AND_RETHROW((s)) } + +void SimpleSymbolTable::addTypeDef(const TypeName& from, const TypeName& to) { try { + EOS_ASSERT(isValidTypeName(to), invalid_type_name_exception, + "Invalid type name: ${name}", ("name", to)); + EOS_ASSERT(!isKnownType(to), duplicate_type_exception, + "Duplicate type name: ${name}", ("name", to)); + EOS_ASSERT(isKnownType(from), unknown_type_exception, + "No such type found: ${type}", ("type", from)); + typedefs[to] = from; + order.push_back(to); +} FC_CAPTURE_AND_RETHROW((from)(to)) } + +bool SimpleSymbolTable::isKnownType(const TypeName& n) { try { + String name(n); + EOS_ASSERT(!name.empty(), invalid_type_name_exception, "Type name cannot be empty"); + if(name.size() > 2 && name.back() == ']') { + FC_ASSERT(name[name.size()-2] == '['); + return isKnownType(name.substr(0, name.size()-2)); + } + return known.find(n) != known.end() || + typedefs.find(n) != typedefs.end() || + structs.find(n) != structs.end(); + } FC_CAPTURE_AND_RETHROW((n)) } + +Struct eos::types::SimpleSymbolTable::getType(TypeName name) const { + name = resolveTypedef(name); + + auto itr = structs.find(name); + if(itr != structs.end()) + return itr->second; + + if(known.find(name) != known.end()) + FC_ASSERT(false, "type is a built in type"); + FC_ASSERT(false, "unknown type: ${n}", ("n", name)); +} + +TypeName SimpleSymbolTable::resolveTypedef(TypeName name) const { + auto tdef = typedefs.find(name); + while(tdef != typedefs.end()) { + name = tdef->second; + tdef = typedefs.find(name); } + return name; +} -} // namespace eos +}} // namespace eos::types diff --git a/libraries/types/include/eos/types/Asset.hpp b/libraries/types/include/eos/types/Asset.hpp index 8333561c0f2d12c5e08bec35e0e20b1a2e74bc11..fbfa1bc11cd617e63274a42fdd42c3c9a262ddcd 100644 --- a/libraries/types/include/eos/types/Asset.hpp +++ b/libraries/types/include/eos/types/Asset.hpp @@ -3,19 +3,19 @@ #include /// eos with 8 digits of precision -#define EOS_SYMBOL (uint64_t(8) | (uint64_t('E') << 8) | (uint64_t('O') << 16) | (uint64_t('S') << 24) ) +#define EOS_SYMBOL (int64_t(8) | (uint64_t('E') << 8) | (uint64_t('O') << 16) | (uint64_t('S') << 24)) /// Defined to be largest power of 10 that fits in 53 bits of precision #define EOS_MAX_SHARE_SUPPLY int64_t(1000000000000000ll) -namespace eos { +namespace eos { namespace types { using AssetSymbol = uint64_t; using ShareType = Int64; struct Asset { - Asset( ShareType a = 0, AssetSymbol id = EOS_SYMBOL ) + Asset(ShareType a = 0, AssetSymbol id = EOS_SYMBOL) :amount(a),symbol(id){} ShareType amount; @@ -28,49 +28,49 @@ namespace eos { int64_t precision()const; void set_decimals(uint8_t d); - static Asset fromString( const String& from ); + static Asset fromString(const String& from); String toString()const; - Asset& operator += ( const Asset& o ) + Asset& operator += (const Asset& o) { - FC_ASSERT( symbol == o.symbol ); + FC_ASSERT(symbol == o.symbol); amount += o.amount; return *this; } - Asset& operator -= ( const Asset& o ) + Asset& operator -= (const Asset& o) { - FC_ASSERT( symbol == o.symbol ); + FC_ASSERT(symbol == o.symbol); amount -= o.amount; return *this; } - Asset operator -()const { return Asset( -amount, symbol ); } + Asset operator -()const { return Asset(-amount, symbol); } - friend bool operator == ( const Asset& a, const Asset& b ) + friend bool operator == (const Asset& a, const Asset& b) { - return std::tie( a.symbol, a.amount ) == std::tie( b.symbol, b.amount ); + return std::tie(a.symbol, a.amount) == std::tie(b.symbol, b.amount); } - friend bool operator < ( const Asset& a, const Asset& b ) + friend bool operator < (const Asset& a, const Asset& b) { - FC_ASSERT( a.symbol == b.symbol ); + FC_ASSERT(a.symbol == b.symbol); return std::tie(a.amount,a.symbol) < std::tie(b.amount,b.symbol); } - friend bool operator <= ( const Asset& a, const Asset& b ) { return (a == b) || (a < b); } - friend bool operator != ( const Asset& a, const Asset& b ) { return !(a == b); } - friend bool operator > ( const Asset& a, const Asset& b ) { return !(a <= b); } - friend bool operator >= ( const Asset& a, const Asset& b ) { return !(a < b); } - - friend Asset operator - ( const Asset& a, const Asset& b ) { - FC_ASSERT( a.symbol == b.symbol ); - return Asset( a.amount - b.amount, a.symbol ); + friend bool operator <= (const Asset& a, const Asset& b) { return (a == b) || (a < b); } + friend bool operator != (const Asset& a, const Asset& b) { return !(a == b); } + friend bool operator > (const Asset& a, const Asset& b) { return !(a <= b); } + friend bool operator >= (const Asset& a, const Asset& b) { return !(a < b); } + + friend Asset operator - (const Asset& a, const Asset& b) { + FC_ASSERT(a.symbol == b.symbol); + return Asset(a.amount - b.amount, a.symbol); } - friend Asset operator + ( const Asset& a, const Asset& b ) { - FC_ASSERT( a.symbol == b.symbol ); - return Asset( a.amount + b.amount, a.symbol ); + friend Asset operator + (const Asset& a, const Asset& b) { + FC_ASSERT(a.symbol == b.symbol); + return Asset(a.amount + b.amount, a.symbol); } - friend std::ostream& operator << ( std::ostream& out, const Asset& a ) { return out << a.toString(); } + friend std::ostream& operator << (std::ostream& out, const Asset& a) { return out << a.toString(); } }; @@ -82,11 +82,11 @@ namespace eos { Price(const Asset& base = Asset(), const Asset quote = Asset()) :base(base),quote(quote){} - static Price max(AssetSymbol base, AssetSymbol quote ); - static Price min(AssetSymbol base, AssetSymbol quote ); + static Price max(AssetSymbol base, AssetSymbol quote); + static Price min(AssetSymbol base, AssetSymbol quote); - Price max()const { return Price::max( base.symbol, quote.symbol ); } - Price min()const { return Price::min( base.symbol, quote.symbol ); } + Price max()const { return Price::max(base.symbol, quote.symbol); } + Price min()const { return Price::min(base.symbol, quote.symbol); } double to_real()const { return base.to_real() / quote.to_real(); } @@ -94,26 +94,28 @@ namespace eos { void validate()const; }; - Price operator / ( const Asset& base, const Asset& quote ); - inline Price operator~( const Price& p ) { return Price{p.quote,p.base}; } + Price operator / (const Asset& base, const Asset& quote); + inline Price operator~(const Price& p) { return Price{p.quote,p.base}; } - bool operator < ( const Asset& a, const Asset& b ); - bool operator <= ( const Asset& a, const Asset& b ); - bool operator < ( const Price& a, const Price& b ); - bool operator <= ( const Price& a, const Price& b ); - bool operator > ( const Price& a, const Price& b ); - bool operator >= ( const Price& a, const Price& b ); - bool operator == ( const Price& a, const Price& b ); - bool operator != ( const Price& a, const Price& b ); - Asset operator * ( const Asset& a, const Price& b ); + bool operator < (const Asset& a, const Asset& b); + bool operator <= (const Asset& a, const Asset& b); + bool operator < (const Price& a, const Price& b); + bool operator <= (const Price& a, const Price& b); + bool operator > (const Price& a, const Price& b); + bool operator >= (const Price& a, const Price& b); + bool operator == (const Price& a, const Price& b); + bool operator != (const Price& a, const Price& b); + Asset operator * (const Asset& a, const Price& b); -} // namespace eos +}} // namespace eos::types namespace fc { - inline void to_variant( const eos::Asset& var, fc::variant& vo ) { vo = var.toString(); } - inline void from_variant( const fc::variant& var, eos::Asset& vo ) { vo = eos::Asset::fromString( var.get_string() ); } + inline void to_variant(const eos::types::Asset& var, fc::variant& vo) { vo = var.toString(); } + inline void from_variant(const fc::variant& var, eos::types::Asset& vo) { + vo = eos::types::Asset::fromString(var.get_string()); + } } -FC_REFLECT( eos::Asset, (amount)(symbol) ) -FC_REFLECT( eos::Price, (base)(quote) ) +FC_REFLECT(eos::types::Asset, (amount)(symbol)) +FC_REFLECT(eos::types::Price, (base)(quote)) diff --git a/libraries/types/include/eos/types/PublicKey.hpp b/libraries/types/include/eos/types/PublicKey.hpp index 008cf7629fe3419cd364857dc2f153c58920fde5..5bec2d01c4c78f36604bbaf36039b15d93cc535d 100644 --- a/libraries/types/include/eos/types/PublicKey.hpp +++ b/libraries/types/include/eos/types/PublicKey.hpp @@ -3,7 +3,7 @@ #include #include -namespace eos { +namespace eos { namespace types { struct PublicKey { struct BinaryKey @@ -14,9 +14,9 @@ namespace eos { }; fc::ecc::public_key_data key_data; PublicKey(); - PublicKey( const fc::ecc::public_key_data& data ); - PublicKey( const fc::ecc::public_key& pubkey ); - explicit PublicKey( const std::string& base58str ); + PublicKey(const fc::ecc::public_key_data& data); + PublicKey(const fc::ecc::public_key& pubkey); + explicit PublicKey(const std::string& base58str); operator fc::ecc::public_key_data() const; operator fc::ecc::public_key() const; explicit operator std::string() const; @@ -24,15 +24,15 @@ namespace eos { friend bool operator == ( const PublicKey& p1, const PublicKey& p2); friend bool operator != ( const PublicKey& p1, const PublicKey& p2); friend bool operator < ( const PublicKey& p1, const PublicKey& p2); - bool is_valid_v1( const std::string& base58str ); + bool is_valid_v1(const std::string& base58str); }; -} +}} // namespace eos::types namespace fc { - void to_variant( const eos::PublicKey& var, fc::variant& vo ); - void from_variant( const fc::variant& var, eos::PublicKey& vo ); + void to_variant(const eos::types::PublicKey& var, fc::variant& vo); + void from_variant(const fc::variant& var, eos::types::PublicKey& vo); } -FC_REFLECT( eos::PublicKey, (key_data) ) -FC_REFLECT( eos::PublicKey::BinaryKey, (data)(check) ) +FC_REFLECT(eos::types::PublicKey, (key_data)) +FC_REFLECT(eos::types::PublicKey::BinaryKey, (data)(check)) diff --git a/libraries/types/include/eos/types/TypeParser.hpp b/libraries/types/include/eos/types/TypeParser.hpp index f26d72daecb2d65212f43c0872dbbf7dbde12298..746002682b9285d8ad3acbe91f350e5bc2698baa 100644 --- a/libraries/types/include/eos/types/TypeParser.hpp +++ b/libraries/types/include/eos/types/TypeParser.hpp @@ -9,103 +9,60 @@ #include #include - -namespace eos { - using std::map; - using std::set; - using std::string; - using std::vector; - - class AbstractSymbolTable { - public: - virtual ~AbstractSymbolTable(){}; - virtual void addType( const Struct& s ) =0; - virtual void addTypeDef( const TypeName& from, const TypeName& to ) = 0; - virtual bool isKnownType( const TypeName& name ) = 0; - - virtual TypeName resolveTypedef( TypeName name )const = 0; - virtual Struct getType( TypeName name )const = 0; - - /** - * Parses the input stream and populatse the symbol table, the table may be pre-populated - */ - void parse( std::istream& in ); - - string binaryToJson( const TypeName& type, const Bytes& binary ); - Bytes jsonToBinary( const TypeName& type, const string& json ); - }; - - - class SimpleSymbolTable : public AbstractSymbolTable { - public: - SimpleSymbolTable(): - known( { "Field", "Struct", "Asset", "FixedString16", "FixedString32", - "UInt8", "UInt16", "UInt32", "UInt64", - "UInt128", "Checksum", "UInt256", "UInt512", - "Int8", "Int16", "Int32", "Int64", - "Int128", "Int224", "Int256", "Int512", - "Bytes", "PublicKey", "Signature", "String", "Time" } ) - { - } - - virtual void addType( const Struct& s ) override { try { - FC_ASSERT( !isKnownType( s.name ) ); - for( const auto& f : s.fields ) { - FC_ASSERT( isKnownType( f.type ), "", ("type",f.type) ); - } - structs[s.name] = s; - order.push_back(s.name); - // wdump((s.name)(s.base)(s.fields)); - } FC_CAPTURE_AND_RETHROW( (s) ) } - - virtual void addTypeDef( const TypeName& from, const TypeName& to ) override { try { - FC_ASSERT( !isKnownType( to ) ); - FC_ASSERT( isKnownType( from ) ); - typedefs[to] = from; - order.push_back(to); - } FC_CAPTURE_AND_RETHROW( (from)(to) ) } - - virtual bool isKnownType( const TypeName& n ) override { try { - String name(n); - FC_ASSERT( name.size() > 0 ); - if( name.size() > 2 && name.back() == ']' ) { - FC_ASSERT( name[name.size()-2] == '[' ); - return isKnownType( name.substr( 0, name.size()-2 ) ); - } - return known.find(n) != known.end() || - typedefs.find(n) != typedefs.end() || - structs.find(n) != structs.end(); - } FC_CAPTURE_AND_RETHROW( (n) ) } - - virtual Struct getType( TypeName name )const override { - name = resolveTypedef( name ); - - auto itr = structs.find( name ); - if( itr != structs.end() ) - return itr->second; - - if( known.find(name) != known.end() ) - FC_ASSERT( false, "type is a built in type" ); - FC_ASSERT( false, "unknown type: ${n}", ("n", name) ); - } - virtual TypeName resolveTypedef( TypeName name )const override { - auto tdef = typedefs.find( name ); - while( tdef != typedefs.end() ) { - name = tdef->second; - tdef = typedefs.find( name ); - } - return name; - } - - -// private: - set known; - vector order; - map typedefs; - map structs; - }; - - -} // namespace eos - -FC_REFLECT( eos::SimpleSymbolTable, (typedefs)(structs) ) +#include + +namespace eos { namespace types { +using std::map; +using std::set; +using std::string; +using std::vector; + +class AbstractSymbolTable { +public: + virtual ~AbstractSymbolTable(){} + virtual void addType(const Struct& s) =0; + virtual void addTypeDef(const TypeName& from, const TypeName& to) = 0; + virtual bool isKnownType(const TypeName& name) = 0; + virtual bool isValidTypeName(const TypeName& name, bool allowArray = false); + + virtual TypeName resolveTypedef(TypeName name)const = 0; + virtual Struct getType(TypeName name)const = 0; + + /** + * Parses the input stream and populatse the symbol table, the table may be pre-populated + */ + void parse(std::istream& in); + + string binaryToJson(const TypeName& type, const Bytes& binary); + Bytes jsonToBinary(const TypeName& type, const string& json); +}; + + +class SimpleSymbolTable : public AbstractSymbolTable { +public: + SimpleSymbolTable(): + known({ "Field", "Struct", "Asset", "FixedString16", "FixedString32", + "UInt8", "UInt16", "UInt32", "UInt64", + "UInt128", "Checksum", "UInt256", "UInt512", + "Int8", "Int16", "Int32", "Int64", + "Int128", "Int224", "Int256", "Int512", + "Bytes", "PublicKey", "Signature", "String", "Time" }) + {} + + virtual void addType(const Struct& s) override; + virtual void addTypeDef(const TypeName& from, const TypeName& to) override; + virtual bool isKnownType(const TypeName& n) override; + virtual Struct getType(TypeName name)const override; + virtual TypeName resolveTypedef(TypeName name)const override; + + + // private: + set known; + vector order; + map typedefs; + map structs; +}; + +}} // namespace eos::types + +FC_REFLECT(eos::types::SimpleSymbolTable, (typedefs)(structs)) diff --git a/libraries/types/include/eos/types/WrenDatastream.hpp b/libraries/types/include/eos/types/WrenDatastream.hpp index 8bd5bef5955a4fa08349ae364cf0d3d6d5b11fbf..ce455bbd3489eb9faea2be730b97a544cdf58f5d 100644 --- a/libraries/types/include/eos/types/WrenDatastream.hpp +++ b/libraries/types/include/eos/types/WrenDatastream.hpp @@ -1,7 +1,7 @@ #pragma once #include -namespace EOS { +namespace eos { namespace types { using fc::datastream; struct InputDatastream { @@ -78,4 +78,4 @@ namespace EOS { uint32_t tellp()const { return ds.tellp(); } }; -} // namespace EOS +}} // namespace eos::types diff --git a/libraries/types/include/eos/types/WrenInt.hpp b/libraries/types/include/eos/types/WrenInt.hpp index d5269f75177e47392e37bdfcca3eef465d2ffefa..2a18ba3ff3040ee1916bfa5fa6e4d46fca79db17 100644 --- a/libraries/types/include/eos/types/WrenInt.hpp +++ b/libraries/types/include/eos/types/WrenInt.hpp @@ -1,7 +1,7 @@ #pragma once #include -namespace EOS { +namespace eos { namespace types { class InputDatastream; class OutputDatastream; @@ -66,4 +66,4 @@ namespace EOS { }; -} /// namespace EOS +}} /// namespace eos::types diff --git a/libraries/types/include/eos/types/exceptions.hpp b/libraries/types/include/eos/types/exceptions.hpp new file mode 100644 index 0000000000000000000000000000000000000000..96797b527add2ac220b67a671b0c489154779e57 --- /dev/null +++ b/libraries/types/include/eos/types/exceptions.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017, Respective Authors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#pragma once + +#include +#include + +namespace eos { namespace types { + + FC_DECLARE_EXCEPTION(type_exception, 4000000, "type exception") + FC_DECLARE_DERIVED_EXCEPTION(unknown_type_exception, type_exception, + 4010000, "Could not find requested type") + FC_DECLARE_DERIVED_EXCEPTION(duplicate_type_exception, type_exception, + 4020000, "Requested type already exists") + FC_DECLARE_DERIVED_EXCEPTION(invalid_type_name_exception, type_exception, + 4030000, "Requested type name is invalid") + +} } // eos::chain diff --git a/libraries/types/include/eos/types/native.hpp b/libraries/types/include/eos/types/native.hpp index eeadb58487328c8f6d607b1351a33d58b1bae42d..05cd3a47ae0a59940ae2cba438d9fd373fb777ad 100644 --- a/libraries/types/include/eos/types/native.hpp +++ b/libraries/types/include/eos/types/native.hpp @@ -17,7 +17,7 @@ #include -namespace eos { +namespace eos { namespace types { using namespace boost::multiprecision; template @@ -95,26 +95,26 @@ namespace eos { /// TODO: make sure this works with FC raw template - void fromBinary( Stream& st, boost::multiprecision::number& value ) { + void fromBinary(Stream& st, boost::multiprecision::number& value) { unsigned char data[(std::numeric_limits::digits+1)/8]; - st.read( (char*)data, sizeof(data) ); - boost::multiprecision::import_bits( value, data, data + sizeof(data), 1 ); + st.read((char*)data, sizeof(data)); + boost::multiprecision::import_bits(value, data, data + sizeof(data), 1); } template - void toBinary( Stream& st, const boost::multiprecision::number& value ) { + void toBinary(Stream& st, const boost::multiprecision::number& value) { unsigned char data[(std::numeric_limits::digits+1)/8]; - boost::multiprecision::export_bits( value, data, 1 ); - st.write( (const char*)data, sizeof(data) ); + boost::multiprecision::export_bits(value, data, 1); + st.write((const char*)data, sizeof(data)); } -} // namespace eos +}} // namespace eos::types namespace fc { - void to_variant( const std::vector& c, fc::variant& v ); - void from_variant( const fc::variant& v, std::vector& check ); - void to_variant( const std::map& c, fc::variant& v ); - void from_variant( const fc::variant& v, std::map& check ); + void to_variant(const std::vector& c, fc::variant& v); + void from_variant(const fc::variant& v, std::vector& check); + void to_variant(const std::map& c, fc::variant& v); + void from_variant(const fc::variant& v, std::map& check); } -FC_REFLECT( eos::Field, (name)(type) ) -FC_REFLECT( eos::Struct, (name)(base)(fields) ) +FC_REFLECT(eos::types::Field, (name)(type)) +FC_REFLECT(eos::types::Struct, (name)(base)(fields)) diff --git a/libraries/types/include/eos/types/native_impl.hpp b/libraries/types/include/eos/types/native_impl.hpp index c2d0b7194bb57a62f431ad7c7021cc751207b039..48ae93602f49b8ec9bc68819d0274ff36c70a117 100644 --- a/libraries/types/include/eos/types/native_impl.hpp +++ b/libraries/types/include/eos/types/native_impl.hpp @@ -1,5 +1,5 @@ #pragma once -namespace EOS { +namespace eos { namespace types { template fc::variant toVariant( const vector& a ) { vector result; @@ -41,4 +41,4 @@ namespace EOS { EOS::fromBinary( ds, result ); return result; } -} +}} // namespace eos::types diff --git a/libraries/types/native.cpp b/libraries/types/native.cpp index f6c480c2a8f271aaf98bd666972f7009af15e227..26ba1db62267854bdc8b51450aec3fc778e86005 100644 --- a/libraries/types/native.cpp +++ b/libraries/types/native.cpp @@ -6,39 +6,39 @@ #include namespace fc { - void to_variant( const std::vector& c, fc::variant& v ) { - fc::mutable_variant_object mvo; mvo.reserve( c.size() ); - for( const auto& f : c ) { - mvo.set( f.name, eos::String(f.type) ); + void to_variant(const std::vector& c, fc::variant& v) { + fc::mutable_variant_object mvo; mvo.reserve(c.size()); + for(const auto& f : c) { + mvo.set(f.name, eos::types::String(f.type)); } v = std::move(mvo); } - void from_variant( const fc::variant& v, std::vector& fields ) { + void from_variant(const fc::variant& v, std::vector& fields) { const auto& obj = v.get_object(); - fields.reserve( obj.size() ); - for( const auto& f : obj ) - fields.emplace_back( eos::Field{ f.key(), f.value().get_string() } ); + fields.reserve(obj.size()); + for(const auto& f : obj) + fields.emplace_back(eos::types::Field{ f.key(), f.value().get_string() }); } - void to_variant( const std::map& c, fc::variant& v ) + void to_variant(const std::map& c, fc::variant& v) { - fc::mutable_variant_object mvo; mvo.reserve( c.size() ); - for( const auto& item : c ) { - if( item.second.base.size() ) - mvo.set( item.first, fc::mutable_variant_object("base",item.second.base)("fields",item.second.fields) ); + fc::mutable_variant_object mvo; mvo.reserve(c.size()); + for(const auto& item : c) { + if(item.second.base.size()) + mvo.set(item.first, fc::mutable_variant_object("base",item.second.base)("fields",item.second.fields)); else - mvo.set( item.first, fc::mutable_variant_object("fields",item.second.fields) ); + mvo.set(item.first, fc::mutable_variant_object("fields",item.second.fields)); } v = std::move(mvo); } - void from_variant( const fc::variant& v, std::map& structs ) { + void from_variant(const fc::variant& v, std::map& structs) { const auto& obj = v.get_object(); structs.clear(); - for( const auto& f : obj ) { + for(const auto& f : obj) { auto& stru = structs[f.key()]; - if( f.value().get_object().contains( "fields" ) ) - fc::from_variant( f.value().get_object()["fields"], stru.fields ); - if( f.value().get_object().contains( "base" ) ) - fc::from_variant( f.value().get_object()["base"], stru.base ); + if(f.value().get_object().contains("fields")) + fc::from_variant(f.value().get_object()["fields"], stru.fields); + if(f.value().get_object().contains("base")) + fc::from_variant(f.value().get_object()["base"], stru.base); stru.name = f.key(); } } diff --git a/libraries/types/test.cpp b/libraries/types/test.cpp index 26734eb857dbef2b8fdd509088b0160503550872..144faf372a157aaea4fe2960c821041dffbd09d0 100644 --- a/libraries/types/test.cpp +++ b/libraries/types/test.cpp @@ -11,13 +11,13 @@ int main( int argc, char** argv ) { try { - eos::Message m; - m.sender = eos::AccountName( "ned" ); - m.recipient = eos::AccountName( "dan" ); + eos::types::Message m; + m.sender = eos::types::AccountName( "ned" ); + m.recipient = eos::types::AccountName( "dan" ); idump( (m) ); - eos::Transfer t; + eos::types::Transfer t; t.from = m.sender; t.to = "other"; diff --git a/libraries/types/type_generator.cpp b/libraries/types/type_generator.cpp index 2d0c919f3bdacb57607375a47cc836f7fe796292..c57e72daea3d1a4c2b2e194c9e973b5bc7001ad8 100644 --- a/libraries/types/type_generator.cpp +++ b/libraries/types/type_generator.cpp @@ -4,6 +4,7 @@ #include using std::string; +namespace eos { using types::SimpleSymbolTable; } bool isVector( const string& type ) { @@ -60,7 +61,7 @@ string call_type_constructor( const string& type ) { return "Vector[" + getWrenType(type) + "]"; return getWrenType(type) + ".new()"; } -string generate_wren( const eos::Struct& s, eos::SimpleSymbolTable& symbols ) { +string generate_wren( const eos::types::Struct& s, eos::types::SimpleSymbolTable& symbols ) { std::stringstream ss; ss << "class " << s.name; @@ -98,15 +99,15 @@ string generate_wren( const eos::Struct& s, eos::SimpleSymbolTable& symbols ) { return ss.str(); } -void generate_wren( eos::SimpleSymbolTable& ss, const char* outfile ) { +void generate_wren( eos::types::SimpleSymbolTable& ss, const char* outfile ) { //for( const auto& s : ss.order ) } -void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) { +void generate_hpp( eos::types::SimpleSymbolTable& ss, const char* outfile ) { wdump((outfile)); std::ofstream out(outfile); out << "#pragma once\n"; - out << "namespace eos { \n"; + out << "namespace eos { namespace types {\n"; for( const auto& s : ss.order ) { if( ss.typedefs.find( s ) != ss.typedefs.end() ) { const auto& td = ss.typedefs[s]; @@ -141,7 +142,7 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) { } - out << "} // namespace eos \n"; + out << "}} // namespace eos::types\n"; for( const auto& s : ss.order ) { if( ss.typedefs.find( s ) != ss.typedefs.end() ) { @@ -150,9 +151,9 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) { const auto& st = ss.structs[s]; if( st.base.size() ) { - out << "FC_REFLECT_DERIVED( eos::" << s << ", (eos::" << st.base <<"), "; + out << "FC_REFLECT_DERIVED( eos::types::" << s << ", (eos::types::" << st.base <<"), "; } else { - out << "FC_REFLECT( eos::" << std::setw(33) << s << ", "; + out << "FC_REFLECT( eos::types::" << std::setw(33) << s << ", "; } for( const auto& f : st.fields ) { out <<"("< 2, "Usage: ${program} input path/to/out.hpp", ("program",string(argv[0])) ); std::ifstream in(argv[1]); - eos::SimpleSymbolTable ss; + eos::types::SimpleSymbolTable ss; ss.parse(in); auto as_json = fc::json::to_pretty_string( ss ); diff --git a/libraries/utilities/include/eos/utilities/exception_macros.hpp b/libraries/utilities/include/eos/utilities/exception_macros.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0eb0c53f8382bc7f4028871dac7da0a459e2ea33 --- /dev/null +++ b/libraries/utilities/include/eos/utilities/exception_macros.hpp @@ -0,0 +1,44 @@ +#define EOS_ASSERT( expr, exc_type, FORMAT, ... ) \ + FC_MULTILINE_MACRO_BEGIN \ + if( !(expr) ) \ + FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \ + FC_MULTILINE_MACRO_END + + +#define EOS_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _validate_exception, \ + eos::chain::message_validate_exception, \ + 3040000 + 100 * operation::tag< op_name ## _operation >::value, \ + #op_name "_operation validation exception" \ + ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _evaluate_exception, \ + eos::chain::message_evaluate_exception, \ + 3050000 + 100 * operation::tag< op_name ## _operation >::value, \ + #op_name "_operation evaluation exception" \ + ) + +#define EOS_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _ ## exc_name, \ + eos::chain::op_name ## _validate_exception, \ + 3040000 + 100 * operation::tag< op_name ## _operation >::value \ + + seqnum, \ + msg \ + ) + +#define EOS_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _ ## exc_name, \ + eos::chain::op_name ## _evaluate_exception, \ + 3050000 + 100 * operation::tag< op_name ## _operation >::value \ + + seqnum, \ + msg \ + ) + +#define EOS_RECODE_EXC( cause_type, effect_type ) \ + catch( const cause_type& e ) \ + { throw( effect_type( e.what(), e.get_log() ) ); } + + diff --git a/plugins/native_system_contract_plugin/native_system_contract_plugin.cpp b/plugins/native_system_contract_plugin/native_system_contract_plugin.cpp index 74cdf50923fcbb7394c28b04ab9dea8d2ad890d2..b7265fd7ab715c1a54d0c109c4fc60175815d875 100644 --- a/plugins/native_system_contract_plugin/native_system_contract_plugin.cpp +++ b/plugins/native_system_contract_plugin/native_system_contract_plugin.cpp @@ -7,6 +7,7 @@ namespace eos { using namespace chain; +using namespace types; class native_system_contract_plugin_impl { public: diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 059f914c5ab115bfd725b0b3be3491449110af1a..2ff4922d44ee4780fb423dbceab2f82d506b4c57 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -39,6 +39,7 @@ using namespace eos; using namespace chain; +using namespace types; BOOST_AUTO_TEST_SUITE(block_tests) @@ -154,7 +155,7 @@ BOOST_FIXTURE_TEST_CASE(create_script, testing_fixture) const auto& processor = db.get("init1"); const auto& recipient = db.get("sys"); - const auto& world = db.get( boost::make_tuple( AccountName("init1"), eos::String("hello") ) ); + const auto& world = db.get(boost::make_tuple(AccountName("init1"), String("hello"))); BOOST_CHECK_EQUAL( string(world.value.c_str()), "world" ); } FC_LOG_AND_RETHROW() } diff --git a/tests/tests/types_tests.cpp b/tests/tests/types_tests.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15ec4d118f719c3592d5f2c36468941782650f8b --- /dev/null +++ b/tests/tests/types_tests.cpp @@ -0,0 +1,67 @@ +#include + +#include + +namespace eos { namespace types { + +BOOST_AUTO_TEST_SUITE(types_tests) + +/// Put the SimpleSymbolTable through its paces +BOOST_AUTO_TEST_CASE(basic_simple_symbol_table_test) +{ try { + SimpleSymbolTable table; + + BOOST_CHECK_THROW(table.addType({"testtype", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"test type", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Testtype[]", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Testtype]", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Testtype[", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Test[]type", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Test]type", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Test[type", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Test!type", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"!Testtype", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"!testtype", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Testtype!", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"_Testtype", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Testtype_", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"Test_type", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"0Testtype", "", {{"f1", "String"}}}), invalid_type_name_exception); + BOOST_CHECK_THROW(table.addType({"0testtype", "", {{"f1", "String"}}}), invalid_type_name_exception); + table.addType({"Testtype", "", {{"f1", "String"}}}); + table.addType({"Testtype1", "", {{"f1", "String"}}}); + table.addType({"Test2type", "", {{"f1", "String"}}}); + BOOST_CHECK_THROW(table.addType({"Testtype", "", {{"f1", "String"}}}), duplicate_type_exception); + + BOOST_CHECK_THROW(table.addTypeDef("Testtype", "Testtype"), duplicate_type_exception); + BOOST_CHECK_THROW(table.addTypeDef("Testtype5", "NewType"), unknown_type_exception); + table.addTypeDef("Testtype", "TestType"); + BOOST_CHECK_THROW(table.addTypeDef("Testtype", "TestType"), duplicate_type_exception); + table.addTypeDef("Testtype[]", "TestTypeArray"); + BOOST_CHECK_THROW(table.addTypeDef("Testtype", "NewType[]"), invalid_type_name_exception); + + BOOST_CHECK(table.isKnownType("Testtype")); + BOOST_CHECK(table.isKnownType("Testtype1")); + BOOST_CHECK(table.isKnownType("Test2type")); + BOOST_CHECK(table.isKnownType("TestType")); + BOOST_CHECK(table.isKnownType("Testtype[]")); + BOOST_CHECK(table.isKnownType("TestTypeArray")); + BOOST_CHECK(!table.isKnownType("Testtype5")); + BOOST_CHECK(!table.isKnownType("NewType")); + BOOST_CHECK(!table.isKnownType("NewType[]")); + + BOOST_CHECK_THROW(table.addType({"Foo", "Bar", {{"f1", "String"}}}), unknown_type_exception); + BOOST_CHECK_THROW(table.addType({"Foo", "Foo", {{"f1", "String"}}}), unknown_type_exception); + BOOST_CHECK_THROW(table.addType({"Foo", "", {{"f1", "Bar"}}}), unknown_type_exception); + BOOST_CHECK_THROW(table.addType({"Foo", "", {{"f1", "Foo"}}}), unknown_type_exception); + table.addType({"Foo", "", {{"f1", "String"}}}); + table.addType({"FooBar", "Foo", {{"f2", "Int32"}}}); + BOOST_CHECK(table.isKnownType("Foo")); + BOOST_CHECK(table.isKnownType("FooBar")); + + BOOST_CHECK_THROW(table.addType({"Bar", "", {{"f1", "Struct"}}}), unknown_type_exception); +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_SUITE_END() + +}} // namespace eos::types