diff options
-rw-r--r-- | .hgignore | 3 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | librabbitmq/amqp.h | 9 | ||||
-rw-r--r-- | librabbitmq/amqp_table.c | 20 | ||||
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/test_tables.c | 44 |
7 files changed, 82 insertions, 3 deletions
@@ -18,7 +18,8 @@ ^librabbitmq/amqp_framing\.[ch]$ -^(|librabbitmq/|examples/)Makefile(\.in)?$ +^(|librabbitmq/|tests/|examples/)Makefile(\.in)?$ +^tests/test_tables$ ^examples/amqp_sendstring$ ^examples/amqp_exchange_declare$ ^examples/amqp_listen$ diff --git a/Makefile.am b/Makefile.am index 60be0cf..8f774b5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ -SUBDIRS=librabbitmq examples +SUBDIRS=librabbitmq tests examples squeakyclean: maintainer-clean - rm -f Makefile.in librabbitmq/Makefile.in examples/Makefile.in + rm -f Makefile.in librabbitmq/Makefile.in tests/Makefile.in examples/Makefile.in rm -f aclocal.m4 rm -f config.guess config.h.in* config.sub configure rm -f depcomp install-sh ltmain.sh missing diff --git a/configure.ac b/configure.ac index d158c6a..9939973 100644 --- a/configure.ac +++ b/configure.ac @@ -30,5 +30,6 @@ AC_SUBST(AMQP_SPEC_JSON_PATH) AC_OUTPUT( Makefile librabbitmq/Makefile +tests/Makefile examples/Makefile ) diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index c5314fb..f27af7f 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -20,6 +20,8 @@ typedef struct amqp_decimal_t_ { uint32_t value; } amqp_decimal_t; +#define AMQP_DECIMAL(d,v) ((amqp_decimal_t) { .decimals = (d), .value = (v) }) + typedef struct amqp_table_t_ { int num_entries; struct amqp_table_entry_t_ *entries; @@ -37,6 +39,13 @@ typedef struct amqp_table_entry_t_ { } value; } amqp_table_entry_t; +#define _AMQP_TE_INIT(ke,ki,v) { .key = (ke), .kind = (ki), .value = { v } } +#define AMQP_TABLE_ENTRY_S(k,v) _AMQP_TE_INIT(amqp_cstring_bytes(k), 'S', .bytes = (v)) +#define AMQP_TABLE_ENTRY_I(k,v) _AMQP_TE_INIT(amqp_cstring_bytes(k), 'I', .i32 = (v)) +#define AMQP_TABLE_ENTRY_D(k,v) _AMQP_TE_INIT(amqp_cstring_bytes(k), 'D', .decimal = (v)) +#define AMQP_TABLE_ENTRY_T(k,v) _AMQP_TE_INIT(amqp_cstring_bytes(k), 'T', .u64 = (v)) +#define AMQP_TABLE_ENTRY_F(k,v) _AMQP_TE_INIT(amqp_cstring_bytes(k), 'F', .table = (v)) + typedef struct amqp_pool_blocklist_t_ { int num_blocks; void **blocklist; diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c index e881f7b..16d85ff 100644 --- a/librabbitmq/amqp_table.c +++ b/librabbitmq/amqp_table.c @@ -7,6 +7,8 @@ #include "amqp.h" #include "amqp_private.h" +#include <assert.h> + #define INITIAL_TABLE_SIZE 16 int amqp_decode_table(amqp_bytes_t encoded, @@ -148,3 +150,21 @@ int amqp_encode_table(amqp_bytes_t encoded, *offsetptr = offset; return 0; } + +int amqp_table_entry_cmp(void const *entry1, void const *entry2) { + amqp_table_entry_t const *p1 = (amqp_table_entry_t const *) entry1; + amqp_table_entry_t const *p2 = (amqp_table_entry_t const *) entry2; + + int d; + int minlen; + + minlen = p1->key.len; + if (p2->key.len < minlen) minlen = p2->key.len; + + d = memcmp(p1->key.bytes, p2->key.bytes, minlen); + if (d != 0) { + return d; + } + + return p1->key.len - p2->key.len; +} diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..dafdba4 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,4 @@ +noinst_PROGRAMS = test_tables + +AM_CFLAGS = -I../librabbitmq +AM_LDFLAGS = ../librabbitmq/librabbitmq.la diff --git a/tests/test_tables.c b/tests/test_tables.c new file mode 100644 index 0000000..9631f49 --- /dev/null +++ b/tests/test_tables.c @@ -0,0 +1,44 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include <stdint.h> +#include <amqp.h> +#include <amqp_framing.h> + +#include <unistd.h> +#include <assert.h> + +int main(int argc, char const * const *argv) { + amqp_table_entry_t entries[8] = { AMQP_TABLE_ENTRY_S("zebra", amqp_cstring_bytes("last")), + AMQP_TABLE_ENTRY_S("aardvark", amqp_cstring_bytes("first")), + AMQP_TABLE_ENTRY_S("middle", amqp_cstring_bytes("third")), + AMQP_TABLE_ENTRY_I("number", 1234), + AMQP_TABLE_ENTRY_D("decimal", AMQP_DECIMAL(2, 1234)), + AMQP_TABLE_ENTRY_T("time", (uint64_t) 1234123412341234LL), + AMQP_TABLE_ENTRY_S("beta", amqp_cstring_bytes("second")), + AMQP_TABLE_ENTRY_S("wombat", amqp_cstring_bytes("fourth")) }; + amqp_table_t table = { .num_entries = sizeof(entries) / sizeof(entries[0]), + .entries = &entries[0] }; + int i; + + qsort(table.entries, table.num_entries, sizeof(amqp_table_entry_t), &amqp_table_entry_cmp); + + for (i = 0; i < table.num_entries; i++) { + amqp_table_entry_t *e = &table.entries[i]; + printf("%.*s -> %c (", (int) e->key.len, (char *) e->key.bytes, e->kind); + switch (e->kind) { + case 'S': printf("%.*s", (int) e->value.bytes.len, (char *) e->value.bytes.bytes); break; + case 'I': printf("%d", e->value.i32); break; + case 'D': printf("%d:::%u", e->value.decimal.decimals, e->value.decimal.value); break; + case 'T': printf("%llu", e->value.u64); break; + case 'F': printf("..."); break; + default: printf("???"); break; + } + printf(")\n"); + } + + return 0; +} |