diff --git a/rai/core_test/interface.cpp b/rai/core_test/interface.cpp index 99c60048..d7197294 100644 --- a/rai/core_test/interface.cpp +++ b/rai/core_test/interface.cpp @@ -7,6 +7,14 @@ #include #include +TEST (interface, xrb_uint128_to_dec) +{ + rai::uint128_union zero (0); + char text[40] = { 0 }; + xrb_uint128_to_dec (zero.bytes.data (), text); + ASSERT_STREQ ("0", text); +} + TEST (interface, xrb_uint256_to_string) { rai::uint256_union zero (0); @@ -31,6 +39,14 @@ TEST (interface, xrb_uint512_to_string) ASSERT_STREQ ("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", text); } +TEST (interface, xrb_uint128_from_dec) +{ + rai::uint128_union zero (0); + ASSERT_EQ (0, xrb_uint128_from_dec ("340282366920938463463374607431768211455", zero.bytes.data ())); + ASSERT_EQ (1, xrb_uint128_from_dec ("340282366920938463463374607431768211456", zero.bytes.data ())); + ASSERT_EQ (1, xrb_uint128_from_dec ("3402823669209384634633%4607431768211455", zero.bytes.data ())); +} + TEST (interface, xrb_uint256_from_string) { rai::uint256_union zero (0); diff --git a/rai/core_test/uint256_union.cpp b/rai/core_test/uint256_union.cpp index a8877cd8..79090e2d 100644 --- a/rai/core_test/uint256_union.cpp +++ b/rai/core_test/uint256_union.cpp @@ -37,6 +37,14 @@ TEST (uint128_union, decode_dec_leading_zero) ASSERT_TRUE (error); } +TEST (uint128_union, decode_dec_overflow) +{ + rai::uint128_union value; + std::string text ("340282366920938463463374607431768211456"); + auto error (value.decode_dec (text)); + ASSERT_TRUE (error); +} + struct test_punct : std::moneypunct { pattern do_pos_format () const diff --git a/rai/lib/interface.cpp b/rai/lib/interface.cpp index dba6dd2a..fe453dff 100644 --- a/rai/lib/interface.cpp +++ b/rai/lib/interface.cpp @@ -15,6 +15,12 @@ #include extern "C" { +void xrb_uint128_to_dec (xrb_uint128 source, char * destination) +{ + auto const & number (*reinterpret_cast (source)); + strncpy (destination, number.to_string_dec ().c_str (), 32); +} + void xrb_uint256_to_string (xrb_uint256 source, char * destination) { auto const & number (*reinterpret_cast (source)); @@ -33,6 +39,13 @@ void xrb_uint512_to_string (xrb_uint512 source, char * destination) strncpy (destination, number.to_string ().c_str (), 128); } +int xrb_uint128_from_dec (const char * source, xrb_uint128 destination) +{ + auto & number (*reinterpret_cast (destination)); + auto error (number.decode_dec (source)); + return error ? 1 : 0; +} + int xrb_uint256_from_string (const char * source, xrb_uint256 destination) { auto & number (*reinterpret_cast (destination)); diff --git a/rai/lib/interface.h b/rai/lib/interface.h index d16db966..457891dc 100644 --- a/rai/lib/interface.h +++ b/rai/lib/interface.h @@ -5,10 +5,13 @@ extern "C" { #endif +typedef unsigned char * xrb_uint128; // 16byte array for public and private keys typedef unsigned char * xrb_uint256; // 32byte array for public and private keys typedef unsigned char * xrb_uint512; // 64byte array for signatures typedef void * xrb_transaction; +// Convert amount bytes 'source' to a 39 byte not-null-terminated decimal string 'destination' +void xrb_uint128_to_dec (const xrb_uint128 source, char * destination); // Convert public/private key bytes 'source' to a 64 byte not-null-terminated hex string 'destination' void xrb_uint256_to_string (const xrb_uint256 source, char * destination); // Convert public key bytes 'source' to a 65 byte non-null-terminated account string 'destination' @@ -16,6 +19,9 @@ void xrb_uint256_to_address (xrb_uint256 source, char * destination); // Convert public/private key bytes 'source' to a 128 byte not-null-terminated hex string 'destination' void xrb_uint512_to_string (const xrb_uint512 source, char * destination); +// Convert 39 byte decimal string 'source' to a byte array 'destination' +// Return 0 on success, nonzero on error +int xrb_uint128_from_dec (const char * source, xrb_uint128 destination); // Convert 64 byte hex string 'source' to a byte array 'destination' // Return 0 on success, nonzero on error int xrb_uint256_from_string (const char * source, xrb_uint256 destination); diff --git a/rai/lib/numbers.cpp b/rai/lib/numbers.cpp index 7eff825b..e2aee857 100644 --- a/rai/lib/numbers.cpp +++ b/rai/lib/numbers.cpp @@ -562,11 +562,12 @@ bool rai::uint128_union::decode_dec (std::string const & text) { std::stringstream stream (text); stream << std::dec << std::noshowbase; - rai::uint128_t number_l; + boost::multiprecision::checked_uint128_t number_l; try { stream >> number_l; - *this = number_l; + rai::uint128_t unchecked (number_l); + *this = unchecked; if (!stream.eof ()) { error = true;