Updates from BitShares FC #22
36 changed files with 319 additions and 802 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -36,7 +36,7 @@ Release/
|
|||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
*.cmake
|
||||
cmake_install.cmake
|
||||
*.cbp
|
||||
|
||||
libfc.a
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ script:
|
|||
- "tests/api 2>&1 | grep -vE 'callback result 9|remote_calc->add. 4, 5 .: 9|set callback|] \\.$'"
|
||||
- tests/hmac_test 2>&1 | cat
|
||||
- tests/ecc_test README.md 2>&1 | cat
|
||||
- tests/log_test 2>&1 | cat
|
||||
- 'find CMakeFiles/fc.dir -type d | while read d; do gcov -o "$d" "${d/CMakeFiles*.dir/./}"/*.cpp; done >/dev/null'
|
||||
- 'which sonar-scanner && sonar-scanner || true'
|
||||
- ccache -s
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ INCLUDE(GetPrerequisites)
|
|||
INCLUDE( VersionMacros )
|
||||
INCLUDE( SetupTargetMacros )
|
||||
INCLUDE(GetGitRevisionDescription)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
INCLUDE(CheckLibcxxAtomic)
|
||||
|
||||
get_git_head_revision(GIT_REFSPEC FC_GIT_REVISION_SHA)
|
||||
get_git_unix_timestamp(FC_GIT_REVISION_UNIX_TIMESTAMP)
|
||||
|
|
@ -38,6 +40,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
|
||||
|
|
@ -153,7 +156,7 @@ IF( WIN32 )
|
|||
SET(Boost_LIBRARIES ${BOOST_LIBRARIES_TEMP} ${Boost_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
set( PLATFORM_SPECIFIC_LIBS wsock32.lib ws2_32.lib userenv.lib)
|
||||
LIST(APPEND PLATFORM_SPECIFIC_LIBS wsock32.lib ws2_32.lib userenv.lib)
|
||||
# iphlpapi.lib
|
||||
|
||||
ELSE(WIN32)
|
||||
|
|
@ -180,6 +183,9 @@ IF(NOT "$ENV{OPENSSL_ROOT_DIR}" STREQUAL "")
|
|||
message(STATUS "Setting up OpenSSL root and include vars to ${OPENSSL_ROOT_DIR}, ${OPENSSL_INCLUDE_DIR}")
|
||||
ENDIF()
|
||||
|
||||
IF( LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB )
|
||||
LIST( APPEND PLATFORM_SPECIFIC_LIBS atomic )
|
||||
ENDIF( LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB )
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
|
|
@ -377,7 +383,9 @@ target_include_directories(fc
|
|||
IF(NOT WIN32)
|
||||
set(LINK_USR_LOCAL_LIB -L/usr/local/lib)
|
||||
ENDIF()
|
||||
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${editline_libraries} secp256k1 )
|
||||
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES}
|
||||
${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library}
|
||||
${editline_libraries} secp256k1 ${CMAKE_REQUIRED_LIBRARIES} )
|
||||
|
||||
if(MSVC)
|
||||
set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
|
||||
|
|
|
|||
50
CMakeModules/CheckLibcxxAtomic.cmake
Normal file
50
CMakeModules/CheckLibcxxAtomic.cmake
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Taken from https://chromium.googlesource.com/chromium/llvm-project/libcxx/+/refs/heads/master/cmake/Modules/CheckLibcxxAtomic.cmake
|
||||
# Apache License v2.0 with LLVM Exceptions
|
||||
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
|
||||
# Sometimes linking against libatomic is required for atomic ops, if
|
||||
# the platform doesn't support lock-free atomics.
|
||||
|
||||
function(check_cxx_atomics varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
|
||||
if (${LIBCXX_GCC_TOOLCHAIN})
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}")
|
||||
endif()
|
||||
if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
|
||||
endif()
|
||||
if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
|
||||
endif()
|
||||
check_cxx_source_compiles("
|
||||
#include <cstdint>
|
||||
#include <boost/lockfree/queue.hpp>
|
||||
|
||||
boost::lockfree::queue<uint32_t*> q;
|
||||
int main(int, char**) {
|
||||
uint32_t* a;
|
||||
uint32_t* b;
|
||||
q.push(a);
|
||||
q.pop(b);
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction(check_cxx_atomics)
|
||||
|
||||
# Perform the check for 64bit atomics without libatomic.
|
||||
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
|
||||
if(LIBCXX_HAS_ATOMIC_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
if (NOT LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
message(WARNING "Host compiler must support std::atomic!")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Host compiler appears to require libatomic, but cannot find it.")
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
||||
inline uint64_t endian_reverse_u64( uint64_t x )
|
||||
{
|
||||
return (((x >> 0x38) & 0xFF) )
|
||||
| (((x >> 0x30) & 0xFF) << 0x08)
|
||||
| (((x >> 0x28) & 0xFF) << 0x10)
|
||||
| (((x >> 0x20) & 0xFF) << 0x18)
|
||||
| (((x >> 0x18) & 0xFF) << 0x20)
|
||||
| (((x >> 0x10) & 0xFF) << 0x28)
|
||||
| (((x >> 0x08) & 0xFF) << 0x30)
|
||||
| (((x ) & 0xFF) << 0x38)
|
||||
;
|
||||
}
|
||||
|
||||
inline uint32_t endian_reverse_u32( uint32_t x )
|
||||
{
|
||||
return (((x >> 0x18) & 0xFF) )
|
||||
| (((x >> 0x10) & 0xFF) << 0x08)
|
||||
| (((x >> 0x08) & 0xFF) << 0x10)
|
||||
| (((x ) & 0xFF) << 0x18)
|
||||
;
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
#include <fc/reflect/typename.hpp>
|
||||
|
|
@ -68,7 +68,7 @@ class ripemd160
|
|||
friend bool operator > ( const ripemd160& h1, const ripemd160& h2 );
|
||||
friend bool operator < ( const ripemd160& h1, const ripemd160& h2 );
|
||||
|
||||
uint32_t _hash[5];
|
||||
boost::endian::little_uint32_buf_t _hash[5];
|
||||
};
|
||||
|
||||
namespace raw {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
|
@ -64,7 +65,7 @@ class sha1
|
|||
friend bool operator > ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator < ( const sha1& h1, const sha1& h2 );
|
||||
|
||||
uint32_t _hash[5];
|
||||
boost::endian::little_uint32_buf_t _hash[5];
|
||||
};
|
||||
|
||||
namespace raw {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
|
||||
|
|
@ -64,9 +64,8 @@ class sha224
|
|||
friend bool operator >= ( const sha224& h1, const sha224& h2 );
|
||||
friend bool operator > ( const sha224& h1, const sha224& h2 );
|
||||
friend bool operator < ( const sha224& h1, const sha224& h2 );
|
||||
friend std::size_t hash_value( const sha224& v ) { return uint64_t(v._hash[1])<<32 | v._hash[2]; }
|
||||
|
||||
uint32_t _hash[7];
|
||||
boost::endian::little_uint32_buf_t _hash[7];
|
||||
};
|
||||
|
||||
namespace raw {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/platform_independence.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
|
||||
namespace fc
|
||||
|
|
@ -67,34 +68,7 @@ class sha256
|
|||
friend bool operator > ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator < ( const sha256& h1, const sha256& h2 );
|
||||
|
||||
uint32_t pop_count()const
|
||||
{
|
||||
return (uint32_t)(__builtin_popcountll(_hash[0]) +
|
||||
__builtin_popcountll(_hash[1]) +
|
||||
__builtin_popcountll(_hash[2]) +
|
||||
__builtin_popcountll(_hash[3]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Count leading zero bits
|
||||
*/
|
||||
uint16_t clz()const;
|
||||
|
||||
/**
|
||||
* Approximate (log_2(x) + 1) * 2**24.
|
||||
*
|
||||
* Detailed specs:
|
||||
* - Return 0 when x == 0.
|
||||
* - High 8 bits of result simply counts nonzero bits.
|
||||
* - Low 24 bits of result are the 24 bits of input immediately after the most significant 1 in the input.
|
||||
* - If above would require reading beyond the end of the input, zeros are used instead.
|
||||
*/
|
||||
uint32_t approx_log_32()const;
|
||||
|
||||
void set_to_inverse_approx_log_32( uint32_t x );
|
||||
static double inverse_approx_log_32_double( uint32_t x );
|
||||
|
||||
uint64_t _hash[4];
|
||||
boost::endian::little_uint64_buf_t _hash[4];
|
||||
};
|
||||
|
||||
namespace raw {
|
||||
|
|
@ -117,8 +91,6 @@ namespace raw {
|
|||
void to_variant( const sha256& bi, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& v, sha256& bi, uint32_t max_depth );
|
||||
|
||||
uint64_t hash64(const char* buf, size_t len);
|
||||
|
||||
} // fc
|
||||
namespace std
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
|
||||
namespace fc
|
||||
|
|
@ -62,7 +63,7 @@ class sha512
|
|||
friend bool operator > ( const sha512& h1, const sha512& h2 );
|
||||
friend bool operator < ( const sha512& h1, const sha512& h2 );
|
||||
|
||||
uint64_t _hash[8];
|
||||
boost::endian::little_uint64_buf_t _hash[8];
|
||||
};
|
||||
|
||||
namespace raw {
|
||||
|
|
|
|||
|
|
@ -89,94 +89,5 @@ class datastream<size_t> {
|
|||
size_t _size;
|
||||
};
|
||||
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int32_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint32_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int64_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int64_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint64_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint64_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int16_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int16_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint16_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint16_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int8_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int8_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint8_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint8_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,178 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
||||
/**
|
||||
* The purpose of this datastream is to provide a fast, effecient, means
|
||||
* of calculating the amount of data "about to be written" and then
|
||||
* writing it. This means having two modes of operation, "test run" where
|
||||
* you call the entire pack sequence calculating the size, and then
|
||||
* actually packing it after doing a single allocation.
|
||||
*/
|
||||
template<typename T>
|
||||
class datastream {
|
||||
public:
|
||||
datastream( T start, size_t s )
|
||||
:_start(start),_pos(start),_end(start+s){};
|
||||
|
||||
|
||||
inline void skip( size_t s ){ _pos += s; }
|
||||
inline bool read( char* d, size_t s ) {
|
||||
if( size_t(_end - _pos) >= (size_t)s ) {
|
||||
memcpy( d, _pos, s );
|
||||
_pos += s;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool write( const char* d, size_t s ) {
|
||||
if( _end - _pos >= (int32_t)s ) {
|
||||
memcpy( _pos, d, s );
|
||||
_pos += s;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool put(char c) {
|
||||
if( _pos < _end ) {
|
||||
*_pos = c;
|
||||
++_pos;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
}
|
||||
|
||||
inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
|
||||
inline bool get( char& c ) {
|
||||
if( _pos < _end ) {
|
||||
c = *_pos;
|
||||
++_pos;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
}
|
||||
|
||||
T pos()const { return _pos; }
|
||||
inline bool valid()const { return _pos <= _end && _pos >= _start; }
|
||||
inline bool seekp(size_t p) { _pos = _start + p; return _pos <= _end; }
|
||||
inline size_t tellp()const { return _pos - _start; }
|
||||
inline size_t remaining()const { return _end - _pos; }
|
||||
private:
|
||||
T _start;
|
||||
T _pos;
|
||||
T _end;
|
||||
};
|
||||
|
||||
template<>
|
||||
class datastream<size_t> {
|
||||
public:
|
||||
datastream( size_t init_size = 0):_size(init_size){};
|
||||
inline bool skip( size_t s ) { _size += s; return true; }
|
||||
inline bool write( const char* d,size_t s ) { _size += s; return true; }
|
||||
inline bool put(char c) { ++_size; return true; }
|
||||
inline bool valid()const { return true; }
|
||||
inline bool seekp(size_t p) { _size = p; return true; }
|
||||
inline size_t tellp()const { return _size; }
|
||||
inline size_t remaining()const { return 0; }
|
||||
private:
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int32_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint32_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int64_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int64_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint64_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint64_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int16_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int16_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint16_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint16_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int8_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int8_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint8_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint8_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/io/raw_variant.hpp>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
#include <fc/io/datastream.hpp>
|
||||
|
|
@ -89,52 +90,62 @@ namespace fc {
|
|||
template<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream, typename T, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth ) {
|
||||
s.write((const char*)&v.data[0],N*sizeof(T));
|
||||
template<typename Stream, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<char,N>& v, uint32_t _max_depth ) {
|
||||
s.write( &v.data[0], N );
|
||||
}
|
||||
template<typename Stream, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<unsigned char,N>& v, uint32_t _max_depth ) {
|
||||
s.write( (char*)&v.data[0], N );
|
||||
}
|
||||
|
||||
template<typename Stream, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<char,N>& v, uint32_t _max_depth ) { try {
|
||||
s.read( &v.data[0], N );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<char,${length}>", ("length",N) ) }
|
||||
template<typename Stream, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<unsigned char,N>& v, uint32_t _max_depth ) { try {
|
||||
s.read( (char*)&v.data[0], N );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<unsigned char,${length}>", ("length",N) ) }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::shared_ptr<T>& v, uint32_t _max_depth )
|
||||
|
|
@ -143,26 +154,20 @@ namespace fc {
|
|||
fc::raw::pack( s, *v, _max_depth - 1 );
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::shared_ptr<const T>& v, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
fc::raw::pack( s, *v, _max_depth - 1 );
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth )
|
||||
{ try {
|
||||
s.read((char*)&v.data[0],N*sizeof(T));
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::shared_ptr<T>& v, uint32_t _max_depth )
|
||||
{ try {
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
v = std::make_shared<T>();
|
||||
fc::raw::unpack( s, *v, _max_depth - 1 );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) }
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<${type}>", ("type",fc::get_typename<T>::name()) ) }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::shared_ptr<const T>& v, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
fc::raw::pack( s, *v, _max_depth - 1 );
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::shared_ptr<const T>& v, uint32_t _max_depth )
|
||||
|
|
@ -345,12 +350,96 @@ namespace fc {
|
|||
template<>
|
||||
struct if_class<fc::false_type> {
|
||||
template<typename Stream, typename T>
|
||||
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<typename Stream, typename T>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
static inline void pack( Stream& s, const int8_t v, uint32_t _max_depth ) {
|
||||
s.write( (char*)&v, 1 );
|
||||
}
|
||||
template<typename Stream>
|
||||
static inline void unpack( Stream& s, int8_t& v, uint32_t _max_depth ) {
|
||||
s.read( (char*)&v, 1 );
|
||||
}
|
||||
template<typename Stream>
|
||||
static inline void pack( Stream& s, const uint8_t v, uint32_t _max_depth ) {
|
||||
s.write( (char*)&v, 1 );
|
||||
}
|
||||
template<typename Stream>
|
||||
static inline void unpack( Stream& s, uint8_t& v, uint32_t _max_depth ) {
|
||||
s.read( (char*)&v, 1 );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -590,6 +679,18 @@ namespace fc {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
|
||||
void pack( Stream& s, const boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
s.write( v.data(), sizeof(v) );
|
||||
}
|
||||
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
|
||||
void unpack( Stream& s, boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
s.read( v.data(), sizeof(v) );
|
||||
}
|
||||
|
||||
|
||||
template<typename Stream, typename T>
|
||||
|
|
@ -688,7 +789,6 @@ namespace fc {
|
|||
FC_ASSERT( _max_depth > 0 );
|
||||
datastream<const char*> ds( d, s );
|
||||
fc::raw::unpack( ds, v, _max_depth - 1 );
|
||||
return v;
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
template<typename Stream>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <fc/config.hpp>
|
||||
#include <fc/container/flat_fwd.hpp>
|
||||
#include <fc/io/varint.hpp>
|
||||
|
|
@ -117,9 +118,19 @@ namespace fc {
|
|||
template<typename Stream> inline void pack( Stream& s, const char* v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
|
||||
inline void pack( Stream& s, const boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth );
|
||||
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
|
||||
inline void unpack( Stream& s, boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth );
|
||||
|
||||
template<typename Stream, typename T, size_t N> inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, typename T, size_t N> inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth ) = delete;
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth ) = delete;
|
||||
template<typename Stream, size_t N> inline void pack( Stream& s, const fc::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, size_t N> inline void unpack( Stream& s, fc::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
template<typename Stream, size_t N> inline void pack( Stream& s, const fc::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
template<typename Stream, size_t N> inline void unpack( Stream& s, fc::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
|
||||
|
||||
template<typename Stream, typename T> inline void pack( Stream& s, const shared_ptr<T>& v,
|
||||
uint32_t _max_depth=FC_PACK_MAX_DEPTH );
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ namespace fc {
|
|||
|
||||
uint64_t to_uint64()const;
|
||||
|
||||
template<typename Stream>
|
||||
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<typename Stream>
|
||||
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<typename Stream>
|
||||
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
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <fc/config.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/crypto/city.hpp>
|
||||
#include <fc/io/raw.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
|
|
@ -127,9 +128,15 @@ namespace fc
|
|||
namespace raw
|
||||
{
|
||||
template<typename Stream>
|
||||
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<typename Stream>
|
||||
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<fc::uint128>
|
||||
{
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/container/flat_fwd.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
|
||||
#ifdef FC_ASSERT
|
||||
|
|
@ -165,6 +166,19 @@ namespace fc
|
|||
template<typename A, typename B>
|
||||
void from_variant( const variant& v, std::pair<A,B>& p, uint32_t max_depth );
|
||||
|
||||
template<boost::endian::order O, class T, std::size_t N, boost::endian::align A>
|
||||
void to_variant( const boost::endian::endian_buffer<O,T,N,A>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
to_variant( var.value(), vo, max_depth );
|
||||
}
|
||||
template<boost::endian::order O, class T, std::size_t N, boost::endian::align A>
|
||||
void from_variant( const variant& var, boost::endian::endian_buffer<O,T,N,A>& vo, uint32_t max_depth )
|
||||
{
|
||||
T tmp;
|
||||
from_variant( var, tmp, max_depth );
|
||||
vo = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stores null, int64, uint64, double, bool, string, std::vector<variant>,
|
||||
* and variant_object's.
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <stdlib.h>
|
||||
# define bswap_64(x) _byteswap_uint64(x)
|
||||
#elif defined(__APPLE__)
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define bswap_64(x) OSSwapInt64(x)
|
||||
#else
|
||||
# include <byteswap.h>
|
||||
#endif
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include <fc/log/logger.hpp>
|
||||
|
||||
#include <fc/thread/thread.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifndef OPENSSL_THREADS
|
||||
|
|
@ -52,7 +53,10 @@ void aes_encoder::init( const fc::sha256& key, const fc::uint128& init_value )
|
|||
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
|
||||
* IV size for *most* modes is the same as the block size. For AES this
|
||||
* is 128 bits */
|
||||
if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value))
|
||||
boost::endian::little_uint64_buf_t iv[2];
|
||||
iv[0] = init_value.hi;
|
||||
iv[1] = init_value.lo;
|
||||
if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (const unsigned char*)iv[0].data()))
|
||||
{
|
||||
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption init",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
|
|
@ -117,7 +121,10 @@ void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value )
|
|||
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
|
||||
* IV size for *most* modes is the same as the block size. For AES this
|
||||
* is 128 bits */
|
||||
if(1 != EVP_DecryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value))
|
||||
boost::endian::little_uint64_buf_t iv[2];
|
||||
iv[0] = init_value.hi;
|
||||
iv[1] = init_value.lo;
|
||||
if(1 != EVP_DecryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (const unsigned char*)iv[0].data()))
|
||||
{
|
||||
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption init",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
#include <fc/crypto/base64.hpp>
|
||||
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include "../byteswap.hpp"
|
||||
|
||||
#include <boost/endian/buffers.hpp>
|
||||
|
||||
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); }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <fc/crypto/city.hpp>
|
||||
#include <fc/uint128.hpp>
|
||||
#include <fc/array.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
|
||||
#if defined(__SSE4_2__) && defined(__x86_64__)
|
||||
#include <nmmintrin.h>
|
||||
|
|
@ -63,18 +64,6 @@ inline uint64_t Hash128to64(const uint128& x) {
|
|||
return b;
|
||||
}
|
||||
|
||||
static uint64_t UNALIGNED_LOAD64(const char *p) {
|
||||
uint64_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t UNALIGNED_LOAD32(const char *p) {
|
||||
uint32_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
@ -121,14 +110,6 @@ static uint32_t UNALIGNED_LOAD32(const char *p) {
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define uint32_in_expected_order(x) (bswap_32(x))
|
||||
#define uint64_in_expected_order(x) (bswap_64(x))
|
||||
#else
|
||||
#define uint32_in_expected_order(x) (x)
|
||||
#define uint64_in_expected_order(x) (x)
|
||||
#endif
|
||||
|
||||
#if !defined(LIKELY)
|
||||
#if HAVE_BUILTIN_EXPECT
|
||||
#define LIKELY(x) (__builtin_expect(!!(x), 1))
|
||||
|
|
@ -138,11 +119,15 @@ static uint32_t UNALIGNED_LOAD32(const char *p) {
|
|||
#endif
|
||||
|
||||
static uint64_t Fetch64(const char *p) {
|
||||
return uint64_in_expected_order(UNALIGNED_LOAD64(p));
|
||||
boost::endian::little_uint64_buf_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
return result.value();
|
||||
}
|
||||
|
||||
static uint32_t Fetch32(const char *p) {
|
||||
return uint32_in_expected_order(UNALIGNED_LOAD32(p));
|
||||
boost::endian::little_uint32_buf_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
return result.value();
|
||||
}
|
||||
|
||||
// Some primes between 2^63 and 2^64 for various uses.
|
||||
|
|
|
|||
|
|
@ -139,11 +139,11 @@ namespace fc { namespace ecc {
|
|||
|
||||
std::string public_key::to_base58( const public_key_data &key )
|
||||
{
|
||||
uint32_t check = (uint32_t)sha256::hash(key.data, sizeof(key))._hash[0];
|
||||
static_assert(sizeof(key) + sizeof(check) == 37, "Elliptic public key size (or its hash) is incorrect");
|
||||
sha256 check = sha256::hash(key.data, sizeof(key));
|
||||
static_assert(sizeof(key) + 4 == 37, "Elliptic public key size (or its hash) is incorrect");
|
||||
array<char, 37> data;
|
||||
memcpy(data.data, key.begin(), key.size());
|
||||
memcpy(data.begin() + key.size(), (const char*)&check, sizeof(check));
|
||||
memcpy(data.begin() + key.size(), (const char*)check._hash, 4);
|
||||
return fc::to_base58(data.begin(), data.size());
|
||||
}
|
||||
|
||||
|
|
@ -154,8 +154,8 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( s == sizeof(data) );
|
||||
|
||||
public_key_data key;
|
||||
uint32_t check = (uint32_t)sha256::hash(data.data, sizeof(key))._hash[0];
|
||||
FC_ASSERT( memcmp( (char*)&check, data.data + sizeof(key), sizeof(check) ) == 0 );
|
||||
sha256 check = sha256::hash(data.data, sizeof(key));
|
||||
FC_ASSERT( memcmp( (char*)check._hash, data.data + sizeof(key), 4 ) == 0 );
|
||||
memcpy( (char*)key.data, data.data, sizeof(key) );
|
||||
return from_key_data(key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,11 +76,11 @@ ripemd160 operator << ( const ripemd160& h1, uint32_t i ) {
|
|||
}
|
||||
ripemd160 operator ^ ( const ripemd160& h1, const ripemd160& h2 ) {
|
||||
ripemd160 result;
|
||||
result._hash[0] = h1._hash[0] ^ h2._hash[0];
|
||||
result._hash[1] = h1._hash[1] ^ h2._hash[1];
|
||||
result._hash[2] = h1._hash[2] ^ h2._hash[2];
|
||||
result._hash[3] = h1._hash[3] ^ h2._hash[3];
|
||||
result._hash[4] = h1._hash[4] ^ h2._hash[4];
|
||||
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
|
||||
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
|
||||
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
|
||||
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
|
||||
result._hash[4] = h1._hash[4].value() ^ h2._hash[4].value();
|
||||
return result;
|
||||
}
|
||||
bool operator >= ( const ripemd160& h1, const ripemd160& h2 ) {
|
||||
|
|
|
|||
|
|
@ -60,11 +60,11 @@ sha1 operator << ( const sha1& h1, uint32_t i ) {
|
|||
}
|
||||
sha1 operator ^ ( const sha1& h1, const sha1& h2 ) {
|
||||
sha1 result;
|
||||
result._hash[0] = h1._hash[0] ^ h2._hash[0];
|
||||
result._hash[1] = h1._hash[1] ^ h2._hash[1];
|
||||
result._hash[2] = h1._hash[2] ^ h2._hash[2];
|
||||
result._hash[3] = h1._hash[3] ^ h2._hash[3];
|
||||
result._hash[4] = h1._hash[4] ^ h2._hash[4];
|
||||
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
|
||||
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
|
||||
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
|
||||
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
|
||||
result._hash[4] = h1._hash[4].value() ^ h2._hash[4].value();
|
||||
return result;
|
||||
}
|
||||
bool operator >= ( const sha1& h1, const sha1& h2 ) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace fc {
|
|||
sha224 operator ^ ( const sha224& h1, const sha224& h2 ) {
|
||||
sha224 result;
|
||||
for( uint32_t i = 0; i < 7; ++i )
|
||||
result._hash[i] = h1._hash[i] ^ h2._hash[i];
|
||||
result._hash[i] = h1._hash[i].value() ^ h2._hash[i].value();
|
||||
return result;
|
||||
}
|
||||
bool operator >= ( const sha224& h1, const sha224& h2 ) {
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ namespace fc {
|
|||
}
|
||||
sha256 operator ^ ( const sha256& h1, const sha256& h2 ) {
|
||||
sha256 result;
|
||||
result._hash[0] = h1._hash[0] ^ h2._hash[0];
|
||||
result._hash[1] = h1._hash[1] ^ h2._hash[1];
|
||||
result._hash[2] = h1._hash[2] ^ h2._hash[2];
|
||||
result._hash[3] = h1._hash[3] ^ h2._hash[3];
|
||||
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
|
||||
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
|
||||
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
|
||||
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
|
||||
return result;
|
||||
}
|
||||
bool operator >= ( const sha256& h1, const sha256& h2 ) {
|
||||
|
|
@ -99,100 +99,6 @@ namespace fc {
|
|||
return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0;
|
||||
}
|
||||
|
||||
uint32_t sha256::approx_log_32()const
|
||||
{
|
||||
uint16_t lzbits = clz();
|
||||
if( lzbits >= 0x100 )
|
||||
return 0;
|
||||
uint8_t nzbits = 0xFF-lzbits;
|
||||
size_t offset = (size_t) (lzbits >> 3);
|
||||
uint8_t* my_bytes = (uint8_t*) data();
|
||||
size_t n = data_size();
|
||||
uint32_t y = (uint32_t( my_bytes[offset ] ) << 0x18)
|
||||
| (uint32_t(offset+1 < n ? my_bytes[offset+1] : 0) << 0x10)
|
||||
| (uint32_t(offset+2 < n ? my_bytes[offset+2] : 0) << 0x08)
|
||||
| (uint32_t(offset+3 < n ? my_bytes[offset+3] : 0) )
|
||||
;
|
||||
//
|
||||
// lzbits&7 == 7 : 00000001 iff nzbits&7 == 0
|
||||
// lzbits&7 == 6 : 0000001x iff nzbits&7 == 1
|
||||
// lzbits&7 == 5 : 000001xx iff nzbits&7 == 2
|
||||
//
|
||||
y >>= (nzbits & 7);
|
||||
y ^= 1 << 0x18;
|
||||
y |= uint32_t( nzbits ) << 0x18;
|
||||
return y;
|
||||
}
|
||||
|
||||
void sha256::set_to_inverse_approx_log_32( uint32_t x )
|
||||
{
|
||||
uint8_t nzbits = uint8_t( x >> 0x18 );
|
||||
_hash[0] = 0;
|
||||
_hash[1] = 0;
|
||||
_hash[2] = 0;
|
||||
_hash[3] = 0;
|
||||
if( nzbits == 0 )
|
||||
return;
|
||||
uint8_t x0 = uint8_t((x ) & 0xFF);
|
||||
uint8_t x1 = uint8_t((x >> 0x08) & 0xFF);
|
||||
uint8_t x2 = uint8_t((x >> 0x10) & 0xFF);
|
||||
uint8_t* my_bytes = (uint8_t*) data();
|
||||
my_bytes[0x1F] = x0;
|
||||
my_bytes[0x1E] = x1;
|
||||
my_bytes[0x1D] = x2;
|
||||
my_bytes[0x1C] = 1;
|
||||
|
||||
if( nzbits <= 0x18 )
|
||||
{
|
||||
(*this) = (*this) >> (0x18 - nzbits);
|
||||
}
|
||||
else
|
||||
(*this) = (*this) << (nzbits - 0x18);
|
||||
}
|
||||
|
||||
double sha256::inverse_approx_log_32_double( uint32_t x )
|
||||
{
|
||||
uint8_t nzbits = uint8_t( x >> 0x18 );
|
||||
if( nzbits == 0 )
|
||||
return 0.0;
|
||||
uint32_t b = 1 << 0x18;
|
||||
uint32_t y = (x & (b-1)) | b;
|
||||
return std::ldexp( y, int( nzbits ) - 0x18 );
|
||||
}
|
||||
|
||||
uint16_t sha256::clz()const
|
||||
{
|
||||
const uint8_t* my_bytes = (uint8_t*) data();
|
||||
size_t size = data_size();
|
||||
size_t lzbits = 0;
|
||||
static const uint8_t char2lzbits[] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
while( true )
|
||||
{
|
||||
uint8_t c = my_bytes[i];
|
||||
lzbits += char2lzbits[c];
|
||||
if( c != 0 )
|
||||
break;
|
||||
++i;
|
||||
if( i >= size )
|
||||
return 0x100;
|
||||
}
|
||||
|
||||
return lzbits;
|
||||
}
|
||||
|
||||
void to_variant( const sha256& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
|
||||
|
|
@ -205,12 +111,6 @@ namespace fc {
|
|||
memcpy( &bi, ve.data(), std::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
||||
uint64_t hash64(const char* buf, size_t len)
|
||||
{
|
||||
sha256 sha_value = sha256::hash(buf,len);
|
||||
return sha_value._hash[0];
|
||||
}
|
||||
|
||||
template<>
|
||||
unsigned int hmac<sha256>::internal_block_size() const { return 64; }
|
||||
} //end namespace fc
|
||||
|
|
|
|||
|
|
@ -59,14 +59,14 @@ namespace fc {
|
|||
}
|
||||
sha512 operator ^ ( const sha512& h1, const sha512& h2 ) {
|
||||
sha512 result;
|
||||
result._hash[0] = h1._hash[0] ^ h2._hash[0];
|
||||
result._hash[1] = h1._hash[1] ^ h2._hash[1];
|
||||
result._hash[2] = h1._hash[2] ^ h2._hash[2];
|
||||
result._hash[3] = h1._hash[3] ^ h2._hash[3];
|
||||
result._hash[4] = h1._hash[4] ^ h2._hash[4];
|
||||
result._hash[5] = h1._hash[5] ^ h2._hash[5];
|
||||
result._hash[6] = h1._hash[6] ^ h2._hash[6];
|
||||
result._hash[7] = h1._hash[7] ^ h2._hash[7];
|
||||
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
|
||||
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
|
||||
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
|
||||
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
|
||||
result._hash[4] = h1._hash[4].value() ^ h2._hash[4].value();
|
||||
result._hash[5] = h1._hash[5].value() ^ h2._hash[5].value();
|
||||
result._hash[6] = h1._hash[6].value() ^ h2._hash[6].value();
|
||||
result._hash[7] = h1._hash[7].value() ^ h2._hash[7].value();
|
||||
return result;
|
||||
}
|
||||
bool operator >= ( const sha512& h1, const sha512& h2 ) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<std::string*>(&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();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#include <fc/uint128.hpp>
|
||||
#include <fc/variant.hpp>
|
||||
#include <fc/crypto/bigint.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#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<fc::uint128>::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.
|
||||
|
|
|
|||
|
|
@ -23,9 +23,6 @@ target_link_libraries( hmac_test fc )
|
|||
add_executable( ecc_test crypto/ecc_test.cpp )
|
||||
target_link_libraries( ecc_test fc )
|
||||
|
||||
add_executable( log_test crypto/log_test.cpp )
|
||||
target_link_libraries( log_test fc )
|
||||
|
||||
#add_executable( test_aes aes_test.cpp )
|
||||
#target_link_libraries( test_aes fc ${rt_library} ${pthread_library} )
|
||||
#add_executable( test_sleep sleep.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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,114 +0,0 @@
|
|||
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
uint64_t endian_reverse( uint64_t x )
|
||||
{
|
||||
uint64_t x0 = ((x ) & 0xFF);
|
||||
uint64_t x1 = ((x >> 0x08) & 0xFF);
|
||||
uint64_t x2 = ((x >> 0x10) & 0xFF);
|
||||
uint64_t x3 = ((x >> 0x18) & 0xFF);
|
||||
uint64_t x4 = ((x >> 0x20) & 0xFF);
|
||||
uint64_t x5 = ((x >> 0x28) & 0xFF);
|
||||
uint64_t x6 = ((x >> 0x30) & 0xFF);
|
||||
uint64_t x7 = ((x >> 0x38) & 0xFF);
|
||||
|
||||
return (x0 << 0x38)
|
||||
| (x1 << 0x30)
|
||||
| (x2 << 0x28)
|
||||
| (x3 << 0x20)
|
||||
| (x4 << 0x18)
|
||||
| (x5 << 0x10)
|
||||
| (x6 << 0x08)
|
||||
| (x7 );
|
||||
}
|
||||
|
||||
int main(int argc, char**argv, char** envp)
|
||||
{
|
||||
std::ifstream infile("log_test.txt");
|
||||
uint32_t ref_clz;
|
||||
std::string str_h;
|
||||
uint32_t ref_log;
|
||||
uint32_t cases = 0;
|
||||
uint32_t errors = 0;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( !(infile >> std::hex >> ref_clz) )
|
||||
break;
|
||||
if( !(infile >> str_h) )
|
||||
break;
|
||||
if( !(infile >> std::hex >> ref_log) )
|
||||
break;
|
||||
fc::sha256 h(str_h);
|
||||
if( ref_clz != h.clz() )
|
||||
{
|
||||
std::cerr << "got error on clz(" << str_h << ")" << std::endl;
|
||||
++errors;
|
||||
}
|
||||
if( ref_log != h.approx_log_32() )
|
||||
{
|
||||
std::cerr << "got error on log(" << str_h << ")" << std::endl;
|
||||
++errors;
|
||||
}
|
||||
double d_ilog_h_test = h.inverse_approx_log_32_double( ref_log );
|
||||
h.set_to_inverse_approx_log_32( ref_log );
|
||||
if( ref_log != h.approx_log_32() )
|
||||
{
|
||||
std::cerr << "got error on ilog(" << ref_log << ")" << std::endl;
|
||||
++errors;
|
||||
}
|
||||
|
||||
std::string str_ilog_h = h.str();
|
||||
boost::multiprecision::uint256_t u256_ilog_h( "0x" + str_ilog_h );
|
||||
double d_ilog_h_ref = u256_ilog_h.template convert_to<double>();
|
||||
if( d_ilog_h_ref != d_ilog_h_test )
|
||||
{
|
||||
std::cerr << "got error on d_ilog(" << ref_log << ")" << std::endl;
|
||||
++errors;
|
||||
}
|
||||
|
||||
if( h != fc::sha256() )
|
||||
{
|
||||
fc::sha256 h_before = h;
|
||||
if( h._hash[3] == 0 )
|
||||
{
|
||||
if( h._hash[2] == 0 )
|
||||
{
|
||||
if( h._hash[1] == 0 )
|
||||
{
|
||||
h._hash[0] = endian_reverse( endian_reverse( h._hash[0] )-1 );
|
||||
}
|
||||
h._hash[1] = endian_reverse( endian_reverse( h._hash[1] )-1 );
|
||||
}
|
||||
h._hash[2] = endian_reverse( endian_reverse( h._hash[2] )-1 );
|
||||
}
|
||||
h._hash[3] = endian_reverse( endian_reverse( h._hash[3] )-1 );
|
||||
bool ok = (h.approx_log_32() < ref_log);
|
||||
if( !ok )
|
||||
{
|
||||
std::cerr << "got error on logm1 for " << ref_log << std::endl;
|
||||
std::cerr << "h0:" << str_h << std::endl;
|
||||
std::cerr << "h1:" << h_before.str() << std::endl;
|
||||
std::cerr << "h2:" << h.str() << std::endl;
|
||||
std::cerr << "ref_log:" << std::hex << std::setw(8) << ref_log << std::endl;
|
||||
std::cerr << "log(h) :" << std::hex << std::setw(8) << h.approx_log_32() << std::endl;
|
||||
std::cerr << std::endl;
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
|
||||
++cases;
|
||||
}
|
||||
|
||||
std::cerr << "sha256_log_test checked " << cases << " cases, got " << errors << " errors" << std::endl;
|
||||
if( errors )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Independent implementation of algorithm
|
||||
# To create log_test.txt, run ./log_test.py > log_test.txt
|
||||
|
||||
import random
|
||||
|
||||
rand = random.Random(1234)
|
||||
|
||||
result = set()
|
||||
|
||||
result.add((0, 256))
|
||||
result.add(((1 << 256)-1, 0))
|
||||
for i in range(256):
|
||||
y = (1 << i)
|
||||
result.add((y, 255-i))
|
||||
for j in range(32):
|
||||
result.add((y+rand.randrange(0, y), 255-i))
|
||||
|
||||
def get_sem_32(y):
|
||||
bs = "{:0256b}".format(y)
|
||||
if "1" not in bs:
|
||||
return 0
|
||||
bs += 32*"0"
|
||||
i = bs.index("1")
|
||||
return ((255-i) << 24) | int(bs[i+1:i+25], 2)
|
||||
|
||||
for y, lz in sorted(result):
|
||||
print("{:02x}".format(lz), "{:064x}".format(y), "{:08x}".format(get_sem_32(y)))
|
||||
Loading…
Reference in a new issue