summaryrefslogtreecommitdiff
path: root/qpid/cpp/src/qpid/framing/Endian.h
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2015-04-16 19:04:23 +0000
committerAlan Conway <aconway@apache.org>2015-04-16 19:04:23 +0000
commitea16e50919f21fbab181e20e25b03d1a314634c8 (patch)
tree59fc8ce516b7ad1e6b46b2f640b418cd9092f10c /qpid/cpp/src/qpid/framing/Endian.h
parente7998631f9c479dd659f409f8e38c910e0028858 (diff)
downloadqpid-python-ea16e50919f21fbab181e20e25b03d1a314634c8.tar.gz
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. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1674137 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src/qpid/framing/Endian.h')
-rw-r--r--qpid/cpp/src/qpid/framing/Endian.h62
1 files changed, 47 insertions, 15 deletions
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*/
+
+
+
+
+
+