You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2012/03/08 19:33:47 UTC
svn commit: r1298498 [3/3] - in /qpid/proton/proton-c: ./ include/
include/proton/ mllib/ src/ src/codec/ src/engine/ src/framing/ src/types/
Added: qpid/proton/proton-c/src/types/array.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/array.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/array.c (added)
+++ qpid/proton/proton-c/src/types/array.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,156 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/util.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include "../codec/encodings.h"
+#include "value-internal.h"
+
+static char type_to_code(enum TYPE type)
+{
+ switch (type)
+ {
+ case EMPTY: return 'n';
+ case BYTE: return 'b';
+ case UBYTE: return 'B';
+ case SHORT: return 'h';
+ case USHORT: return 'H';
+ case INT: return 'i';
+ case UINT: return 'I';
+ case LONG: return 'l';
+ case ULONG: return 'L';
+ case FLOAT: return 'f';
+ case DOUBLE: return 'd';
+ case CHAR: return 'C';
+ case STRING: return 'S';
+ case BINARY: return 'z';
+ case LIST: return 't';
+ case MAP: return 'm';
+ default: return -1;
+ }
+}
+
+static uint8_t type_to_amqp_code(enum TYPE type)
+{
+ switch (type)
+ {
+ case EMPTY: return PNE_NULL;
+ case BOOLEAN: return PNE_BOOLEAN;
+ case BYTE: return PNE_BYTE;
+ case UBYTE: return PNE_UBYTE;
+ case SHORT: return PNE_SHORT;
+ case USHORT: return PNE_USHORT;
+ case INT: return PNE_INT;
+ case UINT: return PNE_UINT;
+ case CHAR: return PNE_UTF32;
+ case LONG: return PNE_LONG;
+ case ULONG: return PNE_ULONG;
+ case FLOAT: return PNE_FLOAT;
+ case DOUBLE: return PNE_DOUBLE;
+ case STRING: return PNE_STR32_UTF8;
+ case BINARY: return PNE_VBIN32;
+ case LIST: return PNE_LIST32;
+ case MAP: return PNE_MAP32;
+ case ARRAY: return PNE_ARRAY32;
+ default:
+ pn_fatal("no amqp code for type: %i", type);
+ return -1;
+ }
+}
+
+pn_array_t *pn_array(enum TYPE type, int capacity)
+{
+ pn_array_t *l = malloc(sizeof(pn_array_t) + capacity*sizeof(pn_value_t));
+ if (l) {
+ l->type = type;
+ l->capacity = capacity;
+ l->size = 0;
+ }
+ return l;
+}
+
+void pn_free_array(pn_array_t *a)
+{
+ free(a);
+}
+
+void pn_visit_array(pn_array_t *a, void (*visitor)(pn_value_t))
+{
+ for (int i = 0; i < a->size; i++)
+ {
+ pn_visit(a->values[i], visitor);
+ }
+}
+
+size_t pn_format_sizeof_array(pn_array_t *array)
+{
+ size_t result = 4;
+ for (int i = 0; i < array->size; i++)
+ {
+ result += pn_format_sizeof(array->values[i]) + 2;
+ }
+ return result;
+}
+
+int pn_format_array(char **pos, char *limit, pn_array_t *array)
+{
+ int e;
+ if ((e = pn_fmt(pos, limit, "@%c[", type_to_code(array->type)))) return e;
+ if ((e = pn_format_value(pos, limit, array->values, array->size))) return e;
+ if ((e = pn_fmt(pos, limit, "]"))) return e;
+ return 0;
+}
+
+size_t pn_encode_sizeof_array(pn_array_t *array)
+{
+ size_t result = 9;
+ for (int i = 0; i < array->size; i++)
+ {
+ // XXX: this is wrong, need to compensate for code
+ result += pn_encode_sizeof(array->values[i]);
+ }
+ return result;
+}
+
+size_t pn_encode_array(pn_array_t *array, char *out)
+{
+ // code
+ out[0] = (uint8_t) PNE_ARRAY32;
+ // size will be backfilled
+ // count
+ *((uint32_t *) (out + 5)) = htonl(array->size);
+ // element code
+ out[9] = (uint8_t) type_to_amqp_code(array->type);
+
+ char *vout = out + 10;
+ for (int i = 0; i < array->size; i++)
+ {
+ char *codeptr = vout - 1;
+ char codeval = *codeptr;
+ vout += pn_encode(array->values[i], vout-1) - 1;
+ *codeptr = codeval;
+ }
+
+ // backfill size
+ *((uint32_t *) (out + 1)) = htonl(vout - out - 5);
+ return vout - out;
+}
Added: qpid/proton/proton-c/src/types/binary.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/binary.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/binary.c (added)
+++ qpid/proton/proton-c/src/types/binary.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,101 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/codec.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "value-internal.h"
+
+pn_binary_t *pn_binary(char *bytes, size_t size)
+{
+ pn_binary_t *bin = malloc(sizeof(pn_binary_t) + size);
+ bin->size = size;
+ memmove(bin->bytes, bytes, size);
+ return bin;
+}
+
+void pn_free_binary(pn_binary_t *b)
+{
+ free(b);
+}
+
+size_t pn_binary_size(pn_binary_t *b)
+{
+ return b->size;
+}
+
+char *pn_binary_bytes(pn_binary_t *b)
+{
+ return b->bytes;
+}
+
+uintptr_t pn_hash_binary(pn_binary_t *b)
+{
+ uintptr_t hash = 0;
+ for (int i = 0; i < b->size; i++)
+ {
+ hash = 31*hash + b->bytes[i];
+ }
+ return hash;
+}
+
+int pn_compare_binary(pn_binary_t *a, pn_binary_t *b)
+{
+ if (a->size == b->size)
+ return memcmp(a->bytes, b->bytes, a->size);
+ else
+ return b->size - a->size;
+}
+
+pn_binary_t *pn_binary_dup(pn_binary_t *b)
+{
+ return pn_binary(b->bytes, b->size);
+}
+
+int pn_format_binary(char **pos, char *limit, pn_binary_t *binary)
+{
+ if (!binary) return pn_fmt(pos, limit, "(null)");
+
+ for (int i = 0; i < binary->size; i++)
+ {
+ uint8_t b = binary->bytes[i];
+ if (isprint(b)) {
+ if (*pos < limit) {
+ **pos = b;
+ *pos += 1;
+ } else {
+ return -1;
+ }
+ } else {
+ if (limit - *pos > 4)
+ {
+ sprintf(*pos, "\\x%.2x", b);
+ *pos += 4;
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
Added: qpid/proton/proton-c/src/types/decode.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/decode.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/decode.c (added)
+++ qpid/proton/proton-c/src/types/decode.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,272 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/codec.h>
+#include <iconv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "../codec/encodings.h"
+#include "value-internal.h"
+
+static enum TYPE amqp_code_to_type(uint8_t code)
+{
+ switch (code)
+ {
+ case PNE_NULL: return EMPTY;
+ // case PNE_TRUE:
+ // case PNE_FALSE:
+ // case PNE_BOOLEAN: return BOOLEAN;
+ case PNE_UBYTE: return UBYTE;
+ case PNE_BYTE: return BYTE;
+ case PNE_USHORT: return USHORT;
+ case PNE_SHORT: return SHORT;
+ case PNE_UINT:
+ case PNE_UINT0: return UINT;
+ case PNE_INT: return INT;
+ case PNE_FLOAT: return FLOAT;
+ case PNE_ULONG0:
+ case PNE_ULONG: return ULONG;
+ case PNE_LONG: return LONG;
+ case PNE_DOUBLE: return DOUBLE;
+ case PNE_VBIN8:
+ case PNE_VBIN32: return BINARY;
+ case PNE_STR8_UTF8:
+ case PNE_STR32_UTF8: return STRING;
+ // case PNE_SYM8:
+ // case PNE_SYM32: return SYMBOL;
+ case PNE_LIST0:
+ case PNE_LIST8:
+ case PNE_LIST32: return LIST;
+ case PNE_ARRAY8:
+ case PNE_ARRAY32: return ARRAY;
+ case PNE_MAP8:
+ case PNE_MAP32: return MAP;
+ }
+ return -1;
+}
+
+struct pn_decode_context_frame_st {
+ size_t count;
+ size_t limit;
+ pn_value_t *values;
+};
+
+struct pn_decode_context_st {
+ size_t depth;
+ struct pn_decode_context_frame_st frames[1024];
+};
+
+#define CTX_CAST(ctx) ((struct pn_decode_context_st *) (ctx))
+
+static void push_frame(void *ptr, pn_value_t *values, size_t limit)
+{
+ struct pn_decode_context_st *ctx = CTX_CAST(ptr);
+ struct pn_decode_context_frame_st *frm = &ctx->frames[ctx->depth++];
+ frm->count = 0;
+ frm->limit = limit;
+ frm->values = values;
+}
+
+static struct pn_decode_context_frame_st *frame(void *ptr)
+{
+ struct pn_decode_context_st *ctx = CTX_CAST(ptr);
+ return &ctx->frames[ctx->depth-1];
+}
+
+static void autopop(void *ptr)
+{
+ struct pn_decode_context_st *ctx = CTX_CAST(ptr);
+ struct pn_decode_context_frame_st *frm = frame(ptr);
+ while (frm->limit && frm->count == frm->limit) {
+ ctx->depth--;
+ frm = frame(ptr);
+ }
+}
+
+static void pop_frame(void *ptr)
+{
+ autopop(ptr);
+ struct pn_decode_context_st *ctx = CTX_CAST(ptr);
+ ctx->depth--;
+}
+
+static pn_value_t *next_value(void *ptr)
+{
+ autopop(ptr);
+ struct pn_decode_context_frame_st *frm = frame(ptr);
+ pn_value_t *result = &frm->values[frm->count++];
+ return result;
+}
+
+static pn_value_t *curr_value(void *ptr)
+{
+ struct pn_decode_context_st *ctx = CTX_CAST(ptr);
+ struct pn_decode_context_frame_st *frm = &ctx->frames[ctx->depth-1];
+ return &frm->values[frm->count - 1];
+}
+
+void pn_decode_null(void *ctx) {
+ pn_value_t *value = next_value(ctx);
+ value->type = EMPTY;
+}
+void pn_decode_bool(void *ctx, bool v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = BOOLEAN;
+ value->u.as_boolean = v;
+}
+void pn_decode_ubyte(void *ctx, uint8_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = UBYTE;
+ value->u.as_ubyte = v;
+}
+void pn_decode_byte(void *ctx, int8_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = BYTE;
+ value->u.as_byte = v;
+}
+void pn_decode_ushort(void *ctx, uint16_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = USHORT;
+ value->u.as_ushort = v;
+}
+void pn_decode_short(void *ctx, int16_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = SHORT;
+ value->u.as_short = v;
+}
+void pn_decode_uint(void *ctx, uint32_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = UINT;
+ value->u.as_uint = v;
+}
+void pn_decode_int(void *ctx, int32_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = INT;
+ value->u.as_int = v;
+}
+void pn_decode_float(void *ctx, float f) {
+ pn_value_t *value = next_value(ctx);
+ value->type = FLOAT;
+ value->u.as_float = f;
+}
+void pn_decode_ulong(void *ctx, uint64_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = ULONG;
+ value->u.as_ulong = v;
+}
+void pn_decode_long(void *ctx, int64_t v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = LONG;
+ value->u.as_long = v;
+}
+void pn_decode_double(void *ctx, double v) {
+ pn_value_t *value = next_value(ctx);
+ value->type = DOUBLE;
+ value->u.as_double = v;
+}
+void pn_decode_binary(void *ctx, size_t size, char *bytes) {
+ pn_value_t *value = next_value(ctx);
+ value->type = BINARY;
+ value->u.as_binary = pn_binary(bytes, size);
+}
+void pn_decode_utf8(void *ctx, size_t size, char *bytes) {
+ pn_value_t *value = next_value(ctx);
+ value->type = STRING;
+ size_t remaining = (size+1)*sizeof(wchar_t);
+ wchar_t buf[size+1];
+ iconv_t cd = iconv_open("WCHAR_T", "UTF-8");
+ wchar_t *out = buf;
+ size_t n = iconv(cd, &bytes, &size, (char **)&out, &remaining);
+ if (n == -1)
+ {
+ perror("pn_decode_utf8");
+ }
+ *out = L'\0';
+ iconv_close(cd);
+ value->u.as_string = pn_string(buf);
+}
+void pn_decode_symbol(void *ctx, size_t size, char *bytes) {
+ // pn_value_t *value = next_value(ctx);
+ // value->type = SYMBOL;
+ // value->u.as_symbol = {.size = size, .bytes = bytes};
+}
+
+void pn_decode_start_array(void *ctx, size_t count, uint8_t code) {
+ pn_value_t *value = next_value(ctx);
+ value->type = ARRAY;
+ value->u.as_array = pn_array(amqp_code_to_type(code), count);
+ push_frame(ctx, value->u.as_array->values, 0);
+}
+void pn_decode_stop_array(void *ctx, size_t count, uint8_t code) {
+ pop_frame(ctx);
+ pn_value_t *value = curr_value(ctx);
+ value->u.as_array->size = count;
+}
+
+void pn_decode_start_list(void *ctx, size_t count) {
+ pn_value_t *value = next_value(ctx);
+ value->type = LIST;
+ value->u.as_list = pn_list(count);
+ push_frame(ctx, value->u.as_list->values, 0);
+}
+
+void pn_decode_stop_list(void *ctx, size_t count) {
+ pop_frame(ctx);
+ pn_value_t *value = curr_value(ctx);
+ value->u.as_list->size = count;
+}
+
+void pn_decode_start_map(void *ctx, size_t count) {
+ pn_value_t *value = next_value(ctx);
+ value->type = MAP;
+ value->u.as_map = pn_map(count/2);
+ push_frame(ctx, value->u.as_map->pairs, 0);
+}
+
+void pn_decode_stop_map(void *ctx, size_t count) {
+ pop_frame(ctx);
+ pn_value_t *value = curr_value(ctx);
+ value->u.as_map->size = count/2;
+}
+
+void pn_decode_start_descriptor(void *ctx) {
+ pn_value_t *value = next_value(ctx);
+ value->type = TAG;
+ value->u.as_tag = pn_tag(EMPTY_VALUE, EMPTY_VALUE);
+ push_frame(ctx, &value->u.as_tag->descriptor, 0);
+}
+
+void pn_decode_stop_descriptor(void *ctx) {
+ pop_frame(ctx);
+ pn_value_t *value = curr_value(ctx);
+ push_frame(ctx, &value->u.as_tag->value, 1);
+}
+
+pn_data_callbacks_t *pn_decoder = &PN_DATA_CALLBACKS(pn_decode);
+
+ssize_t pn_decode(pn_value_t *v, char *bytes, size_t n)
+{
+ struct pn_decode_context_st ctx = {.depth = 0};
+ push_frame(&ctx, v, 0);
+ ssize_t read = pn_read_datum(bytes, n, pn_decoder, &ctx);
+ return read;
+}
Added: qpid/proton/proton-c/src/types/list.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/list.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/list.c (added)
+++ qpid/proton/proton-c/src/types/list.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,212 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/codec.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "value-internal.h"
+
+pn_list_t *pn_list(int capacity)
+{
+ pn_list_t *l = malloc(sizeof(pn_list_t) + capacity*sizeof(pn_value_t));
+ if (l) {
+ l->capacity = capacity;
+ l->size = 0;
+ }
+ return l;
+}
+
+void pn_free_list(pn_list_t *l)
+{
+ free(l);
+}
+
+void pn_visit_list(pn_list_t *l, void (*visitor)(pn_value_t))
+{
+ for (int i = 0; i < l->size; i++)
+ {
+ pn_visit(l->values[i], visitor);
+ }
+}
+
+int pn_list_size(pn_list_t *l)
+{
+ return l->size;
+}
+
+pn_value_t pn_list_get(pn_list_t *l, int index)
+{
+ if (index < l->size)
+ return l->values[index];
+ else
+ return EMPTY_VALUE;
+}
+
+pn_value_t pn_list_set(pn_list_t *l, int index, pn_value_t v)
+{
+ pn_value_t r = l->values[index];
+ l->values[index] = v;
+ return r;
+}
+
+pn_value_t pn_list_pop(pn_list_t *l, int index)
+{
+ int i, n = l->size;
+ pn_value_t v = l->values[index];
+ for (i = index; i < n - 1; i++)
+ l->values[i] = l->values[i+1];
+ l->size--;
+ return v;
+}
+
+int pn_list_add(pn_list_t *l, pn_value_t v)
+{
+ if (l->capacity <= l->size) {
+ fprintf(stderr, "wah!\n");
+ return -1;
+ }
+
+ l->values[l->size++] = v;
+ return 0;
+}
+
+int pn_list_extend(pn_list_t *l, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int n = pn_vscan(l->values + l->size, fmt, ap);
+ va_end(ap);
+ if (n > 0) l->size += n;
+ return n;
+}
+
+int pn_list_index(pn_list_t *l, pn_value_t v)
+{
+ int i, n = l->size;
+ for (i = 0; i < n; i++)
+ if (pn_compare_value(v, l->values[i]) == 0)
+ return i;
+ return -1;
+}
+
+bool pn_list_remove(pn_list_t *l, pn_value_t v)
+{
+ int i = pn_list_index(l, v);
+ if (i >= 0) {
+ pn_list_pop(l, i);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int pn_list_fill(pn_list_t *l, pn_value_t v, int n)
+{
+ int i, e;
+
+ for (i = 0; i < n; i++)
+ if ((e = pn_list_add(l, v))) return e;
+
+ return 0;
+}
+
+void pn_list_clear(pn_list_t *l)
+{
+ l->size = 0;
+}
+
+static int min(int a, int b)
+{
+ if (a < b)
+ return a;
+ else
+ return b;
+}
+
+size_t pn_format_sizeof_list(pn_list_t *list)
+{
+ size_t result = 2;
+ for (int i = 0; i < list->size; i++) {
+ result += pn_format_sizeof(list->values[i]) + 2;
+ }
+ return result;
+}
+
+int pn_format_list(char **pos, char *limit, pn_list_t *list)
+{
+ int e;
+ if ((e = pn_fmt(pos, limit, "["))) return e;
+ if ((e = pn_format_value(pos, limit, list->values, list->size))) return e;
+ if ((e = pn_fmt(pos, limit, "]"))) return e;
+ return 0;
+}
+
+uintptr_t pn_hash_list(pn_list_t *list)
+{
+ int i, n = list->size;
+ uintptr_t hash = 1;
+
+ for (i = 0; i < n; i++)
+ {
+ hash = 31*hash + pn_hash_value(pn_list_get(list, i));
+ }
+
+ return hash;
+}
+
+int pn_compare_list(pn_list_t *a, pn_list_t *b)
+{
+ int i, n = min(a->size, b->size);
+ int c;
+
+ for (i = 0; i < n; i++)
+ {
+ c = pn_compare_value(pn_list_get(a, i), pn_list_get(b, i));
+ if (!c)
+ return c;
+ }
+
+ return 0;
+}
+
+size_t pn_encode_sizeof_list(pn_list_t *l)
+{
+ size_t result = 9;
+ for (int i = 0; i < l->size; i++)
+ {
+ result += pn_encode_sizeof(l->values[i]);
+ }
+ return result;
+}
+
+size_t pn_encode_list(pn_list_t *l, char *out)
+{
+ char *old = out;
+ char *start;
+ // XXX
+ pn_write_start(&out, out + 1024, &start);
+ for (int i = 0; i < l->size; i++)
+ {
+ out += pn_encode(l->values[i], out);
+ }
+ pn_write_list(&out, out + 1024, start, l->size);
+ return out - old;
+}
Added: qpid/proton/proton-c/src/types/map.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/map.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/map.c (added)
+++ qpid/proton/proton-c/src/types/map.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,229 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/codec.h>
+#include <string.h>
+#include <stdlib.h>
+#include "value-internal.h"
+
+pn_map_t *pn_map(int capacity)
+{
+ pn_map_t *map = malloc(sizeof(pn_map_t) + 2*capacity*sizeof(pn_value_t));
+ map->capacity = capacity;
+ map->size = 0;
+ return map;
+}
+
+void pn_free_map(pn_map_t *m)
+{
+ free(m);
+}
+
+pn_value_t pn_map_key(pn_map_t *map, int index)
+{
+ return map->pairs[2*index];
+}
+
+pn_value_t pn_map_value(pn_map_t *map, int index)
+{
+ return map->pairs[2*index+1];
+}
+
+void pn_visit_map(pn_map_t *m, void (*visitor)(pn_value_t))
+{
+ for (int i = 0; i < m->size; i++)
+ {
+ pn_visit(pn_map_key(m, i), visitor);
+ pn_visit(pn_map_value(m, i), visitor);
+ }
+}
+
+size_t pn_format_sizeof_map(pn_map_t *map)
+{
+ size_t result = 2;
+ for (int i = 0; i < map->size; i++)
+ {
+ pn_value_t key = pn_map_key(map, i);
+ pn_value_t value = pn_map_value(map, i);
+ result += pn_format_sizeof(key) + 2 + pn_format_sizeof(value) + 2;
+ }
+ return result;
+}
+
+int pn_format_map(char **pos, char *limit, pn_map_t *map)
+{
+ bool first = true;
+ int i, e;
+ if ((e = pn_fmt(pos, limit, "{"))) return e;
+ for (i = 0; i < map->size; i++)
+ {
+ pn_value_t key = pn_map_key(map, i);
+ pn_value_t value = pn_map_value(map, i);
+ if (first) first = false;
+ else if ((e = pn_fmt(pos, limit, ", "))) return e;
+ if ((e = pn_format_value(pos, limit, &key, 1))) return e;
+ if ((e = pn_fmt(pos, limit, ": "))) return e;
+ if ((e = pn_format_value(pos, limit, &value, 1))) return e;
+ }
+ if ((e = pn_fmt(pos, limit, "}"))) return e;
+ return 0;
+}
+
+uintptr_t pn_hash_map(pn_map_t *map)
+{
+ uintptr_t hash = 0;
+ int i;
+ for (i = 0; i < map->size; i++)
+ {
+ hash += (pn_hash_value(pn_map_key(map, i)) ^
+ pn_hash_value(pn_map_value(map, i)));
+ }
+ return hash;
+}
+
+static bool has_entry(pn_map_t *m, pn_value_t key, pn_value_t value)
+{
+ int i;
+ for (i = 0; i < m->size; i++)
+ {
+ if (!pn_compare_value(pn_map_key(m, i), key) &&
+ !pn_compare_value(pn_map_value(m, i), value))
+ return true;
+ }
+
+ return false;
+}
+
+int pn_compare_map(pn_map_t *a, pn_map_t *b)
+{
+ int i;
+
+ if (a->size != b->size)
+ return b->size - a->size;
+
+ for (i = 0; i < a->size; i++)
+ if (!has_entry(b, pn_map_key(a, i), pn_map_value(a, i)))
+ return -1;
+
+ for (i = 0; i < b->size; i++)
+ if (!has_entry(a, pn_map_key(b, i), pn_map_value(b, i)))
+ return -1;
+
+ return 0;
+}
+
+bool pn_map_has(pn_map_t *map, pn_value_t key)
+{
+ for (int i = 0; i < map->size; i++)
+ {
+ if (!pn_compare_value(key, pn_map_key(map, i)))
+ return true;
+ }
+
+ return false;
+}
+
+pn_value_t pn_map_get(pn_map_t *map, pn_value_t key)
+{
+ for (int i = 0; i < map->size; i++)
+ {
+ if (!pn_compare_value(key, pn_map_key(map, i)))
+ return pn_map_value(map, i);
+ }
+
+ return EMPTY_VALUE;
+}
+
+int pn_map_set(pn_map_t *map, pn_value_t key, pn_value_t value)
+{
+ for (int i = 0; i < map->size; i++)
+ {
+ if (!pn_compare_value(key, pn_map_key(map, i)))
+ {
+ map->pairs[2*i + 1] = value;
+ return 0;
+ }
+ }
+
+ if (map->size < map->capacity)
+ {
+ map->pairs[2*map->size] = key;
+ map->pairs[2*map->size+1] = value;
+ map->size++;
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+pn_value_t pn_map_pop(pn_map_t *map, pn_value_t key)
+{
+ for (int i = 0; i < map->size; i++)
+ {
+ if (!pn_compare_value(key, pn_map_key(map, i)))
+ {
+ pn_value_t result = pn_map_value(map, i);
+ memmove(&map->pairs[2*i], &map->pairs[2*(i+1)],
+ (map->size - i - 1)*2*sizeof(pn_value_t));
+ map->size--;
+ return result;
+ }
+ }
+
+ return EMPTY_VALUE;
+}
+
+int pn_map_size(pn_map_t *map)
+{
+ return map->size;
+}
+
+int pn_map_capacity(pn_map_t *map)
+{
+ return map->capacity;
+}
+
+size_t pn_encode_sizeof_map(pn_map_t *m)
+{
+ size_t result = 0;
+ for (int i = 0; i < 2*m->size; i++)
+ {
+ result += pn_encode_sizeof(m->pairs[i]);
+ }
+ return result;
+}
+
+size_t pn_encode_map(pn_map_t *m, char *out)
+{
+ char *old = out;
+ char *start;
+ int count = 2*m->size;
+ // XXX
+ pn_write_start(&out, out + 1024, &start);
+ for (int i = 0; i < count; i++)
+ {
+ out += pn_encode(m->pairs[i], out);
+ }
+ pn_write_map(&out, out + 1024, start, m->size);
+ return out - old;
+}
Added: qpid/proton/proton-c/src/types/string.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/string.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/string.c (added)
+++ qpid/proton/proton-c/src/types/string.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/codec.h>
+#include <string.h>
+#include <stdlib.h>
+#include "value-internal.h"
+
+pn_string_t *pn_string(wchar_t *wcs)
+{
+ size_t size = wcslen(wcs);
+ pn_string_t *str = malloc(sizeof(pn_string_t) + (size+1)*sizeof(wchar_t));
+ str->size = size;
+ wcscpy(str->wcs, wcs);
+ return str;
+}
+
+void pn_free_string(pn_string_t *str)
+{
+ free(str);
+}
+
+size_t pn_string_size(pn_string_t *str)
+{
+ return str->size;
+}
+
+wchar_t *pn_string_wcs(pn_string_t *str)
+{
+ return str->wcs;
+}
+
+uintptr_t pn_hash_string(pn_string_t *s)
+{
+ wchar_t *c;
+ uintptr_t hash = 1;
+ for (c = s->wcs; *c; c++)
+ {
+ hash = 31*hash + *c;
+ }
+ return hash;
+}
+
+int pn_compare_string(pn_string_t *a, pn_string_t *b)
+{
+ if (a->size == b->size)
+ return wmemcmp(a->wcs, b->wcs, a->size);
+ else
+ return b->size - a->size;
+}
Added: qpid/proton/proton-c/src/types/value-internal.h
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/value-internal.h?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/value-internal.h (added)
+++ qpid/proton/proton-c/src/types/value-internal.h Thu Mar 8 18:33:46 2012
@@ -0,0 +1,56 @@
+#ifndef _PROTON_VALUE_INTERNAL_H
+#define _PROTON_VALUE_INTERNAL_H 1
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/value.h>
+
+struct pn_string_st {
+ size_t size;
+ wchar_t wcs[];
+};
+
+struct pn_binary_st {
+ size_t size;
+ char bytes[];
+};
+
+struct pn_array_st {
+ enum TYPE type;
+ size_t size;
+ size_t capacity;
+ pn_value_t values[];
+};
+
+struct pn_list_st {
+ size_t size;
+ size_t capacity;
+ pn_value_t values[];
+};
+
+struct pn_map_st {
+ size_t size;
+ size_t capacity;
+ pn_value_t pairs[];
+};
+
+#endif /* value-internal.h */
Added: qpid/proton/proton-c/src/types/value.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/types/value.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/types/value.c (added)
+++ qpid/proton/proton-c/src/types/value.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,810 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <proton/codec.h>
+#include <proton/util.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iconv.h>
+#include <arpa/inet.h>
+#include "../codec/encodings.h"
+#include "value-internal.h"
+
+int pn_compare_value(pn_value_t a, pn_value_t b)
+{
+ if (a.type == b.type) {
+ switch (a.type)
+ {
+ case EMPTY:
+ return 0;
+ case BOOLEAN:
+ return b.u.as_boolean && a.u.as_boolean;
+ case UBYTE:
+ return b.u.as_ubyte - a.u.as_ubyte;
+ case USHORT:
+ return b.u.as_ushort - a.u.as_ushort;
+ case UINT:
+ return b.u.as_uint - a.u.as_uint;
+ case ULONG:
+ return b.u.as_ulong - a.u.as_ulong;
+ case BYTE:
+ return b.u.as_byte - a.u.as_byte;
+ case SHORT:
+ return b.u.as_short - a.u.as_short;
+ case INT:
+ return b.u.as_int - a.u.as_int;
+ case LONG:
+ return b.u.as_long - a.u.as_long;
+ case FLOAT:
+ return b.u.as_float - a.u.as_float;
+ case DOUBLE:
+ return b.u.as_double - a.u.as_double;
+ case CHAR:
+ return b.u.as_char - a.u.as_char;
+ case STRING:
+ return pn_compare_string(a.u.as_string, b.u.as_string);
+ case BINARY:
+ return pn_compare_binary(a.u.as_binary, b.u.as_binary);
+ case REF:
+ return (char *)b.u.as_ref - (char *)a.u.as_ref;
+ default:
+ pn_fatal("uncomparable: %s, %s", pn_aformat(a), pn_aformat(b));
+ return -1;
+ }
+ } else {
+ return b.type - a.type;
+ }
+}
+
+uintptr_t pn_hash_value(pn_value_t v)
+{
+ switch (v.type)
+ {
+ case EMPTY:
+ return 0;
+ case UBYTE:
+ return v.u.as_ubyte;
+ case USHORT:
+ return v.u.as_ushort;
+ case UINT:
+ return v.u.as_uint;
+ case ULONG:
+ return v.u.as_ulong;
+ case BYTE:
+ return v.u.as_byte;
+ case SHORT:
+ return v.u.as_short;
+ case INT:
+ return v.u.as_int;
+ case LONG:
+ return v.u.as_long;
+ case FLOAT:
+ return v.u.as_float;
+ case DOUBLE:
+ return v.u.as_double;
+ case CHAR:
+ return v.u.as_char;
+ case STRING:
+ return pn_hash_string(v.u.as_string);
+ case BINARY:
+ return pn_hash_binary(v.u.as_binary);
+ default:
+ return 0;
+ }
+}
+
+int scan_size(const char *str)
+{
+ int i, level = 0, size = 0;
+ for (i = 0; str[i]; i++)
+ {
+ switch (str[i])
+ {
+ case '@':
+ i++;
+ break;
+ case '(':
+ case '[':
+ case '{':
+ level++;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ if (level == 0)
+ return size;
+ level--;
+ // fall through intentionally here
+ default:
+ if (level == 0) size++;
+ break;
+ }
+ }
+
+ return -1;
+}
+
+int pn_scan(pn_value_t *value, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int n = pn_vscan(value, fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+static enum TYPE code_to_type(char c)
+{
+ switch (c)
+ {
+ case 'n': return EMPTY;
+ case 'b': return BYTE;
+ case 'B': return UBYTE;
+ case 'h': return SHORT;
+ case 'H': return USHORT;
+ case 'i': return INT;
+ case 'I': return UINT;
+ case 'l': return LONG;
+ case 'L': return ULONG;
+ case 'f': return FLOAT;
+ case 'd': return DOUBLE;
+ case 'C': return CHAR;
+ case 'S': return STRING;
+ case 'z': return BINARY;
+ case 't': return LIST;
+ case 'm': return MAP;
+ default:
+ pn_fatal("unrecognized code: %c", c);
+ return -1;
+ }
+}
+
+typedef struct stack_frame_st {
+ pn_value_t *value;
+ int count;
+} stack_frame_t;
+
+int pn_vscan(pn_value_t *value, const char *fmt, va_list ap)
+{
+ stack_frame_t stack[strlen(fmt)];
+ int level = 0, count = 0;
+
+ for ( ; *fmt; fmt++)
+ {
+ if (level == 0)
+ count++;
+
+ switch (*fmt)
+ {
+ case 'n':
+ value->type = EMPTY;
+ break;
+ case 'b':
+ value->type = BYTE;
+ value->u.as_byte = va_arg(ap, int);
+ break;
+ case 'B':
+ value->type = UBYTE;
+ value->u.as_ubyte = va_arg(ap, unsigned int);
+ break;
+ case 'h':
+ value->type = SHORT;
+ value->u.as_short = va_arg(ap, int);
+ break;
+ case 'H':
+ value->type = USHORT;
+ value->u.as_ushort = va_arg(ap, unsigned int);
+ break;
+ case 'i':
+ value->type = INT;
+ value->u.as_int = va_arg(ap, int32_t);
+ break;
+ case 'I':
+ value->type = UINT;
+ value->u.as_uint = va_arg(ap, uint32_t);
+ break;
+ case 'l':
+ value->type = LONG;
+ value->u.as_long = va_arg(ap, int64_t);
+ break;
+ case 'L':
+ value->type = ULONG;
+ value->u.as_ulong = va_arg(ap, uint64_t);
+ break;
+ case 'f':
+ value->type = FLOAT;
+ value->u.as_float = va_arg(ap, double);
+ break;
+ case 'd':
+ value->type = DOUBLE;
+ value->u.as_double = va_arg(ap, double);
+ break;
+ case 'C':
+ value->type = CHAR;
+ value->u.as_char = va_arg(ap, wchar_t);
+ break;
+ case 'S':
+ value->type = STRING;
+ wchar_t *wcs = va_arg(ap, wchar_t *);
+ value->u.as_string = pn_string(wcs);
+ break;
+ case 'z':
+ value->type = BINARY;
+ size_t size = va_arg(ap, size_t);
+ char *bytes = va_arg(ap, char *);
+ value->u.as_binary = pn_binary(bytes, size);
+ break;
+ case '[':
+ stack[level] = (stack_frame_t) {value, scan_size(fmt+1)};
+ value->type = LIST;
+ value->u.as_list = pn_list(stack[level].count);
+ value->u.as_list->size = stack[level].count;
+ value = value->u.as_list->values;
+ level++;
+ continue;
+ case ']':
+ value = stack[--level].value;
+ break;
+ case '{':
+ stack[level] = (stack_frame_t) {value, scan_size(fmt+1)};
+ value->type = MAP;
+ value->u.as_map = pn_map(stack[level].count/2);
+ value->u.as_map->size = stack[level].count/2;
+ value = value->u.as_map->pairs;
+ level++;
+ continue;
+ case '}':
+ value = stack[--level].value;
+ break;
+ case '(':
+ // XXX: need to figure out how to detect missing descriptor value here
+ // XXX: also, decrementing count may not work when nested
+ value--;
+ count--;
+ pn_tag_t *tag = pn_tag(*value, EMPTY_VALUE);
+ value->type = TAG;
+ value->u.as_tag = tag;
+ stack[level++] = (stack_frame_t) {value, 0};
+ value = &value->u.as_tag->value;
+ continue;
+ case ')':
+ value = stack[--level].value;
+ break;
+ case '@':
+ value->type = ARRAY;
+ enum TYPE etype = code_to_type(*(++fmt));
+ stack[level] = (stack_frame_t) {value, scan_size(++fmt+1)};
+ value->u.as_array = pn_array(etype, stack[level].count);
+ value->u.as_array->size = stack[level].count;
+ value = value->u.as_array->values;
+ level++;
+ continue;
+ default:
+ fprintf(stderr, "unrecognized type: %c\n", *fmt);
+ return -1;
+ }
+
+ value++;
+ }
+
+ return count;
+}
+
+pn_value_t pn_value(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ pn_value_t value = pn_vvalue(fmt, ap);
+ va_end(ap);
+ return value;
+}
+
+pn_value_t pn_vvalue(const char *fmt, va_list ap)
+{
+ pn_value_t value;
+ pn_vscan(&value, fmt, ap);
+ return value;
+}
+
+pn_list_t *pn_to_list(pn_value_t v)
+{
+ return v.u.as_list;
+}
+
+pn_map_t *pn_to_map(pn_value_t v)
+{
+ return v.u.as_map;
+}
+
+pn_tag_t *pn_to_tag(pn_value_t v)
+{
+ return v.u.as_tag;
+}
+
+void *pn_to_ref(pn_value_t v)
+{
+ return v.u.as_ref;
+}
+
+pn_value_t pn_from_list(pn_list_t *l)
+{
+ return (pn_value_t) {.type = LIST, .u.as_list = l};
+}
+
+pn_value_t pn_from_map(pn_map_t *m)
+{
+ return (pn_value_t) {.type = MAP, .u.as_map = m};
+}
+
+pn_value_t pn_from_tag(pn_tag_t *t)
+{
+ return (pn_value_t) {.type = TAG, .u.as_tag = t};
+}
+
+pn_value_t pn_from_ref(void *r)
+{
+ return (pn_value_t) {.type = REF, .u.as_ref = r};
+}
+
+pn_value_t pn_from_binary(pn_binary_t *b)
+{
+ return (pn_value_t) {.type = BINARY, .u.as_binary = b};
+}
+
+int pn_fmt(char **pos, char *limit, const char *fmt, ...)
+{
+ va_list ap;
+ int result;
+ char *dst = *pos;
+ int n = limit - dst;
+ va_start(ap, fmt);
+ result = vsnprintf(dst, n, fmt, ap);
+ va_end(ap);
+ if (result >= n) {
+ *pos += n;
+ return -1;
+ } else if (result >= 0) {
+ *pos += result;
+ return 0;
+ } else {
+ // XXX: should convert error codes
+ return result;
+ }
+}
+
+int pn_format_value(char **pos, char *limit, pn_value_t *values, size_t n)
+{
+ int e;
+ for (int i = 0; i < n; i++)
+ {
+ if (i > 0 && (e = pn_fmt(pos, limit, ", "))) return e;
+
+ pn_value_t v = values[i];
+ switch (v.type)
+ {
+ case EMPTY:
+ if ((e = pn_fmt(pos, limit, "NULL"))) return e;
+ break;
+ case BOOLEAN:
+ if (v.u.as_boolean) {
+ if ((e = pn_fmt(pos, limit, "true"))) return e;
+ } else {
+ if ((e = pn_fmt(pos, limit, "false"))) return e;
+ }
+ break;
+ case BYTE:
+ if ((e = pn_fmt(pos, limit, "%hhi", v.u.as_byte))) return e;
+ break;
+ case UBYTE:
+ if ((e = pn_fmt(pos, limit, "%hhu", v.u.as_ubyte))) return e;
+ break;
+ case SHORT:
+ if ((e = pn_fmt(pos, limit, "%hi", v.u.as_short))) return e;
+ break;
+ case USHORT:
+ if ((e = pn_fmt(pos, limit, "%hu", v.u.as_ushort))) return e;
+ break;
+ case INT:
+ if ((e = pn_fmt(pos, limit, "%i", v.u.as_int))) return e;
+ break;
+ case UINT:
+ if ((e = pn_fmt(pos, limit, "%u", v.u.as_uint))) return e;
+ break;
+ case LONG:
+ if ((e = pn_fmt(pos, limit, "%lli", v.u.as_long))) return e;
+ break;
+ case ULONG:
+ if ((e = pn_fmt(pos, limit, "%llu", v.u.as_ulong))) return e;
+ break;
+ case FLOAT:
+ if ((e = pn_fmt(pos, limit, "%f", v.u.as_float))) return e;
+ break;
+ case DOUBLE:
+ if ((e = pn_fmt(pos, limit, "%f", v.u.as_double))) return e;
+ break;
+ case CHAR:
+ if ((e = pn_fmt(pos, limit, "%lc", v.u.as_char))) return e;
+ break;
+ case STRING:
+ if ((e = pn_fmt(pos, limit, "%ls", v.u.as_string->wcs))) return e;
+ break;
+ case BINARY:
+ if ((e = pn_format_binary(pos, limit, v.u.as_binary))) return e;
+ break;
+ case ARRAY:
+ if ((e = pn_format_array(pos, limit, v.u.as_array))) return e;
+ break;
+ case LIST:
+ if ((e = pn_format_list(pos, limit, v.u.as_list))) return e;
+ break;
+ case MAP:
+ if ((e = pn_format_map(pos, limit, v.u.as_map))) return e;
+ break;
+ case TAG:
+ if ((e = pn_format_tag(pos, limit, v.u.as_tag))) return e;
+ break;
+ case REF:
+ if ((e = pn_fmt(pos, limit, "%p", v.u.as_ref))) return e;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int pn_format(char *buf, size_t size, pn_value_t v)
+{
+ char *pos = buf;
+ int n = pn_format_value(&pos, buf + size, &v, 1);
+ if (!n) {
+ pos[0] = '\0';
+ } else {
+ if (buf + size - pos < 4) {
+ pos = buf + size - 4;
+ }
+ if (pos > buf) {
+ pn_fmt(&pos, buf + size, "...");
+ pos[0] = '\0';
+ }
+ }
+ return pos - buf;
+}
+
+char *pn_aformat(pn_value_t v)
+{
+ size_t size = pn_format_sizeof(v) + 1;
+ char *buf = malloc(size);
+ if (!buf) return NULL;
+ char *pos = buf;
+ int n = pn_format_value(&pos, buf + size, &v, 1);
+ if (!n) {
+ pos[0] = '\0';
+ return buf;
+ } else {
+ pn_fatal("bad sizeof");
+ free(buf);
+ return NULL;
+ }
+}
+
+size_t pn_format_sizeof(pn_value_t v)
+{
+ switch (v.type)
+ {
+ case EMPTY:
+ return 4;
+ case BOOLEAN:
+ return 5;
+ case BYTE:
+ case UBYTE:
+ return 8;
+ case SHORT:
+ case USHORT:
+ return 16;
+ case INT:
+ case UINT:
+ case CHAR:
+ case FLOAT:
+ return 32;
+ case LONG:
+ case ULONG:
+ case DOUBLE:
+ return 64;
+ case STRING:
+ return 4*v.u.as_string->size;
+ case BINARY:
+ return 4*v.u.as_binary->size;
+ case ARRAY:
+ return pn_format_sizeof_array(v.u.as_array);
+ case LIST:
+ return pn_format_sizeof_list(v.u.as_list);
+ case MAP:
+ return pn_format_sizeof_map(v.u.as_map);
+ case TAG:
+ return pn_format_sizeof_tag(v.u.as_tag);
+ case REF:
+ return 64;
+ default:
+ pn_fatal("xxx");
+ return 0;
+ }
+}
+
+size_t pn_encode_sizeof(pn_value_t v)
+{
+ switch (v.type)
+ {
+ case EMPTY:
+ return 1;
+ case BOOLEAN:
+ case BYTE:
+ case UBYTE:
+ return 2;
+ case SHORT:
+ case USHORT:
+ return 3;
+ case INT:
+ case UINT:
+ case CHAR:
+ case FLOAT:
+ return 5;
+ case LONG:
+ case ULONG:
+ case DOUBLE:
+ return 9;
+ case STRING:
+ return 5 + 4*v.u.as_string->size;
+ case BINARY:
+ return 5 + v.u.as_binary->size;
+ case ARRAY:
+ return pn_encode_sizeof_array(v.u.as_array);
+ case LIST:
+ return pn_encode_sizeof_list(v.u.as_list);
+ case MAP:
+ return pn_encode_sizeof_map(v.u.as_map);
+ case TAG:
+ return pn_encode_sizeof_tag(v.u.as_tag);
+ default:
+ pn_fatal("unencodable type: %s", pn_aformat(v));
+ return 0;
+ }
+}
+
+size_t pn_encode(pn_value_t v, char *out)
+{
+ char *old = out;
+ size_t size = pn_encode_sizeof(v);
+ iconv_t cd;
+ char *inbuf;
+ size_t insize;
+ char *outbuf;
+ size_t utfsize;
+
+ switch (v.type)
+ {
+ case EMPTY:
+ pn_write_null(&out, out + size);
+ return 1;
+ case BOOLEAN:
+ pn_write_boolean(&out, out + size, v.u.as_boolean);
+ return 2;
+ case BYTE:
+ pn_write_byte(&out, out + size, v.u.as_byte);
+ return 2;
+ case UBYTE:
+ pn_write_ubyte(&out, out + size, v.u.as_ubyte);
+ return 2;
+ case SHORT:
+ pn_write_short(&out, out + size, v.u.as_short);
+ return 3;
+ case USHORT:
+ pn_write_ushort(&out, out + size, v.u.as_ushort);
+ return 3;
+ case INT:
+ pn_write_int(&out, out + size, v.u.as_int);
+ return 5;
+ case UINT:
+ pn_write_uint(&out, out + size, v.u.as_uint);
+ return 5;
+ case CHAR:
+ pn_write_char(&out, out + size, v.u.as_char);
+ return 5;
+ case FLOAT:
+ pn_write_float(&out, out + size, v.u.as_float);
+ return 5;
+ case LONG:
+ pn_write_long(&out, out + size, v.u.as_long);
+ return 9;
+ case ULONG:
+ pn_write_ulong(&out, out + size, v.u.as_ulong);
+ return 9;
+ case DOUBLE:
+ pn_write_double(&out, out + size, v.u.as_double);
+ return 9;
+ case STRING:
+ cd = iconv_open("UTF-8", "WCHAR_T");
+ insize = 4*v.u.as_string->size;
+ inbuf = (char *)v.u.as_string->wcs;
+ outbuf = out + 5;
+ utfsize = iconv(cd, &inbuf, &insize, &outbuf, &size);
+ iconv_close(cd);
+ pn_write_utf8(&out, out + size, outbuf - out - 5, out + 5);
+ return out - old;
+ case BINARY:
+ pn_write_binary(&out, out + size, v.u.as_binary->size, v.u.as_binary->bytes);
+ return 5 + v.u.as_binary->size;
+ case ARRAY:
+ return pn_encode_array(v.u.as_array, out);
+ case LIST:
+ return pn_encode_list(v.u.as_list, out);
+ case MAP:
+ return pn_encode_map(v.u.as_map, out);
+ case TAG:
+ return pn_encode_tag(v.u.as_tag, out);
+ default:
+ pn_fatal("unencodable type: %s", pn_aformat(v));
+ return 0;
+ }
+}
+
+void pn_free_value(pn_value_t v)
+{
+ switch (v.type)
+ {
+ case EMPTY:
+ case BOOLEAN:
+ case BYTE:
+ case UBYTE:
+ case SHORT:
+ case USHORT:
+ case INT:
+ case UINT:
+ case CHAR:
+ case FLOAT:
+ case LONG:
+ case ULONG:
+ case DOUBLE:
+ case REF:
+ break;
+ case STRING:
+ pn_free_string(v.u.as_string);
+ break;
+ case BINARY:
+ pn_free_binary(v.u.as_binary);
+ break;
+ case ARRAY:
+ pn_free_array(v.u.as_array);
+ break;
+ case LIST:
+ pn_free_list(v.u.as_list);
+ break;
+ case MAP:
+ pn_free_map(v.u.as_map);
+ break;
+ case TAG:
+ pn_free_tag(v.u.as_tag);
+ break;
+ }
+}
+
+void pn_visit(pn_value_t v, void (*visitor)(pn_value_t))
+{
+ switch (v.type)
+ {
+ case EMPTY:
+ case BOOLEAN:
+ case BYTE:
+ case UBYTE:
+ case SHORT:
+ case USHORT:
+ case INT:
+ case UINT:
+ case CHAR:
+ case FLOAT:
+ case LONG:
+ case ULONG:
+ case DOUBLE:
+ case STRING:
+ case BINARY:
+ case REF:
+ break;
+ case ARRAY:
+ pn_visit_array(v.u.as_array, visitor);
+ break;
+ case LIST:
+ pn_visit_list(v.u.as_list, visitor);
+ break;
+ case MAP:
+ pn_visit_map(v.u.as_map, visitor);
+ break;
+ case TAG:
+ pn_visit_tag(v.u.as_tag, visitor);
+ break;
+ }
+
+ visitor(v);
+}
+
+/* tags */
+
+pn_tag_t *pn_tag(pn_value_t descriptor, pn_value_t value)
+{
+ pn_tag_t *t = malloc(sizeof(pn_tag_t));
+ t->descriptor = descriptor;
+ t->value = value;
+ return t;
+}
+
+void pn_free_tag(pn_tag_t *t)
+{
+ free(t);
+}
+
+void pn_visit_tag(pn_tag_t *t, void (*visitor)(pn_value_t))
+{
+ pn_visit(t->descriptor, visitor);
+ pn_visit(t->value, visitor);
+}
+
+pn_value_t pn_tag_descriptor(pn_tag_t *t)
+{
+ return t->descriptor;
+}
+
+pn_value_t pn_tag_value(pn_tag_t *t)
+{
+ return t->value;
+}
+
+size_t pn_format_sizeof_tag(pn_tag_t *tag)
+{
+ return pn_format_sizeof(tag->descriptor) + pn_format_sizeof(tag->value) + 2;
+}
+
+int pn_format_tag(char **pos, char *limit, pn_tag_t *tag)
+{
+ int e;
+
+ if ((e = pn_format_value(pos, limit, &tag->descriptor, 1))) return e;
+ if ((e = pn_fmt(pos, limit, "("))) return e;
+ if ((e = pn_format_value(pos, limit, &tag->value, 1))) return e;
+ if ((e = pn_fmt(pos, limit, ")"))) return e;
+
+ return 0;
+}
+
+size_t pn_encode_sizeof_tag(pn_tag_t *t)
+{
+ return 1 + pn_encode_sizeof(t->descriptor) + pn_encode_sizeof(t->value);
+}
+
+size_t pn_encode_tag(pn_tag_t *t, char *out)
+{
+ size_t size = 1;
+ pn_write_descriptor(&out, out + 1);
+ size += pn_encode(t->descriptor, out);
+ size += pn_encode(t->value, out + size - 1);
+ return size;
+}
Added: qpid/proton/proton-c/src/util.c
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/util.c?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/util.c (added)
+++ qpid/proton/proton-c/src/util.c Thu Mar 8 18:33:46 2012
@@ -0,0 +1,38 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void pn_vfatal(char *fmt, va_list ap)
+{
+ vfprintf(stderr, fmt, ap);
+ exit(-1);
+}
+
+void pn_fatal(char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ pn_vfatal(fmt, ap);
+ va_end(ap);
+}
Added: qpid/proton/proton-c/src/util.h
URL: http://svn.apache.org/viewvc/qpid/proton/proton-c/src/util.h?rev=1298498&view=auto
==============================================================================
--- qpid/proton/proton-c/src/util.h (added)
+++ qpid/proton/proton-c/src/util.h Thu Mar 8 18:33:46 2012
@@ -0,0 +1,86 @@
+#ifndef _PROTON_UTIL_H
+#define _PROTON_UTIL_H 1
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define DIE_IFR(EXPR, STRERR) \
+ do { \
+ int __code__ = (EXPR); \
+ if (__code__) { \
+ fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, \
+ #EXPR, STRERR(__code__), __code__); \
+ exit(-1); \
+ } \
+ } while (0)
+
+#define DIE_IFE(EXPR) \
+ do { \
+ if ((EXPR) == -1) { \
+ int __code__ = errno; \
+ fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, \
+ #EXPR, strerror(__code__), __code__); \
+ exit(-1); \
+ } \
+ } while (0)
+
+#define __EMPTY__next next
+#define __EMPTY__prev prev
+#define LL_ADD(HEAD, TAIL, NODE) LL_ADD_PFX(HEAD, TAIL, NODE, __EMPTY__)
+#define LL_ADD_PFX(HEAD, TAIL, NODE, PFX) \
+ { \
+ (NODE)-> PFX ## next = NULL; \
+ (NODE)-> PFX ## prev = (TAIL); \
+ if (TAIL) (TAIL)-> PFX ## next = (NODE); \
+ (TAIL) = (NODE); \
+ if (!(HEAD)) (HEAD) = NODE; \
+ }
+
+#define LL_POP(HEAD, TAIL) LL_POP_PFX(HEAD, TAIL, __EMPTY__)
+#define LL_POP_PFX(HEAD, TAIL, PFX) \
+ { \
+ if (HEAD) { \
+ void *_head = (HEAD); \
+ (HEAD) = (HEAD)-> PFX ## next; \
+ if (_head == (TAIL)) \
+ (TAIL) = NULL; \
+ } \
+ }
+
+#define LL_REMOVE(HEAD, TAIL, NODE) LL_REMOVE_PFX(HEAD, TAIL, NODE, __EMPTY__)
+#define LL_REMOVE_PFX(HEAD, TAIL, NODE, PFX) \
+ { \
+ if ((NODE)-> PFX ## prev) \
+ (NODE)-> PFX ## prev-> PFX ## next = (NODE)-> PFX ## next; \
+ if ((NODE)-> PFX ## next) \
+ (NODE)-> PFX ## next-> PFX ## prev = (NODE)-> PFX ## prev; \
+ if ((NODE) == (HEAD)) \
+ (HEAD) = (NODE)-> PFX ## next; \
+ if ((NODE) == (TAIL)) \
+ (TAIL) = (NODE)-> PFX ## prev; \
+ }
+
+#endif /* util.h */
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org