Skip to content

Commit

Permalink
Merge pull request EOSIO#402 from EOSIO/fix_signed_int
Browse files Browse the repository at this point in the history
fix issue EOSIO#400 extract signed_int from datastream
  • Loading branch information
larryk85 authored Feb 7, 2019
2 parents e8915c0 + 1ce6a9f commit 927b34b
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 7 deletions.
11 changes: 4 additions & 7 deletions libraries/eosiolib/varint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*/
#pragma once


/**
* @defgroup varint Variable Length Integer Type
* @brief Defines variable length integer type which provides more efficient serialization
Expand Down Expand Up @@ -406,8 +405,8 @@ struct signed_int {
*/
template<typename DataStream>
friend DataStream& operator << ( DataStream& ds, const signed_int& v ){
uint32_t val = uint32_t((v.value<<1) ^ (v.value>>31));
do {
uint32_t val = uint32_t((v.value<<1) ^ (v.value>>31)); //apply zigzag encoding
do { //store 7 bit chunks
uint8_t b = uint8_t(val) & 0x7f;
val >>= 7;
b |= ((val > 0) << 7);
Expand All @@ -427,14 +426,12 @@ struct signed_int {
template<typename DataStream>
friend DataStream& operator >> ( DataStream& ds, signed_int& vi ){
uint32_t v = 0; char b = 0; int by = 0;
do {
do { //read 7 bit chunks
ds.get(b);
v |= uint32_t(uint8_t(b) & 0x7f) << by;
by += 7;
} while( uint8_t(b) & 0x80 );
vi.value = ((v>>1) ^ (v>>31)) + (v&0x01);
vi.value = v&0x01 ? vi.value : -vi.value;
vi.value = -vi.value;
vi.value= (v>>1) ^ (~(v&1)+1ull); //reverse zigzag encoding
return ds;
}
};
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_test(name_tests ${CMAKE_BINARY_DIR}/tests/unit/name_tests)
add_test(rope_tests ${CMAKE_BINARY_DIR}/tests/unit/rope_tests)
add_test(print_tests ${CMAKE_BINARY_DIR}/tests/unit/print_tests)
add_test(system_tests ${CMAKE_BINARY_DIR}/tests/unit/system_tests)
add_test(varint_tests ${CMAKE_BINARY_DIR}/tests/unit/varint_tests)
if (eosio_FOUND)
add_test(integration_tests ${CMAKE_BINARY_DIR}/tests/integration/integration_tests)
endif()
1 change: 1 addition & 0 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ add_native_executable(name_tests name_tests.cpp)
add_native_executable(system_tests system_tests.cpp)
add_native_executable(rope_tests rope_tests.cpp)
add_native_executable(print_tests print_tests.cpp)
add_native_executable(varint_tests varint_tests.cpp)

add_subdirectory(test_contracts)
28 changes: 28 additions & 0 deletions tests/unit/varint_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <eosiolib/eosio.hpp>
#include <eosio/native/tester.hpp>

using namespace eosio::native;
using namespace eosio;

EOSIO_TEST_BEGIN(signed_int_test) //test datastream insert/extract signed_int
//silence_output(true);

char buffer[32];
datastream ds(buffer,32);
signed_int a(44), b((1<<30)+2), c(-35), d(-(1<<30)-2); //small +, small -, large +, large -
ds << a << b << c << d;
ds.seekp(0);
signed_int aa, bb, cc, dd;
ds >> aa >> bb >> cc >> dd;
char* errmess= "signed_int datastream extract fails";
check(a.value==aa.value,errmess);
check(b.value==bb.value,errmess);
check(c.value==cc.value,errmess);
check(d.value==dd.value,errmess);
silence_output(false);
EOSIO_TEST_END

int main(int argc, char** argv) {
EOSIO_TEST(signed_int_test);
return has_failed();
}

0 comments on commit 927b34b

Please sign in to comment.