summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Scvortov <alexandru@rabbitmq.com>2011-09-06 09:43:42 +0100
committerAlexandru Scvortov <alexandru@rabbitmq.com>2011-09-06 09:43:42 +0100
commitfe142c3131dcd63afc98c622973f4bde65c0adea (patch)
tree3a9511cfb940f9657f862ea6b314a4da384987d3
parenta1116487c0804c2155d3ee0e4217c5721a17d65f (diff)
parent9ad5ead9668d078d6c5c2ab9a24a0d31d60f79d0 (diff)
downloadrabbitmq-c-github-ask-fe142c3131dcd63afc98c622973f4bde65c0adea.tar.gz
merge bug24349 into default (rabbitmq-c should work on platforms that don't support unaligned accesses)
-rw-r--r--configure.ac2
-rw-r--r--librabbitmq/amqp_private.h38
2 files changed, 33 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 2bf9433..e6aac32 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,6 +45,8 @@ AS_IF([test "x$GCC" = "xyes"], [CFLAGS="$CFLAGS -ansi -pedantic"])
AC_C_INLINE
CFLAGS="$orig_cflags"
+AC_C_BIGENDIAN
+
dnl Decide which API abstraction layer to use
PLATFORM_DIR=unix
if test "x$windows" = xyes ; then
diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h
index c6c87e4..6c15383 100644
--- a/librabbitmq/amqp_private.h
+++ b/librabbitmq/amqp_private.h
@@ -138,19 +138,27 @@ static inline void *amqp_offset(void *data, size_t offset)
return (char *)data + offset;
}
-/* assuming a machine that supports unaligned accesses (for now) */
+/* This macro defines the encoding and decoding functions associated with a
+ simple type. */
#define DECLARE_CODEC_BASE_TYPE(bits, htonx, ntohx) \
\
static inline void amqp_e##bits(void *data, size_t offset, \
uint##bits##_t val) \
-{ \
- *(uint##bits##_t *)amqp_offset(data, offset) = htonx(val); \
+{ \
+ /* The AMQP data might be unaligned. So we encode and then copy the \
+ result into place. */ \
+ uint##bits##_t res = htonx(val); \
+ memcpy(amqp_offset(data, offset), &res, bits/8); \
} \
\
static inline uint##bits##_t amqp_d##bits(void *data, size_t offset) \
-{ \
- return ntohx(*(uint##bits##_t *)amqp_offset(data, offset)); \
+{ \
+ /* The AMQP data might be unaligned. So we copy the source value \
+ into a variable and then decode it. */ \
+ uint##bits##_t val; \
+ memcpy(&val, amqp_offset(data, offset), bits/8); \
+ return ntohx(val); \
} \
\
static inline int amqp_encode_##bits(amqp_bytes_t encoded, size_t *offset, \
@@ -174,7 +182,6 @@ static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset, \
size_t o = *offset; \
if ((*offset = o + bits / 8) <= encoded.len) { \
*output = amqp_d##bits(encoded.bytes, o); \
- *output = ntohx(*(uint##bits##_t *)((char *)encoded.bytes + o)); \
return 1; \
} \
else { \
@@ -182,7 +189,7 @@ static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset, \
} \
}
-/* assuming little endian (for now) */
+#ifndef WORDS_BIGENDIAN
#define DECLARE_XTOXLL(func) \
static inline uint64_t func##ll(uint64_t val) \
@@ -199,6 +206,23 @@ static inline uint64_t func##ll(uint64_t val) \
return u.whole; \
}
+#else
+
+#define DECLARE_XTOXLL(func) \
+static inline uint64_t func##ll(uint64_t val) \
+{ \
+ union { \
+ uint64_t whole; \
+ uint32_t halves[2]; \
+ } u; \
+ u.whole = val; \
+ u.halves[0] = func##l(u.halves[0]); \
+ u.halves[1] = func##l(u.halves[1]); \
+ return u.whole; \
+}
+
+#endif
+
DECLARE_XTOXLL(hton)
DECLARE_XTOXLL(ntoh)