summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2017-07-25 22:25:30 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2017-07-25 23:20:27 -0700
commit8bff1f64c1627c698c866bd2ab3e5a460eb731a9 (patch)
tree9fc4064671d9917dc429d68cb9fbc81e42d40126
parentb252de9c855435aab3162ba7eea50af587501a11 (diff)
downloadrabbitmq-c-wireformat.tar.gz
Lib: simplify the byte-swap codewireformat
-rw-r--r--librabbitmq/amqp_connection.c44
-rw-r--r--librabbitmq/amqp_private.h214
2 files changed, 123 insertions, 135 deletions
diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c
index 85a248d..9d4ebbe 100644
--- a/librabbitmq/amqp_connection.c
+++ b/librabbitmq/amqp_connection.c
@@ -287,13 +287,13 @@ int amqp_handle_input(amqp_connection_state_t state,
decoded_frame->channel = 0;
decoded_frame->payload.protocol_header.transport_high
- = amqp_d8(raw_frame, 4);
+ = amqp_d8(amqp_offset(raw_frame, 4));
decoded_frame->payload.protocol_header.transport_low
- = amqp_d8(raw_frame, 5);
+ = amqp_d8(amqp_offset(raw_frame, 5));
decoded_frame->payload.protocol_header.protocol_version_major
- = amqp_d8(raw_frame, 6);
+ = amqp_d8(amqp_offset(raw_frame, 6));
decoded_frame->payload.protocol_header.protocol_version_minor
- = amqp_d8(raw_frame, 7);
+ = amqp_d8(amqp_offset(raw_frame, 7));
return_to_idle(state);
return (int)bytes_consumed;
@@ -306,10 +306,10 @@ int amqp_handle_input(amqp_connection_state_t state,
amqp_channel_t channel;
amqp_pool_t *channel_pool;
/* frame length is 3 bytes in */
- channel = amqp_d16(raw_frame, 1);
+ channel = amqp_d16(amqp_offset(raw_frame, 1));
state->target_size
- = amqp_d32(raw_frame, 3) + HEADER_SIZE + FOOTER_SIZE;
+ = amqp_d32(amqp_offset(raw_frame, 3)) + HEADER_SIZE + FOOTER_SIZE;
if ((size_t)state->frame_max < state->target_size) {
return AMQP_STATUS_BAD_AMQP_DATA;
@@ -346,12 +346,13 @@ int amqp_handle_input(amqp_connection_state_t state,
amqp_pool_t *channel_pool;
/* Check frame end marker (footer) */
- if (amqp_d8(raw_frame, state->target_size - 1) != AMQP_FRAME_END) {
+ if (amqp_d8(amqp_offset(raw_frame, state->target_size - 1)) !=
+ AMQP_FRAME_END) {
return AMQP_STATUS_BAD_AMQP_DATA;
}
- decoded_frame->frame_type = amqp_d8(raw_frame, 0);
- decoded_frame->channel = amqp_d16(raw_frame, 1);
+ decoded_frame->frame_type = amqp_d8(amqp_offset(raw_frame, 0));
+ decoded_frame->channel = amqp_d16(amqp_offset(raw_frame, 1));
channel_pool = amqp_get_or_create_channel_pool(state, decoded_frame->channel);
if (NULL == channel_pool) {
@@ -360,7 +361,8 @@ int amqp_handle_input(amqp_connection_state_t state,
switch (decoded_frame->frame_type) {
case AMQP_FRAME_METHOD:
- decoded_frame->payload.method.id = amqp_d32(raw_frame, HEADER_SIZE);
+ decoded_frame->payload.method.id =
+ amqp_d32(amqp_offset(raw_frame, HEADER_SIZE));
encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 4);
encoded.len = state->target_size - HEADER_SIZE - 4 - FOOTER_SIZE;
@@ -375,10 +377,10 @@ int amqp_handle_input(amqp_connection_state_t state,
case AMQP_FRAME_HEADER:
decoded_frame->payload.properties.class_id
- = amqp_d16(raw_frame, HEADER_SIZE);
+ = amqp_d16(amqp_offset(raw_frame, HEADER_SIZE));
/* unused 2-byte weight field goes here */
decoded_frame->payload.properties.body_size
- = amqp_d64(raw_frame, HEADER_SIZE + 4);
+ = amqp_d64(amqp_offset(raw_frame, HEADER_SIZE + 4));
encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 12);
encoded.len = state->target_size - HEADER_SIZE - 12 - FOOTER_SIZE;
decoded_frame->payload.properties.raw = encoded;
@@ -476,8 +478,8 @@ static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer,
size_t out_frame_len;
int res;
- amqp_e8(out_frame, 0, frame->frame_type);
- amqp_e16(out_frame, 1, frame->channel);
+ amqp_e8(frame->frame_type, amqp_offset(out_frame, 0));
+ amqp_e16(frame->channel, amqp_offset(out_frame, 1));
switch (frame->frame_type) {
case AMQP_FRAME_BODY: {
@@ -491,7 +493,7 @@ static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer,
case AMQP_FRAME_METHOD: {
amqp_bytes_t method_encoded;
- amqp_e32(out_frame, HEADER_SIZE, frame->payload.method.id);
+ amqp_e32(frame->payload.method.id, amqp_offset(out_frame, HEADER_SIZE));
method_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 4);
method_encoded.len = buffer.len - HEADER_SIZE - 4 - FOOTER_SIZE;
@@ -509,9 +511,11 @@ static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer,
case AMQP_FRAME_HEADER: {
amqp_bytes_t properties_encoded;
- amqp_e16(out_frame, HEADER_SIZE, frame->payload.properties.class_id);
- amqp_e16(out_frame, HEADER_SIZE + 2, 0); /* "weight" */
- amqp_e64(out_frame, HEADER_SIZE + 4, frame->payload.properties.body_size);
+ amqp_e16(frame->payload.properties.class_id,
+ amqp_offset(out_frame, HEADER_SIZE));
+ amqp_e16(0, amqp_offset(out_frame, HEADER_SIZE + 2)); /* "weight" */
+ amqp_e64(frame->payload.properties.body_size,
+ amqp_offset(out_frame, HEADER_SIZE + 4));
properties_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 12);
properties_encoded.len = buffer.len - HEADER_SIZE - 12 - FOOTER_SIZE;
@@ -535,8 +539,8 @@ static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer,
return AMQP_STATUS_INVALID_PARAMETER;
}
- amqp_e32(out_frame, 3, (uint32_t)out_frame_len);
- amqp_e8(out_frame, HEADER_SIZE + out_frame_len, AMQP_FRAME_END);
+ amqp_e32((uint32_t)out_frame_len, amqp_offset(out_frame, 3));
+ amqp_e8(AMQP_FRAME_END, amqp_offset(out_frame, HEADER_SIZE + out_frame_len));
encoded->bytes = out_frame;
encoded->len = out_frame_len + HEADER_SIZE + FOOTER_SIZE;
diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h
index 31ce4ea..e02ae76 100644
--- a/librabbitmq/amqp_private.h
+++ b/librabbitmq/amqp_private.h
@@ -222,130 +222,114 @@ static inline void *amqp_offset(void *data, size_t offset)
/* 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) \
- { \
- /* 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) \
- { \
- /* 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, \
- uint##bits##_t input) \
- \
- { \
- size_t o = *offset; \
- if ((*offset = o + bits / 8) <= encoded.len) { \
- amqp_e##bits(encoded.bytes, o, input); \
- return 1; \
- } \
- else { \
- return 0; \
- } \
- } \
- \
- static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset, \
- uint##bits##_t *output) \
- \
- { \
- size_t o = *offset; \
- if ((*offset = o + bits / 8) <= encoded.len) { \
- *output = amqp_d##bits(encoded.bytes, o); \
- return 1; \
- } \
- else { \
- return 0; \
- } \
+#define DECLARE_CODEC_BASE_TYPE(bits) \
+ \
+ static inline int amqp_encode_##bits(amqp_bytes_t encoded, size_t *offset, \
+ uint##bits##_t input) { \
+ size_t o = *offset; \
+ if ((*offset = o + bits / 8) <= encoded.len) { \
+ amqp_e##bits(input, amqp_offset(encoded.bytes, o)); \
+ return 1; \
+ } \
+ return 0; \
+ } \
+ \
+ static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset, \
+ uint##bits##_t *output) { \
+ size_t o = *offset; \
+ if ((*offset = o + bits / 8) <= encoded.len) { \
+ *output = amqp_d##bits(amqp_offset(encoded.bytes, o)); \
+ return 1; \
+ } \
+ return 0; \
}
-/* Determine byte order */
-#if defined(__GLIBC__)
-# include <endian.h>
-# if (__BYTE_ORDER == __LITTLE_ENDIAN)
-# define AMQP_LITTLE_ENDIAN
-# elif (__BYTE_ORDER == __BIG_ENDIAN)
-# define AMQP_BIG_ENDIAN
-# else
-/* Don't define anything */
-# endif
-#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || \
- defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
-# define AMQP_BIG_ENDIAN
-#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) || \
- defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
-# define AMQP_LITTLE_ENDIAN
-#elif defined(__hppa__) || defined(__HPPA__) || defined(__hppa) || \
- defined(_POWER) || defined(__powerpc__) || defined(__ppc___) || \
- defined(_MIPSEB) || defined(__s390__) || \
- defined(__sparc) || defined(__sparc__)
-# define AMQP_BIG_ENDIAN
-#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) || \
- defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || \
- defined(__ia64) || defined(__ia64__) || defined(_M_IA64) || \
- defined(__arm__) || defined(_M_ARM) || \
- defined(__i386__) || defined(_M_IX86)
-# define AMQP_LITTLE_ENDIAN
-#else
-/* Don't define anything */
-#endif
+static inline int is_bigendian(void) {
+ union {
+ uint32_t i;
+ char c[4];
+ } bint = {0x01020304};
+ return bint.c[0] == 1;
+}
+
+static inline void amqp_e8(uint8_t val, void *data) {
+ memcpy(data, &val, sizeof(val));
+}
-#if defined(AMQP_LITTLE_ENDIAN)
-
-#define DECLARE_XTOXLL(func) \
- static inline uint64_t func##ll(uint64_t val) \
- { \
- union { \
- uint64_t whole; \
- uint32_t halves[2]; \
- } u; \
- uint32_t t; \
- u.whole = val; \
- t = u.halves[0]; \
- u.halves[0] = func##l(u.halves[1]); \
- u.halves[1] = func##l(t); \
- return u.whole; \
+static inline uint8_t amqp_d8(void *data) {
+ uint8_t val;
+ memcpy(&val, data, sizeof(val));
+ return val;
+}
+
+static inline void amqp_e16(uint16_t val, void *data) {
+ if (!is_bigendian()) {
+ val = ((val & 0xFF00u) >> 8u) | ((val & 0x00FFu) << 8u);
}
+ memcpy(data, &val, sizeof(val));
+}
-#elif defined(AMQP_BIG_ENDIAN)
-
-#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; \
+static inline uint16_t amqp_d16(void *data) {
+ uint16_t val;
+ memcpy(&val, data, sizeof(val));
+ if (!is_bigendian()) {
+ val = ((val & 0xFF00u) >> 8u) | ((val & 0x00FFu) << 8u);
}
+ return val;
+}
-#else
-# error Endianness not known
-#endif
+static inline void amqp_e32(uint32_t val, void* data) {
+ if (!is_bigendian()) {
+ val = ((val & 0xFF000000u) >> 24u) | ((val & 0x00FF0000u) >> 8u) |
+ ((val & 0x0000FF00u) << 8u) | ((val & 0x000000FFu) << 24u);
+ }
+ memcpy(data, &val, sizeof(val));
+}
-#ifndef HAVE_HTONLL
-DECLARE_XTOXLL(hton)
-DECLARE_XTOXLL(ntoh)
-#endif
+static inline uint32_t amqp_d32(void *data) {
+ uint32_t val;
+ memcpy(&val, data, sizeof(val));
+ if (!is_bigendian()) {
+ val = ((val & 0xFF000000u) >> 24u) | ((val & 0x00FF0000u) >> 8u) |
+ ((val & 0x0000FF00u) << 8u) | ((val & 0x000000FFu) << 24u);
+ }
+ return val;
+}
+
+static inline void amqp_e64(uint64_t val, void *data) {
+ if (!is_bigendian()) {
+ val = ((val & 0xFF00000000000000u) >> 56u) |
+ ((val & 0x00FF000000000000u) >> 40u) |
+ ((val & 0x0000FF0000000000u) >> 24u) |
+ ((val & 0x000000FF00000000u) >> 8u) |
+ ((val & 0x00000000FF000000u) << 8u) |
+ ((val & 0x0000000000FF0000u) << 24u) |
+ ((val & 0x000000000000FF00u) << 40u) |
+ ((val & 0x00000000000000FFu) << 56u);
+ }
+ memcpy(data, &val, sizeof(val));
+}
+
+static inline uint64_t amqp_d64(void *data) {
+ uint64_t val;
+ memcpy(&val, data, sizeof(val));
+ if (!is_bigendian()) {
+ val = ((val & 0xFF00000000000000u) >> 56u) |
+ ((val & 0x00FF000000000000u) >> 40u) |
+ ((val & 0x0000FF0000000000u) >> 24u) |
+ ((val & 0x000000FF00000000u) >> 8u) |
+ ((val & 0x00000000FF000000u) << 8u) |
+ ((val & 0x0000000000FF0000u) << 24u) |
+ ((val & 0x000000000000FF00u) << 40u) |
+ ((val & 0x00000000000000FFu) << 56u);
+ }
+ return val;
+}
-DECLARE_CODEC_BASE_TYPE(8, (uint8_t), (uint8_t))
-DECLARE_CODEC_BASE_TYPE(16, htons, ntohs)
-DECLARE_CODEC_BASE_TYPE(32, htonl, ntohl)
-DECLARE_CODEC_BASE_TYPE(64, htonll, ntohll)
+DECLARE_CODEC_BASE_TYPE(8)
+DECLARE_CODEC_BASE_TYPE(16)
+DECLARE_CODEC_BASE_TYPE(32)
+DECLARE_CODEC_BASE_TYPE(64)
static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset,
amqp_bytes_t input)