diff --git a/include/amqpcpp.h b/include/amqpcpp.h index edfb92d4..77c4f2c2 100644 --- a/include/amqpcpp.h +++ b/include/amqpcpp.h @@ -38,7 +38,7 @@ #include "amqpcpp/classes.h" // utility classes -#include "amqpcpp/endian.h" +//#include "amqpcpp/endian.h" #include "amqpcpp/buffer.h" #include "amqpcpp/bytebuffer.h" #include "amqpcpp/inbuffer.h" diff --git a/include/amqpcpp/endian.h b/include/amqpcpp/endian.h index b790d698..125d2435 100644 --- a/include/amqpcpp/endian.h +++ b/include/amqpcpp/endian.h @@ -72,9 +72,9 @@ #define be32toh(x) ntohl(x) #define le32toh(x) (x) -#define htobe64(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#define htobe64(x) htonll(x) #define htole64(x) (x) -#define be64toh(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#define be64toh(x) ntohll(x) #define le64toh(x) (x) #elif BYTE_ORDER == BIG_ENDIAN diff --git a/include/amqpcpp/field.h b/include/amqpcpp/field.h index 6c04cabb..c622ce76 100644 --- a/include/amqpcpp/field.h +++ b/include/amqpcpp/field.h @@ -107,6 +107,7 @@ class Field * @return Is the field a specific type? */ virtual bool isInteger() const { return false; } + virtual bool isFloat() const { return false; } virtual bool isDecimal() const { return false; } virtual bool isArray() const { return false; } virtual bool isTable() const { return false; } diff --git a/include/amqpcpp/inbuffer.h b/include/amqpcpp/inbuffer.h index 3e68bdff..3b1070f5 100644 --- a/include/amqpcpp/inbuffer.h +++ b/include/amqpcpp/inbuffer.h @@ -51,6 +51,23 @@ class InBuffer */ size_t _skip = 0; + template (0x1234) == 0x12), bool> = true> + const T& be_to_h(const T& value) + { + return value; + } + + template 1) && (static_cast(0x1234) == 0x34), bool> = true> + T be_to_h(const T& value) + { + size_t c = sizeof(T); + const uint8_t(&i)[sizeof(T)] = reinterpret_cast (value); + uint8_t o[sizeof(T)] = {}; + for (auto& v : i) + o[--c] = v; + return reinterpret_cast(o); + } + public: /** * Constructor @@ -123,6 +140,35 @@ class InBuffer */ double nextDouble(); + /** + * Read a numeric from the buffer + * @return double double read from buffer + */ + template = true> + T nextNumeric() + { + auto val = nextUint8(); + return reinterpret_cast(val); + } + template = true> + T nextNumeric() + { + auto val = nextUint16(); + return reinterpret_cast(val); + } + template = true> + T nextNumeric() + { + auto val = nextUint32(); + return reinterpret_cast(val); + } + template = true> + T nextNumeric() + { + auto val = nextUint64(); + return reinterpret_cast(val); + } + /** * Get a pointer to the next binary buffer of a certain size * @param size diff --git a/include/amqpcpp/numericfield.h b/include/amqpcpp/numericfield.h index 1bbc5e70..2fd9e36e 100644 --- a/include/amqpcpp/numericfield.h +++ b/include/amqpcpp/numericfield.h @@ -60,31 +60,7 @@ class NumericField : public Field * Parse based on incoming buffer * @param frame */ - NumericField(InBuffer &frame) - { -// The Microsoft Visual Studio compiler thinks that there is an issue -// with the following code, so we temporarily disable a specific warning -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4244) -#endif - - if (std::is_same::type>::value) _value = frame.nextInt8(); - else if (std::is_same::type>::value) _value = frame.nextInt16(); - else if (std::is_same::type>::value) _value = frame.nextInt32(); - else if (std::is_same::type>::value) _value = frame.nextInt64(); - else if (std::is_same::type>::value) _value = frame.nextUint8(); - else if (std::is_same::type>::value) _value = frame.nextUint16(); - else if (std::is_same::type>::value) _value = frame.nextUint32(); - else if (std::is_same::type>::value) _value = frame.nextUint64(); - else if (std::is_same::type>::value) _value = frame.nextFloat(); - else if (std::is_same::type>::value) _value = frame.nextDouble(); - -// re-enable the warning -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - } + NumericField(InBuffer& frame) : _value{ frame.nextNumeric() } {} /** * Destructor @@ -158,6 +134,16 @@ class NumericField : public Field return std::is_integral::value; } + /** + * We are an floating_point field + * + * @return true, because we are an floating_point + */ + bool isFloat() const override + { + return std::is_floating_point::value; + } + /** * Get the size this field will take when * encoded in the AMQP wire-frame format diff --git a/include/amqpcpp/outbuffer.h b/include/amqpcpp/outbuffer.h index 7463ebd5..8c834726 100644 --- a/include/amqpcpp/outbuffer.h +++ b/include/amqpcpp/outbuffer.h @@ -171,8 +171,11 @@ class OutBuffer */ void add(float value) { + // copy into the buffer + int32_t v = htobe32(reinterpret_cast(value)); + // append the data - append(&value, sizeof(value)); + append(&v, sizeof(v)); } /** @@ -181,8 +184,11 @@ class OutBuffer */ void add(double value) { + // copy into the buffer + int64_t v = htobe64(reinterpret_cast(value)); + // append the data - append(&value, sizeof(value)); + append(&v, sizeof(v)); } }; diff --git a/include/amqpcpp/table.h b/include/amqpcpp/table.h index df5eff80..74fda3f2 100644 --- a/include/amqpcpp/table.h +++ b/include/amqpcpp/table.h @@ -137,6 +137,8 @@ class Table : public Field Table &set(const std::string &name, int32_t value) { return set(name, Long(value)); } Table &set(const std::string &name, uint64_t value) { return set(name, ULongLong(value)); } Table &set(const std::string &name, int64_t value) { return set(name, LongLong(value)); } + Table &set(const std::string &name, float value) { return set(name, Float(value)); } + Table &set(const std::string &name, double value) { return set(name, Double(value)); } Table &set(const std::string &name, const std::string &value) { return set(name, LongString(value)); } Table &set(const std::string &name, const std::string_view &value) { return set(name, LongString(value)); } Table &set(const std::string &name, const char *value) { return set(name, LongString(std::string(value))); } diff --git a/src/inbuffer.cpp b/src/inbuffer.cpp index e836a6c3..ca247408 100644 --- a/src/inbuffer.cpp +++ b/src/inbuffer.cpp @@ -52,8 +52,8 @@ uint16_t InBuffer::nextUint16() // get two bytes, and convert to host-byte-order uint16_t value; - _buffer.copy(_skip, sizeof(uint16_t), &value); - return be16toh(value); + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -67,8 +67,8 @@ int16_t InBuffer::nextInt16() // get two bytes, and convert to host-byte-order int16_t value; - _buffer.copy(_skip, sizeof(int16_t), &value); - return be16toh(value); + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -82,8 +82,8 @@ uint32_t InBuffer::nextUint32() // get four bytes, and convert to host-byte-order uint32_t value; - _buffer.copy(_skip, sizeof(uint32_t), &value); - return be32toh(value); + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -97,8 +97,8 @@ int32_t InBuffer::nextInt32() // get four bytes, and convert to host-byte-order int32_t value; - _buffer.copy(_skip, sizeof(int32_t), &value); - return be32toh(value); + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -112,8 +112,8 @@ uint64_t InBuffer::nextUint64() // get eight bytes, and convert to host-byte-order uint64_t value; - _buffer.copy(_skip, sizeof(uint64_t), &value); - return be64toh(value); + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -127,8 +127,8 @@ int64_t InBuffer::nextInt64() // get eight bytes, and convert to host-byte-order int64_t value; - _buffer.copy(_skip, sizeof(int64_t), &value); - return be64toh(value); + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -142,8 +142,8 @@ float InBuffer::nextFloat() // get four bytes float value; - _buffer.copy(_skip, sizeof(float), &value); - return value; + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -157,8 +157,8 @@ double InBuffer::nextDouble() // get eight bytes, and convert to host-byte-order double value; - _buffer.copy(_skip, sizeof(double), &value); - return value; + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /**