summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qpid/cpp/src/CMakeLists.txt1
-rw-r--r--qpid/cpp/src/qpid/framing/Endian.cpp52
-rw-r--r--qpid/cpp/src/qpid/framing/Endian.h62
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.cpp1
-rw-r--r--qpid/cpp/src/qpid/framing/FieldValue.cpp71
-rw-r--r--qpid/cpp/src/qpid/framing/FieldValue.h100
-rw-r--r--qpid/cpp/src/tests/FieldTable.cpp8
-rw-r--r--qpid/cpp/src/tests/FieldValue.cpp35
8 files changed, 167 insertions, 163 deletions
diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt
index 86606107cc..8e2b5b73e8 100644
--- a/qpid/cpp/src/CMakeLists.txt
+++ b/qpid/cpp/src/CMakeLists.txt
@@ -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
diff --git a/qpid/cpp/src/qpid/framing/Endian.cpp b/qpid/cpp/src/qpid/framing/Endian.cpp
deleted file mode 100644
index decfe4b2d9..0000000000
--- a/qpid/cpp/src/qpid/framing/Endian.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/framing/Endian.h"
-
-namespace qpid {
-namespace framing {
-
-Endian::Endian() : littleEndian(!testBigEndian()) {}
-
-bool Endian::testBigEndian()
-{
- uint16_t a = 1;
- uint16_t b;
- uint8_t* p = (uint8_t*) &b;
- p[0] = 0xFF & (a >> 8);
- p[1] = 0xFF & (a);
- return a == b;
-}
-
-uint8_t* Endian::convertIfRequired(uint8_t* octets, int width)
-{
- if (instance.littleEndian) {
- for (int i = 0; i < (width/2); i++) {
- uint8_t temp = octets[i];
- octets[i] = octets[width - (1 + i)];
- octets[width - (1 + i)] = temp;
- }
- }
- return octets;
-}
-
-const Endian Endian::instance;
-
-}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/Endian.h b/qpid/cpp/src/qpid/framing/Endian.h
index dea8eaa3b7..faf553fed5 100644
--- a/qpid/cpp/src/qpid/framing/Endian.h
+++ b/qpid/cpp/src/qpid/framing/Endian.h
@@ -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*/
+
+
+
+
+
+
diff --git a/qpid/cpp/src/qpid/framing/FieldTable.cpp b/qpid/cpp/src/qpid/framing/FieldTable.cpp
index cd38db1ee8..0b677a6ccb 100644
--- a/qpid/cpp/src/qpid/framing/FieldTable.cpp
+++ b/qpid/cpp/src/qpid/framing/FieldTable.cpp
@@ -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"
diff --git a/qpid/cpp/src/qpid/framing/FieldValue.cpp b/qpid/cpp/src/qpid/framing/FieldValue.cpp
index 1d39c57edf..227c12e44e 100644
--- a/qpid/cpp/src/qpid/framing/FieldValue.cpp
+++ b/qpid/cpp/src/qpid/framing/FieldValue.cpp
@@ -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::string& v) :
{}
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) : FieldValue(0xaa, new EncodedValue<Array
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) const {
out << ')';
}
-uint8_t* FieldValue::convertIfRequired(uint8_t* octets, int width)
-{
- return Endian::convertIfRequired(octets, width);
-}
-
}}
diff --git a/qpid/cpp/src/qpid/framing/FieldValue.h b/qpid/cpp/src/qpid/framing/FieldValue.h
index 94126df053..e20244e7c9 100644
--- a/qpid/cpp/src/qpid/framing/FieldValue.h
+++ b/qpid/cpp/src/qpid/framing/FieldValue.h
@@ -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 FieldValue {
*/
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 FieldValue {
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::ostream& out, const FieldValue& v) {
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 FieldValue::Data {
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() const
{
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() const
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::getFixedWidthValue(unsigned char* value) const
{
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
diff --git a/qpid/cpp/src/tests/FieldTable.cpp b/qpid/cpp/src/tests/FieldTable.cpp
index 81372d87c5..c040f1d433 100644
--- a/qpid/cpp/src/tests/FieldTable.cpp
+++ b/qpid/cpp/src/tests/FieldTable.cpp
@@ -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);
}
}
diff --git a/qpid/cpp/src/tests/FieldValue.cpp b/qpid/cpp/src/tests/FieldValue.cpp
index 3e2a761c38..2182a43e35 100644
--- a/qpid/cpp/src/tests/FieldValue.cpp
+++ b/qpid/cpp/src/tests/FieldValue.cpp
@@ -53,22 +53,15 @@ QPID_AUTO_TEST_CASE(testIntegerValueEquals)
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()