diff options
Diffstat (limited to 'librabbitmq/amqp_table.c')
-rw-r--r-- | librabbitmq/amqp_table.c | 441 |
1 files changed, 0 insertions, 441 deletions
diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c deleted file mode 100644 index e85217f..0000000 --- a/librabbitmq/amqp_table.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. - * - * The Original Code is librabbitmq. - * - * The Initial Developers of the Original Code are LShift Ltd, Cohesive - * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions - * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive - * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright - * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and - * Rabbit Technologies Ltd. - * - * Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift - * Ltd. Portions created by Cohesive Financial Technologies LLC are - * Copyright (C) 2007-2009 Cohesive Financial Technologies - * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) - * 2007-2009 Rabbit Technologies Ltd. - * - * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 - * LShift Ltd and Tony Garnock-Jones. - * - * All Rights Reserved. - * - * Contributor(s): ______________________________________. - * - * Alternatively, the contents of this file may be used under the terms - * of the GNU General Public License Version 2 or later (the "GPL"), in - * which case the provisions of the GPL are applicable instead of those - * above. If you wish to allow use of your version of this file only - * under the terms of the GPL, and not to allow others to use your - * version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the - * notice and other provisions required by the GPL. If you do not - * delete the provisions above, a recipient may use your version of - * this file under the terms of any one of the MPL or the GPL. - * - * ***** END LICENSE BLOCK ***** - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdint.h> - -#include "amqp.h" -#include "amqp_private.h" - -#include <assert.h> - -#define INITIAL_ARRAY_SIZE 16 -#define INITIAL_TABLE_SIZE 16 - -static int amqp_decode_field_value(amqp_bytes_t encoded, - amqp_pool_t *pool, - amqp_field_value_t *entry, - size_t *offset); - -static int amqp_encode_field_value(amqp_bytes_t encoded, - amqp_field_value_t *entry, - size_t *offset); - -/*---------------------------------------------------------------------------*/ - -static int amqp_decode_array(amqp_bytes_t encoded, - amqp_pool_t *pool, - amqp_array_t *output, - size_t *offset) -{ - uint32_t arraysize; - int num_entries = 0; - int allocated_entries = INITIAL_ARRAY_SIZE; - amqp_field_value_t *entries; - size_t limit; - int res; - - if (!amqp_decode_32(encoded, offset, &arraysize)) - return -ERROR_BAD_AMQP_DATA; - - entries = malloc(allocated_entries * sizeof(amqp_field_value_t)); - if (entries == NULL) - return -ERROR_NO_MEMORY; - - limit = *offset + arraysize; - while (*offset < limit) { - if (num_entries >= allocated_entries) { - void *newentries; - allocated_entries = allocated_entries * 2; - newentries = realloc(entries, allocated_entries * sizeof(amqp_field_value_t)); - res = -ERROR_NO_MEMORY; - if (newentries == NULL) - goto out; - - entries = newentries; - } - - res = amqp_decode_field_value(encoded, pool, &entries[num_entries], - offset); - if (res < 0) - goto out; - - num_entries++; - } - - output->num_entries = num_entries; - output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_field_value_t)); - res = -ERROR_NO_MEMORY; - /* NULL is legitimate if we requested a zero-length block. */ - if (output->entries == NULL && num_entries > 0) - goto out; - - memcpy(output->entries, entries, num_entries * sizeof(amqp_field_value_t)); - res = 0; - - out: - free(entries); - return res; -} - -int amqp_decode_table(amqp_bytes_t encoded, - amqp_pool_t *pool, - amqp_table_t *output, - size_t *offset) -{ - uint32_t tablesize; - int num_entries = 0; - amqp_table_entry_t *entries; - int allocated_entries = INITIAL_TABLE_SIZE; - size_t limit; - int res; - - if (!amqp_decode_32(encoded, offset, &tablesize)) - return -ERROR_BAD_AMQP_DATA; - - entries = malloc(allocated_entries * sizeof(amqp_table_entry_t)); - if (entries == NULL) - return -ERROR_NO_MEMORY; - - limit = *offset + tablesize; - while (*offset < limit) { - uint8_t keylen; - - res = -ERROR_BAD_AMQP_DATA; - if (!amqp_decode_8(encoded, offset, &keylen)) - goto out; - - if (num_entries >= allocated_entries) { - void *newentries; - allocated_entries = allocated_entries * 2; - newentries = realloc(entries, allocated_entries * sizeof(amqp_table_entry_t)); - res = -ERROR_NO_MEMORY; - if (newentries == NULL) - goto out; - - entries = newentries; - } - - res = -ERROR_BAD_AMQP_DATA; - if (!amqp_decode_bytes(encoded, offset, &entries[num_entries].key, keylen)) - goto out; - - res = amqp_decode_field_value(encoded, pool, &entries[num_entries].value, - offset); - if (res < 0) - goto out; - - num_entries++; - } - - output->num_entries = num_entries; - output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_table_entry_t)); - res = -ERROR_NO_MEMORY; - /* NULL is legitimate if we requested a zero-length block. */ - if (output->entries == NULL && num_entries > 0) - goto out; - - memcpy(output->entries, entries, num_entries * sizeof(amqp_table_entry_t)); - res = 0; - - out: - free(entries); - return res; -} - -static int amqp_decode_field_value(amqp_bytes_t encoded, - amqp_pool_t *pool, - amqp_field_value_t *entry, - size_t *offset) -{ - int res = -ERROR_BAD_AMQP_DATA; - - if (!amqp_decode_8(encoded, offset, &entry->kind)) - goto out; - -#define TRIVIAL_FIELD_DECODER(bits) if (!amqp_decode_##bits(encoded, offset, &entry->value.u##bits)) goto out; break -#define SIMPLE_FIELD_DECODER(bits, dest, how) { uint##bits##_t val; if (!amqp_decode_##bits(encoded, offset, &val)) goto out; entry->value.dest = how; } break - - switch (entry->kind) { - case AMQP_FIELD_KIND_BOOLEAN: - SIMPLE_FIELD_DECODER(8, boolean, val ? 1 : 0); - - case AMQP_FIELD_KIND_I8: - SIMPLE_FIELD_DECODER(8, i8, (int8_t)val); - case AMQP_FIELD_KIND_U8: - TRIVIAL_FIELD_DECODER(8); - - case AMQP_FIELD_KIND_I16: - SIMPLE_FIELD_DECODER(16, i16, (int16_t)val); - case AMQP_FIELD_KIND_U16: - TRIVIAL_FIELD_DECODER(16); - - case AMQP_FIELD_KIND_I32: - SIMPLE_FIELD_DECODER(32, i32, (int32_t)val); - case AMQP_FIELD_KIND_U32: - TRIVIAL_FIELD_DECODER(32); - - case AMQP_FIELD_KIND_I64: - SIMPLE_FIELD_DECODER(64, i64, (int64_t)val); - case AMQP_FIELD_KIND_U64: - TRIVIAL_FIELD_DECODER(64); - - case AMQP_FIELD_KIND_F32: - TRIVIAL_FIELD_DECODER(32); - /* and by punning, f32 magically gets the right value...! */ - - case AMQP_FIELD_KIND_F64: - TRIVIAL_FIELD_DECODER(64); - /* and by punning, f64 magically gets the right value...! */ - - case AMQP_FIELD_KIND_DECIMAL: - if (!amqp_decode_8(encoded, offset, &entry->value.decimal.decimals) - || !amqp_decode_32(encoded, offset, &entry->value.decimal.value)) - goto out; - break; - - case AMQP_FIELD_KIND_UTF8: - /* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the - same implementation, but different interpretations. */ - /* fall through */ - case AMQP_FIELD_KIND_BYTES: { - uint32_t len; - if (!amqp_decode_32(encoded, offset, &len) - || !amqp_decode_bytes(encoded, offset, &entry->value.bytes, len)) - goto out; - break; - } - - case AMQP_FIELD_KIND_ARRAY: - res = amqp_decode_array(encoded, pool, &(entry->value.array), offset); - goto out; - - case AMQP_FIELD_KIND_TIMESTAMP: - TRIVIAL_FIELD_DECODER(64); - - case AMQP_FIELD_KIND_TABLE: - res = amqp_decode_table(encoded, pool, &(entry->value.table), offset); - goto out; - - case AMQP_FIELD_KIND_VOID: - break; - - default: - goto out; - } - - res = 0; - - out: - return res; -} - -/*---------------------------------------------------------------------------*/ - -static int amqp_encode_array(amqp_bytes_t encoded, - amqp_array_t *input, - size_t *offset) -{ - size_t start = *offset; - int i, res; - - *offset += 4; /* size of the array gets filled in later on */ - - for (i = 0; i < input->num_entries; i++) { - res = amqp_encode_field_value(encoded, &input->entries[i], offset); - if (res < 0) - goto out; - } - - if (amqp_encode_32(encoded, &start, *offset - start - 4)) - res = 0; - else - res = -ERROR_BAD_AMQP_DATA; - - out: - return res; -} - -int amqp_encode_table(amqp_bytes_t encoded, - amqp_table_t *input, - size_t *offset) -{ - size_t start = *offset; - int i, res; - - *offset += 4; /* size of the table gets filled in later on */ - - for (i = 0; i < input->num_entries; i++) { - res = amqp_encode_8(encoded, offset, input->entries[i].key.len); - if (res < 0) - goto out; - - res = amqp_encode_bytes(encoded, offset, input->entries[i].key); - if (res < 0) - goto out; - - res = amqp_encode_field_value(encoded, &input->entries[i].value, offset); - if (res < 0) - goto out; - } - - if (amqp_encode_32(encoded, &start, *offset - start - 4)) - res = 0; - else - res = -ERROR_BAD_AMQP_DATA; - - out: - return res; -} - -static int amqp_encode_field_value(amqp_bytes_t encoded, - amqp_field_value_t *entry, - size_t *offset) -{ - int res = -ERROR_BAD_AMQP_DATA; - - if (!amqp_encode_8(encoded, offset, entry->kind)) - goto out; - -#define FIELD_ENCODER(bits, val) if (!amqp_encode_##bits(encoded, offset, val)) goto out; break - - switch (entry->kind) { - case AMQP_FIELD_KIND_BOOLEAN: - FIELD_ENCODER(8, entry->value.boolean ? 1 : 0); - - case AMQP_FIELD_KIND_I8: - FIELD_ENCODER(8, entry->value.i8); - case AMQP_FIELD_KIND_U8: - FIELD_ENCODER(8, entry->value.u8); - - case AMQP_FIELD_KIND_I16: - FIELD_ENCODER(16, entry->value.i16); - case AMQP_FIELD_KIND_U16: - FIELD_ENCODER(16, entry->value.u16); - - case AMQP_FIELD_KIND_I32: - FIELD_ENCODER(32, entry->value.i32); - case AMQP_FIELD_KIND_U32: - FIELD_ENCODER(32, entry->value.u32); - - case AMQP_FIELD_KIND_I64: - FIELD_ENCODER(64, entry->value.i64); - case AMQP_FIELD_KIND_U64: - FIELD_ENCODER(64, entry->value.u64); - - case AMQP_FIELD_KIND_F32: - /* by punning, u32 magically gets the right value...! */ - FIELD_ENCODER(32, entry->value.u32); - - case AMQP_FIELD_KIND_F64: - /* by punning, u64 magically gets the right value...! */ - FIELD_ENCODER(64, entry->value.u64); - - case AMQP_FIELD_KIND_DECIMAL: - if (!amqp_encode_8(encoded, offset, entry->value.decimal.decimals) - || !amqp_encode_32(encoded, offset, entry->value.decimal.value)) - goto out; - break; - - case AMQP_FIELD_KIND_UTF8: - /* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the - same implementation, but different interpretations. */ - /* fall through */ - case AMQP_FIELD_KIND_BYTES: - if (!amqp_encode_32(encoded, offset, entry->value.bytes.len) - || !amqp_encode_bytes(encoded, offset, entry->value.bytes)) - goto out; - break; - - case AMQP_FIELD_KIND_ARRAY: - res = amqp_encode_array(encoded, &entry->value.array, offset); - goto out; - - case AMQP_FIELD_KIND_TIMESTAMP: - FIELD_ENCODER(64, entry->value.u64); - - case AMQP_FIELD_KIND_TABLE: - res = amqp_encode_table(encoded, &entry->value.table, offset); - goto out; - - case AMQP_FIELD_KIND_VOID: - break; - - default: - abort(); - } - - res = 0; - - out: - return res; -} - -/*---------------------------------------------------------------------------*/ - -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; -} |