summaryrefslogtreecommitdiff
path: root/librabbitmq/amqp_private.h
diff options
context:
space:
mode:
authorDavid Wragg <david@rabbitmq.com>2010-10-21 17:49:04 +0100
committerDavid Wragg <david@rabbitmq.com>2010-10-21 17:49:04 +0100
commit0d25d02e769dca4ced51580a7d47061717da2bec (patch)
tree8d5ccaaf6af7f70278b4cb9711ecea24ed4239d5 /librabbitmq/amqp_private.h
parent905b591638861dafd76d6c9525bf7d9edf64f81f (diff)
downloadrabbitmq-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.h114
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