qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject svn commit: r1674137 - in /qpid/trunk/qpid/cpp/src: CMakeLists.txt qpid/framing/Endian.cpp qpid/framing/Endian.h qpid/framing/FieldTable.cpp qpid/framing/FieldValue.cpp qpid/framing/FieldValue.h tests/FieldTable.cpp tests/FieldValue.cpp
Date Thu, 16 Apr 2015 19:04:24 GMT
Author: aconway
Date: Thu Apr 16 19:04:23 2015
New Revision: 1674137

URL: http://svn.apache.org/r1674137
Log:
QPID-6470: Fix float conversion problems.

Previous code would incorrectly convert between float and int types producing nonsense values,
and would not allow legal conversions between float and double types.

Created FixedWidthIntValue and FixedWidthFloatValue template subclasses to correctly
handle conversions. Enabled FieldValue unit tests for float conversions.

Removed:
    qpid/trunk/qpid/cpp/src/qpid/framing/Endian.cpp
Modified:
    qpid/trunk/qpid/cpp/src/CMakeLists.txt
    qpid/trunk/qpid/cpp/src/qpid/framing/Endian.h
    qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp
    qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp
    qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h
    qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp
    qpid/trunk/qpid/cpp/src/tests/FieldValue.cpp

Modified: qpid/trunk/qpid/cpp/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/CMakeLists.txt?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/src/CMakeLists.txt Thu Apr 16 19:04:23 2015
@@ -777,7 +777,6 @@ set (qpidcommon_SOURCES
      qpid/framing/AMQHeartbeatBody.cpp
      qpid/framing/Array.cpp
      qpid/framing/Buffer.cpp
-     qpid/framing/Endian.cpp
      qpid/framing/FieldTable.cpp
      qpid/framing/FieldValue.cpp
      qpid/framing/FrameSet.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/framing/Endian.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/framing/Endian.h?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/framing/Endian.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/framing/Endian.h Thu Apr 16 19:04:23 2015
@@ -26,21 +26,53 @@
 
 namespace qpid {
 namespace framing {
+namespace endian {
 
-/**
- * Conversion utility for little-endian platforms that need to convert
- * to and from network ordered octet sequences
- */
-class Endian
-{
-  public:
-    static uint8_t* convertIfRequired(uint8_t* octets, int width);
-  private:
-    const bool littleEndian;
-    Endian();
-    static const Endian instance;
-    static bool testBigEndian();
-};
-}} // namespace qpid::framing
+/** Decode integer from network byte order buffer to type T, buffer must be at least sizeof(T).
*/
+template <class T> T decodeInt(const uint8_t* buffer) {
+    T v = buffer[0];
+    for (size_t i = 1; i < sizeof(T); ++i) {
+        v <<= 8;
+        v |= buffer[i];
+    }
+    return v;
+}
+
+/** Encode integer value to network byte order in buffer, buffer must be at least sizeof(T).
*/
+template <class T> void encodeInt(uint8_t* buffer, T value) {
+    for (size_t i = sizeof(T); i > 0; --i) {
+        buffer[i-1] = value & 0XFF;
+        value >>= 8;
+    }
+}
+
+// Compute the int type that can hold a float type.
+template <class T> struct IntBox { typedef T Type; };
+template <> struct IntBox<float> { typedef uint32_t  Type; };
+template <> struct IntBox<double> { typedef  uint64_t Type; };
+
+/** Decode floating from network byte order buffer to type T, buffer must be at least sizeof(T).
*/
+template <class T> T decodeFloat(const uint8_t* buffer) {
+    typedef typename IntBox<T>::Type Box;
+    union { T f; Box i; } u;
+    u.i = decodeInt<Box>(buffer);
+    return u.f;
+}
+
+/** Encode floating value to network byte order in buffer, buffer must be at least sizeof(T).
*/
+template <class T> void encodeFloat(uint8_t* buffer, T value) {
+    typedef typename IntBox<T>::Type Box;
+    union { T f; Box i; } u;
+    u.f = value;
+    encodeInt(buffer, u.i);
+}
+
+}}} // namespace qpid::framing::endian
 
 #endif  /*!QPID_FRAMING_ENDIAN_H*/
+
+
+
+
+
+

Modified: qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp Thu Apr 16 19:04:23 2015
@@ -21,7 +21,6 @@
 #include "qpid/framing/FieldTable.h"
 #include "qpid/framing/Array.h"
 #include "qpid/framing/Buffer.h"
-#include "qpid/framing/Endian.h"
 #include "qpid/framing/FieldValue.h"
 #include "qpid/Exception.h"
 #include "qpid/framing/reply_exceptions.h"

Modified: qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp Thu Apr 16 19:04:23 2015
@@ -21,15 +21,45 @@
 #include "qpid/framing/FieldValue.h"
 #include "qpid/framing/Array.h"
 #include "qpid/framing/Buffer.h"
-#include "qpid/framing/Endian.h"
 #include "qpid/framing/List.h"
 #include "qpid/framing/Uuid.h"
 #include "qpid/framing/reply_exceptions.h"
+#include "qpid/framing/Endian.h"
 #include "qpid/Msg.h"
 
 namespace qpid {
 namespace framing {
 
+// Some template magic for computing types from sizes.
+template<int W> struct IntType{};
+template<> struct IntType<1> { typedef int8_t Type; };
+template<> struct IntType<2> { typedef int16_t Type; };
+template<> struct IntType<4> { typedef int32_t Type; };
+template<> struct IntType<8> { typedef int64_t Type; };
+
+template<int W> struct UintType{};
+template<> struct UintType<1> { typedef uint8_t Type; };
+template<> struct UintType<2> { typedef uint16_t Type; };
+template<> struct UintType<4> { typedef uint32_t Type; };
+template<> struct UintType<8> { typedef uint64_t Type; };
+
+template<int W> struct FloatType{};
+template<> struct FloatType<1> { typedef int8_t Type; }; // Dummy, never used.
+template<> struct FloatType<2> { typedef int16_t Type; }; // Dummy, never used.
+template<> struct FloatType<4> { typedef float Type; };
+template<> struct FloatType<8> { typedef double Type; };
+
+// Construct the right subclass of FixedWidthValue for numeric types using width and kind.
+// Kind 1=int, 2=unsigned int, 3=float
+template<int W> FixedWidthValue<W>* numericFixedWidthValue(uint8_t kind) {
+    switch (kind) {
+      case 1: return new FixedWidthIntValue<typename IntType<W>::Type>();
+      case 2: return new FixedWidthIntValue<typename UintType<W>::Type>();
+      case 3: return new FixedWidthFloatValue<typename FloatType<W>::Type>();
+      default: return new FixedWidthValue<W>();
+    }
+}
+
 uint8_t FieldValue::getType() const
 {
     return typeOctet;
@@ -47,20 +77,22 @@ void FieldValue::setType(uint8_t type)
     } else if (typeOctet == 0x48) {
         data.reset(new UuidData());
     } else {
+        uint8_t kind = typeOctet & 0xF;
         uint8_t lenType = typeOctet >> 4;
         switch(lenType){
           case 0:
-            data.reset(new FixedWidthValue<1>());
+            data.reset(numericFixedWidthValue<1>(kind));
             break;
           case 1:
-            data.reset(new FixedWidthValue<2>());
+            data.reset(numericFixedWidthValue<2>(kind));
             break;
           case 2:
-            data.reset(new FixedWidthValue<4>());
+            data.reset(numericFixedWidthValue<4>(kind));
             break;
           case 3:
-            data.reset(new FixedWidthValue<8>());
+            data.reset(numericFixedWidthValue<8>(kind));
             break;
+            // None of the remaining widths can be numeric types so just use new FixedWidthValue
           case 4:
             data.reset(new FixedWidthValue<16>());
             break;
@@ -157,28 +189,28 @@ Struct32Value::Struct32Value(const std::
 {}
 
 IntegerValue::IntegerValue(int v) :
-    FieldValue(0x21, new FixedWidthValue<4>(v))
+    FieldValue(0x21, new FixedWidthIntValue<int32_t>(v))
 {}
 
 FloatValue::FloatValue(float v) :
-    FieldValue(0x23, new FixedWidthValue<4>(Endian::convertIfRequired(reinterpret_cast<uint8_t*>(&v),
4)))
+    FieldValue(0x23, new FixedWidthFloatValue<float>(v))
 {}
 
 DoubleValue::DoubleValue(double v) :
-    FieldValue(0x33, new FixedWidthValue<8>(Endian::convertIfRequired(reinterpret_cast<uint8_t*>(&v),
8)))
+    FieldValue(0x33, new FixedWidthFloatValue<double>(v))
 {}
 
 Integer64Value::Integer64Value(int64_t v) :
-    FieldValue(0x31, new FixedWidthValue<8>(v))
+    FieldValue(0x31, new FixedWidthIntValue<int64_t>(v))
 {}
 
 Unsigned64Value::Unsigned64Value(uint64_t v) :
-    FieldValue(0x32, new FixedWidthValue<8>(v))
+    FieldValue(0x32, new FixedWidthIntValue<uint64_t>(v))
 {}
 
 
 TimeValue::TimeValue(uint64_t v) :
-    FieldValue(0x38, new FixedWidthValue<8>(v))
+    FieldValue(0x38, new FixedWidthIntValue<uint64_t>(v))
 {
 }
 
@@ -197,24 +229,24 @@ ArrayValue::ArrayValue(const Array& a) :
 VoidValue::VoidValue() : FieldValue(0xf0, new FixedWidthValue<0>()) {}
 
 BoolValue::BoolValue(bool b) :
-    FieldValue(0x08, new FixedWidthValue<1>(b))
+    FieldValue(0x08, new FixedWidthIntValue<bool>(b))
 {}
 
 Unsigned8Value::Unsigned8Value(uint8_t v) :
-    FieldValue(0x02, new FixedWidthValue<1>(v))
+    FieldValue(0x02, new FixedWidthIntValue<uint8_t>(v))
 {}
 Unsigned16Value::Unsigned16Value(uint16_t v) :
-    FieldValue(0x12, new FixedWidthValue<2>(v))
+    FieldValue(0x12, new FixedWidthIntValue<uint16_t>(v))
 {}
 Unsigned32Value::Unsigned32Value(uint32_t v) :
-    FieldValue(0x22, new FixedWidthValue<4>(v))
+    FieldValue(0x22, new FixedWidthIntValue<uint32_t>(v))
 {}
 
 Integer8Value::Integer8Value(int8_t v) :
-    FieldValue(0x01, new FixedWidthValue<1>(v))
+    FieldValue(0x01, new FixedWidthIntValue<int8_t>(v))
 {}
 Integer16Value::Integer16Value(int16_t v) :
-    FieldValue(0x11, new FixedWidthValue<2>(v))
+    FieldValue(0x11, new FixedWidthIntValue<int16_t>(v))
 {}
 
 UuidData::UuidData() {}
@@ -232,9 +264,4 @@ void FieldValue::print(std::ostream& out
     out << ')';
 }
 
-uint8_t* FieldValue::convertIfRequired(uint8_t* octets, int width)
-{
-    return Endian::convertIfRequired(octets, width);
-}
-
 }}

Modified: qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h Thu Apr 16 19:04:23 2015
@@ -25,6 +25,7 @@
 #include "qpid/framing/amqp_types.h"
 #include "qpid/framing/Buffer.h"
 #include "qpid/framing/FieldTable.h"
+#include "qpid/framing/Endian.h"
 #include "qpid/CommonImportExport.h"
 
 #include <iostream>
@@ -66,15 +67,17 @@ class QPID_COMMON_CLASS_EXTERN FieldValu
      */
     class Data {
       public:
-        virtual ~Data() {};
+        virtual ~Data() {}
         virtual uint32_t encodedSize() const = 0;
         virtual void encode(Buffer& buffer) = 0;
         virtual void decode(Buffer& buffer) = 0;
         virtual bool operator==(const Data&) const = 0;
 
         virtual bool convertsToInt() const { return false; }
+        virtual bool convertsToFloat() const { return false; }
         virtual bool convertsToString() const { return false; }
         virtual int64_t getInt() const { throw InvalidConversionException();}
+        virtual double getFloat() const { throw InvalidConversionException();}
         virtual std::string getString() const { throw InvalidConversionException(); }
 
         virtual void print(std::ostream& out) const = 0;
@@ -106,8 +109,6 @@ class QPID_COMMON_CLASS_EXTERN FieldValu
   protected:
     FieldValue(uint8_t t, Data* d): typeOctet(t), data(d) {}
 
-    QPID_COMMON_EXTERN static uint8_t* convertIfRequired(uint8_t* octets, int width);
-
   private:
     uint8_t typeOctet;
     std::auto_ptr<Data> data;
@@ -123,12 +124,24 @@ template <>
 inline bool FieldValue::convertsTo<std::string>() const { return data->convertsToString();
}
 
 template <>
+inline bool FieldValue::convertsTo<float>() const { return data->convertsToFloat();
}
+
+template <>
+inline bool FieldValue::convertsTo<double>() const { return data->convertsToFloat();
}
+
+template <>
 inline int FieldValue::get<int>() const { return static_cast<int>(data->getInt());
}
 
 template <>
 inline int64_t FieldValue::get<int64_t>() const { return data->getInt(); }
 
 template <>
+inline float FieldValue::get<float>() const { return data->getFloat(); }
+
+template <>
+inline double FieldValue::get<double>() const { return data->getFloat(); }
+
+template <>
 inline std::string FieldValue::get<std::string>() const { return data->getString();
}
 
 inline std::ostream& operator<<(std::ostream& out, const FieldValue& v)
{
@@ -138,22 +151,14 @@ inline std::ostream& operator<<(std::ost
 
 template <int width>
 class FixedWidthValue : public FieldValue::Data {
+  protected:
     uint8_t octets[width];
 
   public:
     FixedWidthValue() {}
     FixedWidthValue(const uint8_t (&data)[width]) : octets(data) {}
-    FixedWidthValue(const uint8_t* const data)
-    {
-        for (int i = 0; i < width; i++) octets[i] = data[i];
-    }
-    FixedWidthValue(uint64_t v)
-    {
-        for (int i = width; i > 1; --i) {
-            octets[i-1] = (uint8_t) (0xFF & v); v >>= 8;
-        }
-        octets[0] = (uint8_t) (0xFF & v);
-    }
+    FixedWidthValue(const uint8_t* const data) { std::copy(data, data + width, octets); }
+
     uint32_t encodedSize() const { return width; }
     void encode(Buffer& buffer) { buffer.putRawData(octets, width); }
     void decode(Buffer& buffer) { buffer.getRawData(octets, width); }
@@ -162,23 +167,37 @@ class FixedWidthValue : public FieldValu
         if (rhs == 0) return false;
         else return std::equal(&octets[0], &octets[width], &rhs->octets[0]);
     }
-
-    bool convertsToInt() const { return true; }
-    int64_t getInt() const
-    {
-        int64_t v = 0;
-        for (int i = 0; i < width-1; ++i) {
-            v |= octets[i]; v <<= 8;
-        }
-        v |= octets[width-1];
-        return v;
-    }
     uint8_t* rawOctets() { return octets; }
     const uint8_t* rawOctets() const { return octets; }
 
     void print(std::ostream& o) const { o << "F" << width << ":"; };
 };
 
+template <class T> class FixedWidthIntValue : public FixedWidthValue<sizeof(T)>
{
+  public:
+    FixedWidthIntValue(T v = 0) { endian::encodeInt(this->octets, v); }
+    bool convertsToInt() const { return true; }
+    int64_t getInt() const { return endian::decodeInt<T>(this->octets); }
+    bool convertsToFloat() const { return true; }
+    double getFloat() const { return getInt(); }
+};
+
+template <class T> class FixedWidthFloatValue : public FixedWidthValue<sizeof(T)>
{
+  public:
+    FixedWidthFloatValue(T v = 0) { endian::encodeFloat(this->octets, v); }
+    bool convertsToFloat() const { return true; }
+    double getFloat() const { return endian::decodeFloat<T>(this->octets); }
+};
+
+// Dummy implementations that are never used but needed to avoid compile errors.
+template <> class FixedWidthFloatValue<uint8_t> : public FixedWidthValue<1>
{
+    FixedWidthFloatValue() { assert(0); }
+};
+template <> class FixedWidthFloatValue<uint16_t> : public FixedWidthValue<2>
{
+    FixedWidthFloatValue() { assert(0); }
+};
+
+
 class UuidData : public FixedWidthValue<16> {
   public:
     UuidData();
@@ -192,13 +211,7 @@ inline T FieldValue::getIntegerValue() c
 {
     FixedWidthValue<W>* const fwv = dynamic_cast< FixedWidthValue<W>* const>(data.get());
     if (fwv) {
-        uint8_t* octets = fwv->rawOctets();
-        T v = 0;
-        for (int i = 0; i < W-1; ++i) {
-            v |= octets[i]; v <<= 8;
-        }
-        v |= octets[W-1];
-        return v;
+        return endian::decodeInt<T>(fwv->rawOctets());
     } else {
         throw InvalidConversionException();
     }
@@ -218,14 +231,9 @@ inline T FieldValue::getIntegerValue() c
 
 template <class T, int W>
 inline T FieldValue::getFloatingPointValue() const {
-    const FixedWidthValue<W>* fwv = dynamic_cast<FixedWidthValue<W>*>(data.get());
-    if (fwv) {
-        T value;
-        uint8_t* target = reinterpret_cast<uint8_t*>(&value);
-        const uint8_t* octets = fwv->rawOctets();
-        std::copy(octets, octets + W, target);
-        convertIfRequired(target, W);
-        return value;
+    const FixedWidthFloatValue<T>* fv = dynamic_cast<FixedWidthFloatValue<T>*>(data.get());
+    if (fv) {
+        return endian::decodeFloat<T>(fv->rawOctets());
     } else {
         throw InvalidConversionException();
     }
@@ -235,23 +243,13 @@ template <int W> void FieldValue::getFix
 {
     FixedWidthValue<W>* const fwv = dynamic_cast< FixedWidthValue<W>* const>(data.get());
     if (fwv) {
-        for (size_t i = 0; i < W; ++i) value[i] = fwv->rawOctets()[i];
+        std::copy(fwv->rawOctets(), fwv->rawOctets() + W, value);
     } else {
         throw InvalidConversionException();
     }
 }
 
 template <>
-inline float FieldValue::get<float>() const {
-    return getFloatingPointValue<float, 4>();
-}
-
-template <>
-inline double FieldValue::get<double>() const {
-    return getFloatingPointValue<double, 8>();
-}
-
-template <>
 class FixedWidthValue<0> : public FieldValue::Data {
   public:
     // Implicit default constructor is fine

Modified: qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp Thu Apr 16 19:04:23 2015
@@ -176,19 +176,19 @@ QPID_AUTO_TEST_CASE(testFloatAndDouble)
         Buffer rbuffer(buff, 100);
         FieldTable a;
         rbuffer.get(a);
-        BOOST_CHECK(string("abc") == a.getAsString("string"));
-        BOOST_CHECK(5672 == a.getAsInt("int"));
+        BOOST_CHECK_EQUAL(string("abc"), a.getAsString("string"));
+        BOOST_CHECK_EQUAL(5672, a.getAsInt("int"));
         float f2;
         BOOST_CHECK(!a.getFloat("string", f2));
         BOOST_CHECK(!a.getFloat("int", f2));
         BOOST_CHECK(a.getFloat("float", f2));
-        BOOST_CHECK(f2 == f);
+        BOOST_CHECK_EQUAL(f2, f);
 
         double d2;
         BOOST_CHECK(!a.getDouble("string", d2));
         BOOST_CHECK(!a.getDouble("int", d2));
         BOOST_CHECK(a.getDouble("double", d2));
-        BOOST_CHECK(d2 == d);
+        BOOST_CHECK_EQUAL(d2, d);
     }
 }
 

Modified: qpid/trunk/qpid/cpp/src/tests/FieldValue.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/FieldValue.cpp?rev=1674137&r1=1674136&r2=1674137&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/FieldValue.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/FieldValue.cpp Thu Apr 16 19:04:23 2015
@@ -53,22 +53,15 @@ QPID_AUTO_TEST_CASE(testIntegerValueEqua
     BOOST_CHECK(IntegerValue(5) != i);
     BOOST_CHECK(i != s);
     BOOST_CHECK(i.convertsTo<std::string>() == false);
-    BOOST_CHECK(i.convertsTo<float>() == false);
+    BOOST_CHECK(i.convertsTo<float>() == true);
     BOOST_CHECK(i.convertsTo<int>() == true);
     BOOST_CHECK_THROW(i.get<std::string>(), InvalidConversionException);
-
-    //FIXME aconway 2015-04-03: fails
-    //BOOST_CHECK_THROW(i.get<float>(), InvalidConversionException);
+    BOOST_CHECK_EQUAL(i.get<float>(), 42.0);
 }
 
 QPID_AUTO_TEST_CASE(testFloatValueEquals)
 {
-    // FIXME aconway 2015-04-03: The commented out tests are bug QPID-6470.
-    // The basic problems are:
-    // - allows meaningles conversion between int and float types.
-    // - does not allow expected conversion between float and double types.
-
-    // BOOST_CHECK(f.convertsTo<float>() == true);
+    BOOST_CHECK(f.convertsTo<float>() == true);
     BOOST_CHECK_EQUAL(FloatValue(42.42), f);
     BOOST_CHECK_CLOSE(f.get<float>(), 42.42, 0.001);
     // Check twice, regression test for QPID-6470 where the value was corrupted during get.
@@ -76,20 +69,28 @@ QPID_AUTO_TEST_CASE(testFloatValueEquals
     BOOST_CHECK_CLOSE(f.get<float>(), 42.42, 0.001);
 
     // Float to double conversion
-    // BOOST_CHECK(f.convertsTo<double>() == true);
-    // BOOST_CHECK_CLOSE(f.get<double>(), 42.42, 0.001); 
+    BOOST_CHECK(f.convertsTo<double>() == true);
+    BOOST_CHECK_CLOSE(f.get<double>(), 42.42, 0.001);
 
     // Double value
+    BOOST_CHECK(f.convertsTo<float>() == true);
+    BOOST_CHECK(f.convertsTo<double>() == true);
+    BOOST_CHECK_CLOSE(df.get<float>(), 123.123, 0.001);
     BOOST_CHECK_CLOSE(df.get<double>(), 123.123, 0.001);
-    // BOOST_CHECK(f.convertsTo<float>() == true);
-    // BOOST_CHECK(f.convertsTo<double>() == true);
-    // BOOST_CHECK_CLOSE(df.get<float>(), 123.123, 0.001);
 
     // Invalid conversions should fail.
     BOOST_CHECK(!f.convertsTo<std::string>());
-    // BOOST_CHECK(!f.convertsTo<int>());
+    BOOST_CHECK(!f.convertsTo<int>());
     BOOST_CHECK_THROW(f.get<std::string>(), InvalidConversionException);
-    // BOOST_CHECK_THROW(f.get<int>(), InvalidConversionException);
+    BOOST_CHECK_THROW(f.get<int>(), InvalidConversionException);
+
+    // getFloatingPointValue: check twice, regression test for QPID-6470
+    BOOST_CHECK_CLOSE((f.getFloatingPointValue<float,sizeof(float)>()), 42.42, 0.001);
+    BOOST_CHECK_CLOSE((f.getFloatingPointValue<float,sizeof(float)>()), 42.42, 0.001);
+    BOOST_CHECK_CLOSE((df.getFloatingPointValue<double,sizeof(double)>()), 123.123,
0.001);
+    // getFloatingPointValue should *not* convert float/double, require exact type.
+    BOOST_CHECK_THROW((f.getFloatingPointValue<double,sizeof(double)>()), InvalidConversionException);
+    BOOST_CHECK_THROW((df.getFloatingPointValue<float,sizeof(float)>()), InvalidConversionException);
 }
 
 QPID_AUTO_TEST_SUITE_END()



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message