http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/codec/encoder.c ---------------------------------------------------------------------- diff --git a/proton-c/src/codec/encoder.c b/proton-c/src/codec/encoder.c deleted file mode 100644 index f8145fc..0000000 --- a/proton-c/src/codec/encoder.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * - * 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/error.h> -#include <proton/object.h> -#include <proton/codec.h> -#include "encodings.h" -#include "encoder.h" - -#include <string.h> - -#include "data.h" - -struct pn_encoder_t { - char *output; - size_t size; - char *position; - pn_error_t *error; -}; - -static void pn_encoder_initialize(void *obj) -{ - pn_encoder_t *encoder = (pn_encoder_t *) obj; - encoder->output = NULL; - encoder->size = 0; - encoder->position = NULL; - encoder->error = pn_error(); -} - -static void pn_encoder_finalize(void *obj) { - pn_encoder_t *encoder = (pn_encoder_t *) obj; - pn_error_free(encoder->error); -} - -#define pn_encoder_hashcode NULL -#define pn_encoder_compare NULL -#define pn_encoder_inspect NULL - -pn_encoder_t *pn_encoder() -{ - static const pn_class_t clazz = PN_CLASS(pn_encoder); - return (pn_encoder_t *) pn_class_new(&clazz, sizeof(pn_encoder_t)); -} - -static uint8_t pn_type2code(pn_encoder_t *encoder, pn_type_t type) -{ - switch (type) - { - case PN_NULL: return PNE_NULL; - case PN_BOOL: return PNE_BOOLEAN; - case PN_UBYTE: return PNE_UBYTE; - case PN_BYTE: return PNE_BYTE; - case PN_USHORT: return PNE_USHORT; - case PN_SHORT: return PNE_SHORT; - case PN_UINT: return PNE_UINT; - case PN_INT: return PNE_INT; - case PN_CHAR: return PNE_UTF32; - case PN_FLOAT: return PNE_FLOAT; - case PN_LONG: return PNE_LONG; - case PN_TIMESTAMP: return PNE_MS64; - case PN_DOUBLE: return PNE_DOUBLE; - case PN_DECIMAL32: return PNE_DECIMAL32; - case PN_DECIMAL64: return PNE_DECIMAL64; - case PN_DECIMAL128: return PNE_DECIMAL128; - case PN_UUID: return PNE_UUID; - case PN_ULONG: return PNE_ULONG; - case PN_BINARY: return PNE_VBIN32; - case PN_STRING: return PNE_STR32_UTF8; - case PN_SYMBOL: return PNE_SYM32; - case PN_LIST: return PNE_LIST32; - case PN_ARRAY: return PNE_ARRAY32; - case PN_MAP: return PNE_MAP32; - case PN_DESCRIBED: return PNE_DESCRIPTOR; - default: - return pn_error_format(encoder->error, PN_ERR, "not a value type: %u\n", type); - } -} - -static uint8_t pn_node2code(pn_encoder_t *encoder, pni_node_t *node) -{ - switch (node->atom.type) { - case PN_LONG: - if (-128 <= node->atom.u.as_long && node->atom.u.as_long <= 127) { - return PNE_SMALLLONG; - } else { - return PNE_LONG; - } - case PN_INT: - if (-128 <= node->atom.u.as_int && node->atom.u.as_int <= 127) { - return PNE_SMALLINT; - } else { - return PNE_INT; - } - case PN_ULONG: - if (node->atom.u.as_ulong < 256) { - return PNE_SMALLULONG; - } else { - return PNE_ULONG; - } - case PN_UINT: - if (node->atom.u.as_uint < 256) { - return PNE_SMALLUINT; - } else { - return PNE_UINT; - } - case PN_BOOL: - if (node->atom.u.as_bool) { - return PNE_TRUE; - } else { - return PNE_FALSE; - } - case PN_STRING: - if (node->atom.u.as_bytes.size < 256) { - return PNE_STR8_UTF8; - } else { - return PNE_STR32_UTF8; - } - case PN_SYMBOL: - if (node->atom.u.as_bytes.size < 256) { - return PNE_SYM8; - } else { - return PNE_SYM32; - } - case PN_BINARY: - if (node->atom.u.as_bytes.size < 256) { - return PNE_VBIN8; - } else { - return PNE_VBIN32; - } - default: - return pn_type2code(encoder, node->atom.type); - } -} - -static size_t pn_encoder_remaining(pn_encoder_t *encoder) { - char * end = encoder->output + encoder->size; - if (end > encoder->position) - return end - encoder->position; - else - return 0; -} - -static inline void pn_encoder_writef8(pn_encoder_t *encoder, uint8_t value) -{ - if (pn_encoder_remaining(encoder)) { - encoder->position[0] = value; - } - encoder->position++; -} - -static inline void pn_encoder_writef16(pn_encoder_t *encoder, uint16_t value) -{ - if (pn_encoder_remaining(encoder) >= 2) { - encoder->position[0] = 0xFF & (value >> 8); - encoder->position[1] = 0xFF & (value ); - } - encoder->position += 2; -} - -static inline void pn_encoder_writef32(pn_encoder_t *encoder, uint32_t value) -{ - if (pn_encoder_remaining(encoder) >= 4) { - encoder->position[0] = 0xFF & (value >> 24); - encoder->position[1] = 0xFF & (value >> 16); - encoder->position[2] = 0xFF & (value >> 8); - encoder->position[3] = 0xFF & (value ); - } - encoder->position += 4; -} - -static inline void pn_encoder_writef64(pn_encoder_t *encoder, uint64_t value) { - if (pn_encoder_remaining(encoder) >= 8) { - encoder->position[0] = 0xFF & (value >> 56); - encoder->position[1] = 0xFF & (value >> 48); - encoder->position[2] = 0xFF & (value >> 40); - encoder->position[3] = 0xFF & (value >> 32); - encoder->position[4] = 0xFF & (value >> 24); - encoder->position[5] = 0xFF & (value >> 16); - encoder->position[6] = 0xFF & (value >> 8); - encoder->position[7] = 0xFF & (value ); - } - encoder->position += 8; -} - -static inline void pn_encoder_writef128(pn_encoder_t *encoder, char *value) { - if (pn_encoder_remaining(encoder) >= 16) { - memmove(encoder->position, value, 16); - } - encoder->position += 16; -} - -static inline void pn_encoder_writev8(pn_encoder_t *encoder, const pn_bytes_t *value) -{ - pn_encoder_writef8(encoder, value->size); - if (pn_encoder_remaining(encoder) >= value->size) - memmove(encoder->position, value->start, value->size); - encoder->position += value->size; -} - -static inline void pn_encoder_writev32(pn_encoder_t *encoder, const pn_bytes_t *value) -{ - pn_encoder_writef32(encoder, value->size); - if (pn_encoder_remaining(encoder) >= value->size) - memmove(encoder->position, value->start, value->size); - encoder->position += value->size; -} - -/* True if node is an element of an array - not the descriptor. */ -static bool pn_is_in_array(pn_data_t *data, pni_node_t *parent, pni_node_t *node) { - return (parent && parent->atom.type == PN_ARRAY) /* In array */ - && !(parent->described && !node->prev); /* Not the descriptor */ -} - -/** True if node is the first element of an array, not the descriptor. - *@pre pn_is_in_array(data, parent, node) - */ -static bool pn_is_first_in_array(pn_data_t *data, pni_node_t *parent, pni_node_t *node) { - if (!node->prev) return !parent->described; /* First node */ - return parent->described && (!pn_data_node(data, node->prev)->prev); -} - -typedef union { - uint32_t i; - uint32_t a[2]; - uint64_t l; - float f; - double d; -} conv_t; - -static int pni_encoder_enter(void *ctx, pn_data_t *data, pni_node_t *node) -{ - pn_encoder_t *encoder = (pn_encoder_t *) ctx; - pni_node_t *parent = pn_data_node(data, node->parent); - pn_atom_t *atom = &node->atom; - uint8_t code; - conv_t c; - - /** In an array we don't write the code before each element, only the first. */ - if (pn_is_in_array(data, parent, node)) { - code = pn_type2code(encoder, parent->type); - if (pn_is_first_in_array(data, parent, node)) { - pn_encoder_writef8(encoder, code); - } - } else { - code = pn_node2code(encoder, node); - pn_encoder_writef8(encoder, code); - } - - switch (code) { - case PNE_DESCRIPTOR: - case PNE_NULL: - case PNE_TRUE: - case PNE_FALSE: return 0; - case PNE_BOOLEAN: pn_encoder_writef8(encoder, atom->u.as_bool); return 0; - case PNE_UBYTE: pn_encoder_writef8(encoder, atom->u.as_ubyte); return 0; - case PNE_BYTE: pn_encoder_writef8(encoder, atom->u.as_byte); return 0; - case PNE_USHORT: pn_encoder_writef16(encoder, atom->u.as_ushort); return 0; - case PNE_SHORT: pn_encoder_writef16(encoder, atom->u.as_short); return 0; - case PNE_UINT0: return 0; - case PNE_SMALLUINT: pn_encoder_writef8(encoder, atom->u.as_uint); return 0; - case PNE_UINT: pn_encoder_writef32(encoder, atom->u.as_uint); return 0; - case PNE_SMALLINT: pn_encoder_writef8(encoder, atom->u.as_int); return 0; - case PNE_INT: pn_encoder_writef32(encoder, atom->u.as_int); return 0; - case PNE_UTF32: pn_encoder_writef32(encoder, atom->u.as_char); return 0; - case PNE_ULONG: pn_encoder_writef64(encoder, atom->u.as_ulong); return 0; - case PNE_SMALLULONG: pn_encoder_writef8(encoder, atom->u.as_ulong); return 0; - case PNE_LONG: pn_encoder_writef64(encoder, atom->u.as_long); return 0; - case PNE_SMALLLONG: pn_encoder_writef8(encoder, atom->u.as_long); return 0; - case PNE_MS64: pn_encoder_writef64(encoder, atom->u.as_timestamp); return 0; - case PNE_FLOAT: c.f = atom->u.as_float; pn_encoder_writef32(encoder, c.i); return 0; - case PNE_DOUBLE: c.d = atom->u.as_double; pn_encoder_writef64(encoder, c.l); return 0; - case PNE_DECIMAL32: pn_encoder_writef32(encoder, atom->u.as_decimal32); return 0; - case PNE_DECIMAL64: pn_encoder_writef64(encoder, atom->u.as_decimal64); return 0; - case PNE_DECIMAL128: pn_encoder_writef128(encoder, atom->u.as_decimal128.bytes); return 0; - case PNE_UUID: pn_encoder_writef128(encoder, atom->u.as_uuid.bytes); return 0; - case PNE_VBIN8: pn_encoder_writev8(encoder, &atom->u.as_bytes); return 0; - case PNE_VBIN32: pn_encoder_writev32(encoder, &atom->u.as_bytes); return 0; - case PNE_STR8_UTF8: pn_encoder_writev8(encoder, &atom->u.as_bytes); return 0; - case PNE_STR32_UTF8: pn_encoder_writev32(encoder, &atom->u.as_bytes); return 0; - case PNE_SYM8: pn_encoder_writev8(encoder, &atom->u.as_bytes); return 0; - case PNE_SYM32: pn_encoder_writev32(encoder, &atom->u.as_bytes); return 0; - case PNE_ARRAY32: - node->start = encoder->position; - node->small = false; - // we'll backfill the size on exit - encoder->position += 4; - pn_encoder_writef32(encoder, node->described ? node->children - 1 : node->children); - if (node->described) - pn_encoder_writef8(encoder, 0); - return 0; - case PNE_LIST32: - case PNE_MAP32: - node->start = encoder->position; - node->small = false; - // we'll backfill the size later - encoder->position += 4; - pn_encoder_writef32(encoder, node->children); - return 0; - default: - return pn_error_format(data->error, PN_ERR, "unrecognized encoding: %u", code); - } -} - -#include <stdio.h> - -static int pni_encoder_exit(void *ctx, pn_data_t *data, pni_node_t *node) -{ - pn_encoder_t *encoder = (pn_encoder_t *) ctx; - char *pos; - - switch (node->atom.type) { - case PN_ARRAY: - if ((node->described && node->children == 1) || (!node->described && node->children == 0)) { - pn_encoder_writef8(encoder, pn_type2code(encoder, node->type)); - } - // Fallthrough - case PN_LIST: - case PN_MAP: - pos = encoder->position; - encoder->position = node->start; - if (node->small) { - // backfill size - size_t size = pos - node->start - 1; - pn_encoder_writef8(encoder, size); - } else { - // backfill size - size_t size = pos - node->start - 4; - pn_encoder_writef32(encoder, size); - } - encoder->position = pos; - return 0; - default: - return 0; - } -} - -ssize_t pn_encoder_encode(pn_encoder_t *encoder, pn_data_t *src, char *dst, size_t size) -{ - encoder->output = dst; - encoder->position = dst; - encoder->size = size; - - int err = pni_data_traverse(src, pni_encoder_enter, pni_encoder_exit, encoder); - if (err) return err; - size_t encoded = encoder->position - encoder->output; - if (encoded > size) { - pn_error_format(pn_data_error(src), PN_OVERFLOW, "not enough space to encode"); - return PN_OVERFLOW; - } - return (ssize_t)encoded; -} - -ssize_t pn_encoder_size(pn_encoder_t *encoder, pn_data_t *src) -{ - encoder->output = 0; - encoder->position = 0; - encoder->size = 0; - - pn_handle_t save = pn_data_point(src); - int err = pni_data_traverse(src, pni_encoder_enter, pni_encoder_exit, encoder); - pn_data_restore(src, save); - - if (err) return err; - return encoder->position - encoder->output; -}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/codec/encoder.h ---------------------------------------------------------------------- diff --git a/proton-c/src/codec/encoder.h b/proton-c/src/codec/encoder.h deleted file mode 100644 index 20876cb..0000000 --- a/proton-c/src/codec/encoder.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _PROTON_ENCODER_H -#define _PROTON_ENCODER_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. - * - */ - -typedef struct pn_encoder_t pn_encoder_t; - -pn_encoder_t *pn_encoder(void); -ssize_t pn_encoder_encode(pn_encoder_t *encoder, pn_data_t *src, char *dst, size_t size); -ssize_t pn_encoder_size(pn_encoder_t *encoder, pn_data_t *src); - -#endif /* encoder.h */ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/codec/encodings.h.py ---------------------------------------------------------------------- diff --git a/proton-c/src/codec/encodings.h.py b/proton-c/src/codec/encodings.h.py deleted file mode 100755 index 9f08c6c..0000000 --- a/proton-c/src/codec/encodings.h.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/python -# -# 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. -# - -from __future__ import print_function -import mllib, optparse, os, sys - -xml = os.path.join(os.path.dirname(__file__), "types.xml") -doc = mllib.xml_parse(xml) - -print("/* generated from %s */" % xml) -print("#ifndef _PROTON_ENCODINGS_H") -print("#define _PROTON_ENCODINGS_H 1") -print() -print("#define PNE_DESCRIPTOR (0x00)") - -for enc in doc.query["amqp/section/type/encoding"]: - name = enc["@name"] or enc.parent["@name"] - # XXX: a bit hacky - if name == "ieee-754": - name = enc.parent["@name"] - cname = "PNE_" + name.replace("-", "_").upper() - print("#define %s%s(%s)" % (cname, " "*(20-len(cname)), enc["@code"])) - -print() -print("#endif /* encodings.h */") http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/codec/types.xml ---------------------------------------------------------------------- diff --git a/proton-c/src/codec/types.xml b/proton-c/src/codec/types.xml deleted file mode 100644 index 4aa9c0f..0000000 --- a/proton-c/src/codec/types.xml +++ /dev/null @@ -1,125 +0,0 @@ -<?xml version="1.0"?> - -<!-- -Copyright Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit -Suisse, Deutsche Boerse, Envoy Technologies Inc., Goldman Sachs, HCL -Technologies Ltd, IIT Software GmbH, iMatix Corporation, INETCO Systems Limited, -Informatica Corporation, JPMorgan Chase & Co., Kaazing Corporation, N.A, -Microsoft Corporation, my-Channels, Novell, Progress Software, Red Hat Inc., -Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc., TWIST Process -Innovations Ltd, VMware, Inc., and WS02 Inc. 2006-2011. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products -derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---> - -<amqp name="types" xmlns="http://www.amqp.org/schema/amqp.xsd"> - <section name="encodings"> - <type name="null" class="primitive"> - <encoding code="0x40" category="fixed" width="0"/> - </type> - <type name="boolean" class="primitive"> - <encoding code="0x56" category="fixed" width="1"/> - <encoding name="true" code="0x41" category="fixed" width="0"/> - <encoding name="false" code="0x42" category="fixed" width="0"/> - </type> - <type name="ubyte" class="primitive"> - <encoding code="0x50" category="fixed" width="1"/> - </type> - <type name="ushort" class="primitive"> - <encoding code="0x60" category="fixed" width="2"/> - </type> - <type name="uint" class="primitive"> - <encoding code="0x70" category="fixed" width="4"/> - <encoding name="smalluint" code="0x52" category="fixed" width="1"/> - <encoding name="uint0" code="0x43" category="fixed" width="0"/> - </type> - <type name="ulong" class="primitive"> - <encoding code="0x80" category="fixed" width="8"/> - <encoding name="smallulong" code="0x53" category="fixed" width="1"/> - <encoding name="ulong0" code="0x44" category="fixed" width="0"/> - </type> - <type name="byte" class="primitive"> - <encoding code="0x51" category="fixed" width="1"/> - </type> - <type name="short" class="primitive"> - <encoding code="0x61" category="fixed" width="2"/> - </type> - <type name="int" class="primitive"> - <encoding code="0x71" category="fixed" width="4"/> - <encoding name="smallint" code="0x54" category="fixed" width="1"/> - </type> - <type name="long" class="primitive"> - <encoding code="0x81" category="fixed" width="8"/> - <encoding name="smalllong" code="0x55" category="fixed" width="1"/> - </type> - <type name="float" class="primitive"> - <encoding name="ieee-754" code="0x72" category="fixed" width="4"/> - </type> - <type name="double" class="primitive"> - <encoding name="ieee-754" code="0x82" category="fixed" width="8"/> - </type> - <type name="decimal32" class="primitive"> - <encoding name="ieee-754" code="0x74" category="fixed" width="4"/> - </type> - <type name="decimal64" class="primitive"> - <encoding name="ieee-754" code="0x84" category="fixed" width="8"/> - </type> - <type name="decimal128" class="primitive"> - <encoding name="ieee-754" code="0x94" category="fixed" width="16"/> - </type> - <type name="char" class="primitive"> - <encoding name="utf32" code="0x73" category="fixed" width="4"/> - </type> - <type name="timestamp" class="primitive"> - <encoding name="ms64" code="0x83" category="fixed" width="8"/> - </type> - <type name="uuid" class="primitive"> - <encoding code="0x98" category="fixed" width="16"/> - </type> - <type name="binary" class="primitive"> - <encoding name="vbin8" code="0xa0" category="variable" width="1"/> - <encoding name="vbin32" code="0xb0" category="variable" width="4"/> - </type> - <type name="string" class="primitive"> - <encoding name="str8-utf8" code="0xa1" category="variable" width="1"/> - <encoding name="str32-utf8" code="0xb1" category="variable" width="4"/> - </type> - <type name="symbol" class="primitive"> - <encoding name="sym8" code="0xa3" category="variable" width="1"/> - <encoding name="sym32" code="0xb3" category="variable" width="4"/> - </type> - <type name="list" class="primitive"> - <encoding name="list0" code="0x45" category="fixed" width="0"/> - <encoding name="list8" code="0xc0" category="compound" width="1"/> - <encoding name="list32" code="0xd0" category="compound" width="4"/> - </type> - <type name="map" class="primitive"> - <encoding name="map8" code="0xc1" category="compound" width="1"/> - <encoding name="map32" code="0xd1" category="compound" width="4"/> - </type> - <type name="array" class="primitive"> - <encoding name="array8" code="0xe0" category="array" width="1"/> - <encoding name="array32" code="0xf0" category="array" width="4"/> - </type> - </section> -</amqp> http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/compiler/msvc/snprintf.c ---------------------------------------------------------------------- diff --git a/proton-c/src/compiler/msvc/snprintf.c b/proton-c/src/compiler/msvc/snprintf.c new file mode 100644 index 0000000..f9c14eb --- /dev/null +++ b/proton-c/src/compiler/msvc/snprintf.c @@ -0,0 +1,52 @@ +/* + * + * 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 "platform/platform.h" + +#include <stdarg.h> +#include <stdio.h> + +// [v]snprintf on Windows only matches C99 when no errors or overflow. +int pni_vsnprintf(char *buf, size_t count, const char *fmt, va_list ap) { + if (fmt == NULL) + return -1; + if ((buf == NULL) && (count > 0)) + return -1; + if (count > 0) { + int n = vsnprintf_s(buf, count, _TRUNCATE, fmt, ap); + if (n >= 0) // no overflow + return n; // same as C99 + buf[count-1] = '\0'; + } + // separate call to get needed buffer size on overflow + int n = _vscprintf(fmt, ap); + if (n >= (int) count) + return n; + return -1; +} + +int pni_snprintf(char *buf, size_t count, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int n = pni_vsnprintf(buf, count, fmt, ap); + va_end(ap); + return n; +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/config.h ---------------------------------------------------------------------- diff --git a/proton-c/src/config.h b/proton-c/src/config.h deleted file mode 100644 index 5a2e7bc..0000000 --- a/proton-c/src/config.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef _PROTON_SRC_CONFIG_H -#define _PROTON_SRC_CONFIG_H - -#ifndef PN_TRANSPORT_INITIAL_FRAME_SIZE -# define PN_TRANSPORT_INITIAL_FRAME_SIZE (512) /* bytes */ -#endif - -#ifndef PN_SASL_MAX_BUFFSIZE -# define PN_SASL_MAX_BUFFSIZE (32768) /* bytes */ -#endif - -#endif /* _PROTON_SRC_CONFIG_H */ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/core/autodetect.c ---------------------------------------------------------------------- diff --git a/proton-c/src/core/autodetect.c b/proton-c/src/core/autodetect.c new file mode 100644 index 0000000..00f6d98 --- /dev/null +++ b/proton-c/src/core/autodetect.c @@ -0,0 +1,135 @@ +/* + * + * 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 "autodetect.h" + +#define SASL_HEADER ("AMQP\x03\x01\x00\x00") +#define SSL_HEADER ("AMQP\x02\x01\x00\x00") +#define AMQP_HEADER ("AMQP\x00\x01\x00\x00") + +#define SASL_HEADER_LEN 8 + +/* + * SSLv2 Client Hello format + * http://www.mozilla.org/projects/security/pki/nss/ssl/draft02.html + * + * Bytes 0-1: RECORD-LENGTH + * Byte 2: MSG-CLIENT-HELLO (1) + * Byte 3: CLIENT-VERSION-MSB + * Byte 4: CLIENT-VERSION-LSB + * + * Allowed versions: + * 2.0 - SSLv2 + * 3.0 - SSLv3 + * 3.1 - TLS 1.0 + * 3.2 - TLS 1.1 + * 3.3 - TLS 1.2 + * + * The version sent in the Client-Hello is the latest version supported by + * the client. NSS may send version 3.x in an SSLv2 header for + * maximum compatibility. + */ +/* + * SSLv3/TLS Client Hello format + * RFC 2246 + * + * Byte 0: ContentType (handshake - 22) + * Bytes 1-2: ProtocolVersion {major, minor} + * + * Allowed versions: + * 3.0 - SSLv3 + * 3.1 - TLS 1.0 + * 3.2 - TLS 1.1 + * 3.3 - TLS 1.2 + */ +/* + * AMQP 1.0 Header + * + * Bytes 0-3: "AMQP" + * Byte 4: 0==AMQP, 2==SSL, 3==SASL + * Byte 5: 1 + * Bytes 6-7: 0 + */ +/* + * AMQP Pre 1.0 Header + * + * Bytes 0-3: 'AMQP' + * Byte 4: 1 + * Byte 5: 1 + * Byte 6: 0 (major version) + * Byte 7: Minor version + */ +pni_protocol_type_t pni_sniff_header(const char *buf, size_t len) +{ + if (len < 3) return PNI_PROTOCOL_INSUFFICIENT; + bool isSSL3Handshake = buf[0]==22 && // handshake + buf[1]==3 && buf[2]<=3; // SSL 3.0 & TLS 1.0-1.2 (v3.1-3.3) + if (isSSL3Handshake) return PNI_PROTOCOL_SSL; + + bool isFirst3AMQP = buf[0]=='A' && buf[1]=='M' && buf[2]=='Q'; + bool isFirst3SSL2CLientHello = buf[2]==1; // Client Hello + if (!isFirst3AMQP && !isFirst3SSL2CLientHello) return PNI_PROTOCOL_UNKNOWN; + + + if (len < 4) return PNI_PROTOCOL_INSUFFICIENT; + bool isAMQP = isFirst3AMQP && buf[3]=='P'; + bool isFirst4SSL2ClientHello = isFirst3SSL2CLientHello && (buf[3]==2 || buf[3]==3); + if (!isAMQP && !isFirst4SSL2ClientHello) return PNI_PROTOCOL_UNKNOWN; + + if (len < 5) return PNI_PROTOCOL_INSUFFICIENT; + bool isSSL2Handshake = buf[2] == 1 && // MSG-CLIENT-HELLO + ((buf[3] == 3 && buf[4] <= 3) || // SSL 3.0 & TLS 1.0-1.2 (v3.1-3.3) + (buf[3] == 2 && buf[4] == 0)); // SSL 2 + if (isSSL2Handshake) return PNI_PROTOCOL_SSL; + + bool isFirst5OldAMQP = isAMQP && buf[4]==1; + bool isFirst5AMQP = isAMQP && (buf[4]==0 || buf[4]==2 || buf[4]==3); + if (!isFirst5AMQP && !isFirst5OldAMQP) return PNI_PROTOCOL_UNKNOWN; + + if (len < 6) return PNI_PROTOCOL_INSUFFICIENT; + + // Both old and new versions of AMQP have 1 in byte 5 + if (buf[5]!=1) return PNI_PROTOCOL_UNKNOWN; + + // From here on it must be some sort of AMQP + if (len < 8) return PNI_PROTOCOL_INSUFFICIENT; + if (buf[6]==0 && buf[7]==0) { + // AM<QP 1.0 + if (buf[4]==0) return PNI_PROTOCOL_AMQP1; + if (buf[4]==2) return PNI_PROTOCOL_AMQP_SSL; + if (buf[4]==3) return PNI_PROTOCOL_AMQP_SASL; + } + return PNI_PROTOCOL_AMQP_OTHER; +} + +const char* pni_protocol_name(pni_protocol_type_t p) +{ + static const char* names[] = { + "Insufficient data to determine protocol", + "Unknown protocol", + "SSL/TLS connection", + "AMQP TLS layer", + "AMQP SASL layer", + "AMQP 1.0 layer", + "Pre standard AMQP connection" + }; + return names[p]; +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/core/autodetect.h ---------------------------------------------------------------------- diff --git a/proton-c/src/core/autodetect.h b/proton-c/src/core/autodetect.h new file mode 100644 index 0000000..12cb7d8 --- /dev/null +++ b/proton-c/src/core/autodetect.h @@ -0,0 +1,40 @@ +#ifndef PROTON_AUTODETECT_H +#define PROTON_AUTODETECT_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/types.h" + +typedef enum { + PNI_PROTOCOL_INSUFFICIENT, + PNI_PROTOCOL_UNKNOWN, + PNI_PROTOCOL_SSL, + PNI_PROTOCOL_AMQP_SSL, + PNI_PROTOCOL_AMQP_SASL, + PNI_PROTOCOL_AMQP1, + PNI_PROTOCOL_AMQP_OTHER +} pni_protocol_type_t; + +pni_protocol_type_t pni_sniff_header(const char *data, size_t len); +const char* pni_protocol_name(pni_protocol_type_t p); + +#endif http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/core/buffer.c ---------------------------------------------------------------------- diff --git a/proton-c/src/core/buffer.c b/proton-c/src/core/buffer.c new file mode 100644 index 0000000..c3015f4 --- /dev/null +++ b/proton-c/src/core/buffer.c @@ -0,0 +1,310 @@ +/* + * + * 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/error.h> +#ifndef __cplusplus +#include <stdbool.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "buffer.h" +#include "util.h" + +struct pn_buffer_t { + size_t capacity; + size_t start; + size_t size; + char *bytes; +}; + +pn_buffer_t *pn_buffer(size_t capacity) +{ + pn_buffer_t *buf = (pn_buffer_t *) malloc(sizeof(pn_buffer_t)); + if (buf != NULL) { + buf->capacity = capacity; + buf->start = 0; + buf->size = 0; + if (capacity > 0) { + buf->bytes = (char *)malloc(capacity); + if (buf->bytes == NULL) { + free(buf); + buf = NULL; + } + } + else { + buf->bytes = NULL; + } + } + return buf; +} + +void pn_buffer_free(pn_buffer_t *buf) +{ + if (buf) { + free(buf->bytes); + free(buf); + } +} + +size_t pn_buffer_size(pn_buffer_t *buf) +{ + return buf->size; +} + +size_t pn_buffer_capacity(pn_buffer_t *buf) +{ + return buf->capacity; +} + +size_t pn_buffer_available(pn_buffer_t *buf) +{ + return buf->capacity - buf->size; +} + +static size_t pni_buffer_head(pn_buffer_t *buf) +{ + return buf->start; +} + +static size_t pni_buffer_tail(pn_buffer_t *buf) +{ + size_t tail = buf->start + buf->size; + if (tail >= buf->capacity) + tail -= buf->capacity; + return tail; +} + +static bool pni_buffer_wrapped(pn_buffer_t *buf) +{ + return buf->size && pni_buffer_head(buf) >= pni_buffer_tail(buf); +} + +static size_t pni_buffer_tail_space(pn_buffer_t *buf) +{ + if (pni_buffer_wrapped(buf)) { + return pn_buffer_available(buf); + } else { + return buf->capacity - pni_buffer_tail(buf); + } +} + +static size_t pni_buffer_head_space(pn_buffer_t *buf) +{ + if (pni_buffer_wrapped(buf)) { + return pn_buffer_available(buf); + } else { + return pni_buffer_head(buf); + } +} + +static size_t pni_buffer_head_size(pn_buffer_t *buf) +{ + if (pni_buffer_wrapped(buf)) { + return buf->capacity - pni_buffer_head(buf); + } else { + return pni_buffer_tail(buf) - pni_buffer_head(buf); + } +} + +static size_t pni_buffer_tail_size(pn_buffer_t *buf) +{ + if (pni_buffer_wrapped(buf)) { + return pni_buffer_tail(buf); + } else { + return 0; + } +} + +int pn_buffer_ensure(pn_buffer_t *buf, size_t size) +{ + size_t old_capacity = buf->capacity; + size_t old_head = pni_buffer_head(buf); + bool wrapped = pni_buffer_wrapped(buf); + + while (pn_buffer_available(buf) < size) { + buf->capacity = 2*(buf->capacity ? buf->capacity : 16); + } + + if (buf->capacity != old_capacity) { + char* new_bytes = (char *)realloc(buf->bytes, buf->capacity); + if (new_bytes) { + buf->bytes = new_bytes; + + if (wrapped) { + size_t n = old_capacity - old_head; + memmove(buf->bytes + buf->capacity - n, buf->bytes + old_head, n); + buf->start = buf->capacity - n; + } + } + } + + return 0; +} + +int pn_buffer_append(pn_buffer_t *buf, const char *bytes, size_t size) +{ + int err = pn_buffer_ensure(buf, size); + if (err) return err; + + size_t tail = pni_buffer_tail(buf); + size_t tail_space = pni_buffer_tail_space(buf); + size_t n = pn_min(tail_space, size); + + memmove(buf->bytes + tail, bytes, n); + memmove(buf->bytes, bytes + n, size - n); + + buf->size += size; + + return 0; +} + +int pn_buffer_prepend(pn_buffer_t *buf, const char *bytes, size_t size) +{ + int err = pn_buffer_ensure(buf, size); + if (err) return err; + + size_t head = pni_buffer_head(buf); + size_t head_space = pni_buffer_head_space(buf); + size_t n = pn_min(head_space, size); + + memmove(buf->bytes + head - n, bytes + size - n, n); + memmove(buf->bytes + buf->capacity - (size - n), bytes, size - n); + + if (buf->start >= size) { + buf->start -= size; + } else { + buf->start = buf->capacity - (size - buf->start); + } + + buf->size += size; + + return 0; +} + +static size_t pni_buffer_index(pn_buffer_t *buf, size_t index) +{ + size_t result = buf->start + index; + if (result >= buf->capacity) result -= buf->capacity; + return result; +} + +size_t pn_buffer_get(pn_buffer_t *buf, size_t offset, size_t size, char *dst) +{ + size = pn_min(size, buf->size); + size_t start = pni_buffer_index(buf, offset); + size_t stop = pni_buffer_index(buf, offset + size); + + if (size == 0) return 0; + + size_t sz1; + size_t sz2; + + if (start >= stop) { + sz1 = buf->capacity - start; + sz2 = stop; + } else { + sz1 = stop - start; + sz2 = 0; + } + + memmove(dst, buf->bytes + start, sz1); + memmove(dst + sz1, buf->bytes, sz2); + + return sz1 + sz2; +} + +int pn_buffer_trim(pn_buffer_t *buf, size_t left, size_t right) +{ + if (left + right > buf->size) return PN_ARG_ERR; + + buf->start += left; + if (buf->start >= buf->capacity) + buf->start -= buf->capacity; + + buf->size -= left + right; + + return 0; +} + +void pn_buffer_clear(pn_buffer_t *buf) +{ + buf->start = 0; + buf->size = 0; +} + +static void pn_buffer_rotate (pn_buffer_t *buf, size_t sz) { + if (sz == 0) return; + + unsigned c = 0, v = 0; + for (; c < buf->capacity; v++) { + unsigned t = v, tp = v + sz; + char tmp = buf->bytes[v]; + c++; + while (tp != v) { + buf->bytes[t] = buf->bytes[tp]; + t = tp; + tp += sz; + if (tp >= buf->capacity) tp -= buf->capacity; + c++; + } + buf->bytes[t] = tmp; + } +} + +int pn_buffer_defrag(pn_buffer_t *buf) +{ + pn_buffer_rotate(buf, buf->start); + buf->start = 0; + return 0; +} + +pn_bytes_t pn_buffer_bytes(pn_buffer_t *buf) +{ + if (buf) { + pn_buffer_defrag(buf); + return pn_bytes(buf->size, buf->bytes); + } else { + return pn_bytes(0, NULL); + } +} + +pn_rwbytes_t pn_buffer_memory(pn_buffer_t *buf) +{ + if (buf) { + pn_buffer_defrag(buf); + pn_rwbytes_t r = {buf->size, buf->bytes}; + return r; + } else { + pn_rwbytes_t r = {0, NULL}; + return r; + } +} + +int pn_buffer_print(pn_buffer_t *buf) +{ + printf("pn_buffer(\""); + pn_print_data(buf->bytes + pni_buffer_head(buf), pni_buffer_head_size(buf)); + pn_print_data(buf->bytes, pni_buffer_tail_size(buf)); + printf("\")"); + return 0; +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/core/buffer.h ---------------------------------------------------------------------- diff --git a/proton-c/src/core/buffer.h b/proton-c/src/core/buffer.h new file mode 100644 index 0000000..da557ef --- /dev/null +++ b/proton-c/src/core/buffer.h @@ -0,0 +1,54 @@ +#ifndef PROTON_BUFFER_H +#define PROTON_BUFFER_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/import_export.h> +#include <proton/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct pn_buffer_t pn_buffer_t; + +pn_buffer_t *pn_buffer(size_t capacity); +void pn_buffer_free(pn_buffer_t *buf); +size_t pn_buffer_size(pn_buffer_t *buf); +size_t pn_buffer_capacity(pn_buffer_t *buf); +size_t pn_buffer_available(pn_buffer_t *buf); +int pn_buffer_ensure(pn_buffer_t *buf, size_t size); +int pn_buffer_append(pn_buffer_t *buf, const char *bytes, size_t size); +int pn_buffer_prepend(pn_buffer_t *buf, const char *bytes, size_t size); +size_t pn_buffer_get(pn_buffer_t *buf, size_t offset, size_t size, char *dst); +int pn_buffer_trim(pn_buffer_t *buf, size_t left, size_t right); +void pn_buffer_clear(pn_buffer_t *buf); +int pn_buffer_defrag(pn_buffer_t *buf); +pn_bytes_t pn_buffer_bytes(pn_buffer_t *buf); +pn_rwbytes_t pn_buffer_memory(pn_buffer_t *buf); +int pn_buffer_print(pn_buffer_t *buf); + +#ifdef __cplusplus +} +#endif + +#endif /* buffer.h */ --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
