summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore3
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac1
-rw-r--r--librabbitmq/amqp.h9
-rw-r--r--librabbitmq/amqp_table.c20
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/test_tables.c44
7 files changed, 82 insertions, 3 deletions
diff --git a/.hgignore b/.hgignore
index 045a6ab..325dba1 100644
--- a/.hgignore
+++ b/.hgignore
@@ -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;
+}