diff --git a/src/msgpack/type/float.hpp b/src/msgpack/type/float.hpp index 11df6b2c..6ba06d5c 100644 --- a/src/msgpack/type/float.hpp +++ b/src/msgpack/type/float.hpp @@ -29,8 +29,18 @@ namespace msgpack { inline float& operator>> (object o, float& v) { - if(o.type != type::DOUBLE) { throw type_error(); } - v = (float)o.via.dec; + if(o.type == type::DOUBLE) { + v = (float)o.via.dec; + } + else if (o.type == type::POSITIVE_INTEGER) { + v = (float)o.via.u64; + } + else if (o.type == type::NEGATIVE_INTEGER) { + v = (float)o.via.i64; + } + else { + throw type_error(); + } return v; } @@ -44,8 +54,18 @@ inline packer& operator<< (packer& o, const float& v) inline double& operator>> (object o, double& v) { - if(o.type != type::DOUBLE) { throw type_error(); } - v = o.via.dec; + if(o.type == type::DOUBLE) { + v = o.via.dec; + } + else if (o.type == type::POSITIVE_INTEGER) { + v = (double)o.via.u64; + } + else if (o.type == type::NEGATIVE_INTEGER) { + v = (double)o.via.i64; + } + else { + throw type_error(); + } return v; } diff --git a/test/msgpack_test.cpp b/test/msgpack_test.cpp index 5ed61137..9e1e70b8 100644 --- a/test/msgpack_test.cpp +++ b/test/msgpack_test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -178,6 +179,59 @@ TEST(MSGPACK, simple_buffer_float) } } +namespace { +template +struct TypePair { + typedef F float_type; + typedef I integer_type; +}; +} // namespace + +template +class IntegerToFloatingPointTest : public testing::Test { +}; +TYPED_TEST_CASE_P(IntegerToFloatingPointTest); + +TYPED_TEST_P(IntegerToFloatingPointTest, simple_buffer) +{ + typedef typename TypeParam::float_type float_type; + typedef typename TypeParam::integer_type integer_type; + vector v; + v.push_back(0); + v.push_back(1); + if (is_signed::value) v.push_back(-1); + else v.push_back(2); + v.push_back(numeric_limits::min()); + v.push_back(numeric_limits::max()); + for (unsigned int i = 0; i < kLoop; i++) { + v.push_back(rand()); + } + for (unsigned int i = 0; i < v.size() ; i++) { + msgpack::sbuffer sbuf; + integer_type val1 = v[i]; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + float_type val2; + obj.convert(&val2); + EXPECT_TRUE(fabs(val2 - val1) <= kEPS); + } +} + +REGISTER_TYPED_TEST_CASE_P(IntegerToFloatingPointTest, + simple_buffer); + +typedef testing::Types, + TypePair, + TypePair, + TypePair > IntegerToFloatingPointTestTypes; +INSTANTIATE_TYPED_TEST_CASE_P(IntegerToFloatingPointTestInstance, + IntegerToFloatingPointTest, + IntegerToFloatingPointTestTypes); + TEST(MSGPACK, simple_buffer_double) { vector v;