Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix float double work #536

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/amqpcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions include/amqpcpp/endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/amqpcpp/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
46 changes: 46 additions & 0 deletions include/amqpcpp/inbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,23 @@ class InBuffer
*/
size_t _skip = 0;

template <typename T, std::enable_if_t<(sizeof(T) == 1) || (static_cast<uint8_t>(0x1234) == 0x12), bool> = true>
const T& be_to_h(const T& value)
{
return value;
}

template <typename T, std::enable_if_t<(sizeof(T) > 1) && (static_cast<uint8_t>(0x1234) == 0x34), bool> = true>
T be_to_h(const T& value)
{
size_t c = sizeof(T);
const uint8_t(&i)[sizeof(T)] = reinterpret_cast<const uint8_t(&)[sizeof(T)]> (value);
uint8_t o[sizeof(T)] = {};
for (auto& v : i)
o[--c] = v;
return reinterpret_cast<const T&>(o);
}

public:
/**
* Constructor
Expand Down Expand Up @@ -123,6 +140,35 @@ class InBuffer
*/
double nextDouble();

/**
* Read a numeric from the buffer
* @return double double read from buffer
*/
template <typename T, std::enable_if_t<sizeof(T) == 1, bool> = true>
T nextNumeric()
{
auto val = nextUint8();
return reinterpret_cast<const T&>(val);
}
template <typename T, std::enable_if_t<sizeof(T) == 2, bool> = true>
T nextNumeric()
{
auto val = nextUint16();
return reinterpret_cast<const T&>(val);
}
template <typename T, std::enable_if_t<sizeof(T) == 4, bool> = true>
T nextNumeric()
{
auto val = nextUint32();
return reinterpret_cast<const T&>(val);
}
template <typename T, std::enable_if_t<sizeof(T) == 8, bool> = true>
T nextNumeric()
{
auto val = nextUint64();
return reinterpret_cast<const T&>(val);
}

/**
* Get a pointer to the next binary buffer of a certain size
* @param size
Expand Down
36 changes: 11 additions & 25 deletions include/amqpcpp/numericfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int8_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt8();
else if (std::is_same<int16_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt16();
else if (std::is_same<int32_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt32();
else if (std::is_same<int64_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt64();
else if (std::is_same<uint8_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint8();
else if (std::is_same<uint16_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint16();
else if (std::is_same<uint32_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint32();
else if (std::is_same<uint64_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint64();
else if (std::is_same<float, typename std::remove_cv<T>::type>::value) _value = frame.nextFloat();
else if (std::is_same<double, typename std::remove_cv<T>::type>::value) _value = frame.nextDouble();

// re-enable the warning
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
}
NumericField(InBuffer& frame) : _value{ frame.nextNumeric<T>() } {}

/**
* Destructor
Expand Down Expand Up @@ -158,6 +134,16 @@ class NumericField : public Field
return std::is_integral<T>::value;
}

/**
* We are an floating_point field
*
* @return true, because we are an floating_point
*/
bool isFloat() const override
{
return std::is_floating_point<T>::value;
}

/**
* Get the size this field will take when
* encoded in the AMQP wire-frame format
Expand Down
10 changes: 8 additions & 2 deletions include/amqpcpp/outbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,11 @@ class OutBuffer
*/
void add(float value)
{
// copy into the buffer
int32_t v = htobe32(reinterpret_cast<int32_t&>(value));

// append the data
append(&value, sizeof(value));
append(&v, sizeof(v));
}

/**
Expand All @@ -181,8 +184,11 @@ class OutBuffer
*/
void add(double value)
{
// copy into the buffer
int64_t v = htobe64(reinterpret_cast<int64_t&>(value));

// append the data
append(&value, sizeof(value));
append(&v, sizeof(v));
}
};

Expand Down
2 changes: 2 additions & 0 deletions include/amqpcpp/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))); }
Expand Down
32 changes: 16 additions & 16 deletions src/inbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand Down