diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b62e3b..0acb9f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ SET (ORIGINAL_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) SET(BOOST_COMPONENTS) LIST(APPEND BOOST_COMPONENTS thread date_time filesystem system program_options chrono unit_test_framework context iostreams regex) +# boost::endian is also required, but FindBoost can't handle header-only libs SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) # Configure secp256k1-zkp diff --git a/include/fc/bloom_filter.hpp b/include/fc/bloom_filter.hpp index 3728d9c..a52f2da 100644 --- a/include/fc/bloom_filter.hpp +++ b/include/fc/bloom_filter.hpp @@ -617,11 +617,6 @@ inline bloom_filter operator ^ (const bloom_filter& a, const bloom_filter& b) } // namespace fc - -FC_REFLECT( fc::bloom_filter, (salt_)(bit_table_)(salt_count_)(table_size_)(raw_table_size_)(projected_element_count_)(inserted_element_count_)(random_seed_)(desired_false_positive_probability_) ) -FC_REFLECT( fc::bloom_parameters::optimal_parameters_t, (number_of_hashes)(table_size) ) -FC_REFLECT( fc::bloom_parameters, (minimum_size)(maximum_size)(minimum_number_of_hashes)(maximum_number_of_hashes)(projected_element_count)(false_positive_probability)(random_seed)(optimal_parameters) ) - /* Note 1: If it can be guaranteed that bits_per_char will be of the form 2^n then diff --git a/include/fc/io/datastream.hpp b/include/fc/io/datastream.hpp index 75a4269..0bf36a1 100644 --- a/include/fc/io/datastream.hpp +++ b/include/fc/io/datastream.hpp @@ -89,94 +89,5 @@ class datastream { size_t _size; }; -template -inline datastream& operator<<(datastream& ds, const int32_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator>>(datastream& ds, int32_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const uint32_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, uint32_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const int64_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, int64_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const uint64_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, uint64_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const int16_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, int16_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const uint16_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, uint16_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const int8_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, int8_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} -template -inline datastream& operator<<(datastream& ds, const uint8_t& d) { - ds.write( (const char*)&d, sizeof(d) ); - return ds; -} - -template -inline datastream& operator>>(datastream& ds, uint8_t& d) { - ds.read((char*)&d, sizeof(d) ); - return ds; -} - - } // namespace fc diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 052110c..9d9dd35 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -89,72 +90,66 @@ namespace fc { template inline void pack( Stream& s, const fc::time_point_sec& tp, uint32_t _max_depth ) { - uint32_t usec = tp.sec_since_epoch(); - s.write( (const char*)&usec, sizeof(usec) ); + pack( s, tp.sec_since_epoch(), _max_depth ); } template inline void unpack( Stream& s, fc::time_point_sec& tp, uint32_t _max_depth ) { try { uint32_t sec; - s.read( (char*)&sec, sizeof(sec) ); + unpack( s, sec, _max_depth ); tp = fc::time_point() + fc::seconds(sec); } FC_RETHROW_EXCEPTIONS( warn, "" ) } template inline void pack( Stream& s, const fc::time_point& tp, uint32_t _max_depth ) { - uint64_t usec = tp.time_since_epoch().count(); - s.write( (const char*)&usec, sizeof(usec) ); + pack( s, tp.time_since_epoch().count(), _max_depth ); } template inline void unpack( Stream& s, fc::time_point& tp, uint32_t _max_depth ) { try { uint64_t usec; - s.read( (char*)&usec, sizeof(usec) ); + unpack( s, usec, _max_depth ); tp = fc::time_point() + fc::microseconds(usec); } FC_RETHROW_EXCEPTIONS( warn, "" ) } template inline void pack( Stream& s, const fc::microseconds& usec, uint32_t _max_depth ) { - uint64_t usec_as_int64 = usec.count(); - s.write( (const char*)&usec_as_int64, sizeof(usec_as_int64) ); + pack( s, usec.count(), _max_depth ); } template inline void unpack( Stream& s, fc::microseconds& usec, uint32_t _max_depth ) { try { uint64_t usec_as_int64; - s.read( (char*)&usec_as_int64, sizeof(usec_as_int64) ); + unpack( s, usec_as_int64, _max_depth ); usec = fc::microseconds(usec_as_int64); } FC_RETHROW_EXCEPTIONS( warn, "" ) } template - inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth ) { - s.write((const char*)&v.data[0],N*sizeof(T)); + inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth ) = delete; + template + inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth ) { + s.write( &v.data[0], N ); } - - template - inline void pack( Stream& s, const std::shared_ptr& v, uint32_t _max_depth ) - { - FC_ASSERT( _max_depth > 0 ); - fc::raw::pack( s, *v, _max_depth - 1 ); - } - - template - inline void pack( Stream& s, const std::shared_ptr& v, uint32_t _max_depth ) - { - FC_ASSERT( _max_depth > 0 ); - fc::raw::pack( s, *v, _max_depth - 1 ); + template + inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth ) { + s.write( (char*)&v.data[0], N ); } template - inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth ) - { try { - s.read((char*)&v.data[0],N*sizeof(T)); - } FC_RETHROW_EXCEPTIONS( warn, "fc::array", ("type",fc::get_typename::name())("length",N) ) } + inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth ) = delete; + template + inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth ) { try { + s.read( &v.data[0], N ); + } FC_RETHROW_EXCEPTIONS( warn, "fc::array", ("length",N) ) } + template + inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth ) { try { + s.read( (char*)&v.data[0], N ); + } FC_RETHROW_EXCEPTIONS( warn, "fc::array", ("length",N) ) } template inline void unpack( Stream& s, std::shared_ptr& v, uint32_t _max_depth ) @@ -162,7 +157,14 @@ namespace fc { FC_ASSERT( _max_depth > 0 ); v = std::make_shared(); fc::raw::unpack( s, *v, _max_depth - 1 ); - } FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr", ("type",fc::get_typename::name()) ) } + } FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<${type}>", ("type",fc::get_typename::name()) ) } + + template + inline void pack( Stream& s, const std::shared_ptr& v, uint32_t _max_depth ) + { + FC_ASSERT( _max_depth > 0 ); + fc::raw::pack( s, *v, _max_depth - 1 ); + } template inline void unpack( Stream& s, std::shared_ptr& v, uint32_t _max_depth ) @@ -345,12 +347,96 @@ namespace fc { template<> struct if_class { template - static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) { - s.write( (char*)&v, sizeof(v) ); - } + static inline void pack( Stream& s, const T v, uint32_t _max_depth ) = delete; template - static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) { - s.read( (char*)&v, sizeof(v) ); + static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) = delete; + template + static inline void pack( Stream& s, const int64_t v, uint32_t _max_depth ) { + boost::endian::little_int64_buf_t tmp; + tmp = v; + s.write( (char*)&tmp, sizeof(tmp) ); + } + template + static inline void unpack( Stream& s, int64_t& v, uint32_t _max_depth ) { + boost::endian::little_int64_buf_t tmp; + s.read( (char*)&tmp, sizeof(tmp) ); + v = tmp.value(); + } + template + static inline void pack( Stream& s, const uint64_t v, uint32_t _max_depth ) { + boost::endian::little_uint64_buf_t tmp; + tmp = v; + s.write( (char*)&tmp, sizeof(tmp) ); + } + template + static inline void unpack( Stream& s, uint64_t& v, uint32_t _max_depth ) { + boost::endian::little_uint64_buf_t tmp; + s.read( (char*)&tmp, sizeof(tmp) ); + v = tmp.value(); + } + template + static inline void pack( Stream& s, const int32_t v, uint32_t _max_depth ) { + boost::endian::little_int32_buf_t tmp; + tmp = v; + s.write( (char*)&tmp, sizeof(tmp) ); + } + template + static inline void unpack( Stream& s, int32_t& v, uint32_t _max_depth ) { + boost::endian::little_int32_buf_t tmp; + s.read( (char*)&tmp, sizeof(tmp) ); + v = tmp.value(); + } + template + static inline void pack( Stream& s, const uint32_t v, uint32_t _max_depth ) { + boost::endian::little_uint32_buf_t tmp; + tmp = v; + s.write( (char*)&tmp, sizeof(tmp) ); + } + template + static inline void unpack( Stream& s, uint32_t& v, uint32_t _max_depth ) { + boost::endian::little_uint32_buf_t tmp; + s.read( (char*)&tmp, sizeof(tmp) ); + v = tmp.value(); + } + template + static inline void pack( Stream& s, const int16_t v, uint32_t _max_depth ) { + boost::endian::little_int16_buf_t tmp; + tmp = v; + s.write( (char*)&tmp, sizeof(tmp) ); + } + template + static inline void unpack( Stream& s, int16_t& v, uint32_t _max_depth ) { + boost::endian::little_int16_buf_t tmp; + s.read( (char*)&tmp, sizeof(tmp) ); + v = tmp.value(); + } + template + static inline void pack( Stream& s, const uint16_t v, uint32_t _max_depth ) { + boost::endian::little_uint16_buf_t tmp; + tmp = v; + s.write( (char*)&tmp, sizeof(tmp) ); + } + template + static inline void unpack( Stream& s, uint16_t& v, uint32_t _max_depth ) { + boost::endian::little_uint16_buf_t tmp; + s.read( (char*)&tmp, sizeof(tmp) ); + v = tmp.value(); + } + template + static inline void pack( Stream& s, const int8_t v, uint32_t _max_depth ) { + s.write( (char*)&v, 1 ); + } + template + static inline void unpack( Stream& s, int8_t& v, uint32_t _max_depth ) { + s.read( (char*)&v, 1 ); + } + template + static inline void pack( Stream& s, const uint8_t v, uint32_t _max_depth ) { + s.write( (char*)&v, 1 ); + } + template + static inline void unpack( Stream& s, uint8_t& v, uint32_t _max_depth ) { + s.read( (char*)&v, 1 ); } }; diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index 17f2395..c1c1442 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -120,6 +120,10 @@ namespace fc { template inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); template inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH); + template inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH); + template inline void pack( Stream& s, const fc::array& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void unpack( Stream& s, fc::array& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH); template inline void pack( Stream& s, const shared_ptr& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); diff --git a/include/fc/io/raw_variant.hpp b/include/fc/io/raw_variant.hpp index f4a7e02..b9a1bf3 100644 --- a/include/fc/io/raw_variant.hpp +++ b/include/fc/io/raw_variant.hpp @@ -26,7 +26,7 @@ namespace fc { namespace raw { } virtual void handle( const double& v )const { - fc::raw::pack( s, v, max_depth ); + FC_THROW_EXCEPTION( invalid_arg_exception, "Can't pack double!" ); } virtual void handle( const bool& v )const { @@ -86,10 +86,7 @@ namespace fc { namespace raw { } case variant::double_type: { - double val; - raw::unpack( s, val, _max_depth ); - v = val; - return; + FC_THROW_EXCEPTION( invalid_arg_exception, "Can't unpack double!" ); } case variant::bool_type: { diff --git a/include/fc/real128.hpp b/include/fc/real128.hpp index e445ab6..995c006 100644 --- a/include/fc/real128.hpp +++ b/include/fc/real128.hpp @@ -32,6 +32,10 @@ namespace fc { uint64_t to_uint64()const; + template + inline void pack( Stream& s, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { + pack( s, fixed, _max_depth ); + } private: uint128 fixed; }; @@ -43,13 +47,15 @@ namespace fc { { template inline void pack( Stream& s, const real128& value_to_pack, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) - { s.write( (char*)&value_to_pack, sizeof(value_to_pack) ); } + { value_to_pack.pack( s, _max_depth ); } template inline void unpack( Stream& s, real128& value_to_unpack, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) - { s.read( (char*)&value_to_unpack, sizeof(value_to_unpack) ); } + { + uint128_t delegate; + unpack( s, delegate, _max_depth ); + value_to_unpack = fc::real128::from_fixed( delegate ); + } } - - } // namespace fc diff --git a/include/fc/uint128.hpp b/include/fc/uint128.hpp index 9c49bd6..42c8e3d 100644 --- a/include/fc/uint128.hpp +++ b/include/fc/uint128.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef _MSC_VER #pragma warning (push) @@ -127,9 +128,15 @@ namespace fc namespace raw { template - inline void pack( Stream& s, const uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.write( (char*)&u, sizeof(u) ); } + inline void pack( Stream& s, const uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { + pack( s, u.hi, _max_depth ); + pack( s, u.lo, _max_depth ); + } template - inline void unpack( Stream& s, uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.read( (char*)&u, sizeof(u) ); } + inline void unpack( Stream& s, uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { + unpack( s, u.hi, _max_depth ); + unpack( s, u.lo, _max_depth ); + } } size_t city_hash_size_t(const char *buf, size_t len); @@ -140,10 +147,7 @@ namespace std template<> struct hash { - size_t operator()( const fc::uint128& s )const - { - return fc::city_hash_size_t((char*)&s, sizeof(s)); - } + size_t operator()( const fc::uint128& s )const; }; } diff --git a/src/byteswap.hpp b/src/byteswap.hpp deleted file mode 100644 index e75b8e3..0000000 --- a/src/byteswap.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef _WIN32 -# include -# define bswap_64(x) _byteswap_uint64(x) -#elif defined(__APPLE__) -# include -# define bswap_64(x) OSSwapInt64(x) -#else -# include -#endif diff --git a/src/crypto/bigint.cpp b/src/crypto/bigint.cpp index fd5a688..4c0589b 100644 --- a/src/crypto/bigint.cpp +++ b/src/crypto/bigint.cpp @@ -4,7 +4,8 @@ #include #include -#include "../byteswap.hpp" + +#include namespace fc { bigint::bigint( const char* bige, uint32_t l ) { @@ -30,7 +31,8 @@ namespace fc { bigint::bigint(uint64_t value) { - uint64_t big_endian_value = bswap_64(value); + boost::endian::big_uint64_buf_t big_endian_value; + big_endian_value = value; n = BN_bin2bn((const unsigned char*)&big_endian_value, sizeof(big_endian_value), NULL); } @@ -53,9 +55,10 @@ namespace fc { { FC_ASSERT(BN_num_bits(n) <= 63); size_t size = BN_num_bytes(n); - uint64_t abs_value = 0; - BN_bn2bin(n, (unsigned char*)&abs_value + (sizeof(uint64_t) - size)); - return BN_is_negative(n) ? -(int64_t)bswap_64(abs_value) : bswap_64(abs_value); + boost::endian::big_int64_buf_t abs_value; + abs_value = 0; + BN_bn2bin(n, (unsigned char*)&abs_value + (sizeof(abs_value) - size)); + return BN_is_negative(n) ? -abs_value.value() : abs_value.value(); } int64_t bigint::log2()const { return BN_num_bits(n); } diff --git a/src/io/iostream.cpp b/src/io/iostream.cpp index 4c4a0cc..c44fc83 100644 --- a/src/io/iostream.cpp +++ b/src/io/iostream.cpp @@ -264,67 +264,6 @@ namespace fc { return o; } - istream& operator>>( istream& o, double& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, float& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, int64_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, uint64_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, int32_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, uint32_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, int16_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, uint16_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, int8_t& v ) - { - assert(false && "not implemented"); - return o; - } - - istream& operator>>( istream& o, uint8_t& v ) - { - assert(false && "not implemented"); - return o; - } - - char istream::get() { char tmp; diff --git a/src/io/sstream.cpp b/src/io/sstream.cpp index 70977c0..1f9a87e 100644 --- a/src/io/sstream.cpp +++ b/src/io/sstream.cpp @@ -76,31 +76,6 @@ namespace fc { void stringstream::close(){ my->ss.flush(); }; void stringstream::flush(){ my->ss.flush(); }; - /* - istream& stringstream::read( char* buf, size_t len ) { - my->ss.read(buf,len); - return *this; - } - istream& stringstream::read( int64_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( uint64_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( int32_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( uint32_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( int16_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( uint16_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( int8_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( uint8_t& v ) { my->ss >> v; return *this; } - istream& stringstream::read( float& v ) { my->ss >> v; return *this; } - istream& stringstream::read( double& v ) { my->ss >> v; return *this; } - istream& stringstream::read( bool& v ) { my->ss >> v; return *this; } - istream& stringstream::read( char& v ) { my->ss >> v; return *this; } - istream& stringstream::read( std::string& v ) { my->ss >> *reinterpret_cast(&v); return *this; } - - ostream& stringstream::write( const std::string& s) { - my->ss.write( s.c_str(), s.size() ); - return *this; - } - */ - char stringstream::peek() { char c = my->ss.peek(); diff --git a/src/uint128.cpp b/src/uint128.cpp index 5b12a4d..fa5b795 100644 --- a/src/uint128.cpp +++ b/src/uint128.cpp @@ -1,10 +1,10 @@ #include #include #include +#include #include #include -#include "byteswap.hpp" namespace fc { @@ -119,7 +119,9 @@ namespace fc uint128::operator bigint()const { - auto tmp = uint128( bswap_64( hi ), bswap_64( lo ) ); + boost::endian::big_uint64_buf_t tmp[2]; + tmp[0] = hi; + tmp[1] = lo; bigint bi( (char*)&tmp, sizeof(tmp) ); return bi; } @@ -367,6 +369,15 @@ namespace fc } // namespace fc +namespace std { + size_t hash::operator()( const fc::uint128& s )const + { + boost::endian::little_uint64_buf_t tmp[2]; + tmp[0] = s.hi; + tmp[1] = s.lo; + return fc::city_hash_size_t((char*)&tmp, sizeof(tmp)); + } +} /* * Portions of the above code were adapted from the work of Evan Teran. diff --git a/tests/bloom_test.cpp b/tests/bloom_test.cpp index 1ba7e0d..2ea566a 100644 --- a/tests/bloom_test.cpp +++ b/tests/bloom_test.cpp @@ -59,15 +59,7 @@ BOOST_AUTO_TEST_CASE(bloom_test_1) ++count; } } -// wdump((filter)); - auto packed_filter = fc::raw::pack(filter); -// wdump((packed_filter.size())); -// wdump((packed_filter)); - std::stringstream out; -// std::string str = fc::json::to_string(packed_filter); - auto b64 = fc::base64_encode( packed_filter.data(), packed_filter.size() ); - for( uint32_t i = 0; i < b64.size(); i += 1024 ) - out << '"' << b64.substr( i, 1024 ) << "\",\n"; + // FIXME: this doesn't really test anything. } catch ( const fc::exception& e ) {