提交 44548f35 编写于 作者: N Nathan Hourt

Improvements circa Types

- Move types into eos::types namespace
- Fix lots of bugs in types
- Add tests of types (one still failing)
上级 5599ace3
...@@ -545,7 +545,7 @@ void database::validate_referenced_accounts(const signed_transaction& trx)const ...@@ -545,7 +545,7 @@ void database::validate_referenced_accounts(const signed_transaction& trx)const
for(const auto& msg : trx.messages) { for(const auto& msg : trx.messages) {
get_account(msg.sender); get_account(msg.sender);
get_account(msg.recipient); 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) { for(const auto& current_notify_account : msg.notify) {
get_account(current_notify_account); get_account(current_notify_account);
if(previous_notify_account) { if(previous_notify_account) {
...@@ -798,10 +798,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) ...@@ -798,10 +798,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
create<account_object>([&](account_object& a) { create<account_object>([&](account_object& a) {
a.name = "sys"; a.name = "sys";
}); });
register_type<eos::Transfer>("sys"); register_type<types::Transfer>("sys");
register_type<eos::CreateAccount>("sys"); register_type<types::CreateAccount>("sys");
register_type<eos::DefineStruct>("sys"); register_type<types::DefineStruct>("sys");
register_type<eos::SetMessageHandler>("sys"); register_type<types::SetMessageHandler>("sys");
// Create initial accounts // Create initial accounts
for (const auto& acct : genesis_state.initial_accounts) { for (const auto& acct : genesis_state.initial_accounts) {
...@@ -1129,17 +1129,17 @@ void database::update_producer_schedule() ...@@ -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; 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; 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; 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 { try {
return get<account_object,by_name>(name); return get<account_object,by_name>(name);
} FC_CAPTURE_AND_RETHROW( (name) ) } } FC_CAPTURE_AND_RETHROW( (name) ) }
......
...@@ -51,9 +51,9 @@ namespace eos { namespace chain { ...@@ -51,9 +51,9 @@ namespace eos { namespace chain {
return *this; return *this;
} }
UInt32 threshold = 0; UInt32 threshold = 0;
shared_vector<AccountPermissionWeight> accounts; shared_vector<types::AccountPermissionWeight> accounts;
shared_vector<KeyPermissionWeight> keys; shared_vector<types::KeyPermissionWeight> keys;
}; };
class account_object : public chainbase::object<account_object_type, account_object> class account_object : public chainbase::object<account_object_type, account_object>
...@@ -84,7 +84,7 @@ namespace eos { namespace chain { ...@@ -84,7 +84,7 @@ namespace eos { namespace chain {
id_type id; id_type id;
account_id_type owner; ///< the account this permission belongs to account_id_type owner; ///< the account this permission belongs to
id_type parent; ///< parent permission id_type parent; ///< parent permission
permission_name name; PermissionName name;
shared_authority auth; ///< TODO shared_authority auth; ///< TODO
}; };
...@@ -105,11 +105,11 @@ namespace eos { namespace chain { ...@@ -105,11 +105,11 @@ namespace eos { namespace chain {
ordered_unique<tag<by_owner>, ordered_unique<tag<by_owner>,
composite_key< permission_object, composite_key< permission_object,
member<permission_object, account_object::id_type, &permission_object::owner>, member<permission_object, account_object::id_type, &permission_object::owner>,
member<permission_object, permission_name, &permission_object::name>, member<permission_object, PermissionName, &permission_object::name>,
member<permission_object, permission_object::id_type, &permission_object::id> member<permission_object, permission_object::id_type, &permission_object::id>
> >
>, >,
ordered_unique<tag<by_name>, member<permission_object, permission_name, &permission_object::name> > ordered_unique<tag<by_name>, member<permission_object, PermissionName, &permission_object::name> >
> >
>; >;
......
...@@ -3,20 +3,20 @@ ...@@ -3,20 +3,20 @@
#include <eos/types/generated.hpp> #include <eos/types/generated.hpp>
namespace eos { 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 ); 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 * Makes sure all keys are unique and sorted and all account permissions are unique and sorted
*/ */
inline bool validate( eos::Authority& auth ) { inline bool validate( types::Authority& auth ) {
const KeyPermissionWeight* prev = nullptr; const types::KeyPermissionWeight* prev = nullptr;
for( const auto& k : auth.keys ) { for( const auto& k : auth.keys ) {
if( !prev ) prev = &k; if( !prev ) prev = &k;
else if( prev->key < k.key ) return false; else if( prev->key < k.key ) return false;
} }
const AccountPermissionWeight* pa = nullptr; const types::AccountPermissionWeight* pa = nullptr;
for( const auto& a : auth.accounts ) { for( const auto& a : auth.accounts ) {
if( !pa ) pa = &a; if( !pa ) pa = &a;
else if( pa->permission < a.permission ) return false; else if( pa->permission < a.permission ) return false;
......
...@@ -56,17 +56,17 @@ namespace eos { namespace chain { ...@@ -56,17 +56,17 @@ namespace eos { namespace chain {
class precondition_validate_context : public message_validate_context { class precondition_validate_context : public message_validate_context {
public: 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){} :message_validate_context(t,m),recipient(r),db(d){}
const account_name& recipient; const AccountName& recipient;
const database& db; const database& db;
}; };
class apply_context : public precondition_validate_context { class apply_context : public precondition_validate_context {
public: 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){} :precondition_validate_context(d,t,m,recipient),mutable_db(d){}
String get( String key )const; String get( String key )const;
...@@ -108,8 +108,8 @@ namespace eos { namespace chain { ...@@ -108,8 +108,8 @@ namespace eos { namespace chain {
fc::signal<void(const signed_transaction&)> on_pending_transaction; fc::signal<void(const signed_transaction&)> on_pending_transaction;
template<typename T> template<typename T>
void register_type( account_name scope ) { void register_type( AccountName scope ) {
auto stru = eos::GetStruct<T>::type(); auto stru = eos::types::GetStruct<T>::type();
create<type_object>([&](type_object& o) { create<type_object>([&](type_object& o) {
o.scope = scope; o.scope = scope;
o.name = stru.name; o.name = stru.name;
...@@ -126,9 +126,9 @@ namespace eos { namespace chain { ...@@ -126,9 +126,9 @@ namespace eos { namespace chain {
* The database can override any script handler with native code. * 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_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& 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_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& 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_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v );
//@} //@}
enum validation_steps enum validation_steps
...@@ -193,7 +193,7 @@ namespace eos { namespace chain { ...@@ -193,7 +193,7 @@ namespace eos { namespace chain {
const signed_transaction& get_recent_transaction( const transaction_id_type& trx_id )const; const signed_transaction& get_recent_transaction( const transaction_id_type& trx_id )const;
std::vector<block_id_type> get_block_ids_on_fork(block_id_type head_of_fork) const; std::vector<block_id_type> 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 * Calculate the percent of block production slots that were missed in the
...@@ -383,10 +383,10 @@ namespace eos { namespace chain { ...@@ -383,10 +383,10 @@ namespace eos { namespace chain {
node_property_object _node_property_object; node_property_object _node_property_object;
typedef pair<account_name,message_type> handler_key; typedef pair<AccountName,TypeName> handler_key;
map< account_name, map<handler_key, message_validate_handler> > message_validate_handlers; map< AccountName, map<handler_key, message_validate_handler> > message_validate_handlers;
map< account_name, map<handler_key, precondition_validate_handler> > precondition_validate_handlers; map< AccountName, map<handler_key, precondition_validate_handler> > precondition_validate_handlers;
map< account_name, map<handler_key, apply_handler> > apply_handlers; map< AccountName, map<handler_key, apply_handler> > apply_handlers;
}; };
} } } }
...@@ -25,45 +25,7 @@ ...@@ -25,45 +25,7 @@
#include <fc/exception/exception.hpp> #include <fc/exception/exception.hpp>
#include <eos/chain/protocol.hpp> #include <eos/chain/protocol.hpp>
#include <eos/utilities/exception_macros.hpp>
#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 \
)
namespace eos { namespace chain { namespace eos { namespace chain {
......
...@@ -32,7 +32,7 @@ namespace eos { namespace chain { ...@@ -32,7 +32,7 @@ namespace eos { namespace chain {
OBJECT_CTOR(key_value_object, (key)(value)) OBJECT_CTOR(key_value_object, (key)(value))
id_type id; id_type id;
account_name scope; AccountName scope;
shared_string key; shared_string key;
shared_string value; shared_string value;
}; };
...@@ -44,10 +44,10 @@ namespace eos { namespace chain { ...@@ -44,10 +44,10 @@ namespace eos { namespace chain {
ordered_unique<tag<by_id>, member<key_value_object, key_value_object::id_type, &key_value_object::id>>, ordered_unique<tag<by_id>, member<key_value_object, key_value_object::id_type, &key_value_object::id>>,
ordered_unique<tag<by_scope_key>, ordered_unique<tag<by_scope_key>,
composite_key< key_value_object, composite_key< key_value_object,
member<key_value_object, account_name, &key_value_object::scope>, member<key_value_object, AccountName, &key_value_object::scope>,
member<key_value_object, shared_string, &key_value_object::key> member<key_value_object, shared_string, &key_value_object::key>
>, >,
composite_key_compare< std::less<account_name>, chainbase::strcmp_less > composite_key_compare< std::less<AccountName>, chainbase::strcmp_less >
> >
> >
>; >;
......
...@@ -20,26 +20,26 @@ namespace eos { namespace chain { ...@@ -20,26 +20,26 @@ namespace eos { namespace chain {
*/ */
struct message { struct message {
/// The account which sent the message /// The account which sent the message
account_name sender; AccountName sender;
/// The account to receive the message /// The account to receive the message
account_name recipient; AccountName recipient;
/// Other accounts to notify about this message /// Other accounts to notify about this message
vector<account_name> notify; vector<AccountName> notify;
/** /**
* Every contract defines the set of types that it accepts, these types are * 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 * scoped according to the recipient. This means two contracts can can define
* two different types with the same name. * two different types with the same name.
*/ */
TypeName type; types::TypeName type;
/// The message contents /// The message contents
vector<char> data; vector<char> data;
template<typename T> template<typename T>
void set( const message_type& t, const T& value ) { void set( const TypeName& t, const T& value ) {
type = t; type = t;
data = fc::raw::pack( value ); data = fc::raw::pack( value );
} }
...@@ -47,7 +47,7 @@ struct message { ...@@ -47,7 +47,7 @@ struct message {
T as()const { T as()const {
return fc::raw::unpack<T>(data); return fc::raw::unpack<T>(data);
} }
bool has_notify( const account_name& n )const { bool has_notify( const AccountName& n )const {
for( const auto& no : notify ) for( const auto& no : notify )
if( no == n ) return true; if( no == n ) return true;
return false; return false;
......
...@@ -133,9 +133,9 @@ namespace eos { namespace chain { ...@@ -133,9 +133,9 @@ namespace eos { namespace chain {
*/ */
struct authorization { struct authorization {
/// The account authorizing the transaction /// The account authorizing the transaction
account_name authorizing_account; AccountName authorizing_account;
/// The privileges being invoked to authorize the transaction /// The privileges being invoked to authorize the transaction
permission_name privileges; PermissionName privileges;
}; };
/** /**
......
...@@ -32,9 +32,9 @@ namespace eos { namespace chain { ...@@ -32,9 +32,9 @@ namespace eos { namespace chain {
OBJECT_CTOR(type_object, (fields)) OBJECT_CTOR(type_object, (fields))
id_type id; id_type id;
account_name scope; AccountName scope;
TypeName name; TypeName name;
account_name base_scope; AccountName base_scope;
TypeName base; TypeName base;
shared_vector<Field> fields; shared_vector<Field> fields;
}; };
...@@ -46,8 +46,8 @@ namespace eos { namespace chain { ...@@ -46,8 +46,8 @@ namespace eos { namespace chain {
ordered_unique<tag<by_id>, member<type_object, type_object::id_type, &type_object::id>>, ordered_unique<tag<by_id>, member<type_object, type_object::id_type, &type_object::id>>,
ordered_unique<tag<by_scope_name>, ordered_unique<tag<by_scope_name>,
composite_key< type_object, composite_key< type_object,
member<type_object, account_name, &type_object::scope>, member<type_object, AccountName, &type_object::scope>,
member<type_object, message_type, &type_object::name> member<type_object, TypeName, &type_object::name>
> >
> >
> >
......
...@@ -107,13 +107,27 @@ namespace eos { namespace chain { ...@@ -107,13 +107,27 @@ namespace eos { namespace chain {
using chain_id_type = fc::sha256; using chain_id_type = fc::sha256;
using eos::AccountName; using eos::types::AccountName;
using account_name = eos::AccountName; using eos::types::PermissionName;
using eos::PermissionName; using eos::types::Asset;
using permission_name = eos::PermissionName; using eos::types::Authority;
using message_name = eos::TypeName; using eos::types::PermissionName;
using message_type = message_name; 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 * List all object types from all namespaces here so they can
...@@ -154,7 +168,7 @@ namespace eos { namespace chain { ...@@ -154,7 +168,7 @@ namespace eos { namespace chain {
using signature_type = fc::ecc::compact_signature; using signature_type = fc::ecc::compact_signature;
using weight_type = uint16_t; using weight_type = uint16_t;
using public_key_type = eos::PublicKey; using public_key_type = eos::types::PublicKey;
} } // eos::chain } } // eos::chain
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_int.hpp>
#include <fc/reflect/variant.hpp> #include <fc/reflect/variant.hpp>
namespace eos { namespace eos { namespace types {
typedef boost::multiprecision::int128_t int128_t; typedef boost::multiprecision::int128_t int128_t;
uint8_t Asset::decimals()const { uint8_t Asset::decimals()const {
...@@ -159,4 +159,4 @@ namespace eos { ...@@ -159,4 +159,4 @@ namespace eos {
} FC_CAPTURE_AND_RETHROW( (base)(quote) ) } } FC_CAPTURE_AND_RETHROW( (base)(quote) ) }
} // eos }} // eos::types
...@@ -8,14 +8,14 @@ add_library( eos_types ...@@ -8,14 +8,14 @@ add_library( eos_types
${HEADERS} ${HEADERS}
) )
target_include_directories( eos_types PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) 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 ) add_executable( type_generator type_generator.cpp )
target_link_libraries( type_generator fc eos_types ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) target_link_libraries( type_generator fc eos_types ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
add_custom_command( OUTPUT include/eos/types/generated.hpp 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 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 ) 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} ) target_link_libraries( types_test eos_types fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define KEY_PREFIX "EOS" #define KEY_PREFIX "EOS"
namespace eos { namespace eos { namespace types {
PublicKey::PublicKey():key_data(){}; PublicKey::PublicKey():key_data(){};
...@@ -70,19 +70,19 @@ namespace eos { ...@@ -70,19 +70,19 @@ namespace eos {
return p1.key_data < p2.key_data; return p1.key_data < p2.key_data;
}; };
} // eos }} // eos::types
namespace fc namespace fc
{ {
using namespace std; 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); 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 } // fc
#include <eos/types/TypeParser.hpp> #include <eos/types/TypeParser.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/range.hpp>
#include <algorithm>
#include <iostream> #include <iostream>
namespace eos { namespace eos { namespace types {
void AbstractSymbolTable::parse( std::istream& in ) { namespace alg = boost::algorithm;
vector<string> line_tokens;
bool AbstractSymbolTable::isValidTypeName(const TypeName& name, bool allowArray) {
bool in_struct = false; std::string mutable_name = name;
Struct current; if (name.size() == 0 || !std::isupper(mutable_name[0])) return false;
auto finishStruct = [&](){ // If appropriate, remove trailing []
FC_ASSERT( current.fields.size() > 0, "A struct must specify at least one field" ); if (allowArray && alg::ends_with(mutable_name, "[]"))
this->addType( current ); mutable_name.resize(mutable_name.size() - 2);
current.fields.clear();
current.base = TypeName(); return alg::all_of(mutable_name, alg::is_alnum());
in_struct = false; }
};
void AbstractSymbolTable::parse(std::istream& in) {
int linenum = -1; vector<string> line_tokens;
for( string line; std::getline(in, line); ) {
++linenum; bool in_struct = false;
if( !line.size() ) continue; Struct current;
line = line.substr( 0, line.find( '#' ) );
line = fc::trim(line); auto finishStruct = [&](){
if( !line.size() ) continue; FC_ASSERT(current.fields.size() > 0, "A struct must specify at least one field");
std::cerr << line << "\n"; this->addType(current);
current.fields.clear();
line_tokens.clear(); current.base = TypeName();
split( line_tokens, line, boost::is_any_of( " \t" ), boost::token_compress_on ); in_struct = false;
};
if( !line_tokens.size() ) continue;
if( line_tokens[0] == "struct" ) { int linenum = -1;
if( in_struct ) finishStruct(); for(string line; std::getline(in, line);) {
in_struct = true; ++linenum;
FC_ASSERT( line_tokens.size() >= 2, "Expected a struct name" ); if(!line.size()) continue;
current.name = line_tokens[1]; line = line.substr(0, line.find('#'));
if( line_tokens.size() > 2 ) { line = fc::trim(line);
FC_ASSERT( line_tokens.size() == 4, "Expected a struct name" ); if(!line.size()) continue;
FC_ASSERT( line_tokens[2] == "inherits" ); std::cerr << line << "\n";
current.base = line_tokens[3];
} line_tokens.clear();
} else if( line_tokens[0] == "typedef" ) { split(line_tokens, line, boost::is_any_of(" \t"), boost::token_compress_on);
if( in_struct ) finishStruct();
FC_ASSERT( line_tokens.size() == 3, "Expected a struct name" ); if(!line_tokens.size()) continue;
this->addTypeDef( line_tokens[1], line_tokens[2] ); if(line_tokens[0] == "struct") {
} else if( in_struct ) { // parse field if(in_struct) finishStruct();
idump((line_tokens)); in_struct = true;
FC_ASSERT( line_tokens.size() == 2, "a field must be two tokens long" ); FC_ASSERT(line_tokens.size() >= 2, "Expected a struct name");
const auto& name = line_tokens[0]; current.name = line_tokens[1];
const auto& type = line_tokens[1]; if(line_tokens.size() > 2) {
FC_ASSERT( name.size() > 0 ); FC_ASSERT(line_tokens.size() == 4, "Expected a struct name");
current.fields.emplace_back( Field{name,type} ); FC_ASSERT(line_tokens[2] == "inherits");
current.base = line_tokens[3];
} }
else } else if(line_tokens[0] == "typedef") {
FC_ASSERT( false, "Invalid token ${t} on line ${n}", ("t",line_tokens[0])("n",linenum) ); 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
...@@ -3,19 +3,19 @@ ...@@ -3,19 +3,19 @@
#include <eos/types/native.hpp> #include <eos/types/native.hpp>
/// eos with 8 digits of precision /// 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 /// Defined to be largest power of 10 that fits in 53 bits of precision
#define EOS_MAX_SHARE_SUPPLY int64_t(1000000000000000ll) #define EOS_MAX_SHARE_SUPPLY int64_t(1000000000000000ll)
namespace eos { namespace eos { namespace types {
using AssetSymbol = uint64_t; using AssetSymbol = uint64_t;
using ShareType = Int64; using ShareType = Int64;
struct Asset struct Asset
{ {
Asset( ShareType a = 0, AssetSymbol id = EOS_SYMBOL ) Asset(ShareType a = 0, AssetSymbol id = EOS_SYMBOL)
:amount(a),symbol(id){} :amount(a),symbol(id){}
ShareType amount; ShareType amount;
...@@ -28,49 +28,49 @@ namespace eos { ...@@ -28,49 +28,49 @@ namespace eos {
int64_t precision()const; int64_t precision()const;
void set_decimals(uint8_t d); void set_decimals(uint8_t d);
static Asset fromString( const String& from ); static Asset fromString(const String& from);
String toString()const; 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; amount += o.amount;
return *this; 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; amount -= o.amount;
return *this; 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); 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) || (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 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 ) { friend Asset operator - (const Asset& a, const Asset& b) {
FC_ASSERT( a.symbol == b.symbol ); FC_ASSERT(a.symbol == b.symbol);
return Asset( a.amount - b.amount, a.symbol ); return Asset(a.amount - b.amount, a.symbol);
} }
friend Asset operator + ( const Asset& a, const Asset& b ) { friend Asset operator + (const Asset& a, const Asset& b) {
FC_ASSERT( a.symbol == b.symbol ); FC_ASSERT(a.symbol == b.symbol);
return Asset( a.amount + b.amount, a.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 { ...@@ -82,11 +82,11 @@ namespace eos {
Price(const Asset& base = Asset(), const Asset quote = Asset()) Price(const Asset& base = Asset(), const Asset quote = Asset())
:base(base),quote(quote){} :base(base),quote(quote){}
static Price max(AssetSymbol base, AssetSymbol quote ); static Price max(AssetSymbol base, AssetSymbol quote);
static Price min(AssetSymbol base, AssetSymbol quote ); static Price min(AssetSymbol base, AssetSymbol quote);
Price max()const { return Price::max( base.symbol, quote.symbol ); } Price max()const { return Price::max(base.symbol, quote.symbol); }
Price min()const { return Price::min( 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(); } double to_real()const { return base.to_real() / quote.to_real(); }
...@@ -94,26 +94,28 @@ namespace eos { ...@@ -94,26 +94,28 @@ namespace eos {
void validate()const; void validate()const;
}; };
Price operator / ( const Asset& base, const Asset& quote ); Price operator / (const Asset& base, const Asset& quote);
inline Price operator~( const Price& p ) { return Price{p.quote,p.base}; } 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 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);
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 ); Asset operator * (const Asset& a, const Price& b);
} // namespace eos }} // namespace eos::types
namespace fc { namespace fc {
inline void to_variant( const eos::Asset& var, fc::variant& vo ) { vo = var.toString(); } inline void to_variant(const eos::types::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 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::types::Asset, (amount)(symbol))
FC_REFLECT( eos::Price, (base)(quote) ) FC_REFLECT(eos::types::Price, (base)(quote))
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <fc/reflect/reflect.hpp> #include <fc/reflect/reflect.hpp>
#include <fc/reflect/variant.hpp> #include <fc/reflect/variant.hpp>
namespace eos { namespace eos { namespace types {
struct PublicKey struct PublicKey
{ {
struct BinaryKey struct BinaryKey
...@@ -14,9 +14,9 @@ namespace eos { ...@@ -14,9 +14,9 @@ namespace eos {
}; };
fc::ecc::public_key_data key_data; fc::ecc::public_key_data key_data;
PublicKey(); PublicKey();
PublicKey( const fc::ecc::public_key_data& data ); PublicKey(const fc::ecc::public_key_data& data);
PublicKey( const fc::ecc::public_key& pubkey ); PublicKey(const fc::ecc::public_key& pubkey);
explicit PublicKey( const std::string& base58str ); explicit PublicKey(const std::string& base58str);
operator fc::ecc::public_key_data() const; operator fc::ecc::public_key_data() const;
operator fc::ecc::public_key() const; operator fc::ecc::public_key() const;
explicit operator std::string() const; explicit operator std::string() const;
...@@ -24,15 +24,15 @@ namespace eos { ...@@ -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); 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 namespace fc
{ {
void to_variant( const eos::PublicKey& var, fc::variant& vo ); void to_variant(const eos::types::PublicKey& var, fc::variant& vo);
void from_variant( const fc::variant& var, eos::PublicKey& vo ); void from_variant(const fc::variant& var, eos::types::PublicKey& vo);
} }
FC_REFLECT( eos::PublicKey, (key_data) ) FC_REFLECT(eos::types::PublicKey, (key_data))
FC_REFLECT( eos::PublicKey::BinaryKey, (data)(check) ) FC_REFLECT(eos::types::PublicKey::BinaryKey, (data)(check))
...@@ -9,103 +9,60 @@ ...@@ -9,103 +9,60 @@
#include <fc/reflect/variant.hpp> #include <fc/reflect/variant.hpp>
#include <eos/types/native.hpp> #include <eos/types/native.hpp>
#include <eos/types/exceptions.hpp>
namespace eos {
using std::map; namespace eos { namespace types {
using std::set; using std::map;
using std::string; using std::set;
using std::vector; using std::string;
using std::vector;
class AbstractSymbolTable {
public: class AbstractSymbolTable {
virtual ~AbstractSymbolTable(){}; public:
virtual void addType( const Struct& s ) =0; virtual ~AbstractSymbolTable(){}
virtual void addTypeDef( const TypeName& from, const TypeName& to ) = 0; virtual void addType(const Struct& s) =0;
virtual bool isKnownType( const TypeName& name ) = 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 bool isValidTypeName(const TypeName& name, bool allowArray = false);
virtual Struct getType( TypeName name )const = 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 ); * Parses the input stream and populatse the symbol table, the table may be pre-populated
*/
string binaryToJson( const TypeName& type, const Bytes& binary ); void parse(std::istream& in);
Bytes jsonToBinary( const TypeName& type, const string& json );
}; string binaryToJson(const TypeName& type, const Bytes& binary);
Bytes jsonToBinary(const TypeName& type, const string& json);
};
class SimpleSymbolTable : public AbstractSymbolTable {
public:
SimpleSymbolTable(): class SimpleSymbolTable : public AbstractSymbolTable {
known( { "Field", "Struct", "Asset", "FixedString16", "FixedString32", public:
"UInt8", "UInt16", "UInt32", "UInt64", SimpleSymbolTable():
"UInt128", "Checksum", "UInt256", "UInt512", known({ "Field", "Struct", "Asset", "FixedString16", "FixedString32",
"Int8", "Int16", "Int32", "Int64", "UInt8", "UInt16", "UInt32", "UInt64",
"Int128", "Int224", "Int256", "Int512", "UInt128", "Checksum", "UInt256", "UInt512",
"Bytes", "PublicKey", "Signature", "String", "Time" } ) "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 ) ); virtual void addType(const Struct& s) override;
for( const auto& f : s.fields ) { virtual void addTypeDef(const TypeName& from, const TypeName& to) override;
FC_ASSERT( isKnownType( f.type ), "", ("type",f.type) ); virtual bool isKnownType(const TypeName& n) override;
} virtual Struct getType(TypeName name)const override;
structs[s.name] = s; virtual TypeName resolveTypedef(TypeName name)const override;
order.push_back(s.name);
// wdump((s.name)(s.base)(s.fields));
} FC_CAPTURE_AND_RETHROW( (s) ) } // private:
set<TypeName> known;
virtual void addTypeDef( const TypeName& from, const TypeName& to ) override { try { vector<TypeName> order;
FC_ASSERT( !isKnownType( to ) ); map<TypeName, TypeName> typedefs;
FC_ASSERT( isKnownType( from ) ); map<TypeName, Struct> structs;
typedefs[to] = from; };
order.push_back(to);
} FC_CAPTURE_AND_RETHROW( (from)(to) ) } }} // namespace eos::types
virtual bool isKnownType( const TypeName& n ) override { try { FC_REFLECT(eos::types::SimpleSymbolTable, (typedefs)(structs))
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<TypeName> known;
vector<TypeName> order;
map<TypeName, TypeName> typedefs;
map<TypeName, Struct> structs;
};
} // namespace eos
FC_REFLECT( eos::SimpleSymbolTable, (typedefs)(structs) )
#pragma once #pragma once
#include <fc/io/datastream.hpp> #include <fc/io/datastream.hpp>
namespace EOS { namespace eos { namespace types {
using fc::datastream; using fc::datastream;
struct InputDatastream { struct InputDatastream {
...@@ -78,4 +78,4 @@ namespace EOS { ...@@ -78,4 +78,4 @@ namespace EOS {
uint32_t tellp()const { return ds.tellp(); } uint32_t tellp()const { return ds.tellp(); }
}; };
} // namespace EOS }} // namespace eos::types
#pragma once #pragma once
#include <eos/types/native.hpp> #include <eos/types/native.hpp>
namespace EOS { namespace eos { namespace types {
class InputDatastream; class InputDatastream;
class OutputDatastream; class OutputDatastream;
...@@ -66,4 +66,4 @@ namespace EOS { ...@@ -66,4 +66,4 @@ namespace EOS {
}; };
} /// namespace EOS }} /// namespace eos::types
/*
* 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 <fc/exception/exception.hpp>
#include <eos/utilities/exception_macros.hpp>
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
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <fc/reflect/reflect.hpp> #include <fc/reflect/reflect.hpp>
namespace eos { namespace eos { namespace types {
using namespace boost::multiprecision; using namespace boost::multiprecision;
template<typename... T> template<typename... T>
...@@ -95,26 +95,26 @@ namespace eos { ...@@ -95,26 +95,26 @@ namespace eos {
/// TODO: make sure this works with FC raw /// TODO: make sure this works with FC raw
template<typename Stream, typename Number> template<typename Stream, typename Number>
void fromBinary( Stream& st, boost::multiprecision::number<Number>& value ) { void fromBinary(Stream& st, boost::multiprecision::number<Number>& value) {
unsigned char data[(std::numeric_limits<decltype(value)>::digits+1)/8]; unsigned char data[(std::numeric_limits<decltype(value)>::digits+1)/8];
st.read( (char*)data, sizeof(data) ); st.read((char*)data, sizeof(data));
boost::multiprecision::import_bits( value, data, data + sizeof(data), 1 ); boost::multiprecision::import_bits(value, data, data + sizeof(data), 1);
} }
template<typename Stream, typename Number> template<typename Stream, typename Number>
void toBinary( Stream& st, const boost::multiprecision::number<Number>& value ) { void toBinary(Stream& st, const boost::multiprecision::number<Number>& value) {
unsigned char data[(std::numeric_limits<decltype(value)>::digits+1)/8]; unsigned char data[(std::numeric_limits<decltype(value)>::digits+1)/8];
boost::multiprecision::export_bits( value, data, 1 ); boost::multiprecision::export_bits(value, data, 1);
st.write( (const char*)data, sizeof(data) ); st.write((const char*)data, sizeof(data));
} }
} // namespace eos }} // namespace eos::types
namespace fc { namespace fc {
void to_variant( const std::vector<eos::Field>& c, fc::variant& v ); void to_variant(const std::vector<eos::types::Field>& c, fc::variant& v);
void from_variant( const fc::variant& v, std::vector<eos::Field>& check ); void from_variant(const fc::variant& v, std::vector<eos::types::Field>& check);
void to_variant( const std::map<std::string,eos::Struct>& c, fc::variant& v ); void to_variant(const std::map<std::string,eos::types::Struct>& c, fc::variant& v);
void from_variant( const fc::variant& v, std::map<std::string,eos::Struct>& check ); void from_variant(const fc::variant& v, std::map<std::string,eos::types::Struct>& check);
} }
FC_REFLECT( eos::Field, (name)(type) ) FC_REFLECT(eos::types::Field, (name)(type))
FC_REFLECT( eos::Struct, (name)(base)(fields) ) FC_REFLECT(eos::types::Struct, (name)(base)(fields))
#pragma once #pragma once
namespace EOS { namespace eos { namespace types {
template<typename T> template<typename T>
fc::variant toVariant( const vector<T>& a ) { fc::variant toVariant( const vector<T>& a ) {
vector<fc::variant> result; vector<fc::variant> result;
...@@ -41,4 +41,4 @@ namespace EOS { ...@@ -41,4 +41,4 @@ namespace EOS {
EOS::fromBinary( ds, result ); EOS::fromBinary( ds, result );
return result; return result;
} }
} }} // namespace eos::types
...@@ -6,39 +6,39 @@ ...@@ -6,39 +6,39 @@
#include <fc/reflect/variant.hpp> #include <fc/reflect/variant.hpp>
namespace fc { namespace fc {
void to_variant( const std::vector<eos::Field>& c, fc::variant& v ) { void to_variant(const std::vector<eos::types::Field>& c, fc::variant& v) {
fc::mutable_variant_object mvo; mvo.reserve( c.size() ); fc::mutable_variant_object mvo; mvo.reserve(c.size());
for( const auto& f : c ) { for(const auto& f : c) {
mvo.set( f.name, eos::String(f.type) ); mvo.set(f.name, eos::types::String(f.type));
} }
v = std::move(mvo); v = std::move(mvo);
} }
void from_variant( const fc::variant& v, std::vector<eos::Field>& fields ) { void from_variant(const fc::variant& v, std::vector<eos::types::Field>& fields) {
const auto& obj = v.get_object(); const auto& obj = v.get_object();
fields.reserve( obj.size() ); fields.reserve(obj.size());
for( const auto& f : obj ) for(const auto& f : obj)
fields.emplace_back( eos::Field{ f.key(), f.value().get_string() } ); fields.emplace_back(eos::types::Field{ f.key(), f.value().get_string() });
} }
void to_variant( const std::map<std::string,eos::Struct>& c, fc::variant& v ) void to_variant(const std::map<std::string,eos::types::Struct>& c, fc::variant& v)
{ {
fc::mutable_variant_object mvo; mvo.reserve( c.size() ); fc::mutable_variant_object mvo; mvo.reserve(c.size());
for( const auto& item : c ) { for(const auto& item : c) {
if( item.second.base.size() ) if(item.second.base.size())
mvo.set( item.first, fc::mutable_variant_object("base",item.second.base)("fields",item.second.fields) ); mvo.set(item.first, fc::mutable_variant_object("base",item.second.base)("fields",item.second.fields));
else 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); v = std::move(mvo);
} }
void from_variant( const fc::variant& v, std::map<std::string,eos::Struct>& structs ) { void from_variant(const fc::variant& v, std::map<std::string,eos::types::Struct>& structs) {
const auto& obj = v.get_object(); const auto& obj = v.get_object();
structs.clear(); structs.clear();
for( const auto& f : obj ) { for(const auto& f : obj) {
auto& stru = structs[f.key()]; auto& stru = structs[f.key()];
if( f.value().get_object().contains( "fields" ) ) if(f.value().get_object().contains("fields"))
fc::from_variant( f.value().get_object()["fields"], stru.fields ); fc::from_variant(f.value().get_object()["fields"], stru.fields);
if( f.value().get_object().contains( "base" ) ) if(f.value().get_object().contains("base"))
fc::from_variant( f.value().get_object()["base"], stru.base ); fc::from_variant(f.value().get_object()["base"], stru.base);
stru.name = f.key(); stru.name = f.key();
} }
} }
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
int main( int argc, char** argv ) { int main( int argc, char** argv ) {
try { try {
eos::Message m; eos::types::Message m;
m.sender = eos::AccountName( "ned" ); m.sender = eos::types::AccountName( "ned" );
m.recipient = eos::AccountName( "dan" ); m.recipient = eos::types::AccountName( "dan" );
idump( (m) ); idump( (m) );
eos::Transfer t; eos::types::Transfer t;
t.from = m.sender; t.from = m.sender;
t.to = "other"; t.to = "other";
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <fc/io/json.hpp> #include <fc/io/json.hpp>
using std::string; using std::string;
namespace eos { using types::SimpleSymbolTable; }
bool isVector( const string& type ) { bool isVector( const string& type ) {
...@@ -60,7 +61,7 @@ string call_type_constructor( const string& type ) { ...@@ -60,7 +61,7 @@ string call_type_constructor( const string& type ) {
return "Vector[" + getWrenType(type) + "]"; return "Vector[" + getWrenType(type) + "]";
return getWrenType(type) + ".new()"; 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; std::stringstream ss;
ss << "class " << s.name; ss << "class " << s.name;
...@@ -98,15 +99,15 @@ string generate_wren( const eos::Struct& s, eos::SimpleSymbolTable& symbols ) { ...@@ -98,15 +99,15 @@ string generate_wren( const eos::Struct& s, eos::SimpleSymbolTable& symbols ) {
return ss.str(); 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 ) //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)); wdump((outfile));
std::ofstream out(outfile); std::ofstream out(outfile);
out << "#pragma once\n"; out << "#pragma once\n";
out << "namespace eos { \n"; out << "namespace eos { namespace types {\n";
for( const auto& s : ss.order ) { for( const auto& s : ss.order ) {
if( ss.typedefs.find( s ) != ss.typedefs.end() ) { if( ss.typedefs.find( s ) != ss.typedefs.end() ) {
const auto& td = ss.typedefs[s]; const auto& td = ss.typedefs[s];
...@@ -141,7 +142,7 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) { ...@@ -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 ) { for( const auto& s : ss.order ) {
if( ss.typedefs.find( s ) != ss.typedefs.end() ) { if( ss.typedefs.find( s ) != ss.typedefs.end() ) {
...@@ -150,9 +151,9 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) { ...@@ -150,9 +151,9 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) {
const auto& st = ss.structs[s]; const auto& st = ss.structs[s];
if( st.base.size() ) { 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 { } else {
out << "FC_REFLECT( eos::" << std::setw(33) << s << ", "; out << "FC_REFLECT( eos::types::" << std::setw(33) << s << ", ";
} }
for( const auto& f : st.fields ) { for( const auto& f : st.fields ) {
out <<"("<<f.name<<")"; out <<"("<<f.name<<")";
...@@ -162,7 +163,7 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) { ...@@ -162,7 +163,7 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) {
} }
int count_fields( eos::SimpleSymbolTable& ss, const eos::Struct& st ) { int count_fields( eos::types::SimpleSymbolTable& ss, const eos::types::Struct& st ) {
if( st.base.size() ) if( st.base.size() )
return st.fields.size() + count_fields( ss, ss.getType( st.base ) ); return st.fields.size() + count_fields( ss, ss.getType( st.base ) );
return st.fields.size(); return st.fields.size();
...@@ -173,7 +174,7 @@ int main( int argc, char** argv ) { ...@@ -173,7 +174,7 @@ int main( int argc, char** argv ) {
FC_ASSERT( argc > 2, "Usage: ${program} input path/to/out.hpp", ("program",string(argv[0])) ); FC_ASSERT( argc > 2, "Usage: ${program} input path/to/out.hpp", ("program",string(argv[0])) );
std::ifstream in(argv[1]); std::ifstream in(argv[1]);
eos::SimpleSymbolTable ss; eos::types::SimpleSymbolTable ss;
ss.parse(in); ss.parse(in);
auto as_json = fc::json::to_pretty_string( ss ); auto as_json = fc::json::to_pretty_string( ss );
......
#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() ) ); }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace eos { namespace eos {
using namespace chain; using namespace chain;
using namespace types;
class native_system_contract_plugin_impl { class native_system_contract_plugin_impl {
public: public:
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
using namespace eos; using namespace eos;
using namespace chain; using namespace chain;
using namespace types;
BOOST_AUTO_TEST_SUITE(block_tests) BOOST_AUTO_TEST_SUITE(block_tests)
...@@ -154,7 +155,7 @@ BOOST_FIXTURE_TEST_CASE(create_script, testing_fixture) ...@@ -154,7 +155,7 @@ BOOST_FIXTURE_TEST_CASE(create_script, testing_fixture)
const auto& processor = db.get<account_object,by_name>("init1"); const auto& processor = db.get<account_object,by_name>("init1");
const auto& recipient = db.get<account_object,by_name>("sys"); const auto& recipient = db.get<account_object,by_name>("sys");
const auto& world = db.get<key_value_object,by_scope_key>( boost::make_tuple( AccountName("init1"), eos::String("hello") ) ); const auto& world = db.get<key_value_object,by_scope_key>(boost::make_tuple(AccountName("init1"), String("hello")));
BOOST_CHECK_EQUAL( string(world.value.c_str()), "world" ); BOOST_CHECK_EQUAL( string(world.value.c_str()), "world" );
} FC_LOG_AND_RETHROW() } } FC_LOG_AND_RETHROW() }
......
#include <eos/types/TypeParser.hpp>
#include <boost/test/unit_test.hpp>
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册