blob: 231506f7718dd03204819da956657d1d9b2f7ee5 [file] [log] [blame]
/*
*
* 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 "contexts.hpp"
#include "msg.hpp"
#include "reactor.hpp"
#include "proton_bits.hpp"
#include "proton/error.hpp"
#include <proton/connection.h>
#include <proton/object.h>
#include <proton/link.h>
#include <proton/message.h>
#include <proton/reactor.h>
#include <proton/session.h>
#include <typeinfo>
namespace proton {
namespace {
void cpp_context_finalize(void* v) { reinterpret_cast<context*>(v)->~context(); }
#define CID_cpp_context CID_pn_object
#define cpp_context_initialize NULL
#define cpp_context_finalize cpp_context_finalize
#define cpp_context_hashcode NULL
#define cpp_context_compare NULL
#define cpp_context_inspect NULL
pn_class_t cpp_context_class = PN_CLASS(cpp_context);
// Handles
PN_HANDLE(CONNECTION_CONTEXT)
PN_HANDLE(CONTAINER_CONTEXT)
PN_HANDLE(LISTENER_CONTEXT)
PN_HANDLE(LINK_CONTEXT)
void set_context(pn_record_t* record, pn_handle_t handle, const pn_class_t *clazz, void* value)
{
pn_record_def(record, handle, clazz);
pn_record_set(record, handle, value);
}
template <class T>
T* get_context(pn_record_t* record, pn_handle_t handle) {
return reinterpret_cast<T*>(pn_record_get(record, handle));
}
}
context::~context() {}
void *context::alloc(size_t n) { return pn_object_new(&cpp_context_class, n); }
pn_class_t* context::pn_class() { return &cpp_context_class; }
context::id connection_context::id(pn_connection_t* c) {
return context::id(pn_connection_attachments(c), CONNECTION_CONTEXT);
}
context::id connection_context::id(const connection& c) {
return id(unwrap(c));
}
void container_context::set(const reactor& r, container& c) {
set_context(pn_reactor_attachments(unwrap(r)), CONTAINER_CONTEXT, PN_VOID, &c);
}
container &container_context::get(pn_reactor_t *pn_reactor) {
container *ctx = get_context<container>(pn_reactor_attachments(pn_reactor), CONTAINER_CONTEXT);
if (!ctx) throw error(MSG("Reactor has no C++ container context"));
return *ctx;
}
listener_context& listener_context::get(pn_acceptor_t* a) {
// TODO aconway 2016-05-13: reactor only
// A Proton C pn_acceptor_t is really just a selectable
pn_selectable_t *sel = reinterpret_cast<pn_selectable_t*>(a);
listener_context* ctx =
get_context<listener_context>(pn_selectable_attachments(sel), LISTENER_CONTEXT);
if (!ctx) {
ctx = context::create<listener_context>();
set_context(pn_selectable_attachments(sel), LISTENER_CONTEXT, context::pn_class(), ctx);
pn_decref(ctx);
}
return *ctx;
}
link_context& link_context::get(pn_link_t* l) {
link_context* ctx =
get_context<link_context>(pn_link_attachments(l), LINK_CONTEXT);
if (!ctx) {
ctx = context::create<link_context>();
set_context(pn_link_attachments(l), LINK_CONTEXT, context::pn_class(), ctx);
pn_decref(ctx);
}
return *ctx;
}
}