summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2013-07-05 15:47:01 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2013-07-06 23:00:56 -0700
commit08af83a97a99c08aaa3878724a07829e0bb955da (patch)
tree6f7f7aab9f3537e473992c9dc72037e27fa92df4
parent31ecd4f52f17dbf9e189625cd1ba2ad08af29851 (diff)
downloadrabbitmq-c-github-ask-08af83a97a99c08aaa3878724a07829e0bb955da.tar.gz
Add amqp_table_clone() to deep-copy a amqp_table_t
-rw-r--r--librabbitmq/amqp.h4
-rw-r--r--librabbitmq/amqp_table.c133
2 files changed, 137 insertions, 0 deletions
diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h
index 6adabe0..24547b3 100644
--- a/librabbitmq/amqp.h
+++ b/librabbitmq/amqp.h
@@ -627,6 +627,10 @@ AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, size_t *offset);
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_table_clone(amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool);
+
struct amqp_connection_info {
char *user;
char *password;
diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c
index 6071ece..d9ac939 100644
--- a/librabbitmq/amqp_table.c
+++ b/librabbitmq/amqp_table.c
@@ -462,3 +462,136 @@ int amqp_table_entry_cmp(void const *entry1, void const *entry2)
return p1->key.len - p2->key.len;
}
+
+static int
+amqp_field_value_clone(amqp_field_value_t *original, amqp_field_value_t *clone, amqp_pool_t *pool)
+{
+ int i;
+ int res;
+ clone->kind = original->kind;
+
+ switch (clone->kind) {
+ case AMQP_FIELD_KIND_BOOLEAN:
+ clone->value.boolean = original->value.boolean;
+ break;
+
+ case AMQP_FIELD_KIND_I8:
+ clone->value.i8 = original->value.i8;
+ break;
+
+ case AMQP_FIELD_KIND_U8:
+ clone->value.u8 = original->value.u8;
+ break;
+
+ case AMQP_FIELD_KIND_I16:
+ clone->value.i16 = original->value.i16;
+ break;
+
+ case AMQP_FIELD_KIND_U16:
+ clone->value.u16 = original->value.u16;
+ break;
+
+ case AMQP_FIELD_KIND_I32:
+ clone->value.i32 = original->value.i32;
+ break;
+
+ case AMQP_FIELD_KIND_U32:
+ clone->value.u32 = original->value.u32;
+ break;
+
+ case AMQP_FIELD_KIND_I64:
+ clone->value.i64 = original->value.i64;
+ break;
+
+ case AMQP_FIELD_KIND_U64:
+ case AMQP_FIELD_KIND_TIMESTAMP:
+ clone->value.u64 = original->value.u64;
+ break;
+
+ case AMQP_FIELD_KIND_F32:
+ clone->value.f32 = original->value.f32;
+ break;
+
+ case AMQP_FIELD_KIND_F64:
+ clone->value.f64 = original->value.f64;
+ break;
+
+ case AMQP_FIELD_KIND_DECIMAL:
+ clone->value.decimal = original->value.decimal;
+ break;
+
+ case AMQP_FIELD_KIND_UTF8:
+ case AMQP_FIELD_KIND_BYTES:
+ amqp_pool_alloc_bytes(pool, original->value.bytes.len, &clone->value.bytes);
+ if (NULL == clone->value.bytes.bytes) {
+ return AMQP_STATUS_NO_MEMORY;
+ }
+ memcpy(clone->value.bytes.bytes, original->value.bytes.bytes, clone->value.bytes.len);
+ break;
+
+ case AMQP_FIELD_KIND_ARRAY:
+ clone->value.array.num_entries = original->value.array.num_entries;
+ clone->value.array.entries = amqp_pool_alloc(pool, clone->value.array.num_entries * sizeof(amqp_field_value_t));
+ if (NULL == clone->value.array.entries) {
+ return AMQP_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < clone->value.array.num_entries; ++i) {
+ res = amqp_field_value_clone(&original->value.array.entries[i], &clone->value.array.entries[i], pool);
+ if (AMQP_STATUS_OK != res) {
+ return res;
+ }
+ }
+ break;
+
+ case AMQP_FIELD_KIND_TABLE:
+ return amqp_table_clone(&original->value.table, &clone->value.table, pool);
+
+ case AMQP_FIELD_KIND_VOID:
+ break;
+
+ default:
+ return AMQP_STATUS_INVALID_PARAMETER;
+ }
+
+ return AMQP_STATUS_OK;
+}
+
+
+static int
+amqp_table_entry_clone(amqp_table_entry_t *original, amqp_table_entry_t *clone, amqp_pool_t *pool)
+{
+ amqp_pool_alloc_bytes(pool, original->key.len, &clone->key);
+ if (NULL == clone->key.bytes) {
+ return AMQP_STATUS_NO_MEMORY;
+ }
+
+ memcpy(clone->key.bytes, original->key.bytes, clone->key.len);
+
+ return amqp_field_value_clone(&original->value, &clone->value, pool);
+}
+
+int
+amqp_table_clone(amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool)
+{
+ int i;
+ int res;
+ clone->num_entries = original->num_entries;
+ clone->entries = amqp_pool_alloc(pool, clone->num_entries * sizeof(amqp_table_entry_t));
+
+ if (NULL == clone->entries) {
+ return AMQP_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < clone->num_entries; ++i) {
+ res = amqp_table_entry_clone(&original->entries[i], &clone->entries[i], pool);
+ if (AMQP_STATUS_OK != res) {
+ goto error_out1;
+ }
+ }
+
+ return AMQP_STATUS_OK;
+
+error_out1:
+ return res;
+}