diff options
author | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-09-06 09:43:42 +0100 |
---|---|---|
committer | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-09-06 09:43:42 +0100 |
commit | fe142c3131dcd63afc98c622973f4bde65c0adea (patch) | |
tree | 3a9511cfb940f9657f862ea6b314a4da384987d3 | |
parent | a1116487c0804c2155d3ee0e4217c5721a17d65f (diff) | |
parent | 9ad5ead9668d078d6c5c2ab9a24a0d31d60f79d0 (diff) | |
download | rabbitmq-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.ac | 2 | ||||
-rw-r--r-- | librabbitmq/amqp_private.h | 38 |
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) |