blob: 48b9f5fd8e6e4ed76fe634faccff376f0c9fbaaf [file] [log] [blame]
#ifndef PROTON_BITS_HPP
#define PROTON_BITS_HPP
/*
* 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/link.h>
#include <proton/session.h>
#include <string>
#include <iosfwd>
#include "contexts.hpp"
/**@file
*
* Assorted internal proton utilities.
*/
struct pn_error_t;
struct pn_data_t;
struct pn_transport_t;
struct pn_sasl_t;
struct pn_ssl_t;
struct pn_connection_t;
struct pn_session_t;
struct pn_link_t;
struct pn_delivery_t;
struct pn_condition_t;
struct pn_acceptor_t;
struct pn_terminus_t;
struct pn_reactor_t;
struct pn_record_t;
namespace proton {
namespace internal { class data; }
class transport;
class sasl;
class ssl;
class connection;
class session;
class link;
class sender;
class receiver;
class transfer;
class tracker;
class delivery;
class error_condition;
class acceptor;
class terminus;
class source;
class target;
class reactor;
class messaging_handler;
std::string error_str(long code);
/** Print the error string from pn_error_t, or from code if pn_error_t has no error. */
std::string error_str(pn_error_t*, long code=0);
/** Make a void* inspectable via operator <<. */
struct inspectable { void* value; inspectable(void* o) : value(o) {} };
/** Stream a proton object via pn_inspect. */
std::ostream& operator<<(std::ostream& o, const inspectable& object);
void set_error_condition(const error_condition&, pn_condition_t*);
/// Convert a const char* to std::string, convert NULL to the empty string.
inline std::string str(const char* s) { return s ? s : std::string(); }
namespace internal {
// These traits relate the wrapped and wrapper classes for the templated factories below
template <class T> struct wrapped {};
template <> struct wrapped<internal::data> { typedef pn_data_t type; };
template <> struct wrapped<transport> { typedef pn_transport_t type; };
template <> struct wrapped<connection> { typedef pn_connection_t type; };
template <> struct wrapped<session> { typedef pn_session_t type; };
template <> struct wrapped<link> { typedef pn_link_t type; };
template <> struct wrapped<sender> { typedef pn_link_t type; };
template <> struct wrapped<receiver> { typedef pn_link_t type; };
template <> struct wrapped<transfer> { typedef pn_delivery_t type; };
template <> struct wrapped<tracker> { typedef pn_delivery_t type; };
template <> struct wrapped<delivery> { typedef pn_delivery_t type; };
template <> struct wrapped<error_condition> { typedef pn_condition_t type; };
template <> struct wrapped<terminus> { typedef pn_terminus_t type; };
template <> struct wrapped<source> { typedef pn_terminus_t type; };
template <> struct wrapped<target> { typedef pn_terminus_t type; };
template <class T> struct wrapper {};
template <> struct wrapper<pn_data_t> { typedef internal::data type; };
template <> struct wrapper<pn_transport_t> { typedef transport type; };
template <> struct wrapper<pn_connection_t> { typedef connection type; };
template <> struct wrapper<pn_session_t> { typedef session type; };
template <> struct wrapper<pn_link_t> { typedef link type; };
template <> struct wrapper<pn_delivery_t> { typedef transfer type; };
template <> struct wrapper<pn_condition_t> { typedef error_condition type; };
template <> struct wrapper<pn_terminus_t> { typedef terminus type; };
// Factory for wrapper types
template <class T>
class factory {
public:
static T wrap(typename wrapped<T>::type* t) { return t; }
static typename wrapped<T>::type* unwrap(const T& t) { return t.pn_object(); }
};
template <class T> struct context {};
template <> struct context<link> {typedef link_context type; };
template <> struct context<receiver> {typedef link_context type; };
template <> struct context<sender> {typedef link_context type; };
template <> struct context<session> {typedef session_context type; };
template <> struct context<connection> {typedef connection_context type; };
template <class T>
inline void set_messaging_handler(T t, messaging_handler* mh) { context<T>::type::get(factory<T>::unwrap(t)).handler = mh; }
template <class T>
inline messaging_handler* get_messaging_handler(T* t) { return context<typename internal::wrapper<T>::type>::type::get(t).handler; }
class returned_factory {
public:
template <class T> static returned<T> make(typename internal::wrapped<T>::type* pn) {
return returned<T>(pn);
}
};
} // namespace internal
template <class T>
typename internal::wrapper<T>::type make_wrapper(T* t) { return internal::factory<typename internal::wrapper<T>::type>::wrap(t); }
template <class U>
U make_wrapper(typename internal::wrapped<U>::type* t) { return internal::factory<U>::wrap(t); }
template <class T>
typename internal::wrapped<T>::type* unwrap(const T& t) { return internal::factory<T>::unwrap(t); }
template <class T> returned<T> make_returned(typename internal::wrapped<T>::type* pn) {
return internal::returned_factory::make<T>(pn);
}
// Get an AMQP "multiple" field from a value. A "multiple" field can be encoded as a single
// value or as an array. This function always extracts it as a sequence, a sequence of one
// if it is encoded as a single value.
//
// T should be a valid sequence type for proton::get() with a T::value_type typedef.
//
template<class T>
void get_multiple(const value& v, T& x) {
if (v.empty()) {
x.clear();
} else if (v.type() == ARRAY) {
proton::get(v,x);
} else {
x.resize(1);
proton::get(v,x[0]);
}
}
// Same as previous but returns the value.
template<class T>
T get_multiple(const value& v) {
T x;
get_multiple(v, x);
return x;
}
} // namespace proton
#endif // PROTON_BITS_HPP