diff options
author | David Wragg <david@rabbitmq.com> | 2010-10-21 17:49:04 +0100 |
---|---|---|
committer | David Wragg <david@rabbitmq.com> | 2010-10-21 17:49:04 +0100 |
commit | 0d25d02e769dca4ced51580a7d47061717da2bec (patch) | |
tree | 8d5ccaaf6af7f70278b4cb9711ecea24ed4239d5 /librabbitmq/amqp_private.h | |
parent | 905b591638861dafd76d6c9525bf7d9edf64f81f (diff) | |
download | rabbitmq-c-github-ask-0d25d02e769dca4ced51580a7d47061717da2bec.tar.gz |
Introduce new codec helper inline functions; convert amqp_table.c
These replace the macros that relied on gccisms.
Diffstat (limited to 'librabbitmq/amqp_private.h')
-rw-r--r-- | librabbitmq/amqp_private.h | 114 |
1 files changed, 104 insertions, 10 deletions
diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h index 9d7c4e5..905c638 100644 --- a/librabbitmq/amqp_private.h +++ b/librabbitmq/amqp_private.h @@ -53,10 +53,6 @@ #include "config.h" -#ifdef __cplusplus -extern "C" { -#endif - /* Error numbering: Because of differences in error numbering on * different platforms, we want to keep error numbers opaque for * client code. Internally, we encode the category of an error @@ -80,6 +76,8 @@ extern "C" { extern char *amqp_os_error_string(int err); +#include "socket.h" + /* * Connection states: * @@ -148,6 +146,106 @@ struct amqp_connection_state_t_ { amqp_rpc_reply_t most_recent_api_result; }; +static inline void *amqp_offset(void *data, size_t offset) +{ + return (char *)data + offset; +} + +/* assuming a machine that supports unaligned accesses (for now) */ + +#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); \ +} \ + \ +static inline uint##bits##_t amqp_d##bits(void *data, size_t offset) \ +{ \ + return ntohx(*(uint##bits##_t *)amqp_offset(data, offset)); \ +} \ + \ +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); \ + *output = ntohx(*(uint##bits##_t *)((char *)encoded.bytes + o)); \ + return 1; \ + } \ + else { \ + return 0; \ + } \ +} + +/* assuming little endian (for now) */ + +#define DECLARE_XTOXLL(func) \ +static inline uint64_t func##ll(uint64_t val) \ +{ \ + union { \ + uint64_t whole; \ + uint32_t halves[2]; \ + } u = { val }; \ + uint32_t t = u.halves[0]; \ + u.halves[0] = func##l(u.halves[1]); \ + u.halves[1] = func##l(t); \ + return u.whole; \ +} + +DECLARE_XTOXLL(hton) +DECLARE_XTOXLL(ntoh) + +DECLARE_CODEC_BASE_TYPE(8,,) +DECLARE_CODEC_BASE_TYPE(16, htons, ntohs) +DECLARE_CODEC_BASE_TYPE(32, htonl, ntohl) +DECLARE_CODEC_BASE_TYPE(64, htonll, ntohll) + +static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset, + amqp_bytes_t input) +{ + size_t o = *offset; + if ((*offset = o + input.len) <= encoded.len) { + memcpy(amqp_offset(encoded.bytes, o), input.bytes, input.len); + return 1; + } + else { + return 0; + } +} + +static inline int amqp_decode_bytes(amqp_bytes_t encoded, size_t *offset, + amqp_bytes_t *output, size_t len) +{ + size_t o = *offset; + if ((*offset = o + len) <= encoded.len) { + output->bytes = amqp_offset(encoded.bytes, o); + output->len = len; + return 1; + } + else { + return 0; + } +} + + #define CHECK_LIMIT(b, o, l, v) ({ if ((o + l) > (b).len) { return -ERROR_BAD_AMQP_DATA; } (v); }) #define BUF_AT(b, o) (&(((uint8_t *) (b).bytes)[o])) @@ -175,11 +273,11 @@ struct amqp_connection_state_t_ { extern int amqp_decode_table(amqp_bytes_t encoded, amqp_pool_t *pool, amqp_table_t *output, - int *offsetptr); + size_t *offset); extern int amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, - int *offsetptr); + size_t *offset); #define amqp_assert(condition, ...) \ ({ \ @@ -205,8 +303,4 @@ extern void amqp_dump(void const *buffer, size_t len); #define amqp_dump(buffer, len) ((void) 0) #endif -#ifdef __cplusplus -} -#endif - #endif |