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 2014/11/28 14:50:23 UTC
[45/51] [abbrv] qpid-proton git commit: Sync with proton trunk
revision 1627945 and update CMakeLists.txt
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/include/proton/util.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/util.h b/proton-c/include/proton/util.h
deleted file mode 100644
index 70043eb..0000000
--- a/proton-c/include/proton/util.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#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 <proton/import_export.h>
-#include <stdarg.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-PN_EXTERN void pni_parse_url(char *url, char **scheme, char **user, char **pass, char **host, char **port, char **path);
-PN_EXTERN void pn_fatal(const char *fmt, ...);
-PN_EXTERN void pn_vfatal(const char *fmt, va_list ap);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* util.h */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/codec/codec.c
----------------------------------------------------------------------
diff --git a/proton-c/src/codec/codec.c b/proton-c/src/codec/codec.c
index 87d7df7..afd0c57 100644
--- a/proton-c/src/codec/codec.c
+++ b/proton-c/src/codec/codec.c
@@ -22,7 +22,6 @@
#include <proton/object.h>
#include <proton/codec.h>
#include <proton/error.h>
-#include <proton/util.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -32,9 +31,9 @@
#include "encodings.h"
#define DEFINE_FIELDS
#include "protocol.h"
-#include "../platform.h"
-#include "../platform_fmt.h"
-#include "../util.h"
+#include "platform.h"
+#include "platform_fmt.h"
+#include "util.h"
#include "decoder.h"
#include "encoder.h"
#include "data.h"
@@ -367,7 +366,7 @@ static int pn_data_inspect(void *obj, pn_string_t *dst)
pn_data_t *pn_data(size_t capacity)
{
static const pn_class_t clazz = PN_CLASS(pn_data);
- pn_data_t *data = (pn_data_t *) pn_new(sizeof(pn_data_t), &clazz);
+ pn_data_t *data = (pn_data_t *) pn_class_new(&clazz, sizeof(pn_data_t));
data->capacity = capacity;
data->size = 0;
data->nodes = capacity ? (pni_node_t *) malloc(capacity * sizeof(pni_node_t)) : NULL;
@@ -1112,15 +1111,6 @@ int pn_data_resize(pn_data_t *data, size_t size)
}
-pni_node_t *pn_data_node(pn_data_t *data, pni_nid_t nd)
-{
- if (nd) {
- return &data->nodes[nd - 1];
- } else {
- return NULL;
- }
-}
-
size_t pn_data_id(pn_data_t *data, pni_node_t *node)
{
return node - data->nodes + 1;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/codec/data.h
----------------------------------------------------------------------
diff --git a/proton-c/src/codec/data.h b/proton-c/src/codec/data.h
index be1669a..a528d26 100644
--- a/proton-c/src/codec/data.h
+++ b/proton-c/src/codec/data.h
@@ -61,7 +61,11 @@ struct pn_data_t {
pni_nid_t base_current;
};
-pni_node_t *pn_data_node(pn_data_t *data, pni_nid_t nd);
+inline pni_node_t * pn_data_node(pn_data_t *data, pni_nid_t nd)
+{
+ return nd ? (data->nodes + nd - 1) : NULL;
+}
+
int pni_data_traverse(pn_data_t *data,
int (*enter)(void *ctx, pn_data_t *data, pni_node_t *node),
int (*exit)(void *ctx, pn_data_t *data, pni_node_t *node),
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/codec/decoder.c
----------------------------------------------------------------------
diff --git a/proton-c/src/codec/decoder.c b/proton-c/src/codec/decoder.c
index 7a01388..2bd4ecc 100644
--- a/proton-c/src/codec/decoder.c
+++ b/proton-c/src/codec/decoder.c
@@ -55,7 +55,7 @@ static void pn_decoder_finalize(void *obj) {
pn_decoder_t *pn_decoder()
{
static const pn_class_t clazz = PN_CLASS(pn_decoder);
- return (pn_decoder_t *) pn_new(sizeof(pn_decoder_t), &clazz);
+ return (pn_decoder_t *) pn_class_new(&clazz, sizeof(pn_decoder_t));
}
static inline uint8_t pn_decoder_readf8(pn_decoder_t *decoder)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/codec/encoder.c
----------------------------------------------------------------------
diff --git a/proton-c/src/codec/encoder.c b/proton-c/src/codec/encoder.c
index f0f3cef..4a32183 100644
--- a/proton-c/src/codec/encoder.c
+++ b/proton-c/src/codec/encoder.c
@@ -57,7 +57,7 @@ static void pn_encoder_finalize(void *obj) {
pn_encoder_t *pn_encoder()
{
static const pn_class_t clazz = PN_CLASS(pn_encoder);
- return (pn_encoder_t *) pn_new(sizeof(pn_encoder_t), &clazz);
+ 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)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/dispatcher/dispatcher.c
----------------------------------------------------------------------
diff --git a/proton-c/src/dispatcher/dispatcher.c b/proton-c/src/dispatcher/dispatcher.c
index 296c3ab..6368aa5 100644
--- a/proton-c/src/dispatcher/dispatcher.c
+++ b/proton-c/src/dispatcher/dispatcher.c
@@ -27,8 +27,8 @@
#include <proton/buffer.h>
#include "dispatcher.h"
#include "protocol.h"
-#include "../util.h"
-#include "../platform_fmt.h"
+#include "util.h"
+#include "platform_fmt.h"
#include "dispatch_actions.h"
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/dispatcher/dispatcher.h
----------------------------------------------------------------------
diff --git a/proton-c/src/dispatcher/dispatcher.h b/proton-c/src/dispatcher/dispatcher.h
index a87e383..9ec2dda 100644
--- a/proton-c/src/dispatcher/dispatcher.h
+++ b/proton-c/src/dispatcher/dispatcher.h
@@ -26,8 +26,9 @@
#ifndef __cplusplus
#include <stdbool.h>
#endif
-#include <proton/buffer.h>
-#include <proton/codec.h>
+#include "proton/buffer.h"
+#include "proton/codec.h"
+#include "proton/transport.h"
typedef struct pn_dispatcher_t pn_dispatcher_t;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/engine/engine-internal.h
----------------------------------------------------------------------
diff --git a/proton-c/src/engine/engine-internal.h b/proton-c/src/engine/engine-internal.h
index 03cb630..37e8311 100644
--- a/proton-c/src/engine/engine-internal.h
+++ b/proton-c/src/engine/engine-internal.h
@@ -26,8 +26,8 @@
#include <proton/buffer.h>
#include <proton/engine.h>
#include <proton/types.h>
-#include "../dispatcher/dispatcher.h"
-#include "../util.h"
+#include "dispatcher/dispatcher.h"
+#include "util.h"
typedef enum pn_endpoint_type_t {CONNECTION, SESSION, SENDER, RECEIVER} pn_endpoint_type_t;
@@ -127,6 +127,7 @@ struct pn_transport_t {
uint32_t local_max_frame;
uint32_t remote_max_frame;
pn_condition_t remote_condition;
+ pn_condition_t condition;
#define PN_IO_SSL 0
#define PN_IO_SASL 1
@@ -174,6 +175,8 @@ struct pn_transport_t {
bool tail_closed; // input stream closed by driver
bool head_closed;
bool done_processing; // if true, don't call pn_process again
+ bool posted_head_closed;
+ bool posted_tail_closed;
};
struct pn_connection_t {
@@ -250,6 +253,7 @@ struct pn_link_t {
uint8_t remote_rcv_settle_mode;
bool drain_flag_mode; // receiver only
bool drain;
+ bool detached;
};
struct pn_disposition_t {
@@ -311,5 +315,10 @@ void pn_work_update(pn_connection_t *connection, pn_delivery_t *delivery);
void pn_clear_modified(pn_connection_t *connection, pn_endpoint_t *endpoint);
void pn_connection_unbound(pn_connection_t *conn);
int pn_do_error(pn_transport_t *transport, const char *condition, const char *fmt, ...);
+void pn_session_unbound(pn_session_t* ssn);
+void pn_link_unbound(pn_link_t* link);
+
+void pni_close_tail(pn_transport_t *transport);
+
#endif /* engine-internal.h */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/engine/engine.c
----------------------------------------------------------------------
diff --git a/proton-c/src/engine/engine.c b/proton-c/src/engine/engine.c
index 02e5009..46bf462 100644
--- a/proton-c/src/engine/engine.c
+++ b/proton-c/src/engine/engine.c
@@ -28,12 +28,9 @@
#include <stdarg.h>
#include <stdio.h>
-#include "../sasl/sasl-internal.h"
-#include "../ssl/ssl-internal.h"
-#include "../platform.h"
-#include "../platform_fmt.h"
-#include "../transport/transport.h"
-#include "../engine/event.h"
+#include "platform.h"
+#include "platform_fmt.h"
+#include "transport/transport.h"
// endpoints
@@ -72,8 +69,8 @@ static void pn_endpoint_open(pn_endpoint_t *endpoint)
// TODO: do we care about the current state?
PN_SET_LOCAL(endpoint->state, PN_LOCAL_ACTIVE);
pn_connection_t *conn = pn_ep_get_connection(endpoint);
- pn_collector_put(conn->collector, endpoint_event(endpoint->type, true),
- endpoint);
+ pn_collector_put(conn->collector, PN_OBJECT, endpoint,
+ endpoint_event(endpoint->type, true));
pn_modified(conn, endpoint, true);
}
@@ -82,8 +79,8 @@ static void pn_endpoint_close(pn_endpoint_t *endpoint)
// TODO: do we care about the current state?
PN_SET_LOCAL(endpoint->state, PN_LOCAL_CLOSED);
pn_connection_t *conn = pn_ep_get_connection(endpoint);
- pn_collector_put(conn->collector, endpoint_event(endpoint->type, false),
- endpoint);
+ pn_collector_put(conn->collector, PN_OBJECT, endpoint,
+ endpoint_event(endpoint->type, false));
pn_modified(conn, endpoint, true);
}
@@ -190,7 +187,7 @@ void pn_add_session(pn_connection_t *conn, pn_session_t *ssn)
{
pn_list_add(conn->sessions, ssn);
ssn->connection = conn;
- pn_incref2(conn, ssn); // keep around until finalized
+ pn_incref(conn); // keep around until finalized
}
void pn_remove_session(pn_connection_t *conn, pn_session_t *ssn)
@@ -228,7 +225,7 @@ void pn_session_free(pn_session_t *session)
pn_endpoint_t *endpoint = (pn_endpoint_t *) session;
LL_REMOVE(pn_ep_get_connection(endpoint), endpoint, endpoint);
session->endpoint.freed = true;
- pn_decref2(session, session->connection);
+ pn_decref(session);
}
void *pn_session_get_context(pn_session_t *session)
@@ -266,6 +263,15 @@ void pn_link_close(pn_link_t *link)
pn_endpoint_close(&link->endpoint);
}
+void pn_link_detach(pn_link_t *link)
+{
+ assert(link);
+ link->detached = true;
+ pn_collector_put(link->session->connection->collector, PN_OBJECT, link, PN_LINK_DETACH);
+ pn_modified(link->session->connection, &link->endpoint, true);
+
+}
+
void pn_terminus_free(pn_terminus_t *terminus)
{
pn_free(terminus->address);
@@ -290,10 +296,10 @@ void pn_link_free(pn_link_t *link)
while (link->settled_head) {
delivery = link->settled_head;
LL_POP(link, settled, pn_delivery_t);
- pn_decref2(delivery, link);
+ pn_decref(delivery);
}
link->endpoint.freed = true;
- pn_decref2(link, link->session);
+ pn_decref(link);
}
void *pn_link_get_context(pn_link_t *link)
@@ -332,14 +338,13 @@ void pn_endpoint_tini(pn_endpoint_t *endpoint)
pn_condition_tini(&endpoint->condition);
}
-#include "event.h"
-
static bool pni_post_final(pn_endpoint_t *endpoint, pn_event_type_t type)
{
pn_connection_t *conn = pn_ep_get_connection(endpoint);
if (!endpoint->posted_final) {
endpoint->posted_final = true;
- pn_event_t *event = pn_collector_put(conn->collector, type, endpoint);
+ pn_event_t *event = pn_collector_put(conn->collector, PN_OBJECT, endpoint,
+ type);
if (event) { return true; }
}
@@ -355,7 +360,7 @@ static void pn_connection_finalize(void *object)
return;
}
- pn_decref2(conn->collector, conn);
+ pn_decref(conn->collector);
pn_free(conn->sessions);
pn_free(conn->container);
pn_free(conn->hostname);
@@ -373,7 +378,7 @@ static void pn_connection_finalize(void *object)
pn_connection_t *pn_connection()
{
static const pn_class_t clazz = PN_CLASS(pn_connection);
- pn_connection_t *conn = (pn_connection_t *) pn_new(sizeof(pn_connection_t), &clazz);
+ pn_connection_t *conn = (pn_connection_t *) pn_class_new(&clazz, sizeof(pn_connection_t));
if (!conn) return NULL;
conn->context = NULL;
@@ -382,7 +387,7 @@ pn_connection_t *pn_connection()
pn_endpoint_init(&conn->endpoint, CONNECTION, conn);
conn->transport_head = NULL;
conn->transport_tail = NULL;
- conn->sessions = pn_list(0, 0);
+ conn->sessions = pn_list(PN_WEAKREF, 0);
conn->transport = NULL;
conn->work_head = NULL;
conn->work_tail = NULL;
@@ -406,12 +411,12 @@ static const pn_event_type_t endpoint_init_event_map[] = {
void pn_connection_collect(pn_connection_t *connection, pn_collector_t *collector)
{
- pn_decref2(connection->collector, connection);
+ pn_decref(connection->collector);
connection->collector = collector;
- pn_incref2(connection->collector, connection);
+ pn_incref(connection->collector);
pn_endpoint_t *endpoint = connection->endpoint_head;
while (endpoint) {
- pn_collector_put(connection->collector, endpoint_init_event_map[endpoint->type], endpoint);
+ pn_collector_put(connection->collector, PN_OBJECT, endpoint, endpoint_init_event_map[endpoint->type]);
endpoint = endpoint->endpoint_next;
}
}
@@ -561,7 +566,7 @@ void pn_add_tpwork(pn_delivery_t *delivery)
{
LL_ADD(connection, tpwork, delivery);
delivery->tpwork = true;
- pn_incref2(delivery, connection);
+ pn_incref(delivery);
}
pn_modified(connection, &connection->endpoint, true);
}
@@ -573,7 +578,7 @@ void pn_clear_tpwork(pn_delivery_t *delivery)
{
LL_REMOVE(connection, tpwork, delivery);
delivery->tpwork = false;
- pn_decref2(delivery, connection); // may free delivery!
+ pn_decref(delivery); // may free delivery!
}
}
@@ -595,12 +600,12 @@ void pn_modified(pn_connection_t *connection, pn_endpoint_t *endpoint, bool emit
if (!endpoint->modified) {
LL_ADD(connection, transport, endpoint);
endpoint->modified = true;
- pn_incref2(endpoint, connection);
+ pn_incref(endpoint);
}
if (emit && connection->transport) {
- pn_collector_put(connection->collector, PN_TRANSPORT,
- connection->transport);
+ pn_collector_put(connection->collector, PN_OBJECT, connection->transport,
+ PN_TRANSPORT);
}
}
@@ -611,7 +616,7 @@ void pn_clear_modified(pn_connection_t *connection, pn_endpoint_t *endpoint)
endpoint->transport_next = NULL;
endpoint->transport_prev = NULL;
endpoint->modified = false;
- pn_decref2(endpoint, connection); // may free endpoint!
+ pn_decref(endpoint); // may free endpoint!
}
}
@@ -709,7 +714,7 @@ static void pn_session_finalize(void *object)
pn_delivery_map_free(&session->state.outgoing);
pn_free(session->state.local_handles);
pn_free(session->state.remote_handles);
- pn_decref2(session->connection, session);
+ pn_decref(session->connection);
}
#define pn_session_initialize NULL
@@ -721,12 +726,12 @@ pn_session_t *pn_session(pn_connection_t *conn)
{
assert(conn);
static const pn_class_t clazz = PN_CLASS(pn_session);
- pn_session_t *ssn = (pn_session_t *) pn_new2(sizeof(pn_session_t), &clazz, conn);
+ pn_session_t *ssn = (pn_session_t *) pn_class_new(&clazz, sizeof(pn_session_t));
if (!ssn) return NULL;
pn_endpoint_init(&ssn->endpoint, SESSION, conn);
pn_add_session(conn, ssn);
- ssn->links = pn_list(0, 0);
+ ssn->links = pn_list(PN_WEAKREF, 0);
ssn->context = 0;
ssn->incoming_capacity = 1024*1024;
ssn->incoming_bytes = 0;
@@ -740,14 +745,25 @@ pn_session_t *pn_session(pn_connection_t *conn)
ssn->state.remote_channel = (uint16_t)-1;
pn_delivery_map_init(&ssn->state.incoming, 0);
pn_delivery_map_init(&ssn->state.outgoing, 0);
- ssn->state.local_handles = pn_hash(0, 0.75, PN_REFCOUNT);
- ssn->state.remote_handles = pn_hash(0, 0.75, PN_REFCOUNT);
+ ssn->state.local_handles = pn_hash(PN_OBJECT, 0, 0.75);
+ ssn->state.remote_handles = pn_hash(PN_OBJECT, 0, 0.75);
// end transport state
- pn_collector_put(conn->collector, PN_SESSION_INIT, ssn);
+ pn_collector_put(conn->collector, PN_OBJECT, ssn, PN_SESSION_INIT);
return ssn;
}
+void pn_session_unbound(pn_session_t* ssn)
+{
+ assert(ssn);
+ ssn->state.local_channel = (uint16_t)-1;
+ ssn->state.remote_channel = (uint16_t)-1;
+ ssn->incoming_bytes = 0;
+ ssn->outgoing_bytes = 0;
+ ssn->incoming_deliveries = 0;
+ ssn->outgoing_deliveries = 0;
+}
+
size_t pn_session_get_incoming_capacity(pn_session_t *ssn)
{
assert(ssn);
@@ -817,7 +833,7 @@ static void pn_link_finalize(void *object)
pn_terminus_free(&link->remote_target);
pn_free(link->name);
pn_endpoint_tini(endpoint);
- pn_decref2(link->session, link);
+ pn_decref(link->session);
}
#define pn_link_initialize NULL
@@ -828,11 +844,11 @@ static void pn_link_finalize(void *object)
pn_link_t *pn_link_new(int type, pn_session_t *session, const char *name)
{
static const pn_class_t clazz = PN_CLASS(pn_link);
- pn_link_t *link = (pn_link_t *) pn_new2(sizeof(pn_link_t), &clazz, session);
+ pn_link_t *link = (pn_link_t *) pn_class_new(&clazz, sizeof(pn_link_t));
pn_endpoint_init(&link->endpoint, type, session->connection);
pn_add_link(session, link);
- pn_incref2(session, link); // keep session until link finalized
+ pn_incref(session); // keep session until link finalized
link->name = pn_string(name);
pn_terminus_init(&link->source, PN_SOURCE);
pn_terminus_init(&link->target, PN_TARGET);
@@ -852,6 +868,7 @@ pn_link_t *pn_link_new(int type, pn_session_t *session, const char *name)
link->rcv_settle_mode = PN_RCV_FIRST;
link->remote_snd_settle_mode = PN_SND_MIXED;
link->remote_rcv_settle_mode = PN_RCV_FIRST;
+ link->detached = false;
// begin transport state
link->state.local_handle = -1;
@@ -860,10 +877,19 @@ pn_link_t *pn_link_new(int type, pn_session_t *session, const char *name)
link->state.link_credit = 0;
// end transport state
- pn_collector_put(session->connection->collector, PN_LINK_INIT, link);
+ pn_collector_put(session->connection->collector, PN_OBJECT, link, PN_LINK_INIT);
return link;
}
+void pn_link_unbound(pn_link_t* link)
+{
+ assert(link);
+ link->state.local_handle = -1;
+ link->state.remote_handle = -1;
+ link->state.delivery_count = 0;
+ link->state.link_credit = 0;
+}
+
pn_terminus_t *pn_link_source(pn_link_t *link)
{
return link ? &link->source : NULL;
@@ -1072,7 +1098,7 @@ static void pn_delivery_finalize(void *object)
pn_buffer_free(delivery->bytes);
pn_disposition_finalize(&delivery->local);
pn_disposition_finalize(&delivery->remote);
- pn_decref2(delivery->link, delivery);
+ pn_decref(delivery->link);
}
static void pn_disposition_init(pn_disposition_t *ds)
@@ -1107,10 +1133,10 @@ pn_delivery_t *pn_delivery(pn_link_t *link, pn_delivery_tag_t tag)
LL_POP(link, settled, pn_delivery_t);
if (!delivery) {
static const pn_class_t clazz = PN_CLASS(pn_delivery);
- delivery = (pn_delivery_t *) pn_new2(sizeof(pn_delivery_t), &clazz, link);
+ delivery = (pn_delivery_t *) pn_class_new(&clazz, sizeof(pn_delivery_t));
if (!delivery) return NULL;
delivery->link = link;
- pn_incref2(delivery->link, delivery); // keep link until finalized
+ pn_incref(delivery->link); // keep link until finalized
delivery->tag = pn_buffer(16);
delivery->bytes = pn_buffer(64);
pn_disposition_init(&delivery->local);
@@ -1734,3 +1760,77 @@ int pn_condition_redirect_port(pn_condition_t *condition)
pn_data_rewind(data);
return port;
}
+
+pn_connection_t *pn_event_connection(pn_event_t *event)
+{
+ pn_session_t *ssn;
+ pn_transport_t *transport;
+
+ switch (pn_class_id(pn_event_class(event))) {
+ case CID_pn_connection:
+ return (pn_connection_t *) pn_event_context(event);
+ case CID_pn_transport:
+ transport = pn_event_transport(event);
+ if (transport)
+ return transport->connection;
+ return NULL;
+ default:
+ ssn = pn_event_session(event);
+ if (ssn)
+ return pn_session_connection(ssn);
+ }
+ return NULL;
+}
+
+pn_session_t *pn_event_session(pn_event_t *event)
+{
+ pn_link_t *link;
+ switch (pn_class_id(pn_event_class(event))) {
+ case CID_pn_session:
+ return (pn_session_t *) pn_event_context(event);
+ default:
+ link = pn_event_link(event);
+ if (link)
+ return pn_link_session(link);
+ }
+ return NULL;
+}
+
+pn_link_t *pn_event_link(pn_event_t *event)
+{
+ pn_delivery_t *dlv;
+ switch (pn_class_id(pn_event_class(event))) {
+ case CID_pn_link:
+ return (pn_link_t *) pn_event_context(event);
+ default:
+ dlv = pn_event_delivery(event);
+ if (dlv)
+ return pn_delivery_link(dlv);
+ }
+ return NULL;
+}
+
+pn_delivery_t *pn_event_delivery(pn_event_t *event)
+{
+ switch (pn_class_id(pn_event_class(event))) {
+ case CID_pn_delivery:
+ return (pn_delivery_t *) pn_event_context(event);
+ default:
+ return NULL;
+ }
+}
+
+pn_transport_t *pn_event_transport(pn_event_t *event)
+{
+ switch (pn_class_id(pn_event_class(event))) {
+ case CID_pn_transport:
+ return (pn_transport_t *) pn_event_context(event);
+ default:
+ {
+ pn_connection_t *conn = pn_event_connection(event);
+ if (conn)
+ return pn_connection_transport(conn);
+ return NULL;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/engine/event.c
----------------------------------------------------------------------
diff --git a/proton-c/src/engine/event.c b/proton-c/src/engine/event.c
deleted file mode 100644
index 07e3cb5..0000000
--- a/proton-c/src/engine/event.c
+++ /dev/null
@@ -1,348 +0,0 @@
-#include <proton/engine.h>
-#include <assert.h>
-#include "engine-internal.h"
-
-struct pn_collector_t {
- pn_event_t *head;
- pn_event_t *tail;
- pn_event_t *free_head;
- bool freed;
-};
-
-struct pn_event_t {
- void *context; // depends on type
- pn_event_t *next;
- pn_event_type_t type;
-};
-
-static void pn_collector_initialize(void *obj)
-{
- pn_collector_t *collector = (pn_collector_t *) obj;
- collector->head = NULL;
- collector->tail = NULL;
- collector->free_head = NULL;
- collector->freed = false;
-}
-
-static void pn_collector_drain(pn_collector_t *collector)
-{
- while (pn_collector_peek(collector)) {
- pn_collector_pop(collector);
- }
-
- assert(!collector->head);
- assert(!collector->tail);
-}
-
-static void pn_collector_shrink(pn_collector_t *collector)
-{
- pn_event_t *event = collector->free_head;
- while (event) {
- pn_event_t *next = event->next;
- pn_free(event);
- event = next;
- }
-
- collector->free_head = NULL;
-}
-
-static void pn_collector_finalize(void *obj)
-{
- pn_collector_t *collector = (pn_collector_t *) obj;
- pn_collector_drain(collector);
- pn_collector_shrink(collector);
-}
-
-static int pn_collector_inspect(void *obj, pn_string_t *dst)
-{
- assert(obj);
- pn_collector_t *collector = (pn_collector_t *) obj;
- int err = pn_string_addf(dst, "EVENTS[");
- if (err) return err;
- pn_event_t *event = collector->head;
- bool first = true;
- while (event) {
- if (first) {
- first = false;
- } else {
- err = pn_string_addf(dst, ", ");
- if (err) return err;
- }
- err = pn_inspect(event, dst);
- if (err) return err;
- event = event->next;
- }
- return pn_string_addf(dst, "]");
-}
-
-#define pn_collector_hashcode NULL
-#define pn_collector_compare NULL
-
-pn_collector_t *pn_collector(void)
-{
- static const pn_class_t clazz = PN_CLASS(pn_collector);
- pn_collector_t *collector = (pn_collector_t *) pn_new(sizeof(pn_collector_t), &clazz);
- return collector;
-}
-
-void pn_collector_free(pn_collector_t *collector)
-{
- collector->freed = true;
- pn_collector_drain(collector);
- pn_collector_shrink(collector);
- pn_decref(collector);
-}
-
-pn_event_t *pn_event(void);
-static void pn_event_initialize(void *obj);
-
-pn_event_t *pn_collector_put(pn_collector_t *collector, pn_event_type_t type, void *context)
-{
- if (!collector) {
- return NULL;
- }
-
- assert(context);
-
- if (collector->freed) {
- return NULL;
- }
-
- pn_event_t *tail = collector->tail;
- if (tail && tail->type == type && tail->context == context) {
- return NULL;
- }
-
- pn_event_t *event;
-
- if (collector->free_head) {
- event = collector->free_head;
- collector->free_head = collector->free_head->next;
- pn_event_initialize(event);
- } else {
- event = pn_event();
- }
-
- if (tail) {
- tail->next = event;
- collector->tail = event;
- } else {
- collector->tail = event;
- collector->head = event;
- }
-
- event->type = type;
- event->context = context;
- pn_incref2(event->context, collector);
-
- //printf("event %s on %p\n", pn_event_type_name(event->type), event->context);
-
- return event;
-}
-
-pn_event_t *pn_collector_peek(pn_collector_t *collector)
-{
- return collector->head;
-}
-
-bool pn_collector_pop(pn_collector_t *collector)
-{
- pn_event_t *event = collector->head;
- if (event) {
- collector->head = event->next;
- } else {
- return false;
- }
-
- if (!collector->head) {
- collector->tail = NULL;
- }
-
- // decref before adding to the free list
- if (event->context) {
- pn_decref2(event->context, collector);
- event->context = NULL;
- }
-
- event->next = collector->free_head;
- collector->free_head = event;
-
- return true;
-}
-
-static void pn_event_initialize(void *obj)
-{
- pn_event_t *event = (pn_event_t *) obj;
- event->type = PN_EVENT_NONE;
- event->context = NULL;
- event->next = NULL;
-}
-
-static void pn_event_finalize(void *obj) {}
-
-static int pn_event_inspect(void *obj, pn_string_t *dst)
-{
- assert(obj);
- pn_event_t *event = (pn_event_t *) obj;
- int err = pn_string_addf(dst, "(0x%X", (unsigned int)event->type);
- if (event->context) {
- err = pn_string_addf(dst, ", ");
- if (err) return err;
- err = pn_inspect(event->context, dst);
- if (err) return err;
- }
-
- return pn_string_addf(dst, ")");
-}
-
-#define pn_event_hashcode NULL
-#define pn_event_compare NULL
-
-pn_event_t *pn_event(void)
-{
- static const pn_class_t clazz = PN_CLASS(pn_event);
- pn_event_t *event = (pn_event_t *) pn_new(sizeof(pn_event_t), &clazz);
- return event;
-}
-
-pn_event_type_t pn_event_type(pn_event_t *event)
-{
- return event->type;
-}
-
-pn_event_category_t pn_event_category(pn_event_t *event)
-{
- return (pn_event_category_t)(event->type & 0xFFFF0000);
-}
-
-void *pn_event_context(pn_event_t *event)
-{
- assert(event);
- return event->context;
-}
-
-pn_connection_t *pn_event_connection(pn_event_t *event)
-{
- pn_session_t *ssn;
- pn_transport_t *transport;
-
- switch (pn_event_category(event)) {
- case PN_EVENT_CATEGORY_CONNECTION:
- return (pn_connection_t *)event->context;
- case PN_EVENT_CATEGORY_TRANSPORT:
- transport = pn_event_transport(event);
- if (transport)
- return transport->connection;
- return NULL;
- default:
- ssn = pn_event_session(event);
- if (ssn)
- return pn_session_connection(ssn);
- }
- return NULL;
-}
-
-pn_session_t *pn_event_session(pn_event_t *event)
-{
- pn_link_t *link;
- switch (pn_event_category(event)) {
- case PN_EVENT_CATEGORY_SESSION:
- return (pn_session_t *)event->context;
- default:
- link = pn_event_link(event);
- if (link)
- return pn_link_session(link);
- }
- return NULL;
-}
-
-pn_link_t *pn_event_link(pn_event_t *event)
-{
- pn_delivery_t *dlv;
- switch (pn_event_category(event)) {
- case PN_EVENT_CATEGORY_LINK:
- return (pn_link_t *)event->context;
- default:
- dlv = pn_event_delivery(event);
- if (dlv)
- return pn_delivery_link(dlv);
- }
- return NULL;
-}
-
-pn_delivery_t *pn_event_delivery(pn_event_t *event)
-{
- switch (pn_event_category(event)) {
- case PN_EVENT_CATEGORY_DELIVERY:
- return (pn_delivery_t *)event->context;
- default:
- return NULL;
- }
-}
-
-pn_transport_t *pn_event_transport(pn_event_t *event)
-{
- switch (pn_event_category(event)) {
- case PN_EVENT_CATEGORY_TRANSPORT:
- return (pn_transport_t *)event->context;
- default:
- {
- pn_connection_t *conn = pn_event_connection(event);
- if (conn)
- return pn_connection_transport(conn);
- return NULL;
- }
- }
-}
-
-const char *pn_event_type_name(pn_event_type_t type)
-{
- switch (type) {
- case PN_EVENT_NONE:
- return "PN_EVENT_NONE";
- case PN_CONNECTION_INIT:
- return "PN_CONNECTION_INIT";
- case PN_CONNECTION_REMOTE_OPEN:
- return "PN_CONNECTION_REMOTE_OPEN";
- case PN_CONNECTION_OPEN:
- return "PN_CONNECTION_OPEN";
- case PN_CONNECTION_REMOTE_CLOSE:
- return "PN_CONNECTION_REMOTE_CLOSE";
- case PN_CONNECTION_CLOSE:
- return "PN_CONNECTION_CLOSE";
- case PN_CONNECTION_FINAL:
- return "PN_CONNECTION_FINAL";
- case PN_SESSION_INIT:
- return "PN_SESSION_INIT";
- case PN_SESSION_REMOTE_OPEN:
- return "PN_SESSION_REMOTE_OPEN";
- case PN_SESSION_OPEN:
- return "PN_SESSION_OPEN";
- case PN_SESSION_REMOTE_CLOSE:
- return "PN_SESSION_REMOTE_CLOSE";
- case PN_SESSION_CLOSE:
- return "PN_SESSION_CLOSE";
- case PN_SESSION_FINAL:
- return "PN_SESSION_FINAL";
- case PN_LINK_INIT:
- return "PN_LINK_INIT";
- case PN_LINK_REMOTE_OPEN:
- return "PN_LINK_REMOTE_OPEN";
- case PN_LINK_OPEN:
- return "PN_LINK_OPEN";
- case PN_LINK_REMOTE_CLOSE:
- return "PN_LINK_REMOTE_CLOSE";
- case PN_LINK_CLOSE:
- return "PN_LINK_CLOSE";
- case PN_LINK_FLOW:
- return "PN_LINK_FLOW";
- case PN_LINK_FINAL:
- return "PN_LINK_FINAL";
- case PN_DELIVERY:
- return "PN_DELIVERY";
- case PN_TRANSPORT:
- return "PN_TRANSPORT";
- }
-
- return "<unrecognized>";
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/engine/event.h
----------------------------------------------------------------------
diff --git a/proton-c/src/engine/event.h b/proton-c/src/engine/event.h
deleted file mode 100644
index b05f2d0..0000000
--- a/proton-c/src/engine/event.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _PROTON_EVENT_H
-#define _PROTON_EVENT_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.
- *
- */
-
-pn_event_t *pn_collector_put(pn_collector_t *collector, pn_event_type_t type,
- void *context);
-
-#endif /* event.h */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/events/event.c
----------------------------------------------------------------------
diff --git a/proton-c/src/events/event.c b/proton-c/src/events/event.c
new file mode 100644
index 0000000..95aeb03
--- /dev/null
+++ b/proton-c/src/events/event.c
@@ -0,0 +1,298 @@
+#include <proton/object.h>
+#include <proton/event.h>
+#include <assert.h>
+
+struct pn_collector_t {
+ pn_event_t *head;
+ pn_event_t *tail;
+ pn_event_t *free_head;
+ bool freed;
+};
+
+struct pn_event_t {
+ const pn_class_t *clazz;
+ void *context; // depends on type
+ pn_event_t *next;
+ pn_event_type_t type;
+};
+
+static void pn_collector_initialize(void *obj)
+{
+ pn_collector_t *collector = (pn_collector_t *) obj;
+ collector->head = NULL;
+ collector->tail = NULL;
+ collector->free_head = NULL;
+ collector->freed = false;
+}
+
+static void pn_collector_drain(pn_collector_t *collector)
+{
+ while (pn_collector_peek(collector)) {
+ pn_collector_pop(collector);
+ }
+
+ assert(!collector->head);
+ assert(!collector->tail);
+}
+
+static void pn_collector_shrink(pn_collector_t *collector)
+{
+ pn_event_t *event = collector->free_head;
+ while (event) {
+ pn_event_t *next = event->next;
+ pn_free(event);
+ event = next;
+ }
+
+ collector->free_head = NULL;
+}
+
+static void pn_collector_finalize(void *obj)
+{
+ pn_collector_t *collector = (pn_collector_t *) obj;
+ pn_collector_drain(collector);
+ pn_collector_shrink(collector);
+}
+
+static int pn_collector_inspect(void *obj, pn_string_t *dst)
+{
+ assert(obj);
+ pn_collector_t *collector = (pn_collector_t *) obj;
+ int err = pn_string_addf(dst, "EVENTS[");
+ if (err) return err;
+ pn_event_t *event = collector->head;
+ bool first = true;
+ while (event) {
+ if (first) {
+ first = false;
+ } else {
+ err = pn_string_addf(dst, ", ");
+ if (err) return err;
+ }
+ err = pn_inspect(event, dst);
+ if (err) return err;
+ event = event->next;
+ }
+ return pn_string_addf(dst, "]");
+}
+
+#define pn_collector_hashcode NULL
+#define pn_collector_compare NULL
+
+pn_collector_t *pn_collector(void)
+{
+ static const pn_class_t clazz = PN_CLASS(pn_collector);
+ pn_collector_t *collector = (pn_collector_t *) pn_class_new(&clazz, sizeof(pn_collector_t));
+ return collector;
+}
+
+void pn_collector_free(pn_collector_t *collector)
+{
+ collector->freed = true;
+ pn_collector_drain(collector);
+ pn_collector_shrink(collector);
+ pn_class_decref(PN_OBJECT, collector);
+}
+
+pn_event_t *pn_event(void);
+static void pn_event_initialize(void *obj);
+
+pn_event_t *pn_collector_put(pn_collector_t *collector,
+ const pn_class_t *clazz, void *context,
+ pn_event_type_t type)
+{
+ if (!collector) {
+ return NULL;
+ }
+
+ assert(context);
+
+ if (collector->freed) {
+ return NULL;
+ }
+
+ pn_event_t *tail = collector->tail;
+ if (tail && tail->type == type && tail->context == context) {
+ return NULL;
+ }
+
+ clazz = clazz->reify(context);
+
+ pn_event_t *event;
+
+ if (collector->free_head) {
+ event = collector->free_head;
+ collector->free_head = collector->free_head->next;
+ pn_event_initialize(event);
+ } else {
+ event = pn_event();
+ }
+
+ if (tail) {
+ tail->next = event;
+ collector->tail = event;
+ } else {
+ collector->tail = event;
+ collector->head = event;
+ }
+
+ event->clazz = clazz;
+ event->context = context;
+ event->type = type;
+ pn_class_incref(clazz, event->context);
+
+ //printf("event %s on %p\n", pn_event_type_name(event->type), event->context);
+
+ return event;
+}
+
+pn_event_t *pn_collector_peek(pn_collector_t *collector)
+{
+ return collector->head;
+}
+
+bool pn_collector_pop(pn_collector_t *collector)
+{
+ pn_event_t *event = collector->head;
+ if (event) {
+ collector->head = event->next;
+ } else {
+ return false;
+ }
+
+ if (!collector->head) {
+ collector->tail = NULL;
+ }
+
+ // decref before adding to the free list
+ if (event->context) {
+ pn_class_decref(event->clazz, event->context);
+ event->context = NULL;
+ }
+
+ event->next = collector->free_head;
+ collector->free_head = event;
+
+ return true;
+}
+
+static void pn_event_initialize(void *obj)
+{
+ pn_event_t *event = (pn_event_t *) obj;
+ event->type = PN_EVENT_NONE;
+ event->clazz = NULL;
+ event->context = NULL;
+ event->next = NULL;
+}
+
+static void pn_event_finalize(void *obj) {}
+
+static int pn_event_inspect(void *obj, pn_string_t *dst)
+{
+ assert(obj);
+ pn_event_t *event = (pn_event_t *) obj;
+ int err = pn_string_addf(dst, "(0x%X", (unsigned int)event->type);
+ if (event->context) {
+ err = pn_string_addf(dst, ", ");
+ if (err) return err;
+ err = pn_class_inspect(event->clazz, event->context, dst);
+ if (err) return err;
+ }
+
+ return pn_string_addf(dst, ")");
+}
+
+#define pn_event_hashcode NULL
+#define pn_event_compare NULL
+
+pn_event_t *pn_event(void)
+{
+ static const pn_class_t clazz = PN_CLASS(pn_event);
+ pn_event_t *event = (pn_event_t *) pn_class_new(&clazz, sizeof(pn_event_t));
+ return event;
+}
+
+pn_event_type_t pn_event_type(pn_event_t *event)
+{
+ return event->type;
+}
+
+const pn_class_t *pn_event_class(pn_event_t *event)
+{
+ assert(event);
+ return event->clazz;
+}
+
+void *pn_event_context(pn_event_t *event)
+{
+ assert(event);
+ return event->context;
+}
+
+const char *pn_event_type_name(pn_event_type_t type)
+{
+ switch (type) {
+ case PN_EVENT_NONE:
+ return "PN_EVENT_NONE";
+ case PN_CONNECTION_INIT:
+ return "PN_CONNECTION_INIT";
+ case PN_CONNECTION_BOUND:
+ return "PN_CONNECTION_BOUND";
+ case PN_CONNECTION_UNBOUND:
+ return "PN_CONNECTION_UNBOUND";
+ case PN_CONNECTION_REMOTE_OPEN:
+ return "PN_CONNECTION_REMOTE_OPEN";
+ case PN_CONNECTION_OPEN:
+ return "PN_CONNECTION_OPEN";
+ case PN_CONNECTION_REMOTE_CLOSE:
+ return "PN_CONNECTION_REMOTE_CLOSE";
+ case PN_CONNECTION_CLOSE:
+ return "PN_CONNECTION_CLOSE";
+ case PN_CONNECTION_FINAL:
+ return "PN_CONNECTION_FINAL";
+ case PN_SESSION_INIT:
+ return "PN_SESSION_INIT";
+ case PN_SESSION_REMOTE_OPEN:
+ return "PN_SESSION_REMOTE_OPEN";
+ case PN_SESSION_OPEN:
+ return "PN_SESSION_OPEN";
+ case PN_SESSION_REMOTE_CLOSE:
+ return "PN_SESSION_REMOTE_CLOSE";
+ case PN_SESSION_CLOSE:
+ return "PN_SESSION_CLOSE";
+ case PN_SESSION_FINAL:
+ return "PN_SESSION_FINAL";
+ case PN_LINK_INIT:
+ return "PN_LINK_INIT";
+ case PN_LINK_REMOTE_OPEN:
+ return "PN_LINK_REMOTE_OPEN";
+ case PN_LINK_OPEN:
+ return "PN_LINK_OPEN";
+ case PN_LINK_REMOTE_CLOSE:
+ return "PN_LINK_REMOTE_CLOSE";
+ case PN_LINK_DETACH:
+ return "PN_LINK_DETACH";
+ case PN_LINK_REMOTE_DETACH:
+ return "PN_LINK_REMOTE_DETACH";
+ case PN_LINK_CLOSE:
+ return "PN_LINK_CLOSE";
+ case PN_LINK_FLOW:
+ return "PN_LINK_FLOW";
+ case PN_LINK_FINAL:
+ return "PN_LINK_FINAL";
+ case PN_DELIVERY:
+ return "PN_DELIVERY";
+ case PN_TRANSPORT:
+ return "PN_TRANSPORT";
+ case PN_TRANSPORT_ERROR:
+ return "PN_TRANSPORT_ERROR";
+ case PN_TRANSPORT_HEAD_CLOSED:
+ return "PN_TRANSPORT_HEAD_CLOSED";
+ case PN_TRANSPORT_TAIL_CLOSED:
+ return "PN_TRANSPORT_TAIL_CLOSED";
+ case PN_TRANSPORT_CLOSED:
+ return "PN_TRANSPORT_CLOSED";
+ }
+
+ return "<unrecognized>";
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/message/message.c
----------------------------------------------------------------------
diff --git a/proton-c/src/message/message.c b/proton-c/src/message/message.c
index d91ab63..c158345 100644
--- a/proton-c/src/message/message.c
+++ b/proton-c/src/message/message.c
@@ -29,8 +29,8 @@
#include <stdio.h>
#include <assert.h>
#include "protocol.h"
-#include "../util.h"
-#include "../platform_fmt.h"
+#include "util.h"
+#include "platform_fmt.h"
ssize_t pn_message_data(char *dst, size_t available, const char *src, size_t size)
{
@@ -322,7 +322,7 @@ int pn_message_inspect(void *obj, pn_string_t *dst)
pn_message_t *pn_message()
{
static const pn_class_t clazz = PN_CLASS(pn_message);
- pn_message_t *msg = (pn_message_t *) pn_new(sizeof(pn_message_t), &clazz);
+ pn_message_t *msg = (pn_message_t *) pn_class_new(&clazz, sizeof(pn_message_t));
msg->durable = false;
msg->priority = PN_DEFAULT_PRIORITY;
msg->ttl = 0;
@@ -975,6 +975,7 @@ int pn_message_save_data(pn_message_t *msg, char *data, size_t *size)
pn_data_error(msg->body));
if (scanned) {
if (bytes.size > *size) {
+ *size = bytes.size;
return PN_OVERFLOW;
} else {
memcpy(data, bytes.start, bytes.size);
@@ -997,6 +998,7 @@ int pn_message_save_text(pn_message_t *msg, char *data, size_t *size)
{
pn_bytes_t str = pn_data_get_bytes(msg->body);
if (str.size >= *size) {
+ *size = str.size;
return PN_OVERFLOW;
} else {
memcpy(data, str.start, str.size);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/messenger/messenger.c
----------------------------------------------------------------------
diff --git a/proton-c/src/messenger/messenger.c b/proton-c/src/messenger/messenger.c
index 0e2488b..f0204b9 100644
--- a/proton-c/src/messenger/messenger.c
+++ b/proton-c/src/messenger/messenger.c
@@ -20,10 +20,13 @@
*/
#include <proton/messenger.h>
-#include <proton/sasl.h>
-#include <proton/ssl.h>
-#include <proton/util.h>
+
+#include <proton/connection.h>
+#include <proton/delivery.h>
+#include <proton/event.h>
#include <proton/object.h>
+#include <proton/sasl.h>
+#include <proton/session.h>
#include <proton/selector.h>
#include <assert.h>
@@ -32,13 +35,13 @@
#include <string.h>
#include <stdio.h>
-#include "../util.h"
-#include "../platform.h"
-#include "../platform_fmt.h"
+#include "util.h"
+#include "platform.h"
+#include "platform_fmt.h"
#include "store.h"
#include "transform.h"
#include "subscription.h"
-#include "../selectable.h"
+#include "selectable.h"
typedef struct pn_link_ctx_t pn_link_ctx_t;
@@ -54,10 +57,11 @@ typedef struct {
} pn_address_t;
// algorithm for granting credit to receivers
-typedef enum {
+typedef enum {
// pn_messenger_recv( X ), where:
- LINK_CREDIT_EXPLICIT, // X > 0
- LINK_CREDIT_AUTO // X == -1
+ LINK_CREDIT_EXPLICIT, // X > 0
+ LINK_CREDIT_AUTO, // X == -1
+ LINK_CREDIT_MANUAL // X == -2
} pn_link_credit_mode_t;
struct pn_messenger_t {
@@ -100,6 +104,11 @@ struct pn_messenger_t {
int receivers; // # receiver links
int draining; // # links in drain state
int connection_error;
+ int flags;
+ pn_snd_settle_mode_t snd_settle_mode;
+ pn_rcv_settle_mode_t rcv_settle_mode;
+ pn_tracer_t tracer;
+ pn_ssl_verify_mode_t ssl_peer_authentication_mode;
bool blocking;
bool passive;
bool interrupted;
@@ -372,10 +381,14 @@ static pn_listener_ctx_t *pn_listener_ctx(pn_messenger_t *messenger,
pn_socket_t socket = pn_listen(messenger->io, host, port ? port : default_port(scheme));
if (socket == PN_INVALID_SOCKET) {
pn_error_copy(messenger->error, pn_io_error(messenger->io));
+ pn_error_format(messenger->error, PN_ERR, "CONNECTION ERROR (%s:%s): %s\n",
+ messenger->address.host, messenger->address.port,
+ pn_error_text(messenger->error));
+
return NULL;
}
- pn_listener_ctx_t *ctx = (pn_listener_ctx_t *) pn_new(sizeof(pn_listener_ctx_t), NULL);
+ pn_listener_ctx_t *ctx = (pn_listener_ctx_t *) pn_class_new(PN_OBJECT, sizeof(pn_listener_ctx_t));
ctx->messenger = messenger;
ctx->domain = pn_ssl_domain(PN_SSL_MODE_SERVER);
if (messenger->certificate) {
@@ -596,7 +609,7 @@ pn_messenger_t *pn_messenger(const char *name)
m->blocking = true;
m->passive = false;
m->io = pn_io();
- m->pending = pn_list(0, 0);
+ m->pending = pn_list(PN_WEAKREF, 0);
m->interruptor = pni_selectable
(pni_interruptor_capacity, pni_interruptor_pending,
pni_interruptor_deadline, pni_interruptor_readable,
@@ -611,8 +624,8 @@ pn_messenger_t *pn_messenger(const char *name)
pn_pipe(m->io, m->ctrl);
pni_selectable_set_fd(m->interruptor, m->ctrl[0]);
pni_selectable_set_context(m->interruptor, m);
- m->listeners = pn_list(0, 0);
- m->connections = pn_list(0, 0);
+ m->listeners = pn_list(PN_WEAKREF, 0);
+ m->connections = pn_list(PN_WEAKREF, 0);
m->selector = pn_io_selector(m->io);
m->collector = pn_collector();
m->credit_mode = LINK_CREDIT_EXPLICIT;
@@ -621,13 +634,13 @@ pn_messenger_t *pn_messenger(const char *name)
m->distributed = 0;
m->receivers = 0;
m->draining = 0;
- m->credited = pn_list(0, 0);
- m->blocked = pn_list(0, 0);
+ m->credited = pn_list(PN_WEAKREF, 0);
+ m->blocked = pn_list(PN_WEAKREF, 0);
m->next_drain = 0;
m->next_tag = 0;
m->outgoing = pni_store();
m->incoming = pni_store();
- m->subscriptions = pn_list(0, PN_REFCOUNT);
+ m->subscriptions = pn_list(PN_OBJECT, 0);
m->incoming_subscription = NULL;
m->error = pn_error();
m->routes = pn_transform();
@@ -639,6 +652,11 @@ pn_messenger_t *pn_messenger(const char *name)
m->rewritten = pn_string(NULL);
m->domain = pn_string(NULL);
m->connection_error = 0;
+ m->flags = 0;
+ m->snd_settle_mode = PN_SND_SETTLED;
+ m->rcv_settle_mode = PN_RCV_FIRST;
+ m->tracer = NULL;
+ m->ssl_peer_authentication_mode = PN_SSL_VERIFY_PEER_NAME;
}
return m;
@@ -840,6 +858,8 @@ bool pn_messenger_flow(pn_messenger_t *messenger)
const int used = messenger->distributed + pn_messenger_incoming(messenger);
if (max > used)
messenger->credit = max - used;
+ } else if (messenger->credit_mode == LINK_CREDIT_MANUAL) {
+ return false;
}
const int batch = per_link_credit(messenger);
@@ -896,6 +916,8 @@ static int pn_transport_config(pn_messenger_t *messenger,
{
pn_connection_ctx_t *ctx = (pn_connection_ctx_t *) pn_connection_get_context(connection);
pn_transport_t *transport = pn_connection_transport(connection);
+ if (messenger->tracer)
+ pn_transport_set_tracer(transport, messenger->tracer);
if (ctx->scheme && !strcmp(ctx->scheme, "amqps")) {
pn_ssl_domain_t *d = pn_ssl_domain(PN_SSL_MODE_CLIENT);
if (messenger->certificate && messenger->private_key) {
@@ -913,7 +935,8 @@ static int pn_transport_config(pn_messenger_t *messenger,
pn_error_report("CONNECTION", "invalid certificate db");
return err;
}
- err = pn_ssl_domain_set_peer_authentication(d, PN_SSL_VERIFY_PEER_NAME, NULL);
+ err = pn_ssl_domain_set_peer_authentication(
+ d, messenger->ssl_peer_authentication_mode, NULL);
if (err) {
pn_error_report("CONNECTION", "error configuring ssl to verify peer");
}
@@ -985,33 +1008,38 @@ int pni_pump_in(pn_messenger_t *messenger, const char *address, pn_link_t *recei
n = pn_link_recv(receiver, encoded + pending, 1);
pn_link_advance(receiver);
- // account for the used credit
- assert( ctx );
- assert( messenger->distributed );
- messenger->distributed--;
-
pn_link_t *link = receiver;
- // replenish if low (< 20% maximum batch) and credit available
- if (!pn_link_get_drain(link) && pn_list_size(messenger->blocked) == 0 && messenger->credit > 0) {
- const int max = per_link_credit(messenger);
- const int lo_thresh = (int)(max * 0.2 + 0.5);
- if (pn_link_remote_credit(link) < lo_thresh) {
- const int more = pn_min(messenger->credit, max - pn_link_remote_credit(link));
- messenger->credit -= more;
- messenger->distributed += more;
- pn_link_flow(link, more);
+ if (messenger->credit_mode != LINK_CREDIT_MANUAL) {
+ // account for the used credit
+ assert(ctx);
+ assert(messenger->distributed);
+ messenger->distributed--;
+
+ // replenish if low (< 20% maximum batch) and credit available
+ if (!pn_link_get_drain(link) && pn_list_size(messenger->blocked) == 0 &&
+ messenger->credit > 0) {
+ const int max = per_link_credit(messenger);
+ const int lo_thresh = (int)(max * 0.2 + 0.5);
+ if (pn_link_remote_credit(link) < lo_thresh) {
+ const int more =
+ pn_min(messenger->credit, max - pn_link_remote_credit(link));
+ messenger->credit -= more;
+ messenger->distributed += more;
+ pn_link_flow(link, more);
+ }
}
- }
- // check if blocked
- if (pn_list_index(messenger->blocked, link) < 0 && pn_link_remote_credit(link) == 0) {
- pn_list_remove(messenger->credited, link);
- if (pn_link_get_drain(link)) {
- pn_link_set_drain(link, false);
- assert( messenger->draining > 0 );
- messenger->draining--;
+ // check if blocked
+ if (pn_list_index(messenger->blocked, link) < 0 &&
+ pn_link_remote_credit(link) == 0) {
+ pn_list_remove(messenger->credited, link);
+ if (pn_link_get_drain(link)) {
+ pn_link_set_drain(link, false);
+ assert(messenger->draining > 0);
+ messenger->draining--;
+ }
+ pn_list_add(messenger->blocked, link);
}
- pn_list_add(messenger->blocked, link);
}
if (n != PN_EOS) {
@@ -1248,8 +1276,10 @@ int pn_messenger_process_events(pn_messenger_t *messenger)
break;
case PN_LINK_REMOTE_OPEN:
case PN_LINK_REMOTE_CLOSE:
+ case PN_LINK_REMOTE_DETACH:
case PN_LINK_OPEN:
case PN_LINK_CLOSE:
+ case PN_LINK_DETACH:
pn_messenger_process_link(messenger, event);
break;
case PN_LINK_FLOW:
@@ -1259,10 +1289,18 @@ int pn_messenger_process_events(pn_messenger_t *messenger)
pn_messenger_process_delivery(messenger, event);
break;
case PN_TRANSPORT:
+ case PN_TRANSPORT_ERROR:
+ case PN_TRANSPORT_HEAD_CLOSED:
+ case PN_TRANSPORT_TAIL_CLOSED:
+ case PN_TRANSPORT_CLOSED:
pn_messenger_process_transport(messenger, event);
break;
case PN_EVENT_NONE:
break;
+ case PN_CONNECTION_BOUND:
+ break;
+ case PN_CONNECTION_UNBOUND:
+ break;
case PN_CONNECTION_FINAL:
break;
case PN_SESSION_FINAL:
@@ -1422,11 +1460,85 @@ int pn_messenger_sync(pn_messenger_t *messenger, bool (*predicate)(pn_messenger_
}
}
+static void pni_parse(pn_address_t *address);
+pn_connection_t *pn_messenger_resolve(pn_messenger_t *messenger,
+ const char *address, char **name);
+int pn_messenger_work(pn_messenger_t *messenger, int timeout);
+
int pn_messenger_start(pn_messenger_t *messenger)
{
if (!messenger) return PN_ARG_ERR;
- // right now this is a noop
- return 0;
+
+ int error = 0;
+
+ // When checking of routes is required we attempt to resolve each route
+ // with a substitution that has a defined scheme, address and port. If
+ // any of theses routes is invalid an appropriate error code will be
+ // returned. Currently no attempt is made to check the name part of the
+ // address, as the intent here is to fail fast if the addressed host
+ // is invalid or unavailable.
+ if (messenger->flags | PN_FLAGS_CHECK_ROUTES) {
+ pn_list_t *substitutions = pn_list(PN_WEAKREF, 0);
+ pn_transform_get_substitutions(messenger->routes, substitutions);
+ for (size_t i = 0; i < pn_list_size(substitutions) && error == 0; i++) {
+ pn_string_t *substitution = (pn_string_t *)pn_list_get(substitutions, i);
+ if (substitution) {
+ pn_address_t addr;
+ addr.text = pn_string(NULL);
+ error = pn_string_copy(addr.text, substitution);
+ if (!error) {
+ pni_parse(&addr);
+ if (addr.scheme && strlen(addr.scheme) > 0 &&
+ !strstr(addr.scheme, "$") && addr.host && strlen(addr.host) > 0 &&
+ !strstr(addr.host, "$") && addr.port && strlen(addr.port) > 0 &&
+ !strstr(addr.port, "$")) {
+ pn_string_t *check_addr = pn_string(NULL);
+ // ipv6 hosts need to be wrapped in [] within a URI
+ if (strstr(addr.host, ":")) {
+ pn_string_format(check_addr, "%s://[%s]:%s/", addr.scheme,
+ addr.host, addr.port);
+ } else {
+ pn_string_format(check_addr, "%s://%s:%s/", addr.scheme,
+ addr.host, addr.port);
+ }
+ char *name = NULL;
+ pn_connection_t *connection = pn_messenger_resolve(
+ messenger, pn_string_get(check_addr), &name);
+ pn_free(check_addr);
+ if (!connection) {
+ if (pn_error_code(messenger->error) == 0)
+ pn_error_copy(messenger->error, pn_io_error(messenger->io));
+ pn_error_format(messenger->error, PN_ERR,
+ "CONNECTION ERROR (%s:%s): %s\n",
+ messenger->address.host, messenger->address.port,
+ pn_error_text(messenger->error));
+ error = pn_error_code(messenger->error);
+ } else {
+ // Send and receive outstanding messages until connection
+ // completes or an error occurs
+ int work = pn_messenger_work(messenger, -1);
+ pn_connection_ctx_t *cctx =
+ (pn_connection_ctx_t *)pn_connection_get_context(connection);
+ while ((work > 0 ||
+ (pn_connection_state(connection) & PN_REMOTE_UNINIT) ||
+ pni_connection_pending(cctx->selectable) != (ssize_t)0) &&
+ pn_error_code(messenger->error) == 0)
+ work = pn_messenger_work(messenger, 0);
+ if (work < 0 && work != PN_TIMEOUT) {
+ error = work;
+ } else {
+ error = pn_error_code(messenger->error);
+ }
+ }
+ }
+ pn_free(addr.text);
+ }
+ }
+ }
+ pn_free(substitutions);
+ }
+
+ return error;
}
bool pn_messenger_stopped(pn_messenger_t *messenger)
@@ -1560,12 +1672,12 @@ pn_connection_t *pn_messenger_resolve(pn_messenger_t *messenger, const char *add
return connection;
}
-pn_link_t *pn_messenger_link(pn_messenger_t *messenger, const char *address, bool sender)
+PN_EXTERN pn_link_t *pn_messenger_get_link(pn_messenger_t *messenger,
+ const char *address, bool sender)
{
char *name = NULL;
pn_connection_t *connection = pn_messenger_resolve(messenger, address, &name);
if (!connection) return NULL;
- pn_connection_ctx_t *cctx = (pn_connection_ctx_t *) pn_connection_get_context(connection);
pn_link_t *link = pn_link_head(connection, PN_LOCAL_ACTIVE);
while (link) {
@@ -1578,6 +1690,22 @@ pn_link_t *pn_messenger_link(pn_messenger_t *messenger, const char *address, boo
}
link = pn_link_next(link, PN_LOCAL_ACTIVE);
}
+ return NULL;
+}
+
+pn_link_t *pn_messenger_link(pn_messenger_t *messenger, const char *address,
+ bool sender, pn_seconds_t timeout)
+{
+ char *name = NULL;
+ pn_connection_t *connection = pn_messenger_resolve(messenger, address, &name);
+ if (!connection)
+ return NULL;
+ pn_connection_ctx_t *cctx =
+ (pn_connection_ctx_t *)pn_connection_get_context(connection);
+
+ pn_link_t *link = pn_messenger_get_link(messenger, address, sender);
+ if (link)
+ return link;
pn_session_t *ssn = pn_session(connection);
pn_session_open(ssn);
@@ -1593,9 +1721,9 @@ pn_link_t *pn_messenger_link(pn_messenger_t *messenger, const char *address, boo
if ((sender && pn_messenger_get_outgoing_window(messenger)) ||
(!sender && pn_messenger_get_incoming_window(messenger))) {
- // use explicit settlement via dispositions (not pre-settled)
- pn_link_set_snd_settle_mode( link, PN_SND_UNSETTLED );
- pn_link_set_rcv_settle_mode( link, PN_RCV_SECOND );
+ // use required settlement (defaults to sending pre-settled messages)
+ pn_link_set_snd_settle_mode(link, messenger->snd_settle_mode);
+ pn_link_set_rcv_settle_mode(link, messenger->rcv_settle_mode);
}
// XXX
if (pn_streq(name, "#")) {
@@ -1609,6 +1737,14 @@ pn_link_t *pn_messenger_link(pn_messenger_t *messenger, const char *address, boo
pn_terminus_set_address(pn_link_source(link), name);
}
link_ctx_setup( messenger, connection, link );
+
+ if (timeout > 0) {
+ pn_terminus_set_expiry_policy(pn_link_target(link), PN_EXPIRE_WITH_LINK);
+ pn_terminus_set_expiry_policy(pn_link_source(link), PN_EXPIRE_WITH_LINK);
+ pn_terminus_set_timeout(pn_link_target(link), timeout);
+ pn_terminus_set_timeout(pn_link_source(link), timeout);
+ }
+
if (!sender) {
pn_link_ctx_t *ctx = (pn_link_ctx_t *)pn_link_get_context(link);
assert( ctx );
@@ -1619,18 +1755,27 @@ pn_link_t *pn_messenger_link(pn_messenger_t *messenger, const char *address, boo
return link;
}
-pn_link_t *pn_messenger_source(pn_messenger_t *messenger, const char *source)
+pn_link_t *pn_messenger_source(pn_messenger_t *messenger, const char *source,
+ pn_seconds_t timeout)
{
- return pn_messenger_link(messenger, source, false);
+ return pn_messenger_link(messenger, source, false, timeout);
}
-pn_link_t *pn_messenger_target(pn_messenger_t *messenger, const char *target)
+pn_link_t *pn_messenger_target(pn_messenger_t *messenger, const char *target,
+ pn_seconds_t timeout)
{
- return pn_messenger_link(messenger, target, true);
+ return pn_messenger_link(messenger, target, true, timeout);
}
pn_subscription_t *pn_messenger_subscribe(pn_messenger_t *messenger, const char *source)
{
+ return pn_messenger_subscribe_ttl(messenger, source, 0);
+}
+
+pn_subscription_t *pn_messenger_subscribe_ttl(pn_messenger_t *messenger,
+ const char *source,
+ pn_seconds_t timeout)
+{
pni_route(messenger, source);
if (pn_error_code(messenger->error)) return NULL;
@@ -1647,7 +1792,7 @@ pn_subscription_t *pn_messenger_subscribe(pn_messenger_t *messenger, const char
return NULL;
}
} else {
- pn_link_t *src = pn_messenger_source(messenger, source);
+ pn_link_t *src = pn_messenger_source(messenger, source, timeout);
if (!src) return NULL;
pn_link_ctx_t *ctx = (pn_link_ctx_t *) pn_link_get_context( src );
return ctx ? ctx->subscription : NULL;
@@ -1820,7 +1965,7 @@ int pn_messenger_put(pn_messenger_t *messenger, pn_message_t *msg)
} else {
pni_restore(messenger, msg);
pn_buffer_append(buf, encoded, size); // XXX
- pn_link_t *sender = pn_messenger_target(messenger, address);
+ pn_link_t *sender = pn_messenger_target(messenger, address, 0);
if (!sender) {
int err = pn_error_code(messenger->error);
if (err) {
@@ -1865,6 +2010,18 @@ pn_status_t pn_messenger_status(pn_messenger_t *messenger, pn_tracker_t tracker)
}
}
+pn_delivery_t *pn_messenger_delivery(pn_messenger_t *messenger,
+ pn_tracker_t tracker)
+{
+ pni_store_t *store = pn_tracker_store(messenger, tracker);
+ pni_entry_t *e = pni_store_entry(store, pn_tracker_sequence(tracker));
+ if (e) {
+ return pni_entry_get_delivery(e);
+ } else {
+ return NULL;
+ }
+}
+
bool pn_messenger_buffered(pn_messenger_t *messenger, pn_tracker_t tracker)
{
pni_store_t *store = pn_tracker_store(messenger, tracker);
@@ -2007,7 +2164,9 @@ int pn_messenger_recv(pn_messenger_t *messenger, int n)
return pn_error_format(messenger->error, PN_STATE_ERR, "no valid sources");
// re-compute credit, and update credit scheduler
- if (n == -1) {
+ if (n == -2) {
+ messenger->credit_mode = LINK_CREDIT_MANUAL;
+ } else if (n == -1) {
messenger->credit_mode = LINK_CREDIT_AUTO;
} else {
messenger->credit_mode = LINK_CREDIT_EXPLICIT;
@@ -2100,6 +2259,20 @@ int pn_messenger_reject(pn_messenger_t *messenger, pn_tracker_t tracker, int fla
PN_STATUS_REJECTED, flags, false, false);
}
+PN_EXTERN pn_link_t *pn_messenger_tracker_link(pn_messenger_t *messenger,
+ pn_tracker_t tracker)
+{
+ pni_store_t *store = pn_tracker_store(messenger, tracker);
+ pni_entry_t *e = pni_store_entry(store, pn_tracker_sequence(tracker));
+ if (e) {
+ pn_delivery_t *d = pni_entry_get_delivery(e);
+ if (d) {
+ return pn_delivery_link(d);
+ }
+ }
+ return NULL;
+}
+
int pn_messenger_queued(pn_messenger_t *messenger, bool sender)
{
if (!messenger) return 0;
@@ -2146,3 +2319,81 @@ int pn_messenger_rewrite(pn_messenger_t *messenger, const char *pattern, const c
pn_transform_rule(messenger->rewrites, pattern, address);
return 0;
}
+
+PN_EXTERN int pn_messenger_set_flags(pn_messenger_t *messenger, const int flags)
+{
+ if (!messenger)
+ return PN_ARG_ERR;
+ if (flags != 0 && (flags ^ PN_FLAGS_CHECK_ROUTES) != 0)
+ return PN_ARG_ERR;
+ messenger->flags = flags;
+ return 0;
+}
+
+PN_EXTERN int pn_messenger_get_flags(pn_messenger_t *messenger)
+{
+ return messenger ? messenger->flags : 0;
+}
+
+int pn_messenger_set_snd_settle_mode(pn_messenger_t *messenger,
+ const pn_snd_settle_mode_t mode)
+{
+ if (!messenger)
+ return PN_ARG_ERR;
+ messenger->snd_settle_mode = mode;
+ return 0;
+}
+
+int pn_messenger_set_rcv_settle_mode(pn_messenger_t *messenger,
+ const pn_rcv_settle_mode_t mode)
+{
+ if (!messenger)
+ return PN_ARG_ERR;
+ messenger->rcv_settle_mode = mode;
+ return 0;
+}
+
+void pn_messenger_set_tracer(pn_messenger_t *messenger, pn_tracer_t tracer)
+{
+ assert(messenger);
+ assert(tracer);
+
+ messenger->tracer = tracer;
+}
+
+pn_millis_t pn_messenger_get_remote_idle_timeout(pn_messenger_t *messenger,
+ const char *address)
+{
+ if (!messenger)
+ return PN_ARG_ERR;
+
+ pn_address_t addr;
+ addr.text = pn_string(address);
+ pni_parse(&addr);
+
+ pn_millis_t timeout = -1;
+ for (size_t i = 0; i < pn_list_size(messenger->connections); i++) {
+ pn_connection_t *connection =
+ (pn_connection_t *)pn_list_get(messenger->connections, i);
+ pn_connection_ctx_t *ctx =
+ (pn_connection_ctx_t *)pn_connection_get_context(connection);
+ if (pn_streq(addr.scheme, ctx->scheme) && pn_streq(addr.host, ctx->host) &&
+ pn_streq(addr.port, ctx->port)) {
+ pn_transport_t *transport = pn_connection_transport(connection);
+ if (transport)
+ timeout = pn_transport_get_remote_idle_timeout(transport);
+ break;
+ }
+ }
+ return timeout;
+}
+
+int
+pn_messenger_set_ssl_peer_authentication_mode(pn_messenger_t *messenger,
+ const pn_ssl_verify_mode_t mode)
+{
+ if (!messenger)
+ return PN_ARG_ERR;
+ messenger->ssl_peer_authentication_mode = mode;
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/messenger/store.c
----------------------------------------------------------------------
diff --git a/proton-c/src/messenger/store.c b/proton-c/src/messenger/store.c
index 88d6a5d..83b9b68 100644
--- a/proton-c/src/messenger/store.c
+++ b/proton-c/src/messenger/store.c
@@ -28,7 +28,7 @@
#endif
#include <stdlib.h>
#include <string.h>
-#include "../util.h"
+#include "util.h"
#include "store.h"
typedef struct pni_stream_t pni_stream_t;
@@ -89,7 +89,7 @@ pni_store_t *pni_store()
store->window = 0;
store->lwm = 0;
store->hwm = 0;
- store->tracked = pn_hash(0, 0.75, PN_REFCOUNT);
+ store->tracked = pn_hash(PN_OBJECT, 0, 0.75);
return store;
}
@@ -197,6 +197,7 @@ pni_stream_t *pni_stream_get(pni_store_t *store, const char *address)
return pni_stream(store, address, false);
}
+#define CID_pni_entry CID_pn_object
#define pni_entry_initialize NULL
#define pni_entry_hashcode NULL
#define pni_entry_compare NULL
@@ -210,7 +211,7 @@ pni_entry_t *pni_store_put(pni_store_t *store, const char *address)
if (!address) address = "";
pni_stream_t *stream = pni_stream_put(store, address);
if (!stream) return NULL;
- pni_entry_t *entry = (pni_entry_t *) pn_new(sizeof(pni_entry_t), &clazz);
+ pni_entry_t *entry = (pni_entry_t *) pn_class_new(&clazz, sizeof(pni_entry_t));
if (!entry) return NULL;
entry->stream = stream;
entry->free = false;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/messenger/subscription.c
----------------------------------------------------------------------
diff --git a/proton-c/src/messenger/subscription.c b/proton-c/src/messenger/subscription.c
index 346a23f..c26d40a 100644
--- a/proton-c/src/messenger/subscription.c
+++ b/proton-c/src/messenger/subscription.c
@@ -55,6 +55,7 @@ void pn_subscription_finalize(void *obj)
pn_free(sub->address);
}
+#define CID_pn_subscription CID_pn_object
#define pn_subscription_hashcode NULL
#define pn_subscription_compare NULL
#define pn_subscription_inspect NULL
@@ -65,13 +66,13 @@ pn_subscription_t *pn_subscription(pn_messenger_t *messenger,
const char *port)
{
static const pn_class_t clazz = PN_CLASS(pn_subscription);
- pn_subscription_t *sub = (pn_subscription_t *) pn_new(sizeof(pn_subscription_t), &clazz);
+ pn_subscription_t *sub = (pn_subscription_t *) pn_class_new(&clazz, sizeof(pn_subscription_t));
sub->messenger = messenger;
pn_string_set(sub->scheme, scheme);
pn_string_set(sub->host, host);
pn_string_set(sub->port, port);
pni_messenger_add_subscription(messenger, sub);
- pn_decref(sub);
+ pn_class_decref(PN_OBJECT, sub);
return sub;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/messenger/transform.c
----------------------------------------------------------------------
diff --git a/proton-c/src/messenger/transform.c b/proton-c/src/messenger/transform.c
index 801eb10..8f18667 100644
--- a/proton-c/src/messenger/transform.c
+++ b/proton-c/src/messenger/transform.c
@@ -19,7 +19,6 @@
*
*/
-#include <proton/object.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
@@ -55,6 +54,7 @@ static void pn_rule_finalize(void *object)
pn_free(rule->substitution);
}
+#define CID_pn_rule CID_pn_object
#define pn_rule_initialize NULL
#define pn_rule_hashcode NULL
#define pn_rule_compare NULL
@@ -63,7 +63,7 @@ static void pn_rule_finalize(void *object)
pn_rule_t *pn_rule(const char *pattern, const char *substitution)
{
static const pn_class_t clazz = PN_CLASS(pn_rule);
- pn_rule_t *rule = (pn_rule_t *) pn_new(sizeof(pn_rule_t), &clazz);
+ pn_rule_t *rule = (pn_rule_t *) pn_class_new(&clazz, sizeof(pn_rule_t));
rule->pattern = pn_string(pattern);
rule->substitution = pn_string(substitution);
return rule;
@@ -75,6 +75,7 @@ static void pn_transform_finalize(void *object)
pn_free(transform->rules);
}
+#define CID_pn_transform CID_pn_object
#define pn_transform_initialize NULL
#define pn_transform_hashcode NULL
#define pn_transform_compare NULL
@@ -83,8 +84,8 @@ static void pn_transform_finalize(void *object)
pn_transform_t *pn_transform()
{
static const pn_class_t clazz = PN_CLASS(pn_transform);
- pn_transform_t *transform = (pn_transform_t *) pn_new(sizeof(pn_transform_t), &clazz);
- transform->rules = pn_list(0, PN_REFCOUNT);
+ pn_transform_t *transform = (pn_transform_t *) pn_class_new(&clazz, sizeof(pn_transform_t));
+ transform->rules = pn_list(PN_OBJECT, 0);
transform->matched = false;
return transform;
}
@@ -239,3 +240,15 @@ bool pn_transform_matched(pn_transform_t *transform)
{
return transform->matched;
}
+
+int pn_transform_get_substitutions(pn_transform_t *transform,
+ pn_list_t *substitutions)
+{
+ int size = pn_list_size(transform->rules);
+ for (size_t i = 0; i < (size_t)size; i++) {
+ pn_rule_t *rule = (pn_rule_t *)pn_list_get(transform->rules, i);
+ pn_list_add(substitutions, rule->substitution);
+ }
+
+ return size;
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/messenger/transform.h
----------------------------------------------------------------------
diff --git a/proton-c/src/messenger/transform.h b/proton-c/src/messenger/transform.h
index 1662f38..8160be3 100644
--- a/proton-c/src/messenger/transform.h
+++ b/proton-c/src/messenger/transform.h
@@ -22,6 +22,7 @@
*
*/
+#include <proton/object.h>
#include <proton/buffer.h>
typedef struct pn_transform_t pn_transform_t;
@@ -32,6 +33,7 @@ void pn_transform_rule(pn_transform_t *transform, const char *pattern,
int pn_transform_apply(pn_transform_t *transform, const char *src,
pn_string_t *dest);
bool pn_transform_matched(pn_transform_t *transform);
-
+int pn_transform_get_substitutions(pn_transform_t *transform,
+ pn_list_t *substitutions);
#endif /* transform.h */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/object/iterator.c
----------------------------------------------------------------------
diff --git a/proton-c/src/object/iterator.c b/proton-c/src/object/iterator.c
new file mode 100644
index 0000000..61b3b8e
--- /dev/null
+++ b/proton-c/src/object/iterator.c
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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/object.h>
+#include <stdlib.h>
+#include <assert.h>
+
+struct pn_iterator_t {
+ pn_iterator_next_t next;
+ size_t size;
+ void *state;
+};
+
+static void pn_iterator_initialize(void *object)
+{
+ pn_iterator_t *it = (pn_iterator_t *) object;
+ it->next = NULL;
+ it->size = 0;
+ it->state = NULL;
+}
+
+static void pn_iterator_finalize(void *object)
+{
+ pn_iterator_t *it = (pn_iterator_t *) object;
+ free(it->state);
+}
+
+#define CID_pn_iterator CID_pn_object
+#define pn_iterator_hashcode NULL
+#define pn_iterator_compare NULL
+#define pn_iterator_inspect NULL
+
+pn_iterator_t *pn_iterator()
+{
+ static const pn_class_t clazz = PN_CLASS(pn_iterator);
+ pn_iterator_t *it = (pn_iterator_t *) pn_class_new(&clazz, sizeof(pn_iterator_t));
+ return it;
+}
+
+void *pn_iterator_start(pn_iterator_t *iterator, pn_iterator_next_t next,
+ size_t size) {
+ assert(iterator);
+ assert(next);
+ iterator->next = next;
+ if (iterator->size < size) {
+ iterator->state = realloc(iterator->state, size);
+ }
+ return iterator->state;
+}
+
+void *pn_iterator_next(pn_iterator_t *iterator) {
+ assert(iterator);
+ if (iterator->next) {
+ void *result = iterator->next(iterator->state);
+ if (!result) iterator->next = NULL;
+ return result;
+ } else {
+ return NULL;
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/object/list.c
----------------------------------------------------------------------
diff --git a/proton-c/src/object/list.c b/proton-c/src/object/list.c
new file mode 100644
index 0000000..7936f5b
--- /dev/null
+++ b/proton-c/src/object/list.c
@@ -0,0 +1,225 @@
+/*
+ *
+ * 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/object.h>
+#include <stdlib.h>
+#include <assert.h>
+
+struct pn_list_t {
+ const pn_class_t *clazz;
+ size_t capacity;
+ size_t size;
+ void **elements;
+};
+
+size_t pn_list_size(pn_list_t *list)
+{
+ assert(list);
+ return list->size;
+}
+
+void *pn_list_get(pn_list_t *list, int index)
+{
+ assert(list); assert(list->size);
+ return list->elements[index % list->size];
+}
+
+void pn_list_set(pn_list_t *list, int index, void *value)
+{
+ assert(list); assert(list->size);
+ void *old = list->elements[index % list->size];
+ pn_class_decref(list->clazz, old);
+ list->elements[index % list->size] = value;
+ pn_class_incref(list->clazz, value);
+}
+
+void pn_list_ensure(pn_list_t *list, size_t capacity)
+{
+ assert(list);
+ if (list->capacity < capacity) {
+ size_t newcap = list->capacity;
+ while (newcap < capacity) { newcap *= 2; }
+ list->elements = (void **) realloc(list->elements, newcap * sizeof(void *));
+ assert(list->elements);
+ list->capacity = newcap;
+ }
+}
+
+int pn_list_add(pn_list_t *list, void *value)
+{
+ assert(list);
+ pn_list_ensure(list, list->size + 1);
+ list->elements[list->size++] = value;
+ pn_class_incref(list->clazz, value);
+ return 0;
+}
+
+ssize_t pn_list_index(pn_list_t *list, void *value)
+{
+ for (size_t i = 0; i < list->size; i++) {
+ if (pn_equals(list->elements[i], value)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+bool pn_list_remove(pn_list_t *list, void *value)
+{
+ assert(list);
+ ssize_t idx = pn_list_index(list, value);
+ if (idx < 0) {
+ return false;
+ } else {
+ pn_list_del(list, idx, 1);
+ }
+
+ return true;
+}
+
+void pn_list_del(pn_list_t *list, int index, int n)
+{
+ assert(list);
+ index %= list->size;
+
+ for (int i = 0; i < n; i++) {
+ pn_class_decref(list->clazz, list->elements[index + i]);
+ }
+
+ size_t slide = list->size - (index + n);
+ for (size_t i = 0; i < slide; i++) {
+ list->elements[index + i] = list->elements[index + n + i];
+ }
+
+ list->size -= n;
+}
+
+void pn_list_clear(pn_list_t *list)
+{
+ assert(list);
+ pn_list_del(list, 0, list->size);
+}
+
+void pn_list_fill(pn_list_t *list, void *value, int n)
+{
+ for (int i = 0; i < n; i++) {
+ pn_list_add(list, value);
+ }
+}
+
+typedef struct {
+ pn_list_t *list;
+ size_t index;
+} pni_list_iter_t;
+
+static void *pni_list_next(void *ctx)
+{
+ pni_list_iter_t *iter = (pni_list_iter_t *) ctx;
+ if (iter->index < pn_list_size(iter->list)) {
+ return pn_list_get(iter->list, iter->index++);
+ } else {
+ return NULL;
+ }
+}
+
+void pn_list_iterator(pn_list_t *list, pn_iterator_t *iter)
+{
+ pni_list_iter_t *liter = (pni_list_iter_t *) pn_iterator_start(iter, pni_list_next, sizeof(pni_list_iter_t));
+ liter->list = list;
+ liter->index = 0;
+}
+
+static void pn_list_finalize(void *object)
+{
+ assert(object);
+ pn_list_t *list = (pn_list_t *) object;
+ for (size_t i = 0; i < list->size; i++) {
+ pn_class_decref(list->clazz, pn_list_get(list, i));
+ }
+ free(list->elements);
+}
+
+static uintptr_t pn_list_hashcode(void *object)
+{
+ assert(object);
+ pn_list_t *list = (pn_list_t *) object;
+ uintptr_t hash = 1;
+
+ for (size_t i = 0; i < list->size; i++) {
+ hash = hash * 31 + pn_hashcode(pn_list_get(list, i));
+ }
+
+ return hash;
+}
+
+static intptr_t pn_list_compare(void *oa, void *ob)
+{
+ assert(oa); assert(ob);
+ pn_list_t *a = (pn_list_t *) oa;
+ pn_list_t *b = (pn_list_t *) ob;
+
+ size_t na = pn_list_size(a);
+ size_t nb = pn_list_size(b);
+ if (na != nb) {
+ return nb - na;
+ } else {
+ for (size_t i = 0; i < na; i++) {
+ intptr_t delta = pn_compare(pn_list_get(a, i), pn_list_get(b, i));
+ if (delta) return delta;
+ }
+ }
+
+ return 0;
+}
+
+static int pn_list_inspect(void *obj, pn_string_t *dst)
+{
+ assert(obj);
+ pn_list_t *list = (pn_list_t *) obj;
+ int err = pn_string_addf(dst, "[");
+ if (err) return err;
+ size_t n = pn_list_size(list);
+ for (size_t i = 0; i < n; i++) {
+ if (i > 0) {
+ err = pn_string_addf(dst, ", ");
+ if (err) return err;
+ }
+ err = pn_class_inspect(list->clazz, pn_list_get(list, i), dst);
+ if (err) return err;
+ }
+ return pn_string_addf(dst, "]");
+}
+
+#define pn_list_initialize NULL
+
+pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity)
+{
+ static const pn_class_t list_clazz = PN_CLASS(pn_list);
+
+ pn_list_t *list = (pn_list_t *) pn_class_new(&list_clazz, sizeof(pn_list_t));
+ list->clazz = clazz;
+ list->capacity = capacity ? capacity : 16;
+ list->elements = (void **) malloc(list->capacity * sizeof(void *));
+ list->size = 0;
+ return list;
+}
+
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/92b8098c/proton-c/src/object/map.c
----------------------------------------------------------------------
diff --git a/proton-c/src/object/map.c b/proton-c/src/object/map.c
new file mode 100644
index 0000000..fc98116
--- /dev/null
+++ b/proton-c/src/object/map.c
@@ -0,0 +1,401 @@
+/*
+ *
+ * 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/object.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define PNI_ENTRY_FREE (0)
+#define PNI_ENTRY_LINK (1)
+#define PNI_ENTRY_TAIL (2)
+
+typedef struct {
+ void *key;
+ void *value;
+ size_t next;
+ uint8_t state;
+} pni_entry_t;
+
+struct pn_map_t {
+ const pn_class_t *key;
+ const pn_class_t *value;
+ pni_entry_t *entries;
+ size_t capacity;
+ size_t addressable;
+ size_t size;
+ uintptr_t (*hashcode)(void *key);
+ bool (*equals)(void *a, void *b);
+ float load_factor;
+};
+
+static void pn_map_finalize(void *object)
+{
+ pn_map_t *map = (pn_map_t *) object;
+
+ for (size_t i = 0; i < map->capacity; i++) {
+ if (map->entries[i].state != PNI_ENTRY_FREE) {
+ pn_class_decref(map->key, map->entries[i].key);
+ pn_class_decref(map->value, map->entries[i].value);
+ }
+ }
+
+ free(map->entries);
+}
+
+static uintptr_t pn_map_hashcode(void *object)
+{
+ pn_map_t *map = (pn_map_t *) object;
+
+ uintptr_t hashcode = 0;
+
+ for (size_t i = 0; i < map->capacity; i++) {
+ if (map->entries[i].state != PNI_ENTRY_FREE) {
+ void *key = map->entries[i].key;
+ void *value = map->entries[i].value;
+ hashcode += pn_hashcode(key) ^ pn_hashcode(value);
+ }
+ }
+
+ return hashcode;
+}
+
+static void pni_map_allocate(pn_map_t *map)
+{
+ map->entries = (pni_entry_t *) malloc(map->capacity * sizeof (pni_entry_t));
+ for (size_t i = 0; i < map->capacity; i++) {
+ map->entries[i].key = NULL;
+ map->entries[i].value = NULL;
+ map->entries[i].next = 0;
+ map->entries[i].state = PNI_ENTRY_FREE;
+ }
+ map->size = 0;
+}
+
+static int pn_map_inspect(void *obj, pn_string_t *dst)
+{
+ assert(obj);
+ pn_map_t *map = (pn_map_t *) obj;
+ int err = pn_string_addf(dst, "{");
+ if (err) return err;
+ pn_handle_t entry = pn_map_head(map);
+ bool first = true;
+ while (entry) {
+ if (first) {
+ first = false;
+ } else {
+ err = pn_string_addf(dst, ", ");
+ if (err) return err;
+ }
+ err = pn_class_inspect(map->key, pn_map_key(map, entry), dst);
+ if (err) return err;
+ err = pn_string_addf(dst, ": ");
+ if (err) return err;
+ err = pn_class_inspect(map->value, pn_map_value(map, entry), dst);
+ if (err) return err;
+ entry = pn_map_next(map, entry);
+ }
+ return pn_string_addf(dst, "}");
+}
+
+#define pn_map_initialize NULL
+#define pn_map_compare NULL
+
+pn_map_t *pn_map(const pn_class_t *key, const pn_class_t *value,
+ size_t capacity, float load_factor)
+{
+ static const pn_class_t clazz = PN_CLASS(pn_map);
+
+ pn_map_t *map = (pn_map_t *) pn_class_new(&clazz, sizeof(pn_map_t));
+ map->key = key;
+ map->value = value;
+ map->capacity = capacity ? capacity : 16;
+ map->addressable = (size_t) (map->capacity * 0.86);
+ if (!map->addressable) map->addressable = map->capacity;
+ map->load_factor = load_factor;
+ map->hashcode = pn_hashcode;
+ map->equals = pn_equals;
+ pni_map_allocate(map);
+ return map;
+}
+
+size_t pn_map_size(pn_map_t *map)
+{
+ assert(map);
+ return map->size;
+}
+
+static float pni_map_load(pn_map_t *map)
+{
+ return ((float) map->size) / ((float) map->addressable);
+}
+
+static bool pni_map_ensure(pn_map_t *map, size_t capacity)
+{
+ float load = pni_map_load(map);
+ if (capacity <= map->capacity && load <= map->load_factor) {
+ return false;
+ }
+
+ size_t oldcap = map->capacity;
+
+ while (map->capacity < capacity || pni_map_load(map) > map->load_factor) {
+ map->capacity *= 2;
+ map->addressable = (size_t) (0.86 * map->capacity);
+ }
+
+ pni_entry_t *entries = map->entries;
+ pni_map_allocate(map);
+
+ for (size_t i = 0; i < oldcap; i++) {
+ if (entries[i].state != PNI_ENTRY_FREE) {
+ void *key = entries[i].key;
+ void *value = entries[i].value;
+ pn_map_put(map, key, value);
+ pn_class_decref(map->key, key);
+ pn_class_decref(map->value, value);
+ }
+ }
+
+ free(entries);
+ return true;
+}
+
+static pni_entry_t *pni_map_entry(pn_map_t *map, void *key, pni_entry_t **pprev, bool create)
+{
+ uintptr_t hashcode = map->hashcode(key);
+
+ pni_entry_t *entry = &map->entries[hashcode % map->addressable];
+ pni_entry_t *prev = NULL;
+
+ if (entry->state == PNI_ENTRY_FREE) {
+ if (create) {
+ entry->state = PNI_ENTRY_TAIL;
+ entry->key = key;
+ pn_class_incref(map->key, key);
+ map->size++;
+ return entry;
+ } else {
+ return NULL;
+ }
+ }
+
+ while (true) {
+ if (map->equals(entry->key, key)) {
+ if (pprev) *pprev = prev;
+ return entry;
+ }
+
+ if (entry->state == PNI_ENTRY_TAIL) {
+ break;
+ } else {
+ prev = entry;
+ entry = &map->entries[entry->next];
+ }
+ }
+
+ if (create) {
+ if (pni_map_ensure(map, map->size + 1)) {
+ // if we had to grow the table we need to start over
+ return pni_map_entry(map, key, pprev, create);
+ }
+
+ size_t empty = 0;
+ for (size_t i = 0; i < map->capacity; i++) {
+ size_t idx = map->capacity - i - 1;
+ if (map->entries[idx].state == PNI_ENTRY_FREE) {
+ empty = idx;
+ break;
+ }
+ }
+ entry->next = empty;
+ entry->state = PNI_ENTRY_LINK;
+ map->entries[empty].state = PNI_ENTRY_TAIL;
+ map->entries[empty].key = key;
+ pn_class_incref(map->key, key);
+ if (pprev) *pprev = entry;
+ map->size++;
+ return &map->entries[empty];
+ } else {
+ return NULL;
+ }
+}
+
+int pn_map_put(pn_map_t *map, void *key, void *value)
+{
+ assert(map);
+ pni_entry_t *entry = pni_map_entry(map, key, NULL, true);
+ pn_class_decref(map->value, entry->value);
+ entry->value = value;
+ pn_class_incref(map->value, value);
+ return 0;
+}
+
+void *pn_map_get(pn_map_t *map, void *key)
+{
+ assert(map);
+ pni_entry_t *entry = pni_map_entry(map, key, NULL, false);
+ return entry ? entry->value : NULL;
+}
+
+void pn_map_del(pn_map_t *map, void *key)
+{
+ assert(map);
+ pni_entry_t *prev = NULL;
+ pni_entry_t *entry = pni_map_entry(map, key, &prev, false);
+ if (entry) {
+ void *dref_key = entry->key;
+ void *dref_value = entry->value;
+ if (prev) {
+ prev->next = entry->next;
+ prev->state = entry->state;
+ } else if (entry->next) {
+ assert(entry->state == PNI_ENTRY_LINK);
+ pni_entry_t *next = &map->entries[entry->next];
+ *entry = *next;
+ entry = next;
+ }
+ entry->state = PNI_ENTRY_FREE;
+ entry->next = 0;
+ entry->key = NULL;
+ entry->value = NULL;
+ map->size--;
+ pn_class_decref(map->key, dref_key);
+ pn_class_decref(map->value, dref_value);
+ }
+}
+
+pn_handle_t pn_map_head(pn_map_t *map)
+{
+ assert(map);
+ for (size_t i = 0; i < map->capacity; i++)
+ {
+ if (map->entries[i].state != PNI_ENTRY_FREE) {
+ return i + 1;
+ }
+ }
+
+ return 0;
+}
+
+pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry)
+{
+ for (size_t i = entry; i < map->capacity; i++) {
+ if (map->entries[i].state != PNI_ENTRY_FREE) {
+ return i + 1;
+ }
+ }
+
+ return 0;
+}
+
+void *pn_map_key(pn_map_t *map, pn_handle_t entry)
+{
+ assert(map);
+ assert(entry);
+ return map->entries[entry - 1].key;
+}
+
+void *pn_map_value(pn_map_t *map, pn_handle_t entry)
+{
+ assert(map);
+ assert(entry);
+ return map->entries[entry - 1].value;
+}
+
+struct pn_hash_t {
+ pn_map_t map;
+};
+
+static uintptr_t pni_identity_hashcode(void *obj)
+{
+ return (uintptr_t ) obj;
+}
+
+static bool pni_identity_equals(void *a, void *b)
+{
+ return a == b;
+}
+
+extern const pn_class_t *PN_UINTPTR;
+
+#define CID_pni_uintptr CID_pn_void
+static const pn_class_t *pni_uintptr_reify(void *object) { return PN_UINTPTR; }
+#define pni_uintptr_new NULL
+#define pni_uintptr_free NULL
+#define pni_uintptr_initialize NULL
+static void pni_uintptr_incref(void *object) {}
+static void pni_uintptr_decref(void *object) {}
+static int pni_uintptr_refcount(void *object) { return -1; }
+#define pni_uintptr_finalize NULL
+#define pni_uintptr_hashcode NULL
+#define pni_uintptr_compare NULL
+#define pni_uintptr_inspect NULL
+
+const pn_class_t PNI_UINTPTR = PN_METACLASS(pni_uintptr);
+const pn_class_t *PN_UINTPTR = &PNI_UINTPTR;
+
+pn_hash_t *pn_hash(const pn_class_t *clazz, size_t capacity, float load_factor)
+{
+ pn_hash_t *hash = (pn_hash_t *) pn_map(PN_UINTPTR, clazz, capacity, load_factor);
+ hash->map.hashcode = pni_identity_hashcode;
+ hash->map.equals = pni_identity_equals;
+ return hash;
+}
+
+size_t pn_hash_size(pn_hash_t *hash)
+{
+ return pn_map_size(&hash->map);
+}
+
+int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value)
+{
+ return pn_map_put(&hash->map, (void *) key, value);
+}
+
+void *pn_hash_get(pn_hash_t *hash, uintptr_t key)
+{
+ return pn_map_get(&hash->map, (void *) key);
+}
+
+void pn_hash_del(pn_hash_t *hash, uintptr_t key)
+{
+ pn_map_del(&hash->map, (void *) key);
+}
+
+pn_handle_t pn_hash_head(pn_hash_t *hash)
+{
+ return pn_map_head(&hash->map);
+}
+
+pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry)
+{
+ return pn_map_next(&hash->map, entry);
+}
+
+uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry)
+{
+ return (uintptr_t) pn_map_key(&hash->map, entry);
+}
+
+void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry)
+{
+ return pn_map_value(&hash->map, entry);
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org