From 4d9b974c87c902775f325c44e465336b47f4dd0e Mon Sep 17 00:00:00 2001 From: "m.obukhov" Date: Fri, 22 Dec 2023 15:30:05 +0200 Subject: [PATCH 1/4] float and double fix --- include/amqpcpp/endian.h | 4 ++-- include/amqpcpp/outbuffer.h | 10 ++++++++-- include/amqpcpp/table.h | 2 ++ src/inbuffer.cpp | 10 ++++++---- 4 files changed, 18 insertions(+), 8 deletions(-) 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/outbuffer.h b/include/amqpcpp/outbuffer.h index 7463ebd5..a18f3c0d 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 = htobe64(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..25217e32 100644 --- a/src/inbuffer.cpp +++ b/src/inbuffer.cpp @@ -141,9 +141,10 @@ float InBuffer::nextFloat() BufferCheck check(this, sizeof(float)); // get four bytes - float value; + uint32_t value; _buffer.copy(_skip, sizeof(float), &value); - return value; + value = be32toh(value); + return reinterpret_cast(value); } /** @@ -156,9 +157,10 @@ double InBuffer::nextDouble() BufferCheck check(this, sizeof(double)); // get eight bytes, and convert to host-byte-order - double value; + uint64_t value; _buffer.copy(_skip, sizeof(double), &value); - return value; + value = be64toh(value); + return reinterpret_cast(value); } /** From 1fa309f035aa09b8f2db39edbc19471bbf1f0fe5 Mon Sep 17 00:00:00 2001 From: "m.obukhov" Date: Thu, 7 Nov 2024 11:37:47 +0200 Subject: [PATCH 2/4] fix - add float --- include/amqpcpp/outbuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/amqpcpp/outbuffer.h b/include/amqpcpp/outbuffer.h index a18f3c0d..8c834726 100644 --- a/include/amqpcpp/outbuffer.h +++ b/include/amqpcpp/outbuffer.h @@ -172,7 +172,7 @@ class OutBuffer void add(float value) { // copy into the buffer - int32_t v = htobe64(reinterpret_cast(value)); + int32_t v = htobe32(reinterpret_cast(value)); // append the data append(&v, sizeof(v)); From b0615ac01a8a0e9bc020a44d37417c8f68127f7a Mon Sep 17 00:00:00 2001 From: "m.obukhov" Date: Thu, 7 Nov 2024 16:21:33 +0200 Subject: [PATCH 3/4] Field add isFloat InBuffer add nextNumeric() NumericField refactor constructor add isFloat and --- include/amqpcpp/field.h | 1 + include/amqpcpp/inbuffer.h | 25 +++++++++++++++++++++++ include/amqpcpp/numericfield.h | 36 +++++++++++----------------------- 3 files changed, 37 insertions(+), 25 deletions(-) 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..dc92f4de 100644 --- a/include/amqpcpp/inbuffer.h +++ b/include/amqpcpp/inbuffer.h @@ -123,6 +123,31 @@ class InBuffer */ double nextDouble(); + /** + * Read a numeric from the buffer + * @return double double read from buffer + */ + template = true> + T nextNumeric() + { + return static_cast(nextUint8()); + } + template = true> + T nextNumeric() + { + return static_cast(nextUint16()); + } + template = true> + T nextNumeric() + { + return static_cast(nextUint32()); + } + template = true> + T nextNumeric() + { + return static_cast(nextUint64()); + } + /** * 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 From 2bab2a54157d191efebf32c0c990470c3e0b6a02 Mon Sep 17 00:00:00 2001 From: "m.obukhov" Date: Tue, 19 Nov 2024 16:54:18 +0200 Subject: [PATCH 4/4] fix inbuffer be-to-host --- include/amqpcpp.h | 2 +- include/amqpcpp/inbuffer.h | 29 +++++++++++++++++++++++++---- src/inbuffer.cpp | 38 ++++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 25 deletions(-) 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/inbuffer.h b/include/amqpcpp/inbuffer.h index dc92f4de..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 @@ -130,22 +147,26 @@ class InBuffer template = true> T nextNumeric() { - return static_cast(nextUint8()); + auto val = nextUint8(); + return reinterpret_cast(val); } template = true> T nextNumeric() { - return static_cast(nextUint16()); + auto val = nextUint16(); + return reinterpret_cast(val); } template = true> T nextNumeric() { - return static_cast(nextUint32()); + auto val = nextUint32(); + return reinterpret_cast(val); } template = true> T nextNumeric() { - return static_cast(nextUint64()); + auto val = nextUint64(); + return reinterpret_cast(val); } /** diff --git a/src/inbuffer.cpp b/src/inbuffer.cpp index 25217e32..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); } /** @@ -141,10 +141,9 @@ float InBuffer::nextFloat() BufferCheck check(this, sizeof(float)); // get four bytes - uint32_t value; - _buffer.copy(_skip, sizeof(float), &value); - value = be32toh(value); - return reinterpret_cast(value); + float value; + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /** @@ -157,10 +156,9 @@ double InBuffer::nextDouble() BufferCheck check(this, sizeof(double)); // get eight bytes, and convert to host-byte-order - uint64_t value; - _buffer.copy(_skip, sizeof(double), &value); - value = be64toh(value); - return reinterpret_cast(value); + double value; + _buffer.copy(_skip, sizeof(value), &value); + return be_to_h(value); } /**