diff options
Diffstat (limited to 'qpid/cpp/include/qpid')
25 files changed, 3602 insertions, 0 deletions
diff --git a/qpid/cpp/include/qpid/ImportExport.h b/qpid/cpp/include/qpid/ImportExport.h new file mode 100644 index 0000000000..eecc9503bc --- /dev/null +++ b/qpid/cpp/include/qpid/ImportExport.h @@ -0,0 +1,75 @@ +#ifndef QPID_IMPORTEXPORT_H +#define QPID_IMPORTEXPORT_H + +/* + * 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. + */ + +// +// This header file defines the following macros for the control of library/DLL +// import and export: +// +// QPID_EXPORT - Export declaration for Methods +// QPID_CLASS_EXPORT - Export declaration for Classes +// QPID_INLINE_EXPORT - Export declaration for Inline methods +// +// QPID_IMPORT - Import declaration for Methods +// QPID_CLASS_IMPORT - Import declaration for Classes +// QPID_INLINE_IMPORT - Import declaration for Inline methods +// + +#if defined(WIN32) && !defined(QPID_DECLARE_STATIC) + // + // Import and Export definitions for Windows: + // +# define QPID_EXPORT __declspec(dllexport) +# define QPID_IMPORT __declspec(dllimport) +# ifdef _MSC_VER + // + // Specific to the Microsoft compiler: + // +# define QPID_CLASS_EXPORT +# define QPID_CLASS_IMPORT +# define QPID_INLINE_EXPORT QPID_EXPORT +# define QPID_INLINE_IMPORT QPID_IMPORT +# else + // + // Specific to non-Microsoft compilers (mingw32): + // +# define QPID_CLASS_EXPORT QPID_EXPORT +# define QPID_CLASS_IMPORT QPID_IMPORT +# define QPID_INLINE_EXPORT +# define QPID_INLINE_IMPORT +# endif +#else + // + // Non-Windows (Linux, etc.) definitions: + // +#if __GNUC__ >= 4 +# define QPID_EXPORT __attribute ((visibility ("default"))) +#else +# define QPID_EXPORT +#endif +# define QPID_IMPORT +# define QPID_CLASS_EXPORT QPID_EXPORT +# define QPID_CLASS_IMPORT QPID_IMPORT +# define QPID_INLINE_EXPORT QPID_EXPORT +# define QPID_INLINE_IMPORT QPID_IMPORT +#endif + +#endif /*!QPID_IMPORTEXPORT_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Address.h b/qpid/cpp/include/qpid/messaging/Address.h new file mode 100644 index 0000000000..224a70b193 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Address.h @@ -0,0 +1,165 @@ +#ifndef QPID_MESSAGING_ADDRESS_H +#define QPID_MESSAGING_ADDRESS_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/exceptions.h" +#include "qpid/types/Variant.h" + +#include <string> +#include <ostream> + +namespace qpid { +namespace messaging { + +class AddressImpl; + +/** \ingroup messaging + * Represents an address to which messages can be sent and from which + * messages can be received. Often a simple name is sufficient for + * this, however this can be augmented with a subject pattern and + * options. + * + * All parts of an address can be specified in a string of the + * following form: + * + * <address> [ / <subject> ] ; [ { <key> : <value> , ... } ] + * + * Here the <address> is a simple name for the addressed + * entity and <subject> is a subject or subject pattern for + * messages sent to or received from this address. The options are + * specified as a series of key value pairs enclosed in curly brackets + * (denoting a map). Values can be nested maps, or lists (which are + * denoted as a comma separated list of values inside square brackets, + * e.g. [a, b, c]). + * + * The currently supported options are as follows: + * + * <table border=0> + * + * <tr valign=top> + * <td>create</td> + * <td>Indicate whether the address should be automatically created + * or not. Can be one of <i>always</i>, <i>never</i>, + * <i>sender</i> or <i>receiver</i>. The properties of the node + * to be created can be specified via the node options (see + * below). + * </td> + * </tr> + * + * <tr valign=top> + * <td>assert</td> + * <td>Indicate whether or not to assert any specified node + * properties(see below) match the address. Can be one of + * <i>always</i>, <i>never</i>, <i>sender</i> or + * <i>receiver</i>. + * </td> + * </tr> + * + * <tr valign=top> + * <td>delete</td> + * <td>Indicate whether or not to delete the addressed node when a + * sender or receiver is cancelled. Can be one of <i>always</i>, + * <i>never</i>, <i>sender</i> or <i>receiver</i>. + * </td> + * </tr> + * + * <tr valign=top> + * <td>node</td> + + * <td>A nested map describing properties of the addressed + * node. Current properties supported are type (topic or queue), + * durable (boolean), x-declare and x-bindings. The x-declare + * option is a nested map in whcih protocol amqp 0-10 specific + * options for queue or exchange declare can be specified. The + * x-bindings option is a nested list, each element of which can + * specify a queue, an exchange, a binding-key and arguments, + * which are used to establish a binding on create. The node + * will be used if queue or exchange values are not specified. + * </td> + * </tr> + * + * <tr valign=top> + * <td>link</td> + * <td>A nested map through which properties of the 'link' from + * sender/receiver to node can be configured. Current propeties + * are name, durable, realiability, x-declare, x-subscribe and + * x-bindings. + * </td> + * </tr> + * + * For receivers there is one other option of interest: + * + * <table border=0 valign=top> + * <tr valign=top><td>mode</td><td>(only relevant for queues) + * indicates whether the subscribe should consume (the default) or + * merely browse the messages. Valid values are 'consume' and + * 'browse'</td></tr> + * </table> + * + * An address has value semantics. + */ +class QPID_MESSAGING_CLASS_EXTERN Address +{ + public: + QPID_MESSAGING_EXTERN Address(); + QPID_MESSAGING_EXTERN Address(const std::string& address); + QPID_MESSAGING_EXTERN Address(const std::string& name, const std::string& subject, + const qpid::types::Variant::Map& options, const std::string& type = ""); + QPID_MESSAGING_EXTERN Address(const Address& address); + QPID_MESSAGING_EXTERN ~Address(); + QPID_MESSAGING_EXTERN Address& operator=(const Address&); + QPID_MESSAGING_EXTERN const std::string& getName() const; + QPID_MESSAGING_EXTERN void setName(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getSubject() const; + QPID_MESSAGING_EXTERN void setSubject(const std::string&); + QPID_MESSAGING_EXTERN const qpid::types::Variant::Map& getOptions() const; + QPID_MESSAGING_EXTERN qpid::types::Variant::Map& getOptions(); + QPID_MESSAGING_EXTERN void setOptions(const qpid::types::Variant::Map&); + + QPID_MESSAGING_EXTERN std::string getType() const; + /** + * The type of and addressed node influences how receivers and + * senders are constructed for it. It also affects how a reply-to + * address is encoded. If the type is not specified in the address + * itself, it will be automatically determined by querying the + * broker. The type can be explicitly set to prevent this if + * needed. + */ + QPID_MESSAGING_EXTERN void setType(const std::string&); + + QPID_MESSAGING_EXTERN std::string str() const; + QPID_MESSAGING_EXTERN operator bool() const; + QPID_MESSAGING_EXTERN bool operator !() const; + private: + AddressImpl* impl; + friend class AddressImpl; +}; + +#ifndef SWIG +QPID_MESSAGING_EXTERN std::ostream& operator<<(std::ostream& out, const Address& address); +#endif + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_ADDRESS_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Connection.h b/qpid/cpp/include/qpid/messaging/Connection.h new file mode 100644 index 0000000000..aed3717fa8 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Connection.h @@ -0,0 +1,179 @@ +#ifndef QPID_MESSAGING_CONNECTION_H +#define QPID_MESSAGING_CONNECTION_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/Handle.h" +#include "qpid/messaging/exceptions.h" +#include "qpid/types/Variant.h" + +#include <string> + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif +class ConnectionImpl; +class Session; + +/** \ingroup messaging + * A connection represents a network connection to a remote endpoint. + */ + +class QPID_MESSAGING_CLASS_EXTERN Connection : public qpid::messaging::Handle<ConnectionImpl> +{ + public: + QPID_MESSAGING_EXTERN Connection(ConnectionImpl* impl); + QPID_MESSAGING_EXTERN Connection(const Connection&); + QPID_MESSAGING_EXTERN Connection(); + /** + * Current implementation supports the following options: + * + * - heartbeat: the heartbeat interval in seconds + * - tcp_nodelay: true/false, whether nagle should be disabled or not + * - transport: the underlying transport to use (e.g. tcp, ssl, rdma) + * - protocol: the version of AMQP to use (e.g. amqp0-10 or amqp1.0) + * + * (Note: the transports and/or protocols recognised may depend on + * which plugins are loaded. AT present support for heartbeats is + * missing in AMQP 1.0) + * + * - username: the username to authenticate as + * - password: the password to use if required by the selected authentication mechanism + * - sasl_mechanisms: a space separated list of acceptable SASL mechanisms + * - sasl_min_ssf: the minimum acceptable security strength factor + * - sasl_max_ssf: the maximum acceptable security strength factor + * - sasl_service: the service name if needed by the SASL mechanism in use + * + * Reconnect behaviour can be controlled through the following options: + * + * - reconnect: true/false (enables/disables reconnect entirely) + * - reconnect_timeout: seconds (give up and report failure after specified time) + * - reconnect_limit: n (give up and report failure after specified number of attempts) + * - reconnect_interval_min: seconds (initial delay between failed reconnection attempts) + * - reconnect_interval_max: seconds (maximum delay between failed reconnection attempts) + * - reconnect_interval: shorthand for setting the same reconnect_interval_min/max + * - reconnect_urls: list of alternate urls to try when connecting + * + * The reconnect_interval is the time that the client waits for + * after a failed attempt to reconnect before retrying. It starts + * at the value of the min_retry_interval and is doubled every + * failure until the value of max_retry_interval is reached. + * + * Values in seconds can be fractional, for example 0.001 is a + * millisecond delay. + * + * If the SSL transport is used, the following options apply: + * + * - ssl_cert_name: the name of the certificate to use for a given + * - connection ssl_ignore_hostname_verification_failure: if set + * to true, will allow client to connect to server even + * if the hostname used (or ip address) doesn't match + * what is in the servers certificate. I.e. this disables + * authentication of the server to the client (and should + * be used only as a last resort) + * + * When AMQP 1.0 is used, the following options apply: + * + * - container_id: sets the container id to use for the connection + * - nest_annotations: if true, any annotations in received + * messages will be presented as properties with keys + * x-amqp-delivery-annotations or x-amqp-delivery-annotations + * and values that are nested maps containing the + * annotations. If false, the annotations will simply be merged + * in with the properties. + * - set_to_on_send: If true, all sent messages will have the to + * field set to the node name of the sender + * - properties or client_properties: the properties to include in the open frame sent + * + * The following options can be used to tune behaviour if needed + * (these are not yet supported over AMQP 1.0): + * + * - tcp_nodelay: disables Nagle's algorithm on the underlying tcp socket + * - max_channels: restricts the maximum number of channels supported + * - max_frame_size: restricts the maximum frame size supported + */ + QPID_MESSAGING_EXTERN Connection(const std::string& url, const qpid::types::Variant::Map& options = qpid::types::Variant::Map()); + /** + * Creates a connection using an option string of the form + * {name:value,name2:value2...}, see above for options supported. + * + * @exception InvalidOptionString if the string does not match the correct syntax + */ + QPID_MESSAGING_EXTERN Connection(const std::string& url, const std::string& options); + QPID_MESSAGING_EXTERN ~Connection(); + QPID_MESSAGING_EXTERN Connection& operator=(const Connection&); + QPID_MESSAGING_EXTERN void setOption(const std::string& name, const qpid::types::Variant& value); + QPID_MESSAGING_EXTERN void open(); + QPID_MESSAGING_EXTERN bool isOpen(); + QPID_MESSAGING_EXTERN bool isOpen() const; + + /** + * Attempts to reconnect to the specified url, re-establish + * existing sessions, senders and receivers and resend any indoubt + * messages. + * + * This can be used to directly control reconnect behaviour rather + * than using the reconnect option for automatically handling + * that. + */ + QPID_MESSAGING_EXTERN void reconnect(const std::string& url); + /** + * Attempts to reconnect to the original url, including any + * specified reconnect_urls, re-establish existing sessions, + * senders and receivers and resend any indoubt messages. + * + * This can be used to directly control reconnect behaviour rather + * than using the reconnect option for automatically handling + * that. + */ + QPID_MESSAGING_EXTERN void reconnect(); + /** + * returns a url reprsenting the broker the client is currently + * connected to (or an empty string if it is not connected). + */ + QPID_MESSAGING_EXTERN std::string getUrl() const; + + /** + * Closes a connection and all sessions associated with it. An + * opened connection must be closed before the last handle is + * allowed to go out of scope. + */ + QPID_MESSAGING_EXTERN void close(); + QPID_MESSAGING_EXTERN Session createTransactionalSession(const std::string& name = std::string()); + QPID_MESSAGING_EXTERN Session createSession(const std::string& name = std::string()); + + QPID_MESSAGING_EXTERN Session getSession(const std::string& name) const; + QPID_MESSAGING_EXTERN std::string getAuthenticatedUsername(); + +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Connection>; +#endif +}; + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_CONNECTION_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Duration.h b/qpid/cpp/include/qpid/messaging/Duration.h new file mode 100644 index 0000000000..6b8f05c7c6 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Duration.h @@ -0,0 +1,57 @@ +#ifndef QPID_MESSAGING_DURATION_H +#define QPID_MESSAGING_DURATION_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/sys/IntegerTypes.h" + +namespace qpid { +namespace messaging { + +/** \ingroup messaging + * A duration is a time in milliseconds. + */ +class QPID_MESSAGING_CLASS_EXTERN Duration +{ + public: + QPID_MESSAGING_EXTERN explicit Duration(uint64_t milliseconds); + QPID_MESSAGING_EXTERN uint64_t getMilliseconds() const; + QPID_MESSAGING_EXTERN static const Duration FOREVER; + QPID_MESSAGING_EXTERN static const Duration IMMEDIATE; + QPID_MESSAGING_EXTERN static const Duration SECOND; + QPID_MESSAGING_EXTERN static const Duration MINUTE; + private: + uint64_t milliseconds; +}; + +QPID_MESSAGING_EXTERN Duration operator*(const Duration& duration, + uint64_t multiplier); +QPID_MESSAGING_EXTERN Duration operator*(uint64_t multiplier, + const Duration& duration); +QPID_MESSAGING_EXTERN bool operator==(const Duration& a, const Duration& b); +QPID_MESSAGING_EXTERN bool operator!=(const Duration& a, const Duration& b); + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_DURATION_H*/ diff --git a/qpid/cpp/include/qpid/messaging/FailoverUpdates.h b/qpid/cpp/include/qpid/messaging/FailoverUpdates.h new file mode 100644 index 0000000000..6d7314620a --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/FailoverUpdates.h @@ -0,0 +1,49 @@ +#ifndef QPID_CLIENT_AMQP0_10_FAILOVERUPDATES_H +#define QPID_CLIENT_AMQP0_10_FAILOVERUPDATES_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +namespace qpid { +namespace messaging { +class Connection; +struct FailoverUpdatesImpl; + +/** + * A utility to listen for updates on cluster membership and update + * the list of known urls for a connection accordingly. + */ +class QPID_MESSAGING_CLASS_EXTERN FailoverUpdates +{ + public: + QPID_MESSAGING_EXTERN FailoverUpdates(Connection& connection); + QPID_MESSAGING_EXTERN ~FailoverUpdates(); + private: + FailoverUpdatesImpl* impl; + + //no need to copy instances of this class + FailoverUpdates(const FailoverUpdates&); + FailoverUpdates& operator=(const FailoverUpdates&); +}; +}} // namespace qpid::messaging + +#endif /*!QPID_CLIENT_AMQP0_10_FAILOVERUPDATES_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Handle.h b/qpid/cpp/include/qpid/messaging/Handle.h new file mode 100644 index 0000000000..2edab26744 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Handle.h @@ -0,0 +1,72 @@ +#ifndef QPID_MESSAGING_HANDLE_H +#define QPID_MESSAGING_HANDLE_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +namespace qpid { +namespace messaging { + +template <class> class PrivateImplRef; + +/** \ingroup messaging + * A handle is like a pointer: refers to an underlying implementation object. + * Copying the handle does not copy the object. + * + * Handles can be null, like a 0 pointer. Use isValid(), isNull() or the + * conversion to bool to test for a null handle. + */ +template <class T> class Handle { + public: + + /**@return true if handle is valid, i.e. not null. */ + QPID_MESSAGING_INLINE_EXTERN bool isValid() const { return impl; } + + /**@return true if handle is null. It is an error to call any function on a null handle. */ + QPID_MESSAGING_INLINE_EXTERN bool isNull() const { return !impl; } + + /** Conversion to bool supports idiom if (handle) { handle->... } */ + QPID_MESSAGING_INLINE_EXTERN operator bool() const { return impl; } + + /** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */ + QPID_MESSAGING_INLINE_EXTERN bool operator !() const { return !impl; } + + void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; } + + private: + // Not implemented, subclasses must implement. + Handle(const Handle&); + Handle& operator=(const Handle&); + + protected: + typedef T Impl; + QPID_MESSAGING_INLINE_EXTERN Handle() :impl() {} + + Impl* impl; + + friend class PrivateImplRef<T>; +}; + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_HANDLE_H*/ diff --git a/qpid/cpp/include/qpid/messaging/ImportExport.h b/qpid/cpp/include/qpid/messaging/ImportExport.h new file mode 100644 index 0000000000..ab5f21f618 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/ImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_MESSAGING_IMPORTEXPORT_H +#define QPID_MESSAGING_IMPORTEXPORT_H + +/* + * 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 "qpid/ImportExport.h" + +#if defined(CLIENT_EXPORT) || defined (qpidmessaging_EXPORTS) +# define QPID_MESSAGING_EXTERN QPID_EXPORT +# define QPID_MESSAGING_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_MESSAGING_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_MESSAGING_EXTERN QPID_IMPORT +# define QPID_MESSAGING_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_MESSAGING_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif /*!QPID_MESSAGING_IMPORTEXPORT_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Logger.h b/qpid/cpp/include/qpid/messaging/Logger.h new file mode 100644 index 0000000000..39518e01d4 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Logger.h @@ -0,0 +1,165 @@ +#ifndef QPID_MESSAGING_LOGGING_H +#define QPID_MESSAGING_LOGGING_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include <string> + +namespace qpid { +namespace messaging { +/** + * These log levels need to be kept in sync with the log levels + * defined internally in qpid::log (but I don't think they are likely + * to change anyway + */ +enum Level { trace, debug, info, notice, warning, error, critical }; + +/** \ingroup messaging + * Interface class to allow redirection of log output + */ +class QPID_MESSAGING_CLASS_EXTERN LoggerOutput +{ +public: + QPID_MESSAGING_EXTERN virtual ~LoggerOutput(); + + /** + * Override this member function to receive log messages. + * + * log() will be called for every log message that would be output from the qpid::messaging + * logging subsystem after applying the specified logging filters. + * + * The logging subsystem ensures that log() will not be called simultaneously in different threads. + * @param level The severity of the log message can be (in order of severity) + * trace, debug, info, notice, warning, error, critical + * @param user Flag which is set if the log message came from the user application ( using qpid::messaging::Logger::log() ) + * (if not set then the message comes from the qpid library) + * @param file The source code file name reported as the origin of the log message + * @param line The source code line number reported as the origin of the log message + * @param function The source code function reported as the origin of the log message + * @param message The log message + */ + virtual void log(Level level, bool user, const char* file, int line, const char* function, const std::string& message) = 0; +}; + +/** \ingroup messaging + * A utility class to allow the application to control the logging + * output of the qpid messaging library + * + * This class represents a singleton logging facility within the qpid messaging library so there are only static + * methods in the class + */ +class QPID_MESSAGING_CLASS_EXTERN Logger +{ +public: + /** + * Configure the logging subsystem + * + * This function takes an array of text options (which could easily come from a programs + * command line) and uses them to configure the logging subsystem. + * + * If the prefix parameter is specified then the accepted command line options are prefixed + * by <<prefix>>- for example if the prefix is "qpid" then the options all start "--qpid-log..." + * + * Accepted options are: + * --log-enable RULE + * --log-disable RULE + * + * Both --log-enable and --log-disable can be specified multiple times in a single command line. + * The enables are acted upon and after them the disables are acted upon. + * + * RULE is in the form LEVEL[("+"|"-")][:PATTERN] + * LEVEL is one of "trace", "debug", "info", "notice", "warning", "error", "critical" + * "+" operates on the level and all higher levels + * "-" operates on the level and all lower levels + * PATTERN is a category name or a fragment of a fully namespace qualified function (Case sensitive). + * + * --log-to-stdout ("on"|"off|"0"|"1") + * --log-to-stderr ("on"|"off|"0"|"1") + * --log-to-file FILENAME + * + * These options control where the qpid logging subsystem sends log messages + * + * --log-time ("on"|"off|"0"|"1") + * --log-level ("on"|"off|"0"|"1") + * --log-source ("on"|"off|"0"|"1") + * --log-thread ("on"|"off|"0"|"1") + * --log-function ("on"|"off|"0"|"1") + * --log-hires-timestamp ("on"|"off|"0"|"1") + * + * These options control what information is included in the logging message sent by the logging subsystem. + * + * @param argc count of options - identical to meaning for main(). + * @param argv array of pointers to options - identical to meaning for main(). + * @param prefix (optional) If present prefix all logging options with this string + * @throws MessagingException if it cannot parse an option it recognises + */ + QPID_MESSAGING_EXTERN static void configure(int argc, const char* argv[], const std::string& prefix=std::string()); + + /** + * Get a user friendly usage message. + * + * This returns a usage message that is suitable for outputting directly to + * a console user. The message only contains the command line options that + * are understood by qpid::messaging::Logger::configure(). + * + * NB. You must call qpid::messaging::Logger::configure() before calling this + * to populate the usage string as the usage string depends on the prefix that + * is passed in to qpid::messaging::Logger::configure(). + * + * @return string containing the usage message for the command line options + */ + QPID_MESSAGING_EXTERN static std::string usage(); + + /** + * Register a custom handler for log messages + * + * This allows application programs to intercept the log messages coming from qpid::messaging + * and handle them in whatever way is consonent with the applications own handling of + * log messages. + * + * In order to do this create a class that inherits from qpid::messaging::LoggerOutput + * and override the log() member function. + */ + QPID_MESSAGING_EXTERN static void setOutput(LoggerOutput& output); + + /** + * Output a log message. This will get sent to all the specified logging outputs including any + * the application has registered. The message will get filtered along with the internal messages + * according to the specified logging filters. + * + * When a log message output using log() is received by a LoggerOutput::log() method the "user" bool parameter will be set true. + */ + QPID_MESSAGING_EXTERN static void log(Level level, const char* file, int line, const char* function, const std::string& message); + +private: + //This class has only one instance so no need to copy + Logger(); + ~Logger(); + + Logger(const Logger&); + Logger operator=(const Logger&); +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_LOGGING_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Message.h b/qpid/cpp/include/qpid/messaging/Message.h new file mode 100644 index 0000000000..6315d3e86f --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Message.h @@ -0,0 +1,262 @@ +#ifndef QPID_MESSAGING_MESSAGE_H +#define QPID_MESSAGING_MESSAGE_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/Duration.h" +#include "qpid/types/Exception.h" +#include "qpid/types/Variant.h" + +#include <string> + +namespace qpid { +namespace messaging { + +class Address; +class Codec; +class MessageImpl; + +/** \ingroup messaging + * Representation of a message. + */ +class QPID_MESSAGING_CLASS_EXTERN Message +{ + public: + QPID_MESSAGING_EXTERN Message(qpid::types::Variant&); + QPID_MESSAGING_EXTERN Message(const std::string& bytes = std::string()); + QPID_MESSAGING_EXTERN Message(const char*, size_t); + QPID_MESSAGING_EXTERN Message(const Message&); + QPID_MESSAGING_EXTERN ~Message(); + + QPID_MESSAGING_EXTERN Message& operator=(const Message&); + + QPID_MESSAGING_EXTERN void setReplyTo(const Address&); + QPID_MESSAGING_EXTERN const Address& getReplyTo() const; + + QPID_MESSAGING_EXTERN void setSubject(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getSubject() const; + + /** + * Set the content type (i.e. the MIME type) for the message. This + * should be set by the sending application and indicates to + * recipients of message how to interpret or decode the content. + */ + QPID_MESSAGING_EXTERN void setContentType(const std::string&); + /** + * Returns the content type (i.e. the MIME type) for the + * message. This can be used to determine how to decode the + * message content. + */ + QPID_MESSAGING_EXTERN const std::string& getContentType() const; + + /** + * Set an application defined identifier for the message. At + * present this must be a stringfied UUID (support for less + * restrictive IDs is anticipated however). + */ + QPID_MESSAGING_EXTERN void setMessageId(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getMessageId() const; + + /** + * Sets the user id of the message. This should in general be the + * user-id as which the sending connection authenticated itself as + * the messaging infrastructure will verify this. See + * Connection::getAuthenticatedUsername() + */ + QPID_MESSAGING_EXTERN void setUserId(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getUserId() const; + + /** + * Can be used to set application specific correlation identifiers + * as part of a protocol for message exchange patterns. E.g. a + * request-reponse pattern might require the correlation-id of the + * request and response to match, or might use the message-id of + * the request as the correlation-id on the response etc. + */ + QPID_MESSAGING_EXTERN void setCorrelationId(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getCorrelationId() const; + + /** + * Sets a priority level on the message. This may be used by the + * messaging infrastructure to prioritise delivery of higher + * priority messages. + */ + QPID_MESSAGING_EXTERN void setPriority(uint8_t); + QPID_MESSAGING_EXTERN uint8_t getPriority() const; + + /** + * Set the time to live for this message in milliseconds. This can + * be used by the messaging infrastructure to discard messages + * that are no longer of relevance. + */ + QPID_MESSAGING_EXTERN void setTtl(Duration ttl); + /** + *Get the time to live for this message in milliseconds. + */ + QPID_MESSAGING_EXTERN Duration getTtl() const; + + /** + * Mark the message as durable. This is a hint to the messaging + * infrastructure that the message should be persisted or + * otherwise stored such that failoures or shutdown do not cause + * it to be lost. + */ + QPID_MESSAGING_EXTERN void setDurable(bool durable); + QPID_MESSAGING_EXTERN bool getDurable() const; + + /** + * The redelivered flag if set implies that the message *may* have + * been previously delivered and thus is a hint to the application + * or messaging infrastructure that if de-duplication is required + * this message should be examined to determine if it is a + * duplicate. + */ + QPID_MESSAGING_EXTERN bool getRedelivered() const; + /** + * Can be used to provide a hint to the application or messaging + * infrastructure that if de-duplication is required this message + * should be examined to determine if it is a duplicate. + */ + QPID_MESSAGING_EXTERN void setRedelivered(bool); + + /** + * In addition to a payload (i.e. the content), messages can + * include annotations describing aspectf of the message. In + * addition to the standard annotations such as TTL and content + * type, application- or context- specific properties can also be + * defined. Each message has a map of name values for such custom + * properties. The value is specified as a Variant. + */ + QPID_MESSAGING_EXTERN const qpid::types::Variant::Map& getProperties() const; + QPID_MESSAGING_EXTERN qpid::types::Variant::Map& getProperties(); + QPID_MESSAGING_EXTERN void setProperties(const qpid::types::Variant::Map&); + + /** + * Set the content to the data held in the string parameter. Note: + * this is treated as raw bytes and need not be text. Consider + * setting the content-type to indicate how the data should be + * interpreted by recipients. + */ + QPID_MESSAGING_EXTERN void setContent(const std::string&); + /** + * Copy count bytes from the region pointed to by chars as the + * message content. + */ + QPID_MESSAGING_EXTERN void setContent(const char* chars, size_t count); + + /** Get the content as a std::string */ + QPID_MESSAGING_EXTERN std::string getContent() const; + /** Get the content as raw bytes (an alias for getContent() */ + QPID_MESSAGING_EXTERN std::string getContentBytes() const; + /** Set the content as raw bytes (an alias for setContent() */ + QPID_MESSAGING_EXTERN void setContentBytes(const std::string&); + /** + * Get the content as a Variant, which can represent an object of + * different types. This can be used for content representing a + * map or a list for example. + */ + QPID_MESSAGING_EXTERN qpid::types::Variant& getContentObject(); + /** + * Get the content as a Variant, which can represent an object of + * different types. This can be used for content representing a + * map or a list for example. + */ + QPID_MESSAGING_EXTERN const qpid::types::Variant& getContentObject() const; + /** + * Set the content using a Variant, which can represent an object + * of different types. + */ + QPID_MESSAGING_EXTERN void setContentObject(const qpid::types::Variant&); + /** + * Get a const pointer to the start of the content data. The + * memory pointed to is owned by the message. The getContentSize() + * method indicates how much data there is (i.e. the extent of the + * memory region pointed to by the return value of this method). + */ + QPID_MESSAGING_EXTERN const char* getContentPtr() const; + /** Get the size of content in bytes. */ + QPID_MESSAGING_EXTERN size_t getContentSize() const; + + QPID_MESSAGING_EXTERN void setProperty(const std::string&, const qpid::types::Variant&); + private: + MessageImpl* impl; + friend struct MessageImplAccess; +}; + +struct QPID_MESSAGING_CLASS_EXTERN EncodingException : qpid::types::Exception +{ + QPID_MESSAGING_EXTERN EncodingException(const std::string& msg); +}; + +/** + * Decodes message content into a Variant::Map. + * + * @param message the message whose content should be decoded + * @param map the map into which the message contents will be decoded + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void decode(const Message& message, + qpid::types::Variant::Map& map, + const std::string& encoding = std::string()); +/** + * Decodes message content into a Variant::List. + * + * @param message the message whose content should be decoded + * @param list the list into which the message contents will be decoded + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void decode(const Message& message, + qpid::types::Variant::List& list, + const std::string& encoding = std::string()); +/** + * Encodes a Variant::Map into a message. + * + * @param map the map to be encoded + * @param message the message whose content should be set to the encoded map + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::Map& map, + Message& message, + const std::string& encoding = std::string()); +/** + * Encodes a Variant::List into a message. + * + * @param list the list to be encoded + * @param message the message whose content should be set to the encoded list + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::List& list, + Message& message, + const std::string& encoding = std::string()); + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_MESSAGE_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Message_io.h b/qpid/cpp/include/qpid/messaging/Message_io.h new file mode 100644 index 0000000000..810c44810c --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Message_io.h @@ -0,0 +1,34 @@ +#ifndef QPID_MESSAGING_MESSAGE_IO_H +#define QPID_MESSAGING_MESSAGE_IO_H + +/* + * + * 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 "Message.h" +#include <iosfwd> + +namespace qpid { +namespace messaging { + +QPID_MESSAGING_EXTERN std::ostream& operator<<(std::ostream&, const Message&); + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_MESSAGE_IO_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Receiver.h b/qpid/cpp/include/qpid/messaging/Receiver.h new file mode 100644 index 0000000000..6c6fdaa7cb --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Receiver.h @@ -0,0 +1,150 @@ +#ifndef QPID_MESSAGING_RECEIVER_H +#define QPID_MESSAGING_RECEIVER_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/exceptions.h" +#include "qpid/messaging/Handle.h" +#include "qpid/messaging/Duration.h" + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif + +class Address; +class Message; +class ReceiverImpl; +class Session; + +/** \ingroup messaging + * Interface through which messages are received. + */ +class QPID_MESSAGING_CLASS_EXTERN Receiver : public qpid::messaging::Handle<ReceiverImpl> +{ + public: + QPID_MESSAGING_EXTERN Receiver(ReceiverImpl* impl = 0); + QPID_MESSAGING_EXTERN Receiver(const Receiver&); + QPID_MESSAGING_EXTERN ~Receiver(); + QPID_MESSAGING_EXTERN Receiver& operator=(const Receiver&); + /** + * Retrieves a message from this receivers local queue, or waits + * for upto the specified timeout for a message to become + * available. + */ + QPID_MESSAGING_EXTERN bool get(Message& message, Duration timeout=Duration::FOREVER); + /** + * Retrieves a message from this receivers local queue, or waits + * for up to the specified timeout for a message to become + * available. + * + * @exception NoMessageAvailable if there is no message to give + * after waiting for the specified timeout, or if the Receiver is + * closed, in which case isClose() will be true. + */ + QPID_MESSAGING_EXTERN Message get(Duration timeout=Duration::FOREVER); + /** + * Retrieves a message for this receivers subscription or waits + * for up to the specified timeout for one to become + * available. Unlike get() this method will check with the server + * that there is no message for the subscription this receiver is + * serving before returning false. + * + * @return false if there is no message to give after + * waiting for the specified timeout, or if the Receiver is + * closed, in which case isClose() will be true. + */ + QPID_MESSAGING_EXTERN bool fetch(Message& message, Duration timeout=Duration::FOREVER); + /** + * Retrieves a message for this receivers subscription or waits + * for up to the specified timeout for one to become + * available. Unlike get() this method will check with the server + * that there is no message for the subscription this receiver is + * serving before throwing an exception. + * + * @exception NoMessageAvailable if there is no message to give + * after waiting for the specified timeout, or if the Receiver is + * closed, in which case isClose() will be true. + */ + QPID_MESSAGING_EXTERN Message fetch(Duration timeout=Duration::FOREVER); + /** + * Sets the capacity for the receiver. The capacity determines how + * many incoming messages can be held in the receiver before being + * requested by a client via fetch() (or pushed to a listener). + */ + QPID_MESSAGING_EXTERN void setCapacity(uint32_t); + /** + * @return the capacity of the receiver. The capacity determines + * how many incoming messages can be held in the receiver before + * being requested by a client via fetch() (or pushed to a + * listener). + */ + QPID_MESSAGING_EXTERN uint32_t getCapacity(); + /** + * @return the number of messages received and waiting to be + * fetched. + */ + QPID_MESSAGING_EXTERN uint32_t getAvailable(); + /** + * @return a count of the number of messages received on this + * receiver that have been acknowledged, but for which that + * acknowledgement has not yet been confirmed as processed by the + * server. + */ + QPID_MESSAGING_EXTERN uint32_t getUnsettled(); + + /** + * Cancels this receiver. + */ + QPID_MESSAGING_EXTERN void close(); + + /** + * Return true if the receiver was closed by a call to close() + */ + QPID_MESSAGING_EXTERN bool isClosed() const; + + /** + * Returns the name of this receiver. + */ + QPID_MESSAGING_EXTERN const std::string& getName() const; + + /** + * Returns a handle to the session associated with this receiver. + */ + QPID_MESSAGING_EXTERN Session getSession() const; + + /** + * Returns an address for this receiver. + */ + QPID_MESSAGING_EXTERN Address getAddress() const; + +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Receiver>; +#endif +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_RECEIVER_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Sender.h b/qpid/cpp/include/qpid/messaging/Sender.h new file mode 100644 index 0000000000..9c7bca1905 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Sender.h @@ -0,0 +1,105 @@ +#ifndef QPID_MESSAGING_SENDER_H +#define QPID_MESSAGING_SENDER_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/Handle.h" +#include "qpid/sys/IntegerTypes.h" + +#include <string> + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif +class Address; +class Message; +class SenderImpl; +class Session; +/** \ingroup messaging + * Interface through which messages are sent. + */ +class QPID_MESSAGING_CLASS_EXTERN Sender : public qpid::messaging::Handle<SenderImpl> +{ + public: + QPID_MESSAGING_EXTERN Sender(SenderImpl* impl = 0); + QPID_MESSAGING_EXTERN Sender(const Sender&); + QPID_MESSAGING_EXTERN ~Sender(); + QPID_MESSAGING_EXTERN Sender& operator=(const Sender&); + + /** + * Sends a message + * + * @param message the message to send + * @param sync if true the call will block until the server + * confirms receipt of the messages; if false will only block for + * available capacity (i.e. pending == capacity) + */ + QPID_MESSAGING_EXTERN void send(const Message& message, bool sync=false); + QPID_MESSAGING_EXTERN void close(); + + /** + * Sets the capacity for the sender. The capacity determines how + * many outgoing messages can be held pending confirmation of + * receipt by the broker. + */ + QPID_MESSAGING_EXTERN void setCapacity(uint32_t); + /** + * Returns the capacity of the sender. + * @see setCapacity + */ + QPID_MESSAGING_EXTERN uint32_t getCapacity(); + /** + * Returns the number of sent messages pending confirmation of + * receipt by the broker. (These are the 'in-doubt' messages). + */ + QPID_MESSAGING_EXTERN uint32_t getUnsettled(); + /** + * Returns the number of messages for which there is available + * capacity. + */ + QPID_MESSAGING_EXTERN uint32_t getAvailable(); + /** + * Returns the name of this sender. + */ + QPID_MESSAGING_EXTERN const std::string& getName() const; + + /** + * Returns a handle to the session associated with this sender. + */ + QPID_MESSAGING_EXTERN Session getSession() const; + + /** + * Returns an address for this sender. + */ + QPID_MESSAGING_EXTERN Address getAddress() const; +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Sender>; +#endif +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_SENDER_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Session.h b/qpid/cpp/include/qpid/messaging/Session.h new file mode 100644 index 0000000000..999af7c65b --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Session.h @@ -0,0 +1,221 @@ +#ifndef QPID_MESSAGING_SESSION_H +#define QPID_MESSAGING_SESSION_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/exceptions.h" +#include "qpid/messaging/Duration.h" +#include "qpid/messaging/Handle.h" + +#include <string> + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif +class Address; +class Connection; +class Message; +class Sender; +class Receiver; +class SessionImpl; + +/** \ingroup messaging + * A session represents a distinct 'conversation' which can involve + * sending and receiving messages to and from different addresses. + */ +class QPID_MESSAGING_CLASS_EXTERN Session : public qpid::messaging::Handle<SessionImpl> +{ + public: + QPID_MESSAGING_EXTERN Session(SessionImpl* impl = 0); + QPID_MESSAGING_EXTERN Session(const Session&); + QPID_MESSAGING_EXTERN ~Session(); + QPID_MESSAGING_EXTERN Session& operator=(const Session&); + + /** + * Closes a session and all associated senders and receivers. An + * opened session should be closed before the last handle to it + * goes out of scope. All a connections sessions can be closed by + * a call to Connection::close(). + */ + QPID_MESSAGING_EXTERN void close(); + + /** + * Commits the sessions transaction. + * + * @exception TransactionAborted if the transaction was rolled back due to an error. + * @exception TransactionUnknown if the connection was lost and the transaction outcome is unknown. + * forcing an automatic rollback. + */ + QPID_MESSAGING_EXTERN void commit(); + QPID_MESSAGING_EXTERN void rollback(); + + /** + * Acknowledges all outstanding messages that have been received + * by the application on this session. + * + * @param sync if true, blocks until the acknowledgement has been + * processed by the server + */ + QPID_MESSAGING_EXTERN void acknowledge(bool sync=false); + /** + * Acknowledges the specified message. + */ + QPID_MESSAGING_EXTERN void acknowledge(Message&, bool sync=false); + /** + * Acknowledges all message up to the specified message. + */ + QPID_MESSAGING_EXTERN void acknowledgeUpTo(Message&, bool sync=false); + /** + * Rejects the specified message. The broker does not redeliver a + * message that has been rejected. Once a message has been + * acknowledged, it can no longer be rejected. + */ + QPID_MESSAGING_EXTERN void reject(Message&); + /** + * Releases the specified message. The broker may redeliver the + * message. Once a message has been acknowledged, it can no longer + * be released. + */ + QPID_MESSAGING_EXTERN void release(Message&); + + /** + * Request synchronisation with the server. + * + * @param block if true, this call will block until the server + * confirms completion of all pending operations; if false the + * call will request notification from the server but will return + * before receiving it. + */ + QPID_MESSAGING_EXTERN void sync(bool block=true); + + /** + * Returns the total number of messages received and waiting to be + * fetched by all Receivers belonging to this session. This is the + * total number of available messages across all receivers on this + * session. + */ + QPID_MESSAGING_EXTERN uint32_t getReceivable(); + /** + * Returns a count of the number of messages received this session + * that have been acknowledged, but for which that acknowledgement + * has not yet been confirmed as processed by the server. + */ + QPID_MESSAGING_EXTERN uint32_t getUnsettledAcks(); + /** + * Retrieves the receiver for the next available message. If there + * are no available messages at present the call will block for up + * to the specified timeout waiting for one to arrive. Returns + * true if a message was available at the point of return, in + * which case the passed in receiver reference will be set to the + * receiver for that message or false if no message was available. + */ + QPID_MESSAGING_EXTERN bool nextReceiver(Receiver&, Duration timeout=Duration::FOREVER); + /** + * Returns the receiver for the next available message. If there + * are no available messages at present the call will block for up + * to the specified timeout waiting for one to arrive. + * + * @exception Receiver::NoMessageAvailable if no message became + * available in time. + */ + QPID_MESSAGING_EXTERN Receiver nextReceiver(Duration timeout=Duration::FOREVER); + + /** + * Create a new sender through which messages can be sent to the + * specified address. + * + * @exception ResolutionError if there is an error in resolving + * the address + */ + QPID_MESSAGING_EXTERN Sender createSender(const Address& address); + /** + * Create a new sender through which messages can be sent to the + * specified address. + * + * @exception ResolutionError if there is an error in resolving + * the address + * + * @exception MalformedAddress if the syntax of address is not + * valid + */ + QPID_MESSAGING_EXTERN Sender createSender(const std::string& address); + + /** + * Create a new receiver through which messages can be received + * from the specified address. + * + * @exception ResolutionError if there is an error in resolving + * the address + */ + QPID_MESSAGING_EXTERN Receiver createReceiver(const Address& address); + /** + * Create a new receiver through which messages can be received + * from the specified address. + * + * @exception ResolutionError if there is an error in resolving + * the address + * + * @exception MalformedAddress if the syntax of address is not + * valid + */ + QPID_MESSAGING_EXTERN Receiver createReceiver(const std::string& address); + + /** + * Returns the sender with the specified name. + * @exception KeyError if there is none for that name. + */ + QPID_MESSAGING_EXTERN Sender getSender(const std::string& name) const; + /** + * Returns the receiver with the specified name. + * @exception KeyError if there is none for that name. + */ + QPID_MESSAGING_EXTERN Receiver getReceiver(const std::string& name) const; + /** + * Returns a handle to the connection this session is associated + * with. + */ + QPID_MESSAGING_EXTERN Connection getConnection() const; + + /** + * @returns true if the session has been rendered invalid by some + * exception, false if it is valid for use. + */ + QPID_MESSAGING_EXTERN bool hasError(); + /** + * If the session has been rendered invalid by some exception, + * this method will result in that exception being thrown on + * calling this method. + */ + QPID_MESSAGING_EXTERN void checkError(); + +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Session>; +#endif +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_SESSION_H*/ diff --git a/qpid/cpp/include/qpid/messaging/exceptions.h b/qpid/cpp/include/qpid/messaging/exceptions.h new file mode 100644 index 0000000000..04d4d818f7 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/exceptions.h @@ -0,0 +1,247 @@ +#ifndef QPID_MESSAGING_EXCEPTIONS_H +#define QPID_MESSAGING_EXCEPTIONS_H + +/* + * + * 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 "qpid/messaging/ImportExport.h" +#include "qpid/types/Exception.h" +#include "qpid/types/Variant.h" + +namespace qpid { +namespace messaging { + +/** \ingroup messaging + */ + +/** + * This is the base class for all messaging related exceptions thrown + * by this API. + */ +struct QPID_MESSAGING_CLASS_EXTERN MessagingException : public qpid::types::Exception +{ + QPID_MESSAGING_EXTERN MessagingException(const std::string& msg); + QPID_MESSAGING_EXTERN virtual ~MessagingException() throw(); +}; + +/** + * Thrown when the syntax of the option string used to configure a + * connection in not valid + */ +struct QPID_MESSAGING_CLASS_EXTERN InvalidOptionString : public MessagingException +{ + QPID_MESSAGING_EXTERN InvalidOptionString(const std::string& msg); +}; + +/** + * Thrown to indicate a failed lookup of some local object. For + * example when attempting to retrieve a session, sender or receiver + * by name. + */ +struct QPID_MESSAGING_CLASS_EXTERN KeyError : public MessagingException +{ + QPID_MESSAGING_EXTERN KeyError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN LinkError : public MessagingException +{ + QPID_MESSAGING_EXTERN LinkError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN AddressError : public LinkError +{ + QPID_MESSAGING_EXTERN AddressError(const std::string&); +}; + +/** + * Thrown when a syntactically correct address cannot be resolved or + * used. + */ +struct QPID_MESSAGING_CLASS_EXTERN ResolutionError : public AddressError +{ + QPID_MESSAGING_EXTERN ResolutionError(const std::string& msg); +}; + +/** + * Thrown when creating a sender or receiver for an address for which + * some asserted property of the node is not matched. + */ +struct QPID_MESSAGING_CLASS_EXTERN AssertionFailed : public ResolutionError +{ + QPID_MESSAGING_EXTERN AssertionFailed(const std::string& msg); +}; + +/** + * Thrown on attempts to create a sender or receiver to a non-existent + * node. + */ +struct QPID_MESSAGING_CLASS_EXTERN NotFound : public ResolutionError +{ + QPID_MESSAGING_EXTERN NotFound(const std::string& msg); +}; + +/** + * Thrown when an address string with invalid syntax is used. + */ +struct QPID_MESSAGING_CLASS_EXTERN MalformedAddress : public AddressError +{ + QPID_MESSAGING_EXTERN MalformedAddress(const std::string& msg); +}; + +struct QPID_MESSAGING_CLASS_EXTERN ReceiverError : public LinkError +{ + QPID_MESSAGING_EXTERN ReceiverError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN FetchError : public ReceiverError +{ + QPID_MESSAGING_EXTERN FetchError(const std::string&); +}; + +/** + * Thrown by Receiver::fetch(), Receiver::get() and + * Session::nextReceiver() to indicate that there no message was + * available before the timeout specified. + */ +struct QPID_MESSAGING_CLASS_EXTERN NoMessageAvailable : public FetchError +{ + QPID_MESSAGING_EXTERN NoMessageAvailable(); +}; + +struct QPID_MESSAGING_CLASS_EXTERN SenderError : public LinkError +{ + QPID_MESSAGING_EXTERN SenderError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN SendError : public SenderError +{ + QPID_MESSAGING_EXTERN SendError(const std::string&); +}; + +/** + * Thrown on a synchronous send to indicate that the message being + * sent was rejected. + */ +struct QPID_MESSAGING_CLASS_EXTERN MessageRejected : public SendError +{ + QPID_MESSAGING_EXTERN MessageRejected(const std::string&); +}; + +/** + * Thrown to indicate that the sender attempted to send a message that + * would result in the target node on the peer exceeding a + * preconfigured capacity. + */ +struct QPID_MESSAGING_CLASS_EXTERN TargetCapacityExceeded : public SendError +{ + QPID_MESSAGING_EXTERN TargetCapacityExceeded(const std::string&); +}; + +/** + * Thrown to indicate that the locally configured sender capacity has + * been reached, and thus no further messages can be put on the replay + * buffer. + */ +struct QPID_MESSAGING_CLASS_EXTERN OutOfCapacity : public SendError +{ + QPID_MESSAGING_EXTERN OutOfCapacity(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN SessionError : public MessagingException +{ + QPID_MESSAGING_EXTERN SessionError(const std::string&); +}; + +/** + * Thrown to indicate that the sesion was closed by this client (probably in + * a different thread) whilst we were waiting on it. This is not really an + * error condition but there is no other way to return this. + */ +struct QPID_MESSAGING_CLASS_EXTERN SessionClosed : public SessionError +{ + QPID_MESSAGING_EXTERN SessionClosed(); +}; + +/** Base class for transactional errors */ +struct QPID_MESSAGING_CLASS_EXTERN TransactionError : public SessionError +{ + QPID_MESSAGING_EXTERN TransactionError(const std::string&); +}; + +/** + * The transaction was automatically rolled back. This could be due to an error + * on the broker, such as a store failure, or a connection failure during the + * transaction + */ +struct QPID_MESSAGING_CLASS_EXTERN TransactionAborted : public TransactionError +{ + QPID_MESSAGING_EXTERN TransactionAborted(const std::string&); +}; + +/** + * The outcome of the transaction on the broker, commit or roll-back, is not + * known. This occurs when the connection fails after we sent the commit but + * before we received a result. + */ +struct QPID_MESSAGING_CLASS_EXTERN TransactionUnknown : public TransactionError +{ + QPID_MESSAGING_EXTERN TransactionUnknown(const std::string&); +}; + +/** + * Thrown to indicate that the application attempted to do something + * for which it was not authorised by its peer. + */ +struct QPID_MESSAGING_CLASS_EXTERN UnauthorizedAccess : public SessionError +{ + QPID_MESSAGING_EXTERN UnauthorizedAccess(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN ConnectionError : public MessagingException +{ + QPID_MESSAGING_EXTERN ConnectionError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN ProtocolVersionError : public ConnectionError +{ + QPID_MESSAGING_EXTERN ProtocolVersionError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN AuthenticationFailure : public ConnectionError +{ + QPID_MESSAGING_EXTERN AuthenticationFailure(const std::string&); +}; + +/** + * Thrown to indicate loss of underlying connection. When + * auto-reconnect is used this will be caught by the library and used + * to trigger reconnection attempts. If reconnection fails (according + * to whatever settings have been configured), then an instnace of + * this class will be thrown to signal that. + */ +struct QPID_MESSAGING_CLASS_EXTERN TransportFailure : public MessagingException +{ + QPID_MESSAGING_EXTERN TransportFailure(const std::string&); +}; + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_EXCEPTIONS_H*/ diff --git a/qpid/cpp/include/qpid/qpid.i b/qpid/cpp/include/qpid/qpid.i new file mode 100644 index 0000000000..70f4ce8105 --- /dev/null +++ b/qpid/cpp/include/qpid/qpid.i @@ -0,0 +1,103 @@ +/* + * 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. + */ + +/* + * Need some magic to wrap getContentPtr, otherwise it could return char * + * containing NULL, which would be incorrectly interpreted as end of string + */ +%extend qpid::messaging::Message +{ + mystr getContentPtr() + { + mystr s; + s.ptr = self->getContentPtr(); + s.len = self->getContentSize(); + return s; + } +} +%ignore qpid::messaging::Message::getContentPtr; +%typemap(out,fragment="SWIG_FromCharPtrAndSize") (mystr) { + %append_output(SWIG_FromCharPtrAndSize($1.ptr, $1.len)); +} + +%{ + +struct mystr +{ + size_t len; + const char *ptr; +}; + +#include <qpid/messaging/exceptions.h> +#include <qpid/messaging/Address.h> +#include <qpid/messaging/Connection.h> +#include <qpid/messaging/Session.h> +#include <qpid/messaging/Receiver.h> +#include <qpid/messaging/Sender.h> +#include <qpid/messaging/Message.h> +#include <qpid/messaging/Duration.h> +#include <qpid/messaging/FailoverUpdates.h> +#include <qpid/messaging/Logger.h> + +// +// Wrapper functions for map-decode and list-decode. This allows us to avoid +// the complexity of output parameter mapping. +// +qpid::types::Variant::Map& decodeMap(const qpid::messaging::Message& msg) { + static qpid::types::Variant::Map map; + map.clear(); + qpid::messaging::decode(msg, map); + return map; +} + +qpid::types::Variant::List& decodeList(const qpid::messaging::Message& msg) { + static qpid::types::Variant::List list; + list.clear(); + qpid::messaging::decode(msg, list); + return list; +} + +%} + +%include <qpid/ImportExport.h> +%include <qpid/messaging/ImportExport.h> +%include <qpid/messaging/Address.h> +%include <qpid/messaging/Duration.h> +%include <qpid/messaging/Message.h> +%include <qpid/messaging/Receiver.h> +%include <qpid/messaging/Sender.h> +%include <qpid/messaging/Session.h> +%include <qpid/messaging/Connection.h> +%include <qpid/messaging/FailoverUpdates.h> +%include <qpid/messaging/Logger.h> + +qpid::types::Variant::Map& decodeMap(const qpid::messaging::Message&); +qpid::types::Variant::List& decodeList(const qpid::messaging::Message&); + + +%{ + +%}; + +%extend qpid::messaging::Duration { + qpid::messaging::Duration __mul__(uint64_t multiplier) { + return qpid::messaging::Duration(self->getMilliseconds() * multiplier); + } +}; + diff --git a/qpid/cpp/include/qpid/swig_perl_typemaps.i b/qpid/cpp/include/qpid/swig_perl_typemaps.i new file mode 100644 index 0000000000..e1fa908f9f --- /dev/null +++ b/qpid/cpp/include/qpid/swig_perl_typemaps.i @@ -0,0 +1,343 @@ +/* + * 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. + */ + +%newobject VariantToPerl; +%wrapper %{ + +#include <stdarg.h> + + SV* MapToPerl(const qpid::types::Variant::Map*); + SV* ListToPerl(const qpid::types::Variant::List*); + void PerlToMap(SV*, qpid::types::Variant::Map*); + void PerlToList(SV*, qpid::types::Variant::List*); + + qpid::types::Variant PerlToVariant(SV* value) { + if (SvROK(value)) { + if (SvTYPE(SvRV(value)) == SVt_PVHV) { + qpid::types::Variant::Map map; + PerlToMap(value, &map); + return qpid::types::Variant(map); + } + else if (SvTYPE(SvRV(value)) == SVt_PVAV) { + qpid::types::Variant::List list; + PerlToList(value, &list); + return qpid::types::Variant(list); + } + } + else { + if (SvIOK(value)) { + return qpid::types::Variant((int64_t) SvIV(value)); + } + else if (SvNOK(value)) { + return qpid::types::Variant((double)SvNV(value)); + } + else if (SvPOK(value)) { + STRLEN len; + char *ptr = SvPV(value, len); + qpid::types::Variant v = qpid::types::Variant(std::string(ptr,len)); + if (SvUTF8(value)) { + v.setEncoding("utf8"); + } + return v; + } + } + return qpid::types::Variant(); + } + + SV* VariantToPerl(const qpid::types::Variant* v) { + SV* result = 0; + try { + switch (v->getType()) { + case qpid::types::VAR_VOID: { + result = newSViv(0); + break; + } + case qpid::types::VAR_BOOL : { + result = boolSV(v->asBool()); + break; + } + case qpid::types::VAR_UINT8 : + case qpid::types::VAR_UINT16 : + case qpid::types::VAR_UINT32 : { + result = newSVuv((UV)v->asUint32()); + break; + } + case qpid::types::VAR_UINT64 : { + result = newSVuv((UV)v->asUint64()); + break; + } + case qpid::types::VAR_INT8 : + case qpid::types::VAR_INT16 : + case qpid::types::VAR_INT32 : { + result = newSViv((IV)v->asInt32()); + break; + } + case qpid::types::VAR_INT64 : { + result = newSViv((IV)v->asInt64()); + break; + } + case qpid::types::VAR_FLOAT : { + result = newSVnv((double)v->asFloat()); + break; + } + case qpid::types::VAR_DOUBLE : { + result = newSVnv((double)v->asDouble()); + break; + } + case qpid::types::VAR_STRING : { + const std::string val(v->asString()); + result = newSVpvn(val.c_str(), val.size()); + if( v->getEncoding() == "utf8" ) { + SvUTF8_on(result); + } + break; + } + case qpid::types::VAR_MAP : { + result = MapToPerl(&(v->asMap())); + break; + } + case qpid::types::VAR_LIST : { + result = ListToPerl(&(v->asList())); + break; + } + case qpid::types::VAR_UUID : { + } + } + } catch (qpid::types::Exception& ex) { + Perl_croak(aTHX_ "%s", ex.what()); + } + + if (!result) + result = newSV(0); + + return result; + } + + SV* MapToPerl(const qpid::types::Variant::Map* map) { + HV *hv = newHV(); + qpid::types::Variant::Map::const_iterator iter; + for (iter = map->begin(); iter != map->end(); iter++) { + const std::string key(iter->first); + SV* perlval = VariantToPerl(&(iter->second)); + hv_store(hv, key.c_str(), key.size(), perlval, 0); + } + return newRV_noinc((SV *)hv); + } + + SV* ListToPerl(const qpid::types::Variant::List* list) { + AV* av = newAV(); + qpid::types::Variant::List::const_iterator iter; + for (iter = list->begin(); iter != list->end(); iter++) { + SV* perlval = VariantToPerl(&(*iter)); + av_push(av, perlval); + } + return newRV_noinc((SV *)av); + } + + void PerlToMap(SV* hash, qpid::types::Variant::Map* map) { + map->clear(); + HV* hv = (HV *)SvRV(hash); + HE* he; + while((he = hv_iternext(hv)) != NULL) { + SV* svkey = HeSVKEY_force(he); + SV* svval = HeVAL(he); + (*map)[std::string(SvPV_nolen(svkey))] = PerlToVariant(svval); + } + } + + void PerlToList(SV* ary, qpid::types::Variant::List* list) { + list->clear(); + AV * av = (AV *)SvRV(ary); + I32 len = av_len(av) + 1; + if (len > 0) { + for (I32 i = 0; i < len; i++) { + list->push_back(PerlToVariant(*av_fetch(av, i, 0))); + } + } + } +%} + +%typemap (in) void * { + $1 = (void *)SvIV($input); +} + +%typemap (out) void * { + sv_setiv($result, (IV)$1); + argvi++; +} + +%typemap (in) uint8_t, uint16_t, uint32_t, uint64_t { + if (SvIOK($input)) { + $1 = ($1_ltype)SvUV($input); + } + else { + SWIG_exception_fail(SWIG_ValueError, "not an integer"); + } +} + +%typemap (out) uint8_t, uint16_t, uint32_t, uint64_t { + SV* tmp = sv_newmortal(); + sv_setuv(tmp, (UV)$1); + $result = tmp; + argvi++; +} + +%typemap (in) int8_t, int16_t, int32_t, int64_t { + if (SvIOK($input)) { + $1 = ($1_ltype)SvIV($input); + } + else { + SWIG_exception_fail(SWIG_ValueError, "not an integer"); + } +} + +%typemap (out) int8_t, int16_t, int32_t, int64_t { + SV* tmp = sv_newmortal(); + sv_setiv(tmp, (IV)$1); + $result = tmp; + argvi++; +} + +%typemap(in) bool { + $1 = (bool)SvTRUE($input); +} + +%typemap (out) bool { + $result = boolSV($1); + argvi++; +} + + +%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT64) uint64_t { + $1 = SvIOK($input) ? 1 : 0; +} + +%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT32) uint32_t { + $1 = SvIOK($input) ? 1 : 0; +} + + +/* + * Variant types: C++ --> Perl + */ +%typemap(out) qpid::types::Variant::Map { + $result = sv_2mortal(MapToPerl(&$1)); + argvi++; +} + +%typemap(out) qpid::types::Variant::Map& { + $result = sv_2mortal(MapToPerl($1)); + argvi++; +} + +%typemap(out) qpid::types::Variant::List { + $result = sv_2mortal(ListToPerl(&$1)); + argvi++; +} + +%typemap(out) qpid::types::Variant::List& { + $result = sv_2mortal(ListToPerl($1)); + argvi++; +} + +%typemap(out) qpid::types::Variant& { + $result = sv_2mortal(VariantToPerl($1)); + argvi++; +} + + +/* + * Variant types: Perl --> C++ + */ +%typemap(in) qpid::types::Variant& { + $1 = new qpid::types::Variant(PerlToVariant($input)); +} + +%typemap(in) qpid::types::Variant::Map& { + $1 = new qpid::types::Variant::Map(); + PerlToMap($input, $1); + +} + +%typemap(in) qpid::types::Variant::List& { + $1 = new qpid::types::Variant::List(); + PerlToList($input, $1); + +} + +%typemap(in) const qpid::types::Variant::Map const & { + $1 = new qpid::types::Variant::Map(); + PerlToMap($input, $1); +} + +%typemap(in) const qpid::types::Variant::List const & { + $1 = new qpid::types::Variant::List(); + PerlToList($input, $1); +} + +%typemap(freearg) qpid::types::Variant& { + delete $1; +} + +%typemap(freearg) qpid::types::Variant::Map& { + delete $1; +} + +%typemap(freearg) qpid::types::Variant::List& { + delete $1; +} + + +/* + * Variant types: typecheck maps + */ +%typemap(typecheck) qpid::types::Variant::Map& { + $1 = (SvTYPE(SvRV($input)) == SVt_PVHV) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List& { + $1 = (SvTYPE(SvRV($input)) == SVt_PVAV) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant& { + $1 = (SvIOK($input) || + SvNOK($input) || + SvPOK($input) ) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant::Map const & { + $1 = (SvTYPE(SvRV($input)) == SVt_PVHV) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant::List const & { + $1 = (SvTYPE(SvRV($input)) == SVt_PVAV) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant const & { + $1 = (SvIOK($input) || + SvNOK($input) || + SvPOK($input) ) ? 1 : 0; +} + +/* No boolean type for perl. + Boolean is simply and integer in perl +*/ +%typecheck(SWIG_TYPECHECK_BOOL) bool { + $1 = (SvIOK($input)) ? 1 : 0; +} diff --git a/qpid/cpp/include/qpid/swig_python_typemaps.i b/qpid/cpp/include/qpid/swig_python_typemaps.i new file mode 100644 index 0000000000..52b0d978dc --- /dev/null +++ b/qpid/cpp/include/qpid/swig_python_typemaps.i @@ -0,0 +1,465 @@ +/* + * 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. + */ + +/* For UUID objects, to convert them to Python uuid.UUID objects, + * we'll need a reference to the uuid module. + */ +%{ +static PyObject* pUuidModule; +%} + +%init %{ + /* Instead of directly referencing the uuid module (which is not available + * on older versions of Python), reference the wrapper defined in + * qpid.datatypes. + */ + pUuidModule = PyImport_ImportModule("qpid.datatypes"); + if (pUuidModule) { + /* Although it is not required, we'll publish the uuid module in our + * module, as if this module was a python module and we called + * "import uuid" + */ + Py_INCREF(pUuidModule); + PyModule_AddObject(m, "uuid", pUuidModule); + } else { + if (!PyErr_Occurred()) PyErr_SetString(PyExc_ImportError, "Cannot import qpid.datatypes"); + } +%} + + +%wrapper %{ + +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + + + PyObject* MapToPy(const qpid::types::Variant::Map*); + PyObject* ListToPy(const qpid::types::Variant::List*); + PyObject* UuidToPy(const qpid::types::Uuid*); + void PyToMap(PyObject*, qpid::types::Variant::Map*); + void PyToList(PyObject*, qpid::types::Variant::List*); + + qpid::types::Variant PyToVariant(PyObject* value) { + if (PyBool_Check(value)) return qpid::types::Variant(bool(PyInt_AS_LONG(value) ? true : false)); + if (PyFloat_Check(value)) return qpid::types::Variant(PyFloat_AS_DOUBLE(value)); + if (PyInt_Check(value)) return qpid::types::Variant(int64_t(PyInt_AS_LONG(value))); + if (PyLong_Check(value)) return qpid::types::Variant(int64_t(PyLong_AsLongLong(value))); + if (PyString_Check(value)) return qpid::types::Variant(std::string(PyString_AS_STRING(value))); + if (PyUnicode_Check(value)) { + qpid::types::Variant v(std::string(PyUnicode_AS_DATA(value))); + v.setEncoding("utf8"); + return v; + } + if (PyDict_Check(value)) { + qpid::types::Variant::Map map; + PyToMap(value, &map); + return qpid::types::Variant(map); + } + if (PyList_Check(value)) { + qpid::types::Variant::List list; + PyToList(value, &list); + return qpid::types::Variant(list); + } + return qpid::types::Variant(); + } + + PyObject* VariantToPy(const qpid::types::Variant* v) { + PyObject* result; + try { + switch (v->getType()) { + case qpid::types::VAR_VOID: { + result = Py_None; + Py_INCREF(result); + break; + } + case qpid::types::VAR_BOOL : { + result = v->asBool() ? Py_True : Py_False; + break; + } + case qpid::types::VAR_UINT8 : + case qpid::types::VAR_UINT16 : + case qpid::types::VAR_UINT32 : { + result = PyInt_FromLong((long) v->asUint32()); + break; + } + case qpid::types::VAR_UINT64 : { + result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) v->asUint64()); + break; + } + case qpid::types::VAR_INT8 : + case qpid::types::VAR_INT16 : + case qpid::types::VAR_INT32 : { + result = PyInt_FromLong((long) v->asInt32()); + break; + } + case qpid::types::VAR_INT64 : { + result = PyLong_FromLongLong((PY_LONG_LONG) v->asInt64()); + break; + } + case qpid::types::VAR_FLOAT : { + result = PyFloat_FromDouble((double) v->asFloat()); + break; + } + case qpid::types::VAR_DOUBLE : { + result = PyFloat_FromDouble((double) v->asDouble()); + break; + } + case qpid::types::VAR_STRING : { + const std::string val(v->asString()); + if (v->getEncoding() == "utf8") + result = PyUnicode_DecodeUTF8(val.c_str(), val.size(), NULL); + else + result = PyString_FromStringAndSize(val.c_str(), val.size()); + break; + } + case qpid::types::VAR_MAP : { + result = MapToPy(&(v->asMap())); + break; + } + case qpid::types::VAR_LIST : { + result = ListToPy(&(v->asList())); + break; + } + case qpid::types::VAR_UUID : { + qpid::types::Uuid uuid = v->asUuid(); + result = UuidToPy(&uuid); + break; + } + } + } catch (qpid::types::Exception& ex) { + PyErr_SetString(PyExc_RuntimeError, ex.what()); + result = 0; + } + + return result; + } + + PyObject* MapToPy(const qpid::types::Variant::Map* map) { + PyObject* result = PyDict_New(); + qpid::types::Variant::Map::const_iterator iter; + for (iter = map->begin(); iter != map->end(); iter++) { + const std::string key(iter->first); + PyObject* pyval = VariantToPy(&(iter->second)); + if (pyval == 0) + return 0; + PyDict_SetItem(result, PyString_FromStringAndSize(key.c_str(), key.size()), pyval); + } + return result; + } + + PyObject* ListToPy(const qpid::types::Variant::List* list) { + PyObject* result = PyList_New(list->size()); + qpid::types::Variant::List::const_iterator iter; + Py_ssize_t idx(0); + for (iter = list->begin(); iter != list->end(); iter++) { + PyObject* pyval = VariantToPy(&(*iter)); + if (pyval == 0) + return 0; + PyList_SetItem(result, idx, pyval); + idx++; + } + return result; + } + + PyObject* UuidToPy(const qpid::types::Uuid * uuid) { + PyObject* pUuidClass = PyObject_GetAttrString(pUuidModule, "UUID"); + if (!pUuidClass) { + // Failed to get UUID class + return 0; + } + + PyObject* pArgs = PyTuple_New(0); + PyObject* pKw = PyDict_New(); + PyObject* pData = PyString_FromStringAndSize( + (const char*)(uuid->data()), 16); + PyDict_SetItemString(pKw, "bytes", pData); + + PyObject* result = PyObject_Call(pUuidClass, pArgs, pKw); + + Py_DECREF(pData); + Py_DECREF(pKw); + Py_DECREF(pArgs); + Py_DECREF(pUuidClass); + + return result; + } + + + void PyToMap(PyObject* obj, qpid::types::Variant::Map* map) { + map->clear(); + Py_ssize_t iter(0); + PyObject *key; + PyObject *val; + while (PyDict_Next(obj, &iter, &key, &val)) + (*map)[std::string(PyString_AS_STRING(key))] = PyToVariant(val); + } + + void PyToList(PyObject* obj, qpid::types::Variant::List* list) { + list->clear(); + Py_ssize_t count(PyList_Size(obj)); + for (Py_ssize_t idx = 0; idx < count; idx++) + list->push_back(PyToVariant(PyList_GetItem(obj, idx))); + } + +%} + + +/* unsigned32 Convert from Python --> C */ +%typemap(in) uint32_t { + if (PyInt_Check($input)) { + $1 = (uint32_t) PyInt_AsUnsignedLongMask($input); + } else if (PyLong_Check($input)) { + $1 = (uint32_t) PyLong_AsUnsignedLong($input); + } else { + SWIG_exception_fail(SWIG_ValueError, "unknown integer type"); + } +} + +/* unsinged32 Convert from C --> Python */ +%typemap(out) uint32_t { + $result = PyInt_FromLong((long)$1); +} + + +/* unsigned16 Convert from Python --> C */ +%typemap(in) uint16_t { + if (PyInt_Check($input)) { + $1 = (uint16_t) PyInt_AsUnsignedLongMask($input); + } else if (PyLong_Check($input)) { + $1 = (uint16_t) PyLong_AsUnsignedLong($input); + } else { + SWIG_exception_fail(SWIG_ValueError, "unknown integer type"); + } +} + +/* unsigned16 Convert from C --> Python */ +%typemap(out) uint16_t { + $result = PyInt_FromLong((long)$1); +} + + +/* signed32 Convert from Python --> C */ +%typemap(in) int32_t { + if (PyInt_Check($input)) { + $1 = (int32_t) PyInt_AsLong($input); + } else if (PyLong_Check($input)) { + $1 = (int32_t) PyLong_AsLong($input); + } else { + SWIG_exception_fail(SWIG_ValueError, "unknown integer type"); + } +} + +/* signed32 Convert from C --> Python */ +%typemap(out) int32_t { + $result = PyInt_FromLong((long)$1); +} + + +/* unsigned64 Convert from Python --> C */ +%typemap(in) uint64_t { +%#ifdef HAVE_LONG_LONG + if (PyLong_Check($input)) { + $1 = (uint64_t)PyLong_AsUnsignedLongLong($input); + } else if (PyInt_Check($input)) { + $1 = (uint64_t)PyInt_AsUnsignedLongLongMask($input); + } else +%#endif + { + SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - uint64_t input too large"); + } +} + +/* unsigned64 Convert from C --> Python */ +%typemap(out) uint64_t { +%#ifdef HAVE_LONG_LONG + $result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)$1); +%#else + SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - uint64_t output too large"); +%#endif +} + +/* signed64 Convert from Python --> C */ +%typemap(in) int64_t { +%#ifdef HAVE_LONG_LONG + if (PyLong_Check($input)) { + $1 = (int64_t)PyLong_AsLongLong($input); + } else if (PyInt_Check($input)) { + $1 = (int64_t)PyInt_AsLong($input); + } else +%#endif + { + SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - int64_t input too large"); + } +} + +/* signed64 Convert from C --> Python */ +%typemap(out) int64_t { +%#ifdef HAVE_LONG_LONG + $result = PyLong_FromLongLong((PY_LONG_LONG)$1); +%#else + SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - int64_t output too large"); +%#endif +} + + +/* Convert from Python --> C */ +%typemap(in) void * { + $1 = (void *)$input; +} + +/* Convert from C --> Python */ +%typemap(out) void * { + $result = (PyObject *) $1; + Py_INCREF($result); +} + +/* + * Variant types: C++ --> Python + */ +%typemap(out) qpid::types::Variant::Map { + $result = MapToPy(&$1); +} + +%typemap(out) qpid::types::Variant::Map& { + $result = MapToPy($1); +} + +%typemap(out) qpid::types::Variant::List { + $result = ListToPy(&$1); +} + +%typemap(out) qpid::types::Variant::List& { + $result = ListToPy($1); +} + +%typemap(out) qpid::types::Variant& { + $result = VariantToPy($1); +} + +/* + * UUID type: C++ --> Python + */ +%typemap(out) qpid::types::UUID & { + $result = UuidToPy($1); +} + + +/* + * Variant types: Ruby --> C++ + */ +%typemap(in) qpid::types::Variant& { + $1 = new qpid::types::Variant(PyToVariant($input)); +} + +%typemap(in) qpid::types::Variant::Map& { + $1 = new qpid::types::Variant::Map(); + PyToMap($input, $1); +} + +%typemap(in) qpid::types::Variant::List& { + $1 = new qpid::types::Variant::List(); + PyToList($input, $1); +} + +%typemap(in) const qpid::types::Variant::Map const & { + $1 = new qpid::types::Variant::Map(); + PyToMap($input, $1); +} + +%typemap(in) const qpid::types::Variant::List const & { + $1 = new qpid::types::Variant::List(); + PyToList($input, $1); +} + +%typemap(freearg) qpid::types::Variant& { + delete $1; +} + +%typemap(freearg) qpid::types::Variant::Map& { + delete $1; +} + +%typemap(freearg) qpid::types::Variant::List& { + delete $1; +} + + +/* + * Variant types: typecheck maps + */ +%typemap(typecheck) qpid::types::Variant::Map& { + $1 = PyDict_Check($input) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List& { + $1 = PyList_Check($input) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant& { + $1 = (PyFloat_Check($input) || + PyString_Check($input) || + PyInt_Check($input) || + PyLong_Check($input) || + PyDict_Check($input) || + PyList_Check($input) || + PyBool_Check($input)) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant::Map const & { + $1 = PyDict_Check($input) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant::List const & { + $1 = PyList_Check($input) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant const & { + $1 = (PyFloat_Check($input) || + PyString_Check($input) || + PyInt_Check($input) || + PyLong_Check($input) || + PyDict_Check($input) || + PyList_Check($input) || + PyBool_Check($input)) ? 1 : 0; +} + +%typemap(typecheck) bool { + $1 = PyBool_Check($input) ? 1 : 0; +} + + + +%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT64) uint64_t { + $1 = PyLong_Check($input) ? 1 : 0; +} + +%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT32) uint32_t { + $1 = PyInt_Check($input) ? 1 : 0; +} + + +/** + * argc,argv as python list + */ + +%include <argcargv.i> +%apply (int ARGC, char **ARGV) { (int argc, const char *argv[]) } diff --git a/qpid/cpp/include/qpid/swig_ruby_typemaps.i b/qpid/cpp/include/qpid/swig_ruby_typemaps.i new file mode 100644 index 0000000000..4e07088bce --- /dev/null +++ b/qpid/cpp/include/qpid/swig_ruby_typemaps.i @@ -0,0 +1,368 @@ +/* + * 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. + */ + +%wrapper %{ + +#include <stdarg.h> + + VALUE MapToRb(const qpid::types::Variant::Map*); + VALUE ListToRb(const qpid::types::Variant::List*); + void RbToMap(VALUE, qpid::types::Variant::Map*); + void RbToList(VALUE, qpid::types::Variant::List*); + + qpid::types::Variant RbToVariant(VALUE value) { + switch (TYPE(value)) { + case T_FLOAT: return qpid::types::Variant(NUM2DBL(value)); + case T_STRING: return qpid::types::Variant(StringValuePtr(value)); + case T_FIXNUM: return qpid::types::Variant((int64_t) FIX2LONG(value)); + case T_BIGNUM: return qpid::types::Variant((int64_t) NUM2LL(value)); + case T_TRUE: return qpid::types::Variant(true); + case T_FALSE: return qpid::types::Variant(false); + case T_HASH: { + qpid::types::Variant::Map map; + RbToMap(value, &map); + return qpid::types::Variant(map); + } + case T_ARRAY: { + qpid::types::Variant::List list; + RbToList(value, &list); + return qpid::types::Variant(list); + } + default: return qpid::types::Variant(); + } + } + + VALUE VariantToRb(const qpid::types::Variant* v) { + VALUE result = Qnil; + try { + switch (v->getType()) { + case qpid::types::VAR_VOID: { + result = Qnil; + break; + } + case qpid::types::VAR_BOOL : { + result = v->asBool() ? Qtrue : Qfalse; + break; + } + case qpid::types::VAR_UINT8 : + case qpid::types::VAR_UINT16 : + case qpid::types::VAR_UINT32 : { + result = UINT2NUM(v->asUint32()); + break; + } + case qpid::types::VAR_UINT64 : { + result = ULL2NUM(v->asUint64()); + break; + } + case qpid::types::VAR_INT8 : + case qpid::types::VAR_INT16 : + case qpid::types::VAR_INT32 : { + result = INT2NUM(v->asInt32()); + break; + } + case qpid::types::VAR_INT64 : { + result = LL2NUM(v->asInt64()); + break; + } + case qpid::types::VAR_FLOAT : { + result = rb_float_new((double) v->asFloat()); + break; + } + case qpid::types::VAR_DOUBLE : { + result = rb_float_new(v->asDouble()); + break; + } + case qpid::types::VAR_STRING : { + const std::string val(v->asString()); + result = rb_str_new(val.c_str(), val.size()); + break; + } + case qpid::types::VAR_MAP : { + result = MapToRb(&(v->asMap())); + break; + } + case qpid::types::VAR_LIST : { + result = ListToRb(&(v->asList())); + break; + } + case qpid::types::VAR_UUID : { + } + } + } catch (qpid::types::Exception& ex) { + static VALUE error = rb_define_class("Error", rb_eStandardError); + rb_raise(error, "%s", ex.what()); + } + + return result; + } + + VALUE MapToRb(const qpid::types::Variant::Map* map) { + VALUE result = rb_hash_new(); + qpid::types::Variant::Map::const_iterator iter; + for (iter = map->begin(); iter != map->end(); iter++) { + const std::string key(iter->first); + VALUE rbval = VariantToRb(&(iter->second)); + rb_hash_aset(result, rb_str_new(key.c_str(), key.size()), rbval); + } + return result; + } + + VALUE ListToRb(const qpid::types::Variant::List* list) { + VALUE result = rb_ary_new2(list->size()); + qpid::types::Variant::List::const_iterator iter; + for (iter = list->begin(); iter != list->end(); iter++) { + VALUE rbval = VariantToRb(&(*iter)); + rb_ary_push(result, rbval); + } + return result; + } + + VALUE HashIter(VALUE data_ary, VALUE context) { + VALUE key = rb_ary_entry(data_ary, 0); + VALUE val = rb_ary_entry(data_ary, 1); + qpid::types::Variant::Map* map((qpid::types::Variant::Map*) context); + (*map)[std::string(StringValuePtr(key))] = RbToVariant(val); + return data_ary; + } + + VALUE AryIter(VALUE data, VALUE context) { + qpid::types::Variant::List* list((qpid::types::Variant::List*) context); + list->push_back(RbToVariant(data)); + return data; + } + + void RbToMap(VALUE hash, qpid::types::Variant::Map* map) { + map->clear(); + rb_iterate(rb_each, hash, (VALUE(*)(ANYARGS))HashIter, (VALUE) map); + } + + void RbToList(VALUE ary, qpid::types::Variant::List* list) { + list->clear(); + rb_iterate(rb_each, ary, (VALUE(*)(ANYARGS))AryIter, (VALUE) list); + } +%} + +%typemap (in) void * +{ + $1 = (void *) $input; +} + +%typemap (out) void * +{ + $result = (VALUE) $1; +} + +%typemap (in) uint8_t +{ + $1 = NUM2UINT ($input); +} + +%typemap (out) uint8_t +{ + $result = UINT2NUM((uint8_t) $1); +} + +%typemap (in) int8_t +{ + $1 = NUM2INT ($input); +} + +%typemap (out) int8_t +{ + $result = INT2NUM((int8_t) $1); +} + +%typemap (in) uint16_t +{ + $1 = NUM2UINT ($input); +} + +%typemap (out) uint16_t +{ + $result = UINT2NUM((uint16_t) $1); +} + +%typemap (in) uint32_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2UINT($input); + else + $1 = FIX2UINT($input); +} + +%typemap (out) uint32_t +{ + $result = UINT2NUM((uint32_t) $1); +} + +%typemap (in) int32_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2INT($input); + else + $1 = FIX2INT($input); +} + +%typemap (out) int32_t +{ + $result = INT2NUM((int32_t) $1); +} + +%typemap (typecheck, precedence=SWIG_TYPECHECK_INTEGER) uint32_t { + $1 = FIXNUM_P($input); +} + +%typemap (in) uint64_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2ULL($input); + else + $1 = (uint64_t) FIX2ULONG($input); +} + +%typemap (out) uint64_t +{ + $result = ULL2NUM((uint64_t) $1); +} + +%typemap (in) int64_t +{ + if (TYPE($input) == T_BIGNUM) + $1 = NUM2LL($input); + else + $1 = (int64_t) FIX2LONG($input); +} + +%typemap (out) int64_t +{ + $result = LL2NUM((int64_t) $1); +} + +/* + * Variant types: C++ --> Ruby + */ +%typemap(out) qpid::types::Variant::Map { + $result = MapToRb(&$1); +} + +%typemap(out) qpid::types::Variant::Map& { + $result = MapToRb($1); +} + +%typemap(out) qpid::types::Variant::List { + $result = ListToRb(&$1); +} + +%typemap(out) qpid::types::Variant::List& { + $result = ListToRb($1); +} + +%typemap(out) qpid::types::Variant& { + $result = VariantToRb($1); +} + + +/* + * Variant types: Ruby --> C++ + */ +%typemap(in) qpid::types::Variant& { + $1 = new qpid::types::Variant(RbToVariant($input)); +} + +%typemap(in) qpid::types::Variant::Map& { + $1 = new qpid::types::Variant::Map(); + RbToMap($input, $1); +} + +%typemap(in) qpid::types::Variant::List& { + $1 = new qpid::types::Variant::List(); + RbToList($input, $1); +} + +%typemap(in) const qpid::types::Variant::Map const & { + $1 = new qpid::types::Variant::Map(); + RbToMap($input, $1); +} + +%typemap(in) const qpid::types::Variant::List const & { + $1 = new qpid::types::Variant::List(); + RbToList($input, $1); +} + +%typemap(freearg) qpid::types::Variant& { + delete $1; +} + +%typemap(freearg) qpid::types::Variant::Map& { + delete $1; +} + +%typemap(freearg) qpid::types::Variant::List& { + delete $1; +} + + +/* + * Variant types: typecheck maps + */ +%typemap(typecheck) qpid::types::Variant::Map& { + $1 = (TYPE($input) == T_HASH) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List& { + $1 = (TYPE($input) == T_ARRAY) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant& { + $1 = (TYPE($input) == T_FLOAT || + TYPE($input) == T_STRING || + TYPE($input) == T_FIXNUM || + TYPE($input) == T_BIGNUM || + TYPE($input) == T_TRUE || + TYPE($input) == T_FALSE) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::Map const & { + $1 = (TYPE($input) == T_HASH) ? 1 : 0; +} + +%typemap(typecheck) qpid::types::Variant::List const & { + $1 = (TYPE($input) == T_ARRAY) ? 1 : 0; +} + +%typemap(typecheck) const qpid::types::Variant const & { + $1 = (TYPE($input) == T_FLOAT || + TYPE($input) == T_STRING || + TYPE($input) == T_FIXNUM || + TYPE($input) == T_BIGNUM || + TYPE($input) == T_TRUE || + TYPE($input) == T_FALSE) ? 1 : 0; +} + +%typemap(typecheck) bool { + $1 = (TYPE($input) == T_TRUE || + TYPE($input) == T_FALSE) ? 1 : 0; +} + + + +%typemap (typecheck, precedence=SWIG_TYPECHECK_INTEGER) uint64_t { + $1 = FIXNUM_P($input); +} + diff --git a/qpid/cpp/include/qpid/sys/IntegerTypes.h b/qpid/cpp/include/qpid/sys/IntegerTypes.h new file mode 100755 index 0000000000..75fa921de0 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/IntegerTypes.h @@ -0,0 +1,31 @@ +#ifndef QPID_SYS_INTEGERTYPES_H +#define QPID_SYS_INTEGERTYPES_H + +/* + * 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. + * + */ + +#if (defined(_WINDOWS) || defined (WIN32)) +#include "qpid/sys/windows/IntegerTypes.h" +#endif +#if !defined _WINDOWS && !defined WIN32 +#include "qpid/sys/posix/IntegerTypes.h" +#endif + +#endif /*!QPID_SYS_INTEGERTYPES_H*/ diff --git a/qpid/cpp/include/qpid/sys/posix/IntegerTypes.h b/qpid/cpp/include/qpid/sys/posix/IntegerTypes.h new file mode 100755 index 0000000000..ce97f7bde8 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/IntegerTypes.h @@ -0,0 +1,26 @@ +#ifndef QPID_SYS_POSIX_INTEGERTYPES_H +#define QPID_SYS_POSIX_INTEGERTYPES_H + +/* + * 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 <stdint.h> + +#endif /*!QPID_SYS_INTEGERTYPES_H*/ diff --git a/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h b/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h new file mode 100755 index 0000000000..28b82da1a0 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h @@ -0,0 +1,40 @@ +#ifndef QPID_SYS_WINDOWS_INTEGERTYPES_H +#define QPID_SYS_WINDOWS_INTEGERTYPES_H + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +#if defined(_MSC_VER) +typedef signed char int8_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#else +#include <stdint.h> +#endif + +// Visual Studio doesn't define other common types, so set them up here too. +typedef unsigned int uint; + +#endif /*!QPID_SYS_WINDOWS_INTEGERTYPES_H*/ diff --git a/qpid/cpp/include/qpid/types/Exception.h b/qpid/cpp/include/qpid/types/Exception.h new file mode 100644 index 0000000000..483d104cc8 --- /dev/null +++ b/qpid/cpp/include/qpid/types/Exception.h @@ -0,0 +1,44 @@ +#ifndef QPID_TYPES_EXCEPTION_H +#define QPID_TYPES_EXCEPTION_H + +/* + * + * 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 <string> +#include "qpid/types/ImportExport.h" + +namespace qpid { +namespace types { + +class QPID_TYPES_CLASS_EXTERN Exception : public std::exception +{ + public: + QPID_TYPES_EXTERN explicit Exception(const std::string& message=std::string()) throw(); + QPID_TYPES_EXTERN virtual ~Exception() throw(); + QPID_TYPES_EXTERN virtual const char* what() const throw(); + + private: + const std::string message; +}; + +}} // namespace qpid::types + +#endif /*!QPID_TYPES_EXCEPTION_H*/ diff --git a/qpid/cpp/include/qpid/types/ImportExport.h b/qpid/cpp/include/qpid/types/ImportExport.h new file mode 100644 index 0000000000..8fa41884fb --- /dev/null +++ b/qpid/cpp/include/qpid/types/ImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_TYPES_IMPORTEXPORT_H +#define QPID_TYPES_IMPORTEXPORT_H + +/* + * 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 "qpid/ImportExport.h" + +#if defined(TYPES_EXPORT) || defined (qpidtypes_EXPORTS) +# define QPID_TYPES_EXTERN QPID_EXPORT +# define QPID_TYPES_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_TYPES_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_TYPES_EXTERN QPID_IMPORT +# define QPID_TYPES_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_TYPES_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif /*!QPID_TYPES_IMPORTEXPORT_H*/ diff --git a/qpid/cpp/include/qpid/types/Uuid.h b/qpid/cpp/include/qpid/types/Uuid.h new file mode 100644 index 0000000000..6384103f43 --- /dev/null +++ b/qpid/cpp/include/qpid/types/Uuid.h @@ -0,0 +1,107 @@ +#ifndef QPID_TYPES_UUID_H +#define QPID_TYPES_UUID_H + +/* + * + * 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 "qpid/types/ImportExport.h" +#include <iosfwd> +#include <string> + +namespace qpid { +namespace types { + +class QPID_TYPES_CLASS_EXTERN Uuid +{ + public: + QPID_TYPES_EXTERN static const size_t SIZE; + /** + * If unique is true, this will generate a new unique uuid, if not + * it will construct a null uuid. + */ + QPID_TYPES_EXTERN Uuid(bool unique=false); + QPID_TYPES_EXTERN Uuid(const Uuid&); + QPID_TYPES_EXTERN Uuid& operator=(const Uuid&); + /** Copy the UUID from data16, which must point to a 16-byte UUID */ + QPID_TYPES_EXTERN Uuid(const unsigned char* data16); + QPID_TYPES_EXTERN Uuid(const char* data16); + + /** Set to a new unique identifier. */ + QPID_TYPES_EXTERN void generate(); + + /** Set to all zeros. */ + QPID_TYPES_EXTERN void clear(); + + /** Test for null (all zeros). */ + QPID_TYPES_EXTERN bool isNull() const; + QPID_TYPES_EXTERN operator bool() const; + QPID_TYPES_EXTERN bool operator!() const; + + /** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ + QPID_TYPES_EXTERN std::string str() const; + + QPID_TYPES_EXTERN size_t size() const; + QPID_TYPES_EXTERN const unsigned char* data() const; + + friend QPID_TYPES_EXTERN bool operator==(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator!=(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator<(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator>(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator<=(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator>=(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream&, Uuid); + friend QPID_TYPES_EXTERN std::istream& operator>>(std::istream&, Uuid&); + + /** Hash value suitable for use with unordered_map */ + QPID_TYPES_EXTERN size_t hash() const; + + /** Hasher for use with unordered_map */ + struct Hasher { + size_t operator()(const Uuid& u) const { return u.hash(); } + }; + + private: + unsigned char bytes[16]; +}; + +/** Hash value function for use with boots::hash or std::hash */ +inline size_t hash_value(const Uuid& uuid) { return uuid.hash(); } + +/** Returns true if the uuids are equal, false otherwise. **/ +QPID_TYPES_EXTERN bool operator==(const Uuid&, const Uuid&); +/** Returns true if the uuids are NOT equal, false if they are. **/ +QPID_TYPES_EXTERN bool operator!=(const Uuid&, const Uuid&); + +QPID_TYPES_EXTERN bool operator<(const Uuid&, const Uuid&); +QPID_TYPES_EXTERN bool operator>(const Uuid&, const Uuid&); +QPID_TYPES_EXTERN bool operator<=(const Uuid&, const Uuid&); +QPID_TYPES_EXTERN bool operator>=(const Uuid&, const Uuid&); + +/** Print in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream&, Uuid); + +/** Read from format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ +QPID_TYPES_EXTERN std::istream& operator>>(std::istream&, Uuid&); + +}} // namespace qpid::types + + +#endif /*!QPID_TYPES_UUID_H*/ diff --git a/qpid/cpp/include/qpid/types/Variant.h b/qpid/cpp/include/qpid/types/Variant.h new file mode 100644 index 0000000000..843870e438 --- /dev/null +++ b/qpid/cpp/include/qpid/types/Variant.h @@ -0,0 +1,224 @@ +#ifndef QPID_TYPES_VARIANT_H +#define QPID_TYPES_VARIANT_H + +/* + * + * 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 <list> +#include <map> +#include <ostream> +#include <string> +#include "Uuid.h" +#include "qpid/types/Exception.h" +#include "qpid/sys/IntegerTypes.h" +#include "qpid/types/ImportExport.h" + +namespace qpid { +namespace types { + +/** + * Thrown when an illegal conversion of a variant is attempted. + */ +struct QPID_TYPES_CLASS_EXTERN InvalidConversion : public Exception +{ + QPID_TYPES_EXTERN InvalidConversion(const std::string& msg); + QPID_TYPES_EXTERN ~InvalidConversion() throw(); +}; + +enum VariantType { + VAR_VOID = 0, + VAR_BOOL, + VAR_UINT8, + VAR_UINT16, + VAR_UINT32, + VAR_UINT64, + VAR_INT8, + VAR_INT16, + VAR_INT32, + VAR_INT64, + VAR_FLOAT, + VAR_DOUBLE, + VAR_STRING, + VAR_MAP, + VAR_LIST, + VAR_UUID +}; + +QPID_TYPES_EXTERN std::string getTypeName(VariantType type); + +QPID_TYPES_EXTERN bool isIntegerType(VariantType type); + +class VariantImpl; + +/** + * Represents a value of variable type. + */ +class QPID_TYPES_CLASS_EXTERN Variant +{ + public: + typedef std::map<std::string, Variant> Map; + typedef std::list<Variant> List; + + QPID_TYPES_EXTERN Variant(); + QPID_TYPES_EXTERN Variant(bool); + QPID_TYPES_EXTERN Variant(uint8_t); + QPID_TYPES_EXTERN Variant(uint16_t); + QPID_TYPES_EXTERN Variant(uint32_t); + QPID_TYPES_EXTERN Variant(uint64_t); + QPID_TYPES_EXTERN Variant(int8_t); + QPID_TYPES_EXTERN Variant(int16_t); + QPID_TYPES_EXTERN Variant(int32_t); + QPID_TYPES_EXTERN Variant(int64_t); + QPID_TYPES_EXTERN Variant(float); + QPID_TYPES_EXTERN Variant(double); + QPID_TYPES_EXTERN Variant(const std::string&); + QPID_TYPES_EXTERN Variant(const std::string& value, const std::string& encoding); + QPID_TYPES_EXTERN Variant(const char*); + QPID_TYPES_EXTERN Variant(const char* value, const char* encoding); + QPID_TYPES_EXTERN Variant(const Map&); + QPID_TYPES_EXTERN Variant(const List&); + QPID_TYPES_EXTERN Variant(const Variant&); + QPID_TYPES_EXTERN Variant(const Uuid&); + + QPID_TYPES_EXTERN ~Variant(); + + QPID_TYPES_EXTERN VariantType getType() const; + QPID_TYPES_EXTERN bool isVoid() const; + + QPID_TYPES_EXTERN Variant& operator=(bool); + QPID_TYPES_EXTERN Variant& operator=(uint8_t); + QPID_TYPES_EXTERN Variant& operator=(uint16_t); + QPID_TYPES_EXTERN Variant& operator=(uint32_t); + QPID_TYPES_EXTERN Variant& operator=(uint64_t); + QPID_TYPES_EXTERN Variant& operator=(int8_t); + QPID_TYPES_EXTERN Variant& operator=(int16_t); + QPID_TYPES_EXTERN Variant& operator=(int32_t); + QPID_TYPES_EXTERN Variant& operator=(int64_t); + QPID_TYPES_EXTERN Variant& operator=(float); + QPID_TYPES_EXTERN Variant& operator=(double); + QPID_TYPES_EXTERN Variant& operator=(const std::string&); + QPID_TYPES_EXTERN Variant& operator=(const char*); + QPID_TYPES_EXTERN Variant& operator=(const Map&); + QPID_TYPES_EXTERN Variant& operator=(const List&); + QPID_TYPES_EXTERN Variant& operator=(const Variant&); + QPID_TYPES_EXTERN Variant& operator=(const Uuid&); + + /** + * Parses the argument and assigns itself the appropriate + * value. Recognises integers, doubles and booleans. + */ + QPID_TYPES_EXTERN Variant& parse(const std::string&); + + QPID_TYPES_EXTERN bool asBool() const; + QPID_TYPES_EXTERN uint8_t asUint8() const; + QPID_TYPES_EXTERN uint16_t asUint16() const; + QPID_TYPES_EXTERN uint32_t asUint32() const; + QPID_TYPES_EXTERN uint64_t asUint64() const; + QPID_TYPES_EXTERN int8_t asInt8() const; + QPID_TYPES_EXTERN int16_t asInt16() const; + QPID_TYPES_EXTERN int32_t asInt32() const; + QPID_TYPES_EXTERN int64_t asInt64() const; + QPID_TYPES_EXTERN float asFloat() const; + QPID_TYPES_EXTERN double asDouble() const; + QPID_TYPES_EXTERN std::string asString() const; + QPID_TYPES_EXTERN Uuid asUuid() const; + + QPID_TYPES_EXTERN operator bool() const; + QPID_TYPES_EXTERN operator uint8_t() const; + QPID_TYPES_EXTERN operator uint16_t() const; + QPID_TYPES_EXTERN operator uint32_t() const; + QPID_TYPES_EXTERN operator uint64_t() const; + QPID_TYPES_EXTERN operator int8_t() const; + QPID_TYPES_EXTERN operator int16_t() const; + QPID_TYPES_EXTERN operator int32_t() const; + QPID_TYPES_EXTERN operator int64_t() const; + QPID_TYPES_EXTERN operator float() const; + QPID_TYPES_EXTERN operator double() const; + QPID_TYPES_EXTERN operator std::string() const; + QPID_TYPES_EXTERN operator Uuid() const; + + QPID_TYPES_EXTERN const Map& asMap() const; + QPID_TYPES_EXTERN Map& asMap(); + QPID_TYPES_EXTERN const List& asList() const; + QPID_TYPES_EXTERN List& asList(); + + /** + * Unlike asString(), getString() will not do any conversions. + * @exception InvalidConversion if the type is not STRING. + */ + QPID_TYPES_EXTERN const std::string& getString() const; + QPID_TYPES_EXTERN std::string& getString(); + + QPID_TYPES_EXTERN void setEncoding(const std::string&); + QPID_TYPES_EXTERN const std::string& getEncoding() const; + + QPID_TYPES_EXTERN bool isEqualTo(const Variant& a) const; + + /** Reset value to VOID, does not reset the descriptors. */ + QPID_TYPES_EXTERN void reset(); + + /** True if there is at least one descriptor associated with this variant. */ + QPID_TYPES_EXTERN bool isDescribed() const; + + /** Get the first descriptor associated with this variant. + * + * Normally there is at most one descriptor, when there are multiple + * descriptors use getDescriptors() + * + *@return The first descriptor or VOID if there is no descriptor. + *@see isDescribed, getDescriptors + */ + QPID_TYPES_EXTERN Variant getDescriptor() const; + + /** Set a single descriptor for this Variant. The descriptor must be a string or integer. */ + QPID_TYPES_EXTERN void setDescriptor(const Variant& descriptor); + + /** Return a modifiable list of descriptors for this Variant. + * Used in case where there are multiple descriptors, for a single descriptor use + * getDescriptor and setDescriptor. + */ + QPID_TYPES_EXTERN List& getDescriptors(); + + /** Return the list of descriptors for this Variant. + * Used in case where there are multiple descriptors, for a single descriptor use + * getDescriptor and setDescriptor. + */ + QPID_TYPES_EXTERN const List& getDescriptors() const; + + /** Create a described value */ + QPID_TYPES_EXTERN static Variant described(const Variant& descriptor, const Variant& value); + + /** Create a described list, a common special case */ + QPID_TYPES_EXTERN static Variant described(const Variant& descriptor, const List& value); + + private: + mutable VariantImpl* impl; +}; + +#ifndef SWIG +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream& out, const Variant& value); +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream& out, const Variant::Map& map); +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream& out, const Variant::List& list); +QPID_TYPES_EXTERN bool operator==(const Variant& a, const Variant& b); +QPID_TYPES_EXTERN bool operator!=(const Variant& a, const Variant& b); +#endif +}} // namespace qpid::types + +#endif /*!QPID_TYPES_VARIANT_H*/ |