From 74478b24b0542e8b454f60cb99ff78099f550464 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 31 Oct 2019 14:04:25 -0700 Subject: [PATCH] add librabbitmq binaries for macos for testing central controller --- ext/librabbitmq/macos/include/amqp.h | 2538 +++++++++++++++++ ext/librabbitmq/macos/include/amqp_framing.h | 1144 ++++++++ .../macos/include/amqp_tcp_socket.h | 68 + ext/librabbitmq/macos/lib/librabbitmq.a | Bin 0 -> 95704 bytes make-mac.mk | 3 +- 5 files changed, 3752 insertions(+), 1 deletion(-) create mode 100644 ext/librabbitmq/macos/include/amqp.h create mode 100644 ext/librabbitmq/macos/include/amqp_framing.h create mode 100644 ext/librabbitmq/macos/include/amqp_tcp_socket.h create mode 100644 ext/librabbitmq/macos/lib/librabbitmq.a diff --git a/ext/librabbitmq/macos/include/amqp.h b/ext/librabbitmq/macos/include/amqp.h new file mode 100644 index 000000000..2983b1665 --- /dev/null +++ b/ext/librabbitmq/macos/include/amqp.h @@ -0,0 +1,2538 @@ +/** \file */ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2014 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifndef AMQP_H +#define AMQP_H + +/** \cond HIDE_FROM_DOXYGEN */ + +#ifdef __cplusplus +#define AMQP_BEGIN_DECLS extern "C" { +#define AMQP_END_DECLS } +#else +#define AMQP_BEGIN_DECLS +#define AMQP_END_DECLS +#endif + +/* + * \internal + * Important API decorators: + * AMQP_PUBLIC_FUNCTION - a public API function + * AMQP_PUBLIC_VARIABLE - a public API external variable + * AMQP_CALL - calling convension (used on Win32) + */ + +#if defined(_WIN32) && defined(_MSC_VER) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(_WIN32) && defined(__BORLANDC__) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(_WIN32) && defined(__MINGW32__) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(_WIN32) && defined(__CYGWIN__) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define AMQP_PUBLIC_FUNCTION __attribute__((visibility("default"))) +#define AMQP_PUBLIC_VARIABLE __attribute__((visibility("default"))) extern +#define AMQP_CALL +#else +#define AMQP_PUBLIC_FUNCTION +#define AMQP_PUBLIC_VARIABLE extern +#define AMQP_CALL +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define AMQP_DEPRECATED(function) function __attribute__((__deprecated__)) +#elif defined(_MSC_VER) +#define AMQP_DEPRECATED(function) __declspec(deprecated) function +#else +#define AMQP_DEPRECATED(function) +#endif + +/* Define ssize_t on Win32/64 platforms + See: http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-April/030649.html for + details + */ +#if !defined(_W64) +#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +#define _W64 __w64 +#else +#define _W64 +#endif +#endif + +#ifdef _MSC_VER +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif +#endif + +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif + +/** \endcond */ + +#include +#include + +struct timeval; + +AMQP_BEGIN_DECLS + +/** + * \def AMQP_VERSION_MAJOR + * + * Major library version number compile-time constant + * + * The major version is incremented when backwards incompatible API changes + * are made. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ + +/** + * \def AMQP_VERSION_MINOR + * + * Minor library version number compile-time constant + * + * The minor version is incremented when new APIs are added. Existing APIs + * are left alone. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ + +/** + * \def AMQP_VERSION_PATCH + * + * Patch library version number compile-time constant + * + * The patch version is incremented when library code changes, but the API + * is not changed. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ + +/** + * \def AMQP_VERSION_IS_RELEASE + * + * Version constant set to 1 for tagged release, 0 otherwise + * + * NOTE: versions that are not tagged releases are not guaranteed to be API/ABI + * compatible with older releases, and may change commit-to-commit. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ +/* + * Developer note: when changing these, be sure to update SOVERSION constants + * in CMakeLists.txt and configure.ac + */ + +#define AMQP_VERSION_MAJOR 0 +#define AMQP_VERSION_MINOR 10 +#define AMQP_VERSION_PATCH 0 +#define AMQP_VERSION_IS_RELEASE 0 + +/** + * \def AMQP_VERSION_CODE + * + * Helper macro to geneate a packed version code suitable for + * comparison with AMQP_VERSION. + * + * \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR, + * AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE, AMQP_VERSION + * + * \since v0.6.1 + */ +#define AMQP_VERSION_CODE(major, minor, patch, release) \ + ((major << 24) | (minor << 16) | (patch << 8) | (release)) + +/** + * \def AMQP_VERSION + * + * Packed version number + * + * AMQP_VERSION is a 4-byte unsigned integer with the most significant byte + * set to AMQP_VERSION_MAJOR, the second most significant byte set to + * AMQP_VERSION_MINOR, third most significant byte set to AMQP_VERSION_PATCH, + * and the lowest byte set to AMQP_VERSION_IS_RELEASE. + * + * For example version 2.3.4 which is released version would be encoded as + * 0x02030401 + * + * \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR, + * AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE, AMQP_VERSION_CODE + * + * \since v0.4.0 + */ +#define AMQP_VERSION \ + AMQP_VERSION_CODE(AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR, \ + AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE) + +/** \cond HIDE_FROM_DOXYGEN */ +#define AMQ_STRINGIFY(s) AMQ_STRINGIFY_HELPER(s) +#define AMQ_STRINGIFY_HELPER(s) #s + +#define AMQ_VERSION_STRING \ + AMQ_STRINGIFY(AMQP_VERSION_MAJOR) \ + "." AMQ_STRINGIFY(AMQP_VERSION_MINOR) "." AMQ_STRINGIFY(AMQP_VERSION_PATCH) +/** \endcond */ + +/** + * \def AMQP_VERSION_STRING + * + * Version string compile-time constant + * + * Non-released versions of the library will have "-pre" appended to the + * version string + * + * \sa amqp_version() + * + * \since v0.4.0 + */ +#if AMQP_VERSION_IS_RELEASE +#define AMQP_VERSION_STRING AMQ_VERSION_STRING +#else +#define AMQP_VERSION_STRING AMQ_VERSION_STRING "-pre" +#endif + +/** + * Returns the rabbitmq-c version as a packed integer. + * + * See \ref AMQP_VERSION + * + * \return packed 32-bit integer representing version of library at runtime + * + * \sa AMQP_VERSION, amqp_version() + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +uint32_t AMQP_CALL amqp_version_number(void); + +/** + * Returns the rabbitmq-c version as a string. + * + * See \ref AMQP_VERSION_STRING + * + * \return a statically allocated string describing the version of rabbitmq-c. + * + * \sa amqp_version_number(), AMQP_VERSION_STRING, AMQP_VERSION + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +char const *AMQP_CALL amqp_version(void); + +/** + * \def AMQP_DEFAULT_FRAME_SIZE + * + * Default frame size (128Kb) + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.4.0 + */ +#define AMQP_DEFAULT_FRAME_SIZE 131072 + +/** + * \def AMQP_DEFAULT_MAX_CHANNELS + * + * Default maximum number of channels (2047, RabbitMQ default limit of 2048, + * minus 1 for channel 0). RabbitMQ set a default limit of 2048 channels per + * connection in v3.7.5 to prevent broken clients from leaking too many + * channels. + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.4.0 + */ +#define AMQP_DEFAULT_MAX_CHANNELS 2047 + +/** + * \def AMQP_DEFAULT_HEARTBEAT + * + * Default heartbeat interval (0, heartbeat disabled) + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.4.0 + */ +#define AMQP_DEFAULT_HEARTBEAT 0 + +/** + * \def AMQP_DEFAULT_VHOST + * + * Default RabbitMQ vhost: "/" + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.9.0 + */ +#define AMQP_DEFAULT_VHOST "/" + +/** + * boolean type 0 = false, true otherwise + * + * \since v0.1 + */ +typedef int amqp_boolean_t; + +/** + * Method number + * + * \since v0.1 + */ +typedef uint32_t amqp_method_number_t; + +/** + * Bitmask for flags + * + * \since v0.1 + */ +typedef uint32_t amqp_flags_t; + +/** + * Channel type + * + * \since v0.1 + */ +typedef uint16_t amqp_channel_t; + +/** + * Buffer descriptor + * + * \since v0.1 + */ +typedef struct amqp_bytes_t_ { + size_t len; /**< length of the buffer in bytes */ + void *bytes; /**< pointer to the beginning of the buffer */ +} amqp_bytes_t; + +/** + * Decimal data type + * + * \since v0.1 + */ +typedef struct amqp_decimal_t_ { + uint8_t decimals; /**< the location of the decimal point */ + uint32_t value; /**< the value before the decimal point is applied */ +} amqp_decimal_t; + +/** + * AMQP field table + * + * An AMQP field table is a set of key-value pairs. + * A key is a UTF-8 encoded string up to 128 bytes long, and are not null + * terminated. + * A value can be one of several different datatypes. \sa + * amqp_field_value_kind_t + * + * \sa amqp_table_entry_t + * + * \since v0.1 + */ +typedef struct amqp_table_t_ { + int num_entries; /**< length of entries array */ + struct amqp_table_entry_t_ *entries; /**< an array of table entries */ +} amqp_table_t; + +/** + * An AMQP Field Array + * + * A repeated set of field values, all must be of the same type + * + * \since v0.1 + */ +typedef struct amqp_array_t_ { + int num_entries; /**< Number of entries in the table */ + struct amqp_field_value_t_ *entries; /**< linked list of field values */ +} amqp_array_t; + +/* + 0-9 0-9-1 Qpid/Rabbit Type Remarks +--------------------------------------------------------------------------- + t t Boolean + b b Signed 8-bit + B Unsigned 8-bit + U s Signed 16-bit (A1) + u Unsigned 16-bit + I I I Signed 32-bit + i Unsigned 32-bit + L l Signed 64-bit (B) + l Unsigned 64-bit + f f 32-bit float + d d 64-bit float + D D D Decimal + s Short string (A2) + S S S Long string + A Nested Array + T T T Timestamp (u64) + F F F Nested Table + V V V Void + x Byte array + +Remarks: + + A1, A2: Notice how the types **CONFLICT** here. In Qpid and Rabbit, + 's' means a signed 16-bit integer; in 0-9-1, it means a + short string. + + B: Notice how the signednesses **CONFLICT** here. In Qpid and Rabbit, + 'l' means a signed 64-bit integer; in 0-9-1, it means an unsigned + 64-bit integer. + +I'm going with the Qpid/Rabbit types, where there's a conflict, and +the 0-9-1 types otherwise. 0-8 is a subset of 0-9, which is a subset +of the other two, so this will work for both 0-8 and 0-9-1 branches of +the code. +*/ + +/** + * A field table value + * + * \since v0.1 + */ +typedef struct amqp_field_value_t_ { + uint8_t kind; /**< the type of the entry /sa amqp_field_value_kind_t */ + union { + amqp_boolean_t boolean; /**< boolean type AMQP_FIELD_KIND_BOOLEAN */ + int8_t i8; /**< int8_t type AMQP_FIELD_KIND_I8 */ + uint8_t u8; /**< uint8_t type AMQP_FIELD_KIND_U8 */ + int16_t i16; /**< int16_t type AMQP_FIELD_KIND_I16 */ + uint16_t u16; /**< uint16_t type AMQP_FIELD_KIND_U16 */ + int32_t i32; /**< int32_t type AMQP_FIELD_KIND_I32 */ + uint32_t u32; /**< uint32_t type AMQP_FIELD_KIND_U32 */ + int64_t i64; /**< int64_t type AMQP_FIELD_KIND_I64 */ + uint64_t u64; /**< uint64_t type AMQP_FIELD_KIND_U64, + AMQP_FIELD_KIND_TIMESTAMP */ + float f32; /**< float type AMQP_FIELD_KIND_F32 */ + double f64; /**< double type AMQP_FIELD_KIND_F64 */ + amqp_decimal_t decimal; /**< amqp_decimal_t AMQP_FIELD_KIND_DECIMAL */ + amqp_bytes_t bytes; /**< amqp_bytes_t type AMQP_FIELD_KIND_UTF8, + AMQP_FIELD_KIND_BYTES */ + amqp_table_t table; /**< amqp_table_t type AMQP_FIELD_KIND_TABLE */ + amqp_array_t array; /**< amqp_array_t type AMQP_FIELD_KIND_ARRAY */ + } value; /**< a union of the value */ +} amqp_field_value_t; + +/** + * An entry in a field-table + * + * \sa amqp_table_encode(), amqp_table_decode(), amqp_table_clone() + * + * \since v0.1 + */ +typedef struct amqp_table_entry_t_ { + amqp_bytes_t key; /**< the table entry key. Its a null-terminated UTF-8 + * string, with a maximum size of 128 bytes */ + amqp_field_value_t value; /**< the table entry values */ +} amqp_table_entry_t; + +/** + * Field value types + * + * \since v0.1 + */ +typedef enum { + AMQP_FIELD_KIND_BOOLEAN = + 't', /**< boolean type. 0 = false, 1 = true @see amqp_boolean_t */ + AMQP_FIELD_KIND_I8 = 'b', /**< 8-bit signed integer, datatype: int8_t */ + AMQP_FIELD_KIND_U8 = 'B', /**< 8-bit unsigned integer, datatype: uint8_t */ + AMQP_FIELD_KIND_I16 = 's', /**< 16-bit signed integer, datatype: int16_t */ + AMQP_FIELD_KIND_U16 = 'u', /**< 16-bit unsigned integer, datatype: uint16_t */ + AMQP_FIELD_KIND_I32 = 'I', /**< 32-bit signed integer, datatype: int32_t */ + AMQP_FIELD_KIND_U32 = 'i', /**< 32-bit unsigned integer, datatype: uint32_t */ + AMQP_FIELD_KIND_I64 = 'l', /**< 64-bit signed integer, datatype: int64_t */ + AMQP_FIELD_KIND_U64 = 'L', /**< 64-bit unsigned integer, datatype: uint64_t */ + AMQP_FIELD_KIND_F32 = + 'f', /**< single-precision floating point value, datatype: float */ + AMQP_FIELD_KIND_F64 = + 'd', /**< double-precision floating point value, datatype: double */ + AMQP_FIELD_KIND_DECIMAL = + 'D', /**< amqp-decimal value, datatype: amqp_decimal_t */ + AMQP_FIELD_KIND_UTF8 = 'S', /**< UTF-8 null-terminated character string, + datatype: amqp_bytes_t */ + AMQP_FIELD_KIND_ARRAY = 'A', /**< field array (repeated values of another + datatype. datatype: amqp_array_t */ + AMQP_FIELD_KIND_TIMESTAMP = 'T', /**< 64-bit timestamp. datatype uint64_t */ + AMQP_FIELD_KIND_TABLE = 'F', /**< field table. encapsulates a table inside a + table entry. datatype: amqp_table_t */ + AMQP_FIELD_KIND_VOID = 'V', /**< empty entry */ + AMQP_FIELD_KIND_BYTES = + 'x' /**< unformatted byte string, datatype: amqp_bytes_t */ +} amqp_field_value_kind_t; + +/** + * A list of allocation blocks + * + * \since v0.1 + */ +typedef struct amqp_pool_blocklist_t_ { + int num_blocks; /**< Number of blocks in the block list */ + void **blocklist; /**< Array of memory blocks */ +} amqp_pool_blocklist_t; + +/** + * A memory pool + * + * \since v0.1 + */ +typedef struct amqp_pool_t_ { + size_t pagesize; /**< the size of the page in bytes. Allocations less than or + * equal to this size are allocated in the pages block list. + * Allocations greater than this are allocated in their own + * own block in the large_blocks block list */ + + amqp_pool_blocklist_t pages; /**< blocks that are the size of pagesize */ + amqp_pool_blocklist_t + large_blocks; /**< allocations larger than the pagesize */ + + int next_page; /**< an index to the next unused page block */ + char *alloc_block; /**< pointer to the current allocation block */ + size_t alloc_used; /**< number of bytes in the current allocation block that + has been used */ +} amqp_pool_t; + +/** + * An amqp method + * + * \since v0.1 + */ +typedef struct amqp_method_t_ { + amqp_method_number_t id; /**< the method id number */ + void *decoded; /**< pointer to the decoded method, + * cast to the appropriate type to use */ +} amqp_method_t; + +/** + * An AMQP frame + * + * \since v0.1 + */ +typedef struct amqp_frame_t_ { + uint8_t frame_type; /**< frame type. The types: + * - AMQP_FRAME_METHOD - use the method union member + * - AMQP_FRAME_HEADER - use the properties union member + * - AMQP_FRAME_BODY - use the body_fragment union member + */ + amqp_channel_t channel; /**< the channel the frame was received on */ + union { + amqp_method_t + method; /**< a method, use if frame_type == AMQP_FRAME_METHOD */ + struct { + uint16_t class_id; /**< the class for the properties */ + uint64_t body_size; /**< size of the body in bytes */ + void *decoded; /**< the decoded properties */ + amqp_bytes_t raw; /**< amqp-encoded properties structure */ + } properties; /**< message header, a.k.a., properties, + use if frame_type == AMQP_FRAME_HEADER */ + amqp_bytes_t body_fragment; /**< a body fragment, use if frame_type == + AMQP_FRAME_BODY */ + struct { + uint8_t transport_high; /**< @internal first byte of handshake */ + uint8_t transport_low; /**< @internal second byte of handshake */ + uint8_t protocol_version_major; /**< @internal third byte of handshake */ + uint8_t protocol_version_minor; /**< @internal fourth byte of handshake */ + } protocol_header; /**< Used only when doing the initial handshake with the + broker, don't use otherwise */ + } payload; /**< the payload of the frame */ +} amqp_frame_t; + +/** + * Response type + * + * \since v0.1 + */ +typedef enum amqp_response_type_enum_ { + AMQP_RESPONSE_NONE = 0, /**< the library got an EOF from the socket */ + AMQP_RESPONSE_NORMAL, /**< response normal, the RPC completed successfully */ + AMQP_RESPONSE_LIBRARY_EXCEPTION, /**< library error, an error occurred in the + library, examine the library_error */ + AMQP_RESPONSE_SERVER_EXCEPTION /**< server exception, the broker returned an + error, check replay */ +} amqp_response_type_enum; + +/** + * Reply from a RPC method on the broker + * + * \since v0.1 + */ +typedef struct amqp_rpc_reply_t_ { + amqp_response_type_enum reply_type; /**< the reply type: + * - AMQP_RESPONSE_NORMAL - the RPC + * completed successfully + * - AMQP_RESPONSE_SERVER_EXCEPTION - the + * broker returned + * an exception, check the reply field + * - AMQP_RESPONSE_LIBRARY_EXCEPTION - the + * library + * encountered an error, check the + * library_error field + */ + amqp_method_t reply; /**< in case of AMQP_RESPONSE_SERVER_EXCEPTION this + * field will be set to the method returned from the + * broker */ + int library_error; /**< in case of AMQP_RESPONSE_LIBRARY_EXCEPTION this + * field will be set to an error code. An error + * string can be retrieved using amqp_error_string */ +} amqp_rpc_reply_t; + +/** + * SASL method type + * + * \since v0.1 + */ +typedef enum amqp_sasl_method_enum_ { + AMQP_SASL_METHOD_UNDEFINED = -1, /**< Invalid SASL method */ + AMQP_SASL_METHOD_PLAIN = + 0, /**< the PLAIN SASL method for authentication to the broker */ + AMQP_SASL_METHOD_EXTERNAL = + 1 /**< the EXTERNAL SASL method for authentication to the broker */ +} amqp_sasl_method_enum; + +/** + * connection state object + * + * \since v0.1 + */ +typedef struct amqp_connection_state_t_ *amqp_connection_state_t; + +/** + * Socket object + * + * \since v0.4.0 + */ +typedef struct amqp_socket_t_ amqp_socket_t; + +/** + * Status codes + * + * \since v0.4.0 + */ +/* NOTE: When updating this enum, update the strings in librabbitmq/amqp_api.c + */ +typedef enum amqp_status_enum_ { + AMQP_STATUS_OK = 0x0, /**< Operation successful */ + AMQP_STATUS_NO_MEMORY = -0x0001, /**< Memory allocation + failed */ + AMQP_STATUS_BAD_AMQP_DATA = -0x0002, /**< Incorrect or corrupt + data was received from + the broker. This is a + protocol error. */ + AMQP_STATUS_UNKNOWN_CLASS = -0x0003, /**< An unknown AMQP class + was received. This is + a protocol error. */ + AMQP_STATUS_UNKNOWN_METHOD = -0x0004, /**< An unknown AMQP method + was received. This is + a protocol error. */ + AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED = -0x0005, /**< Unable to resolve the + * hostname */ + AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION = -0x0006, /**< The broker advertised + an incompaible AMQP + version */ + AMQP_STATUS_CONNECTION_CLOSED = -0x0007, /**< The connection to the + broker has been closed + */ + AMQP_STATUS_BAD_URL = -0x0008, /**< malformed AMQP URL */ + AMQP_STATUS_SOCKET_ERROR = -0x0009, /**< A socket error + occurred */ + AMQP_STATUS_INVALID_PARAMETER = -0x000A, /**< An invalid parameter + was passed into the + function */ + AMQP_STATUS_TABLE_TOO_BIG = -0x000B, /**< The amqp_table_t object + cannot be serialized + because the output + buffer is too small */ + AMQP_STATUS_WRONG_METHOD = -0x000C, /**< The wrong method was + received */ + AMQP_STATUS_TIMEOUT = -0x000D, /**< Operation timed out */ + AMQP_STATUS_TIMER_FAILURE = -0x000E, /**< The underlying system + timer facility failed */ + AMQP_STATUS_HEARTBEAT_TIMEOUT = -0x000F, /**< Timed out waiting for + heartbeat */ + AMQP_STATUS_UNEXPECTED_STATE = -0x0010, /**< Unexpected protocol + state */ + AMQP_STATUS_SOCKET_CLOSED = -0x0011, /**< Underlying socket is + closed */ + AMQP_STATUS_SOCKET_INUSE = -0x0012, /**< Underlying socket is + already open */ + AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD = -0x0013, /**< Broker does not + support the requested + SASL mechanism */ + AMQP_STATUS_UNSUPPORTED = -0x0014, /**< Parameter is unsupported + in this version */ + _AMQP_STATUS_NEXT_VALUE = -0x0015, /**< Internal value */ + + AMQP_STATUS_TCP_ERROR = -0x0100, /**< A generic TCP error + occurred */ + AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR = -0x0101, /**< An error occurred trying + to initialize the + socket library*/ + _AMQP_STATUS_TCP_NEXT_VALUE = -0x0102, /**< Internal value */ + + AMQP_STATUS_SSL_ERROR = -0x0200, /**< A generic SSL error + occurred. */ + AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED = -0x0201, /**< SSL validation of + hostname against + peer certificate + failed */ + AMQP_STATUS_SSL_PEER_VERIFY_FAILED = -0x0202, /**< SSL validation of peer + certificate failed. */ + AMQP_STATUS_SSL_CONNECTION_FAILED = -0x0203, /**< SSL handshake failed. */ + _AMQP_STATUS_SSL_NEXT_VALUE = -0x0204 /**< Internal value */ +} amqp_status_enum; + +/** + * AMQP delivery modes. + * Use these values for the #amqp_basic_properties_t::delivery_mode field. + * + * \since v0.5 + */ +typedef enum { + AMQP_DELIVERY_NONPERSISTENT = 1, /**< Non-persistent message */ + AMQP_DELIVERY_PERSISTENT = 2 /**< Persistent message */ +} amqp_delivery_mode_enum; + +AMQP_END_DECLS + +#include + +AMQP_BEGIN_DECLS + +/** + * Empty bytes structure + * + * \since v0.2 + */ +AMQP_PUBLIC_VARIABLE const amqp_bytes_t amqp_empty_bytes; + +/** + * Empty table structure + * + * \since v0.2 + */ +AMQP_PUBLIC_VARIABLE const amqp_table_t amqp_empty_table; + +/** + * Empty table array structure + * + * \since v0.2 + */ +AMQP_PUBLIC_VARIABLE const amqp_array_t amqp_empty_array; + +/* Compatibility macros for the above, to avoid the need to update + code written against earlier versions of librabbitmq. */ + +/** + * \def AMQP_EMPTY_BYTES + * + * Deprecated, use \ref amqp_empty_bytes instead + * + * \deprecated use \ref amqp_empty_bytes instead + * + * \since v0.1 + */ +#define AMQP_EMPTY_BYTES amqp_empty_bytes + +/** + * \def AMQP_EMPTY_TABLE + * + * Deprecated, use \ref amqp_empty_table instead + * + * \deprecated use \ref amqp_empty_table instead + * + * \since v0.1 + */ +#define AMQP_EMPTY_TABLE amqp_empty_table + +/** + * \def AMQP_EMPTY_ARRAY + * + * Deprecated, use \ref amqp_empty_array instead + * + * \deprecated use \ref amqp_empty_array instead + * + * \since v0.1 + */ +#define AMQP_EMPTY_ARRAY amqp_empty_array + +/** + * Initializes an amqp_pool_t memory allocation pool for use + * + * Readies an allocation pool for use. An amqp_pool_t + * must be initialized before use + * + * \param [in] pool the amqp_pool_t structure to initialize. + * Calling this function on a pool a pool that has + * already been initialized will result in undefined + * behavior + * \param [in] pagesize the unit size that the pool will allocate + * memory chunks in. Anything allocated against the pool + * with a requested size will be carved out of a block + * this size. Allocations larger than this will be + * allocated individually + * + * \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(), + * amqp_pool_alloc_bytes(), amqp_pool_t + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL init_amqp_pool(amqp_pool_t *pool, size_t pagesize); + +/** + * Recycles an amqp_pool_t memory allocation pool + * + * Recycles the space allocate by the pool + * + * This invalidates all allocations made against the pool before this call is + * made, any use of any allocations made before recycle_amqp_pool() is called + * will result in undefined behavior. + * + * Note: this may or may not release memory, to force memory to be released + * call empty_amqp_pool(). + * + * \param [in] pool the amqp_pool_t to recycle + * + * \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(), + * amqp_pool_alloc_bytes() + * + * \since v0.1 + * + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL recycle_amqp_pool(amqp_pool_t *pool); + +/** + * Empties an amqp memory pool + * + * Releases all memory associated with an allocation pool + * + * \param [in] pool the amqp_pool_t to empty + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL empty_amqp_pool(amqp_pool_t *pool); + +/** + * Allocates a block of memory from an amqp_pool_t memory pool + * + * Memory will be aligned on a 8-byte boundary. If a 0-length allocation is + * requested, a NULL pointer will be returned. + * + * \param [in] pool the allocation pool to allocate the memory from + * \param [in] amount the size of the allocation in bytes. + * \return a pointer to the memory block, or NULL if the allocation cannot + * be satisfied. + * + * \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(), + * amqp_pool_alloc_bytes() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void *AMQP_CALL amqp_pool_alloc(amqp_pool_t *pool, size_t amount); + +/** + * Allocates a block of memory from an amqp_pool_t to an amqp_bytes_t + * + * Memory will be aligned on a 8-byte boundary. If a 0-length allocation is + * requested, output.bytes = NULL. + * + * \param [in] pool the allocation pool to allocate the memory from + * \param [in] amount the size of the allocation in bytes + * \param [in] output the location to store the pointer. On success + * output.bytes will be set to the beginning of the buffer + * output.len will be set to amount + * On error output.bytes will be set to NULL and output.len + * set to 0 + * + * \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(), + * amqp_pool_alloc() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, + amqp_bytes_t *output); + +/** + * Wraps a c string in an amqp_bytes_t + * + * Takes a string, calculates its length and creates an + * amqp_bytes_t that points to it. The string is not duplicated. + * + * For a given input cstr, The amqp_bytes_t output.bytes is the + * same as cstr, output.len is the length of the string not including + * the \0 terminator + * + * This function uses strlen() internally so cstr must be properly + * terminated + * + * \param [in] cstr the c string to wrap + * \return an amqp_bytes_t that describes the string + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_bytes_t AMQP_CALL amqp_cstring_bytes(char const *cstr); + +/** + * Duplicates an amqp_bytes_t buffer. + * + * The buffer is cloned and the contents copied. + * + * The memory associated with the output is allocated + * with amqp_bytes_malloc() and should be freed with + * amqp_bytes_free() + * + * \param [in] src + * \return a clone of the src + * + * \sa amqp_bytes_free(), amqp_bytes_malloc() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_bytes_t AMQP_CALL amqp_bytes_malloc_dup(amqp_bytes_t src); + +/** + * Allocates a amqp_bytes_t buffer + * + * Creates an amqp_bytes_t buffer of the specified amount, the buffer should be + * freed using amqp_bytes_free() + * + * \param [in] amount the size of the buffer in bytes + * \returns an amqp_bytes_t with amount bytes allocated. + * output.bytes will be set to NULL on error + * + * \sa amqp_bytes_free(), amqp_bytes_malloc_dup() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_bytes_t AMQP_CALL amqp_bytes_malloc(size_t amount); + +/** + * Frees an amqp_bytes_t buffer + * + * Frees a buffer allocated with amqp_bytes_malloc() or amqp_bytes_malloc_dup() + * + * Calling amqp_bytes_free on buffers not allocated with one + * of those two functions will result in undefined behavior + * + * \param [in] bytes the buffer to free + * + * \sa amqp_bytes_malloc(), amqp_bytes_malloc_dup() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_bytes_free(amqp_bytes_t bytes); + +/** + * Allocate and initialize a new amqp_connection_state_t object + * + * amqp_connection_state_t objects created with this function + * should be freed with amqp_destroy_connection() + * + * \returns an opaque pointer on success, NULL or 0 on failure. + * + * \sa amqp_destroy_connection() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_connection_state_t AMQP_CALL amqp_new_connection(void); + +/** + * Get the underlying socket descriptor for the connection + * + * \warning Use the socket returned from this function carefully, incorrect use + * of the socket outside of the library will lead to undefined behavior. + * Additionally rabbitmq-c may use the socket differently version-to-version, + * what may work in one version, may break in the next version. Be sure to + * throughly test any applications that use the socket returned by this + * function especially when using a newer version of rabbitmq-c + * + * \param [in] state the connection object + * \returns the socket descriptor if one has been set, -1 otherwise + * + * \sa amqp_tcp_socket_new(), amqp_ssl_socket_new(), amqp_socket_open() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_sockfd(amqp_connection_state_t state); + +/** + * Deprecated, use amqp_tcp_socket_new() or amqp_ssl_socket_new() + * + * \deprecated Use amqp_tcp_socket_new() or amqp_ssl_socket_new() + * + * Sets the socket descriptor associated with the connection. The socket + * should be connected to a broker, and should not be read to or written from + * before calling this function. A socket descriptor can be created and opened + * using amqp_open_socket() + * + * \param [in] state the connection object + * \param [in] sockfd the socket + * + * \sa amqp_open_socket(), amqp_tcp_socket_new(), amqp_ssl_socket_new() + * + * \since v0.1 + */ +AMQP_DEPRECATED(AMQP_PUBLIC_FUNCTION void AMQP_CALL + amqp_set_sockfd(amqp_connection_state_t state, int sockfd)); + +/** + * Tune client side parameters + * + * \warning This function may call abort() if the connection is in a certain + * state. As such it should probably not be called code outside the library. + * connection parameters should be specified when calling amqp_login() or + * amqp_login_with_properties() + * + * This function changes channel_max, frame_max, and heartbeat parameters, on + * the client side only. It does not try to renegotiate these parameters with + * the broker. Using this function will lead to unexpected results. + * + * \param [in] state the connection object + * \param [in] channel_max the maximum number of channels. + * The largest this can be is 65535 + * \param [in] frame_max the maximum size of an frame. + * The smallest this can be is 4096 + * The largest this can be is 2147483647 + * Unless you know what you're doing the recommended + * size is 131072 or 128KB + * \param [in] heartbeat the number of seconds between heartbeats + * + * \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise. + * Possible error codes include: + * - AMQP_STATUS_NO_MEMORY memory allocation failed. + * - AMQP_STATUS_TIMER_FAILURE the underlying system timer indicated it + * failed. + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_tune_connection(amqp_connection_state_t state, + int channel_max, int frame_max, + int heartbeat); + +/** + * Get the maximum number of channels the connection can handle + * + * The maximum number of channels is set when connection negotiation takes + * place in amqp_login() or amqp_login_with_properties(). + * + * \param [in] state the connection object + * \return the maximum number of channels. 0 if there is no limit + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_channel_max(amqp_connection_state_t state); + +/** + * Get the maximum size of an frame the connection can handle + * + * The maximum size of an frame is set when connection negotiation takes + * place in amqp_login() or amqp_login_with_properties(). + * + * \param [in] state the connection object + * \return the maximum size of an frame. + * + * \since v0.6 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_frame_max(amqp_connection_state_t state); + +/** + * Get the number of seconds between heartbeats of the connection + * + * The number of seconds between heartbeats is set when connection + * negotiation takes place in amqp_login() or amqp_login_with_properties(). + * + * \param [in] state the connection object + * \return the number of seconds between heartbeats. + * + * \since v0.6 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_heartbeat(amqp_connection_state_t state); + +/** + * Destroys an amqp_connection_state_t object + * + * Destroys a amqp_connection_state_t object that was created with + * amqp_new_connection(). If the connection with the broker is open, it will be + * implicitly closed with a reply code of 200 (success). Any memory that + * would be freed with amqp_maybe_release_buffers() or + * amqp_maybe_release_buffers_on_channel() will be freed, and use of that + * memory will caused undefined behavior. + * + * \param [in] state the connection object + * \return AMQP_STATUS_OK on success. amqp_status_enum value failure + * + * \sa amqp_new_connection() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_destroy_connection(amqp_connection_state_t state); + +/** + * Process incoming data + * + * \warning This is a low-level function intended for those who want to + * have greater control over input and output over the socket from the + * broker. Correctly using this function requires in-depth knowledge of AMQP + * and rabbitmq-c. + * + * For a given buffer of data received from the broker, decode the first + * frame in the buffer. If more than one frame is contained in the input buffer + * the return value will be less than the received_data size, the caller should + * adjust received_data buffer descriptor to point to the beginning of the + * buffer + the return value. + * + * \param [in] state the connection object + * \param [in] received_data a buffer of data received from the broker. The + * function will return the number of bytes of the buffer it used. The + * function copies these bytes to an internal buffer: this part of the buffer + * may be reused after this function successfully completes. + * \param [in,out] decoded_frame caller should pass in a pointer to an + * amqp_frame_t struct. If there is enough data in received_data for a + * complete frame, decoded_frame->frame_type will be set to something OTHER + * than 0. decoded_frame may contain members pointing to memory owned by + * the state object. This memory can be recycled with + * amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel(). + * \return number of bytes consumed from received_data or 0 if a 0-length + * buffer was passed. A negative return value indicates failure. Possible + * errors: + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_handle_input(amqp_connection_state_t state, + amqp_bytes_t received_data, + amqp_frame_t *decoded_frame); + +/** + * Check to see if connection memory can be released + * + * \deprecated This function is deprecated in favor of + * amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel() + * + * Checks the state of an amqp_connection_state_t object to see if + * amqp_release_buffers() can be called successfully. + * + * \param [in] state the connection object + * \returns TRUE if the buffers can be released FALSE otherwise + * + * \sa amqp_release_buffers() amqp_maybe_release_buffers() + * amqp_maybe_release_buffers_on_channel() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_release_buffers_ok(amqp_connection_state_t state); + +/** + * Release amqp_connection_state_t owned memory + * + * \deprecated This function is deprecated in favor of + * amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel() + * + * \warning caller should ensure amqp_release_buffers_ok() returns true before + * calling this function. Failure to do so may result in abort() being called. + * + * Release memory owned by the amqp_connection_state_t for reuse by the + * library. Use of any memory returned by the library before this function is + * called will result in undefined behavior. + * + * \note internally rabbitmq-c tries to reuse memory when possible. As a result + * its possible calling this function may not have a noticeable effect on + * memory usage. + * + * \param [in] state the connection object + * + * \sa amqp_release_buffers_ok() amqp_maybe_release_buffers() + * amqp_maybe_release_buffers_on_channel() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_release_buffers(amqp_connection_state_t state); + +/** + * Release amqp_connection_state_t owned memory + * + * Release memory owned by the amqp_connection_state_t object related to any + * channel, allowing reuse by the library. Use of any memory returned by the + * library before this function is called with result in undefined behavior. + * + * \note internally rabbitmq-c tries to reuse memory when possible. As a result + * its possible calling this function may not have a noticeable effect on + * memory usage. + * + * \param [in] state the connection object + * + * \sa amqp_maybe_release_buffers_on_channel() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_maybe_release_buffers(amqp_connection_state_t state); + +/** + * Release amqp_connection_state_t owned memory related to a channel + * + * Release memory owned by the amqp_connection_state_t object related to the + * specified channel, allowing reuse by the library. Use of any memory returned + * the library for a specific channel will result in undefined behavior. + * + * \note internally rabbitmq-c tries to reuse memory when possible. As a result + * its possible calling this function may not have a noticeable effect on + * memory usage. + * + * \param [in] state the connection object + * \param [in] channel the channel specifier for which memory should be + * released. Note that the library does not care about the state of the + * channel when calling this function + * + * \sa amqp_maybe_release_buffers() + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_maybe_release_buffers_on_channel( + amqp_connection_state_t state, amqp_channel_t channel); + +/** + * Send a frame to the broker + * + * \param [in] state the connection object + * \param [in] frame the frame to send to the broker + * \return AMQP_STATUS_OK on success, an amqp_status_enum value on error. + * Possible error codes: + * - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or + * properties was too large to fit in a single AMQP frame, or the + * method contains an invalid value. The frame was not sent. + * - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is + * too large to fit in a single AMQP frame. Frame was not sent. + * - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in + * - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame + * was sent + * - AMQP_STATUS_SOCKET_ERROR + * - AMQP_STATUS_SSL_ERROR + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_send_frame(amqp_connection_state_t state, + amqp_frame_t const *frame); + +/** + * Compare two table entries + * + * Works just like strcmp(), comparing two the table keys, datatype, then values + * + * \param [in] entry1 the entry on the left + * \param [in] entry2 the entry on the right + * \return 0 if entries are equal, 0 < if left is greater, 0 > if right is + * greater + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_table_entry_cmp(void const *entry1, void const *entry2); + +/** + * Open a socket to a remote host + * + * \deprecated This function is deprecated in favor of amqp_socket_open() + * + * Looks up the hostname, then attempts to open a socket to the host using + * the specified portnumber. It also sets various options on the socket to + * improve performance and correctness. + * + * \param [in] hostname this can be a hostname or IP address. + * Both IPv4 and IPv6 are acceptable + * \param [in] portnumber the port to connect on. RabbitMQ brokers + * listen on port 5672, and 5671 for SSL + * \return a positive value indicates success and is the sockfd. A negative + * value (see amqp_status_enum)is returned on failure. Possible error codes: + * - AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR Initialization of underlying socket + * library failed. + * - AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED hostname lookup failed. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. errno or + * WSAGetLastError() may return more useful information. + * + * \note IPv6 support was added in v0.3 + * + * \sa amqp_socket_open() amqp_set_sockfd() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_open_socket(char const *hostname, int portnumber); + +/** + * Send initial AMQP header to the broker + * + * \warning this is a low level function intended for those who want to + * interact with the broker at a very low level. Use of this function without + * understanding what it does will result in AMQP protocol errors. + * + * This function sends the AMQP protocol header to the broker. + * + * \param [in] state the connection object + * \return AMQP_STATUS_OK on success, a negative value on failure. Possible + * error codes: + * - AMQP_STATUS_CONNECTION_CLOSED the connection to the broker was closed. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. It is likely the + * underlying socket has been closed. errno or WSAGetLastError() may provide + * further information. + * - AMQP_STATUS_SSL_ERROR a SSL error occurred. The connection to the broker + * was closed. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_send_header(amqp_connection_state_t state); + +/** + * Checks to see if there are any incoming frames ready to be read + * + * Checks to see if there are any amqp_frame_t objects buffered by the + * amqp_connection_state_t object. Having one or more frames buffered means + * that amqp_simple_wait_frame() or amqp_simple_wait_frame_noblock() will + * return a frame without potentially blocking on a read() call. + * + * \param [in] state the connection object + * \return TRUE if there are frames enqueued, FALSE otherwise + * + * \sa amqp_simple_wait_frame() amqp_simple_wait_frame_noblock() + * amqp_data_in_buffer() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_frames_enqueued(amqp_connection_state_t state); + +/** + * Read a single amqp_frame_t + * + * Waits for the next amqp_frame_t frame to be read from the broker. + * This function has the potential to block for a long time in the case of + * waiting for a basic.deliver method frame from the broker. + * + * The library may buffer frames. When an amqp_connection_state_t object + * has frames buffered calling amqp_simple_wait_frame() will return an + * amqp_frame_t without entering a blocking read(). You can test to see if + * an amqp_connection_state_t object has frames buffered by calling the + * amqp_frames_enqueued() function. + * + * The library has a socket read buffer. When there is data in an + * amqp_connection_state_t read buffer, amqp_simple_wait_frame() may return an + * amqp_frame_t without entering a blocking read(). You can test to see if an + * amqp_connection_state_t object has data in its read buffer by calling the + * amqp_data_in_buffer() function. + * + * \param [in] state the connection object + * \param [out] decoded_frame the frame + * \return AMQP_STATUS_OK on success, an amqp_status_enum value + * is returned otherwise. Possible errors include: + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat + * from the broker. The connection has been closed. + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has + * been closed + * - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has + * been closed. + * + * \sa amqp_simple_wait_frame_noblock() amqp_frames_enqueued() + * amqp_data_in_buffer() + * + * \note as of v0.4.0 this function will no longer return heartbeat frames + * when enabled by specifying a non-zero heartbeat value in amqp_login(). + * Heartbeating is handled internally by the library. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_simple_wait_frame(amqp_connection_state_t state, + amqp_frame_t *decoded_frame); + +/** + * Read a single amqp_frame_t with a timeout. + * + * Waits for the next amqp_frame_t frame to be read from the broker, up to + * a timespan specified by tv. The function will return AMQP_STATUS_TIMEOUT + * if the timeout is reached. The tv value is not modified by the function. + * + * If a 0 timeval is specified, the function behaves as if its non-blocking: it + * will test to see if a frame can be read from the broker, and return + * immediately. + * + * If NULL is passed in for tv, the function will behave like + * amqp_simple_wait_frame() and block until a frame is received from the broker + * + * The library may buffer frames. When an amqp_connection_state_t object + * has frames buffered calling amqp_simple_wait_frame_noblock() will return an + * amqp_frame_t without entering a blocking read(). You can test to see if an + * amqp_connection_state_t object has frames buffered by calling the + * amqp_frames_enqueued() function. + * + * The library has a socket read buffer. When there is data in an + * amqp_connection_state_t read buffer, amqp_simple_wait_frame_noblock() may + * return + * an amqp_frame_t without entering a blocking read(). You can test to see if an + * amqp_connection_state_t object has data in its read buffer by calling the + * amqp_data_in_buffer() function. + * + * \note This function does not return heartbeat frames. When enabled, + * heartbeating is handed internally internally by the library. + * + * \param [in,out] state the connection object + * \param [out] decoded_frame the frame + * \param [in] tv the maximum time to wait for a frame to be read. Setting + * tv->tv_sec = 0 and tv->tv_usec = 0 will do a non-blocking read. Specifying + * NULL for tv will make the function block until a frame is read. + * \return AMQP_STATUS_OK on success. An amqp_status_enum value is returned + * otherwise. Possible errors include: + * - AMQP_STATUS_TIMEOUT the timeout was reached while waiting for a frame + * from the broker. + * - AMQP_STATUS_INVALID_PARAMETER the tv parameter contains an invalid value. + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat + * from the broker. The connection has been closed. + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has + * been closed + * - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has + * been closed. + * + * \sa amqp_simple_wait_frame() amqp_frames_enqueued() amqp_data_in_buffer() + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_simple_wait_frame_noblock(amqp_connection_state_t state, + amqp_frame_t *decoded_frame, + struct timeval *tv); + +/** + * Waits for a specific method from the broker + * + * \warning You probably don't want to use this function. If this function + * doesn't receive exactly the frame requested it closes the whole connection. + * + * Waits for a single method on a channel from the broker. + * If a frame is received that does not match expected_channel + * or expected_method the program will abort + * + * \param [in] state the connection object + * \param [in] expected_channel the channel that the method should be delivered + * on + * \param [in] expected_method the method to wait for + * \param [out] output the method + * \returns AMQP_STATUS_OK on success. An amqp_status_enum value is returned + * otherwise. Possible errors include: + * - AMQP_STATUS_WRONG_METHOD a frame containing the wrong method, wrong frame + * type or wrong channel was received. The connection is closed. + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat + * from the broker. The connection has been closed. + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has + * been closed + * - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has + * been closed. + * + * \since v0.1 + */ + +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_simple_wait_method(amqp_connection_state_t state, + amqp_channel_t expected_channel, + amqp_method_number_t expected_method, + amqp_method_t *output); + +/** + * Sends a method to the broker + * + * This is a thin wrapper around amqp_send_frame(), providing a way to send + * a method to the broker on a specified channel. + * + * \param [in] state the connection object + * \param [in] channel the channel object + * \param [in] id the method number + * \param [in] decoded the method object + * \returns AMQP_STATUS_OK on success, an amqp_status_enum value otherwise. + * Possible errors include: + * - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or + * properties was too large to fit in a single AMQP frame, or the + * method contains an invalid value. The frame was not sent. + * - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is + * too large to fit in a single AMQP frame. Frame was not sent. + * - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in + * - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame + * was sent + * - AMQP_STATUS_SOCKET_ERROR + * - AMQP_STATUS_SSL_ERROR + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_send_method(amqp_connection_state_t state, + amqp_channel_t channel, amqp_method_number_t id, + void *decoded); + +/** + * Sends a method to the broker and waits for a method response + * + * \param [in] state the connection object + * \param [in] channel the channel object + * \param [in] request_id the method number of the request + * \param [in] expected_reply_ids a 0 terminated array of expected response + * method numbers + * \param [in] decoded_request_method the method to be sent to the broker + * \return a amqp_rpc_reply_t: + * - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred + * within the library. Examine r.library_error and compare it against + * amqp_status_enum values to determine the error. + * + * \sa amqp_simple_rpc_decoded() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_simple_rpc( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_method_number_t request_id, amqp_method_number_t *expected_reply_ids, + void *decoded_request_method); + +/** + * Sends a method to the broker and waits for a method response + * + * \param [in] state the connection object + * \param [in] channel the channel object + * \param [in] request_id the method number of the request + * \param [in] reply_id the method number expected in response + * \param [in] decoded_request_method the request method + * \return a pointer to the method returned from the broker, or NULL on error. + * On error amqp_get_rpc_reply() will return an amqp_rpc_reply_t with + * details on the error that occurred. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void *AMQP_CALL amqp_simple_rpc_decoded(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_method_number_t request_id, + amqp_method_number_t reply_id, + void *decoded_request_method); + +/** + * Get the last global amqp_rpc_reply + * + * The API methods corresponding to most synchronous AMQP methods + * return a pointer to the decoded method result. Upon error, they + * return NULL, and we need some way of discovering what, if anything, + * went wrong. amqp_get_rpc_reply() returns the most recent + * amqp_rpc_reply_t instance corresponding to such an API operation + * for the given connection. + * + * Only use it for operations that do not themselves return + * amqp_rpc_reply_t; operations that do return amqp_rpc_reply_t + * generally do NOT update this per-connection-global amqp_rpc_reply_t + * instance. + * + * \param [in] state the connection object + * \return the most recent amqp_rpc_reply_t: + * - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred + * within the library. Examine r.library_error and compare it against + * amqp_status_enum values to determine the error. + * + * \sa amqp_simple_rpc_decoded() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_get_rpc_reply(amqp_connection_state_t state); + +/** + * Login to the broker + * + * After using amqp_open_socket and amqp_set_sockfd, call + * amqp_login to complete connecting to the broker + * + * \param [in] state the connection object + * \param [in] vhost the virtual host to connect to on the broker. The default + * on most brokers is "/" + * \param [in] channel_max the limit for number of channels for the connection. + * 0 means no limit, and is a good default + * (AMQP_DEFAULT_MAX_CHANNELS) + * Note that the maximum number of channels the protocol supports + * is 65535 (2^16, with the 0-channel reserved). The server can + * set a lower channel_max and then the client will use the lowest + * of the two + * \param [in] frame_max the maximum size of an AMQP frame on the wire to + * request of the broker for this connection. 4096 is the minimum + * size, 2^31-1 is the maximum, a good default is 131072 (128KB), + * or AMQP_DEFAULT_FRAME_SIZE + * \param [in] heartbeat the number of seconds between heartbeat frames to + * request of the broker. A value of 0 disables heartbeats. + * Note rabbitmq-c only has partial support for heartbeats, as of + * v0.4.0 they are only serviced during amqp_basic_publish() and + * amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock() + * \param [in] sasl_method the SASL method to authenticate with the broker. + * followed by the authentication information. The following SASL + * methods are implemented: + * - AMQP_SASL_METHOD_PLAIN, the AMQP_SASL_METHOD_PLAIN argument + * should be followed by two arguments in this order: + * const char* username, and const char* password. + * - AMQP_SASL_METHOD_EXTERNAL, the AMQP_SASL_METHOD_EXTERNAL + * argument should be followed one argument: + * const char* identity. + * \return amqp_rpc_reply_t indicating success or failure. + * - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors + * from the broker when logging in will be represented by the broker closing + * the socket. In this case r.library_error will be set to + * AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of + * error conditions including: invalid vhost, authentication failure. + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_login(amqp_connection_state_t state, + char const *vhost, int channel_max, + int frame_max, int heartbeat, + amqp_sasl_method_enum sasl_method, ...); + +/** + * Login to the broker passing a properties table + * + * This function is similar to amqp_login() and differs in that it provides a + * way to pass client properties to the broker. This is commonly used to + * negotiate newer protocol features as they are supported by the broker. + * + * \param [in] state the connection object + * \param [in] vhost the virtual host to connect to on the broker. The default + * on most brokers is "/" + * \param [in] channel_max the limit for the number of channels for the + * connection. + * 0 means no limit, and is a good default + * (AMQP_DEFAULT_MAX_CHANNELS) + * Note that the maximum number of channels the protocol supports + * is 65535 (2^16, with the 0-channel reserved). The server can + * set a lower channel_max and then the client will use the lowest + * of the two + * \param [in] frame_max the maximum size of an AMQP frame ont he wire to + * request of the broker for this connection. 4096 is the minimum + * size, 2^31-1 is the maximum, a good default is 131072 (128KB), + * or AMQP_DEFAULT_FRAME_SIZE + * \param [in] heartbeat the number of seconds between heartbeat frame to + * request of the broker. A value of 0 disables heartbeats. + * Note rabbitmq-c only has partial support for hearts, as of + * v0.4.0 heartbeats are only serviced during amqp_basic_publish(), + * and amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock() + * \param [in] properties a table of properties to send the broker. + * \param [in] sasl_method the SASL method to authenticate with the broker + * followed by the authentication information. The following SASL + * methods are implemented: + * - AMQP_SASL_METHOD_PLAIN, the AMQP_SASL_METHOD_PLAIN argument + * should be followed by two arguments in this order: + * const char* username, and const char* password. + * - AMQP_SASL_METHOD_EXTERNAL, the AMQP_SASL_METHOD_EXTERNAL + * argument should be followed one argument: + * const char* identity. + * \return amqp_rpc_reply_t indicating success or failure. + * - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors + * from the broker when logging in will be represented by the broker closing + * the socket. In this case r.library_error will be set to + * AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of + * error conditions including: invalid vhost, authentication failure. + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_login_with_properties( + amqp_connection_state_t state, char const *vhost, int channel_max, + int frame_max, int heartbeat, const amqp_table_t *properties, + amqp_sasl_method_enum sasl_method, ...); + +struct amqp_basic_properties_t_; + +/** + * Publish a message to the broker + * + * Publish a message on an exchange with a routing key. + * + * Note that at the AMQ protocol level basic.publish is an async method: + * this means error conditions that occur on the broker (such as publishing to + * a non-existent exchange) will not be reflected in the return value of this + * function. + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] exchange the exchange on the broker to publish to + * \param [in] routing_key the routing key to use when publishing the message + * \param [in] mandatory indicate to the broker that the message MUST be routed + * to a queue. If the broker cannot do this it should respond with + * a basic.return method. + * \param [in] immediate indicate to the broker that the message MUST be + * delivered to a consumer immediately. If the broker cannot do this + * it should respond with a basic.return method. + * \param [in] properties the properties associated with the message + * \param [in] body the message body + * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. Note + * that basic.publish is an async method, the return value from this + * function only indicates that the message data was successfully + * transmitted to the broker. It does not indicate failures that occur + * on the broker, such as publishing to a non-existent exchange. + * Possible error values: + * - AMQP_STATUS_TIMER_FAILURE: system timer facility returned an error + * the message was not sent. + * - AMQP_STATUS_HEARTBEAT_TIMEOUT: connection timed out waiting for a + * heartbeat from the broker. The message was not sent. + * - AMQP_STATUS_NO_MEMORY: memory allocation failed. The message was + * not sent. + * - AMQP_STATUS_TABLE_TOO_BIG: a table in the properties was too large + * to fit in a single frame. Message was not sent. + * - AMQP_STATUS_CONNECTION_CLOSED: the connection was closed. + * - AMQP_STATUS_SSL_ERROR: a SSL error occurred. + * - AMQP_STATUS_TCP_ERROR: a TCP error occurred. errno or + * WSAGetLastError() may provide more information + * + * Note: this function does heartbeat processing as of v0.4.0 + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_publish( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_boolean_t mandatory, + amqp_boolean_t immediate, struct amqp_basic_properties_t_ const *properties, + amqp_bytes_t body); + +/** + * Closes an channel + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] code the reason for closing the channel, AMQP_REPLY_SUCCESS is a + * good default + * \return amqp_rpc_reply_t indicating success or failure + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_channel_close(amqp_connection_state_t state, + amqp_channel_t channel, int code); + +/** + * Closes the entire connection + * + * Implicitly closes all channels and informs the broker the connection + * is being closed, after receiving acknowledgment from the broker it closes + * the socket. + * + * \param [in] state the connection object + * \param [in] code the reason code for closing the connection. + * AMQP_REPLY_SUCCESS is a good default. + * \return amqp_rpc_reply_t indicating the result + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_connection_close(amqp_connection_state_t state, + int code); + +/** + * Acknowledges a message + * + * Does a basic.ack on a received message + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] delivery_tag the delivery tag of the message to be ack'd + * \param [in] multiple if true, ack all messages up to this delivery tag, if + * false ack only this delivery tag + * \return 0 on success, 0 > on failing to send the ack to the broker. + * this will not indicate failure if something goes wrong on the + * broker + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_ack(amqp_connection_state_t state, + amqp_channel_t channel, uint64_t delivery_tag, + amqp_boolean_t multiple); + +/** + * Do a basic.get + * + * Synchonously polls the broker for a message in a queue, and + * retrieves the message if a message is in the queue. + * + * \param [in] state the connection object + * \param [in] channel the channel identifier to use + * \param [in] queue the queue name to retrieve from + * \param [in] no_ack if true the message is automatically ack'ed + * if false amqp_basic_ack should be called once the message + * retrieved has been processed + * \return amqp_rpc_reply indicating success or failure + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_basic_get(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_bytes_t queue, + amqp_boolean_t no_ack); + +/** + * Do a basic.reject + * + * Actively reject a message that has been delivered + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] delivery_tag the delivery tag of the message to reject + * \param [in] requeue indicate to the broker whether it should requeue the + * message or just discard it. + * \return 0 on success, 0 > on failing to send the reject method to the broker. + * This will not indicate failure if something goes wrong on the + * broker. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_reject(amqp_connection_state_t state, + amqp_channel_t channel, uint64_t delivery_tag, + amqp_boolean_t requeue); + +/** + * Do a basic.nack + * + * Actively reject a message, this has the same effect as amqp_basic_reject() + * however, amqp_basic_nack() can negatively acknowledge multiple messages with + * one call much like amqp_basic_ack() can acknowledge mutliple messages with + * one call. + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] delivery_tag the delivery tag of the message to reject + * \param [in] multiple if set to 1 negatively acknowledge all unacknowledged + * messages on this channel. + * \param [in] requeue indicate to the broker whether it should requeue the + * message or dead-letter it. + * \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise. + * + * \since v0.5.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_nack(amqp_connection_state_t state, + amqp_channel_t channel, uint64_t delivery_tag, + amqp_boolean_t multiple, amqp_boolean_t requeue); +/** + * Check to see if there is data left in the receive buffer + * + * Can be used to see if there is data still in the buffer, if so + * calling amqp_simple_wait_frame will not immediately enter a + * blocking read. + * + * \param [in] state the connection object + * \return true if there is data in the recieve buffer, false otherwise + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_data_in_buffer(amqp_connection_state_t state); + +/** + * Get the error string for the given error code. + * + * \deprecated This function has been deprecated in favor of + * \ref amqp_error_string2() which returns statically allocated + * string which do not need to be freed by the caller. + * + * The returned string resides on the heap; the caller is responsible + * for freeing it. + * + * \param [in] err return error code + * \return the error string + * + * \since v0.1 + */ +AMQP_DEPRECATED( + AMQP_PUBLIC_FUNCTION char *AMQP_CALL amqp_error_string(int err)); + +/** + * Get the error string for the given error code. + * + * Get an error string associated with an error code. The string is statically + * allocated and does not need to be freed + * + * \param [in] err the error code + * \return the error string + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +const char *AMQP_CALL amqp_error_string2(int err); + +/** + * Deserialize an amqp_table_t from AMQP wireformat + * + * This is an internal function and is not typically used by + * client applications + * + * \param [in] encoded the buffer containing the serialized data + * \param [in] pool memory pool used to allocate the table entries from + * \param [in] output the amqp_table_t structure to fill in. Any existing + * entries will be erased + * \param [in,out] offset The offset into the encoded buffer to start + * reading the serialized table. It will be updated + * by this function to end of the table + * \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure + * Possible error codes: + * - AMQP_STATUS_NO_MEMORY out of memory + * - AMQP_STATUS_BAD_AMQP_DATA invalid wireformat + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_decode_table(amqp_bytes_t encoded, amqp_pool_t *pool, + amqp_table_t *output, size_t *offset); + +/** + * Serializes an amqp_table_t to the AMQP wireformat + * + * This is an internal function and is not typically used by + * client applications + * + * \param [in] encoded the buffer where to serialize the table to + * \param [in] input the amqp_table_t to serialize + * \param [in,out] offset The offset into the encoded buffer to start + * writing the serialized table. It will be updated + * by this function to where writing left off + * \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure + * Possible error codes: + * - AMQP_STATUS_TABLE_TOO_BIG the serialized form is too large for the + * buffer + * - AMQP_STATUS_BAD_AMQP_DATA invalid table + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, + size_t *offset); + +/** + * Create a deep-copy of an amqp_table_t object + * + * Creates a deep-copy of an amqp_table_t object, using the provided pool + * object to allocate the necessary memory. This memory can be freed later by + * call recycle_amqp_pool(), or empty_amqp_pool() + * + * \param [in] original the table to copy + * \param [in,out] clone the table to copy to + * \param [in] pool the initialized memory pool to do allocations for the table + * from + * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. + * Possible error values: + * - AMQP_STATUS_NO_MEMORY - memory allocation failure. + * - AMQP_STATUS_INVALID_PARAMETER - invalid table (e.g., no key name) + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_table_clone(const amqp_table_t *original, + amqp_table_t *clone, amqp_pool_t *pool); + +/** + * A message object + * + * \since v0.4.0 + */ +typedef struct amqp_message_t_ { + amqp_basic_properties_t properties; /**< message properties */ + amqp_bytes_t body; /**< message body */ + amqp_pool_t pool; /**< pool used to allocate properties */ +} amqp_message_t; + +/** + * Reads the next message on a channel + * + * Reads a complete message (header + body) on a specified channel. This + * function is intended to be used with amqp_basic_get() or when an + * AMQP_BASIC_DELIVERY_METHOD method is received. + * + * \param [in,out] state the connection object + * \param [in] channel the channel on which to read the message from + * \param [in,out] message a pointer to a amqp_message_t object. Caller should + * call amqp_message_destroy() when it is done using the + * fields in the message object. The caller is responsible for + * allocating/destroying the amqp_message_t object itself. + * \param [in] flags pass in 0. Currently unused. + * \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL on + * success. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_read_message(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_message_t *message, + int flags); + +/** + * Frees memory associated with a amqp_message_t allocated in amqp_read_message + * + * \param [in] message + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_destroy_message(amqp_message_t *message); + +/** + * Envelope object + * + * \since v0.4.0 + */ +typedef struct amqp_envelope_t_ { + amqp_channel_t channel; /**< channel message was delivered on */ + amqp_bytes_t + consumer_tag; /**< the consumer tag the message was delivered to */ + uint64_t delivery_tag; /**< the messages delivery tag */ + amqp_boolean_t redelivered; /**< flag indicating whether this message is being + redelivered */ + amqp_bytes_t exchange; /**< exchange this message was published to */ + amqp_bytes_t + routing_key; /**< the routing key this message was published with */ + amqp_message_t message; /**< the message */ +} amqp_envelope_t; + +/** + * Wait for and consume a message + * + * Waits for a basic.deliver method on any channel, upon receipt of + * basic.deliver it reads that message, and returns. If any other method is + * received before basic.deliver, this function will return an amqp_rpc_reply_t + * with ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, and + * ret.library_error == AMQP_STATUS_UNEXPECTED_STATE. The caller should then + * call amqp_simple_wait_frame() to read this frame and take appropriate action. + * + * This function should be used after starting a consumer with the + * amqp_basic_consume() function + * + * \param [in,out] state the connection object + * \param [in,out] envelope a pointer to a amqp_envelope_t object. Caller + * should call #amqp_destroy_envelope() when it is done using + * the fields in the envelope object. The caller is responsible + * for allocating/destroying the amqp_envelope_t object itself. + * \param [in] timeout a timeout to wait for a message delivery. Passing in + * NULL will result in blocking behavior. + * \param [in] flags pass in 0. Currently unused. + * \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL + * on success. If ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, + * and ret.library_error == AMQP_STATUS_UNEXPECTED_STATE, a frame other + * than AMQP_BASIC_DELIVER_METHOD was received, the caller should call + * amqp_simple_wait_frame() to read this frame and take appropriate + * action. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_consume_message(amqp_connection_state_t state, + amqp_envelope_t *envelope, + struct timeval *timeout, + int flags); + +/** + * Frees memory associated with a amqp_envelope_t allocated in + * amqp_consume_message() + * + * \param [in] envelope + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_destroy_envelope(amqp_envelope_t *envelope); + +/** + * Parameters used to connect to the RabbitMQ broker + * + * \since v0.2 + */ +struct amqp_connection_info { + char *user; /**< the username to authenticate with the broker, default on most + broker is 'guest' */ + char *password; /**< the password to authenticate with the broker, default on + most brokers is 'guest' */ + char *host; /**< the hostname of the broker */ + char *vhost; /**< the virtual host on the broker to connect to, a good default + is "/" */ + int port; /**< the port that the broker is listening on, default on most + brokers is 5672 */ + amqp_boolean_t ssl; +}; + +/** + * Initialze an amqp_connection_info to default values + * + * The default values are: + * - user: "guest" + * - password: "guest" + * - host: "localhost" + * - vhost: "/" + * - port: 5672 + * + * \param [out] parsed the connection info to set defaults on + * + * \since v0.2 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL + amqp_default_connection_info(struct amqp_connection_info *parsed); + +/** + * Parse a connection URL + * + * An amqp connection url takes the form: + * + * amqp://[$USERNAME[:$PASSWORD]\@]$HOST[:$PORT]/[$VHOST] + * + * Examples: + * amqp://guest:guest\@localhost:5672// + * amqp://guest:guest\@localhost/myvhost + * + * Any missing parts of the URL will be set to the defaults specified in + * amqp_default_connection_info. For amqps: URLs the default port will be set + * to 5671 instead of 5672 for non-SSL URLs. + * + * \note This function modifies url parameter. + * + * \param [in] url URI to parse, note that this parameter is modified by the + * function. + * \param [out] parsed the connection info gleaned from the URI. The char* + * members will point to parts of the url input parameter. + * Memory management will depend on how the url is allocated. + * \returns AMQP_STATUS_OK on success, AMQP_STATUS_BAD_URL on failure + * + * \since v0.2 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_parse_url(char *url, struct amqp_connection_info *parsed); + +/* socket API */ + +/** + * Open a socket connection. + * + * This function opens a socket connection returned from amqp_tcp_socket_new() + * or amqp_ssl_socket_new(). This function should be called after setting + * socket options and prior to assigning the socket to an AMQP connection with + * amqp_set_socket(). + * + * \param [in,out] self A socket object. + * \param [in] host Connect to this host. + * \param [in] port Connect on this remote port. + * + * \return AMQP_STATUS_OK on success, an amqp_status_enum on failure + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_socket_open(amqp_socket_t *self, const char *host, int port); + +/** + * Open a socket connection. + * + * This function opens a socket connection returned from amqp_tcp_socket_new() + * or amqp_ssl_socket_new(). This function should be called after setting + * socket options and prior to assigning the socket to an AMQP connection with + * amqp_set_socket(). + * + * \param [in,out] self A socket object. + * \param [in] host Connect to this host. + * \param [in] port Connect on this remote port. + * \param [in] timeout Max allowed time to spent on opening. If NULL - run in + * blocking mode + * + * \return AMQP_STATUS_OK on success, an amqp_status_enum on failure. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_socket_open_noblock(amqp_socket_t *self, const char *host, + int port, struct timeval *timeout); + +/** + * Get the socket descriptor in use by a socket object. + * + * Retrieve the underlying socket descriptor. This function can be used to + * perform low-level socket operations that aren't supported by the socket + * interface. Use with caution! + * + * \param [in,out] self A socket object. + * + * \return The underlying socket descriptor, or -1 if there is no socket + * descriptor associated with + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_socket_get_sockfd(amqp_socket_t *self); + +/** + * Get the socket object associated with a amqp_connection_state_t + * + * \param [in] state the connection object to get the socket from + * \return a pointer to the socket object, or NULL if one has not been assigned + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_socket_t *AMQP_CALL amqp_get_socket(amqp_connection_state_t state); + +/** + * Get the broker properties table + * + * \param [in] state the connection object + * \return a pointer to an amqp_table_t containing the properties advertised + * by the broker on connection. The connection object owns the table, it + * should not be modified. + * + * \since v0.5.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_table_t *AMQP_CALL + amqp_get_server_properties(amqp_connection_state_t state); + +/** + * Get the client properties table + * + * Get the properties that were passed to the broker on connection. + * + * \param [in] state the connection object + * \return a pointer to an amqp_table_t containing the properties advertised + * by the client on connection. The connection object owns the table, it + * should not be modified. + * + * \since v0.7.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_table_t *AMQP_CALL + amqp_get_client_properties(amqp_connection_state_t state); + +/** + * Get the login handshake timeout. + * + * amqp_login and amqp_login_with_properties perform the login handshake with + * the broker. This function returns the timeout associated with completing + * this operation from the client side. This value can be set by using the + * amqp_set_handshake_timeout. + * + * Note that the RabbitMQ broker has configurable timeout for completing the + * login handshake, the default is 10 seconds. rabbitmq-c has a default of 12 + * seconds. + * + * \param [in] state the connection object + * \return a struct timeval representing the current login timeout for the state + * object. A NULL value represents an infinite timeout. The memory returned is + * owned by the connection object. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +struct timeval *AMQP_CALL + amqp_get_handshake_timeout(amqp_connection_state_t state); + +/** + * Set the login handshake timeout. + * + * amqp_login and amqp_login_with_properties perform the login handshake with + * the broker. This function sets the timeout associated with completing this + * operation from the client side. + * + * The timeout must be set before amqp_login or amqp_login_with_properties is + * called to change from the default timeout. + * + * Note that the RabbitMQ broker has a configurable timeout for completing the + * login handshake, the default is 10 seconds. rabbitmq-c has a default of 12 + * seconds. + * + * \param [in] state the connection object + * \param [in] timeout a struct timeval* representing new login timeout for the + * state object. NULL represents an infinite timeout. The value of timeout is + * copied internally, the caller is responsible for ownership of the passed in + * pointer, it does not need to remain valid after this function is called. + * \return AMQP_STATUS_OK on success. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_set_handshake_timeout(amqp_connection_state_t state, + struct timeval *timeout); + +/** + * Get the RPC timeout + * + * Gets the timeout for any RPC-style AMQP command (e.g., amqp_queue_declare). + * This timeout may be changed at any time by calling \amqp_set_rpc_timeout + * function with a new timeout. The timeout applies individually to each RPC + * that is made. + * + * The default value is NULL, or an infinite timeout. + * + * When an RPC times out, the function will return an error AMQP_STATUS_TIMEOUT, + * and the connection will be closed. + * + *\warning RPC-timeouts are an advanced feature intended to be used to detect + * dead connections quickly when the rabbitmq-c implementation of heartbeats + * does not work. Do not use RPC timeouts unless you understand the implications + * of doing so. + * + * \param [in] state the connection object + * \return a struct timeval representing the current RPC timeout for the state + * object. A NULL value represents an infinite timeout. The memory returned is + * owned by the connection object. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +struct timeval *AMQP_CALL amqp_get_rpc_timeout(amqp_connection_state_t state); + +/** + * Set the RPC timeout + * + * Sets the timeout for any RPC-style AMQP command (e.g., amqp_queue_declare). + * This timeout may be changed at any time by calling this function with a new + * timeout. The timeout applies individually to each RPC that is made. + * + * The default value is NULL, or an infinite timeout. + * + * When an RPC times out, the function will return an error AMQP_STATUS_TIMEOUT, + * and the connection will be closed. + * + *\warning RPC-timeouts are an advanced feature intended to be used to detect + * dead connections quickly when the rabbitmq-c implementation of heartbeats + * does not work. Do not use RPC timeouts unless you understand the implications + * of doing so. + * + * \param [in] state the connection object + * \param [in] timeout a struct timeval* representing new RPC timeout for the + * state object. NULL represents an infinite timeout. The value of timeout is + * copied internally, the caller is responsible for ownership of the passed + * pointer, it does not need to remain valid after this function is called. + * \return AMQP_STATUS_SUCCESS on success. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_set_rpc_timeout(amqp_connection_state_t state, + struct timeval *timeout); + +AMQP_END_DECLS + +#endif /* AMQP_H */ diff --git a/ext/librabbitmq/macos/include/amqp_framing.h b/ext/librabbitmq/macos/include/amqp_framing.h new file mode 100644 index 000000000..fb20acc1f --- /dev/null +++ b/ext/librabbitmq/macos/include/amqp_framing.h @@ -0,0 +1,1144 @@ +/* Generated code. Do not edit. Edit and re-run codegen.py instead. + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +/** @file amqp_framing.h */ +#ifndef AMQP_FRAMING_H +#define AMQP_FRAMING_H + +#include + +AMQP_BEGIN_DECLS + +#define AMQP_PROTOCOL_VERSION_MAJOR 0 /**< AMQP protocol version major */ +#define AMQP_PROTOCOL_VERSION_MINOR 9 /**< AMQP protocol version minor */ +#define AMQP_PROTOCOL_VERSION_REVISION \ + 1 /**< AMQP protocol version revision \ + */ +#define AMQP_PROTOCOL_PORT 5672 /**< Default AMQP Port */ +#define AMQP_FRAME_METHOD 1 /**< Constant: FRAME-METHOD */ +#define AMQP_FRAME_HEADER 2 /**< Constant: FRAME-HEADER */ +#define AMQP_FRAME_BODY 3 /**< Constant: FRAME-BODY */ +#define AMQP_FRAME_HEARTBEAT 8 /**< Constant: FRAME-HEARTBEAT */ +#define AMQP_FRAME_MIN_SIZE 4096 /**< Constant: FRAME-MIN-SIZE */ +#define AMQP_FRAME_END 206 /**< Constant: FRAME-END */ +#define AMQP_REPLY_SUCCESS 200 /**< Constant: REPLY-SUCCESS */ +#define AMQP_CONTENT_TOO_LARGE 311 /**< Constant: CONTENT-TOO-LARGE */ +#define AMQP_NO_ROUTE 312 /**< Constant: NO-ROUTE */ +#define AMQP_NO_CONSUMERS 313 /**< Constant: NO-CONSUMERS */ +#define AMQP_ACCESS_REFUSED 403 /**< Constant: ACCESS-REFUSED */ +#define AMQP_NOT_FOUND 404 /**< Constant: NOT-FOUND */ +#define AMQP_RESOURCE_LOCKED 405 /**< Constant: RESOURCE-LOCKED */ +#define AMQP_PRECONDITION_FAILED 406 /**< Constant: PRECONDITION-FAILED */ +#define AMQP_CONNECTION_FORCED 320 /**< Constant: CONNECTION-FORCED */ +#define AMQP_INVALID_PATH 402 /**< Constant: INVALID-PATH */ +#define AMQP_FRAME_ERROR 501 /**< Constant: FRAME-ERROR */ +#define AMQP_SYNTAX_ERROR 502 /**< Constant: SYNTAX-ERROR */ +#define AMQP_COMMAND_INVALID 503 /**< Constant: COMMAND-INVALID */ +#define AMQP_CHANNEL_ERROR 504 /**< Constant: CHANNEL-ERROR */ +#define AMQP_UNEXPECTED_FRAME 505 /**< Constant: UNEXPECTED-FRAME */ +#define AMQP_RESOURCE_ERROR 506 /**< Constant: RESOURCE-ERROR */ +#define AMQP_NOT_ALLOWED 530 /**< Constant: NOT-ALLOWED */ +#define AMQP_NOT_IMPLEMENTED 540 /**< Constant: NOT-IMPLEMENTED */ +#define AMQP_INTERNAL_ERROR 541 /**< Constant: INTERNAL-ERROR */ + +/* Function prototypes. */ + +/** + * Get constant name string from constant + * + * @param [in] constantNumber constant to get the name of + * @returns string describing the constant. String is managed by + * the library and should not be free()'d by the program + */ +AMQP_PUBLIC_FUNCTION +char const *AMQP_CALL amqp_constant_name(int constantNumber); + +/** + * Checks to see if a constant is a hard error + * + * A hard error occurs when something severe enough + * happens that the connection must be closed. + * + * @param [in] constantNumber the error constant + * @returns true if its a hard error, false otherwise + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_constant_is_hard_error(int constantNumber); + +/** + * Get method name string from method number + * + * @param [in] methodNumber the method number + * @returns method name string. String is managed by the library + * and should not be freed()'d by the program + */ +AMQP_PUBLIC_FUNCTION +char const *AMQP_CALL amqp_method_name(amqp_method_number_t methodNumber); + +/** + * Check whether a method has content + * + * A method that has content will receive the method frame + * a properties frame, then 1 to N body frames + * + * @param [in] methodNumber the method number + * @returns true if method has content, false otherwise + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL + amqp_method_has_content(amqp_method_number_t methodNumber); + +/** + * Decodes a method from AMQP wireformat + * + * @param [in] methodNumber the method number for the decoded parameter + * @param [in] pool the memory pool to allocate the decoded method from + * @param [in] encoded the encoded byte string buffer + * @param [out] decoded pointer to the decoded method struct + * @returns 0 on success, an error code otherwise + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_decode_method(amqp_method_number_t methodNumber, + amqp_pool_t *pool, amqp_bytes_t encoded, + void **decoded); + +/** + * Decodes a header frame properties structure from AMQP wireformat + * + * @param [in] class_id the class id for the decoded parameter + * @param [in] pool the memory pool to allocate the decoded properties from + * @param [in] encoded the encoded byte string buffer + * @param [out] decoded pointer to the decoded properties struct + * @returns 0 on success, an error code otherwise + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_decode_properties(uint16_t class_id, amqp_pool_t *pool, + amqp_bytes_t encoded, void **decoded); + +/** + * Encodes a method structure in AMQP wireformat + * + * @param [in] methodNumber the method number for the decoded parameter + * @param [in] decoded the method structure (e.g., amqp_connection_start_t) + * @param [in] encoded an allocated byte buffer for the encoded method + * structure to be written to. If the buffer isn't large enough + * to hold the encoded method, an error code will be returned. + * @returns 0 on success, an error code otherwise. + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_encode_method(amqp_method_number_t methodNumber, + void *decoded, amqp_bytes_t encoded); + +/** + * Encodes a properties structure in AMQP wireformat + * + * @param [in] class_id the class id for the decoded parameter + * @param [in] decoded the properties structure (e.g., amqp_basic_properties_t) + * @param [in] encoded an allocated byte buffer for the encoded properties to + * written to. + * If the buffer isn't large enough to hold the encoded method, an + * an error code will be returned + * @returns 0 on success, an error code otherwise. + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_encode_properties(uint16_t class_id, void *decoded, + amqp_bytes_t encoded); + +/* Method field records. */ + +#define AMQP_CONNECTION_START_METHOD \ + ((amqp_method_number_t)0x000A000A) /**< connection.start method id \ + @internal 10, 10; 655370 */ +/** connection.start method fields */ +typedef struct amqp_connection_start_t_ { + uint8_t version_major; /**< version-major */ + uint8_t version_minor; /**< version-minor */ + amqp_table_t server_properties; /**< server-properties */ + amqp_bytes_t mechanisms; /**< mechanisms */ + amqp_bytes_t locales; /**< locales */ +} amqp_connection_start_t; + +#define AMQP_CONNECTION_START_OK_METHOD \ + ((amqp_method_number_t)0x000A000B) /**< connection.start-ok method id \ + @internal 10, 11; 655371 */ +/** connection.start-ok method fields */ +typedef struct amqp_connection_start_ok_t_ { + amqp_table_t client_properties; /**< client-properties */ + amqp_bytes_t mechanism; /**< mechanism */ + amqp_bytes_t response; /**< response */ + amqp_bytes_t locale; /**< locale */ +} amqp_connection_start_ok_t; + +#define AMQP_CONNECTION_SECURE_METHOD \ + ((amqp_method_number_t)0x000A0014) /**< connection.secure method id \ + @internal 10, 20; 655380 */ +/** connection.secure method fields */ +typedef struct amqp_connection_secure_t_ { + amqp_bytes_t challenge; /**< challenge */ +} amqp_connection_secure_t; + +#define AMQP_CONNECTION_SECURE_OK_METHOD \ + ((amqp_method_number_t)0x000A0015) /**< connection.secure-ok method id \ + @internal 10, 21; 655381 */ +/** connection.secure-ok method fields */ +typedef struct amqp_connection_secure_ok_t_ { + amqp_bytes_t response; /**< response */ +} amqp_connection_secure_ok_t; + +#define AMQP_CONNECTION_TUNE_METHOD \ + ((amqp_method_number_t)0x000A001E) /**< connection.tune method id \ + @internal 10, 30; 655390 */ +/** connection.tune method fields */ +typedef struct amqp_connection_tune_t_ { + uint16_t channel_max; /**< channel-max */ + uint32_t frame_max; /**< frame-max */ + uint16_t heartbeat; /**< heartbeat */ +} amqp_connection_tune_t; + +#define AMQP_CONNECTION_TUNE_OK_METHOD \ + ((amqp_method_number_t)0x000A001F) /**< connection.tune-ok method id \ + @internal 10, 31; 655391 */ +/** connection.tune-ok method fields */ +typedef struct amqp_connection_tune_ok_t_ { + uint16_t channel_max; /**< channel-max */ + uint32_t frame_max; /**< frame-max */ + uint16_t heartbeat; /**< heartbeat */ +} amqp_connection_tune_ok_t; + +#define AMQP_CONNECTION_OPEN_METHOD \ + ((amqp_method_number_t)0x000A0028) /**< connection.open method id \ + @internal 10, 40; 655400 */ +/** connection.open method fields */ +typedef struct amqp_connection_open_t_ { + amqp_bytes_t virtual_host; /**< virtual-host */ + amqp_bytes_t capabilities; /**< capabilities */ + amqp_boolean_t insist; /**< insist */ +} amqp_connection_open_t; + +#define AMQP_CONNECTION_OPEN_OK_METHOD \ + ((amqp_method_number_t)0x000A0029) /**< connection.open-ok method id \ + @internal 10, 41; 655401 */ +/** connection.open-ok method fields */ +typedef struct amqp_connection_open_ok_t_ { + amqp_bytes_t known_hosts; /**< known-hosts */ +} amqp_connection_open_ok_t; + +#define AMQP_CONNECTION_CLOSE_METHOD \ + ((amqp_method_number_t)0x000A0032) /**< connection.close method id \ + @internal 10, 50; 655410 */ +/** connection.close method fields */ +typedef struct amqp_connection_close_t_ { + uint16_t reply_code; /**< reply-code */ + amqp_bytes_t reply_text; /**< reply-text */ + uint16_t class_id; /**< class-id */ + uint16_t method_id; /**< method-id */ +} amqp_connection_close_t; + +#define AMQP_CONNECTION_CLOSE_OK_METHOD \ + ((amqp_method_number_t)0x000A0033) /**< connection.close-ok method id \ + @internal 10, 51; 655411 */ +/** connection.close-ok method fields */ +typedef struct amqp_connection_close_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_connection_close_ok_t; + +#define AMQP_CONNECTION_BLOCKED_METHOD \ + ((amqp_method_number_t)0x000A003C) /**< connection.blocked method id \ + @internal 10, 60; 655420 */ +/** connection.blocked method fields */ +typedef struct amqp_connection_blocked_t_ { + amqp_bytes_t reason; /**< reason */ +} amqp_connection_blocked_t; + +#define AMQP_CONNECTION_UNBLOCKED_METHOD \ + ((amqp_method_number_t)0x000A003D) /**< connection.unblocked method id \ + @internal 10, 61; 655421 */ +/** connection.unblocked method fields */ +typedef struct amqp_connection_unblocked_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_connection_unblocked_t; + +#define AMQP_CHANNEL_OPEN_METHOD \ + ((amqp_method_number_t)0x0014000A) /**< channel.open method id @internal \ + 20, 10; 1310730 */ +/** channel.open method fields */ +typedef struct amqp_channel_open_t_ { + amqp_bytes_t out_of_band; /**< out-of-band */ +} amqp_channel_open_t; + +#define AMQP_CHANNEL_OPEN_OK_METHOD \ + ((amqp_method_number_t)0x0014000B) /**< channel.open-ok method id \ + @internal 20, 11; 1310731 */ +/** channel.open-ok method fields */ +typedef struct amqp_channel_open_ok_t_ { + amqp_bytes_t channel_id; /**< channel-id */ +} amqp_channel_open_ok_t; + +#define AMQP_CHANNEL_FLOW_METHOD \ + ((amqp_method_number_t)0x00140014) /**< channel.flow method id @internal \ + 20, 20; 1310740 */ +/** channel.flow method fields */ +typedef struct amqp_channel_flow_t_ { + amqp_boolean_t active; /**< active */ +} amqp_channel_flow_t; + +#define AMQP_CHANNEL_FLOW_OK_METHOD \ + ((amqp_method_number_t)0x00140015) /**< channel.flow-ok method id \ + @internal 20, 21; 1310741 */ +/** channel.flow-ok method fields */ +typedef struct amqp_channel_flow_ok_t_ { + amqp_boolean_t active; /**< active */ +} amqp_channel_flow_ok_t; + +#define AMQP_CHANNEL_CLOSE_METHOD \ + ((amqp_method_number_t)0x00140028) /**< channel.close method id @internal \ + 20, 40; 1310760 */ +/** channel.close method fields */ +typedef struct amqp_channel_close_t_ { + uint16_t reply_code; /**< reply-code */ + amqp_bytes_t reply_text; /**< reply-text */ + uint16_t class_id; /**< class-id */ + uint16_t method_id; /**< method-id */ +} amqp_channel_close_t; + +#define AMQP_CHANNEL_CLOSE_OK_METHOD \ + ((amqp_method_number_t)0x00140029) /**< channel.close-ok method id \ + @internal 20, 41; 1310761 */ +/** channel.close-ok method fields */ +typedef struct amqp_channel_close_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_channel_close_ok_t; + +#define AMQP_ACCESS_REQUEST_METHOD \ + ((amqp_method_number_t)0x001E000A) /**< access.request method id @internal \ + 30, 10; 1966090 */ +/** access.request method fields */ +typedef struct amqp_access_request_t_ { + amqp_bytes_t realm; /**< realm */ + amqp_boolean_t exclusive; /**< exclusive */ + amqp_boolean_t passive; /**< passive */ + amqp_boolean_t active; /**< active */ + amqp_boolean_t write; /**< write */ + amqp_boolean_t read; /**< read */ +} amqp_access_request_t; + +#define AMQP_ACCESS_REQUEST_OK_METHOD \ + ((amqp_method_number_t)0x001E000B) /**< access.request-ok method id \ + @internal 30, 11; 1966091 */ +/** access.request-ok method fields */ +typedef struct amqp_access_request_ok_t_ { + uint16_t ticket; /**< ticket */ +} amqp_access_request_ok_t; + +#define AMQP_EXCHANGE_DECLARE_METHOD \ + ((amqp_method_number_t)0x0028000A) /**< exchange.declare method id \ + @internal 40, 10; 2621450 */ +/** exchange.declare method fields */ +typedef struct amqp_exchange_declare_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t type; /**< type */ + amqp_boolean_t passive; /**< passive */ + amqp_boolean_t durable; /**< durable */ + amqp_boolean_t auto_delete; /**< auto-delete */ + amqp_boolean_t internal; /**< internal */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_exchange_declare_t; + +#define AMQP_EXCHANGE_DECLARE_OK_METHOD \ + ((amqp_method_number_t)0x0028000B) /**< exchange.declare-ok method id \ + @internal 40, 11; 2621451 */ +/** exchange.declare-ok method fields */ +typedef struct amqp_exchange_declare_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_declare_ok_t; + +#define AMQP_EXCHANGE_DELETE_METHOD \ + ((amqp_method_number_t)0x00280014) /**< exchange.delete method id \ + @internal 40, 20; 2621460 */ +/** exchange.delete method fields */ +typedef struct amqp_exchange_delete_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t exchange; /**< exchange */ + amqp_boolean_t if_unused; /**< if-unused */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_exchange_delete_t; + +#define AMQP_EXCHANGE_DELETE_OK_METHOD \ + ((amqp_method_number_t)0x00280015) /**< exchange.delete-ok method id \ + @internal 40, 21; 2621461 */ +/** exchange.delete-ok method fields */ +typedef struct amqp_exchange_delete_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_delete_ok_t; + +#define AMQP_EXCHANGE_BIND_METHOD \ + ((amqp_method_number_t)0x0028001E) /**< exchange.bind method id @internal \ + 40, 30; 2621470 */ +/** exchange.bind method fields */ +typedef struct amqp_exchange_bind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t destination; /**< destination */ + amqp_bytes_t source; /**< source */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_exchange_bind_t; + +#define AMQP_EXCHANGE_BIND_OK_METHOD \ + ((amqp_method_number_t)0x0028001F) /**< exchange.bind-ok method id \ + @internal 40, 31; 2621471 */ +/** exchange.bind-ok method fields */ +typedef struct amqp_exchange_bind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_bind_ok_t; + +#define AMQP_EXCHANGE_UNBIND_METHOD \ + ((amqp_method_number_t)0x00280028) /**< exchange.unbind method id \ + @internal 40, 40; 2621480 */ +/** exchange.unbind method fields */ +typedef struct amqp_exchange_unbind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t destination; /**< destination */ + amqp_bytes_t source; /**< source */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_exchange_unbind_t; + +#define AMQP_EXCHANGE_UNBIND_OK_METHOD \ + ((amqp_method_number_t)0x00280033) /**< exchange.unbind-ok method id \ + @internal 40, 51; 2621491 */ +/** exchange.unbind-ok method fields */ +typedef struct amqp_exchange_unbind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_unbind_ok_t; + +#define AMQP_QUEUE_DECLARE_METHOD \ + ((amqp_method_number_t)0x0032000A) /**< queue.declare method id @internal \ + 50, 10; 3276810 */ +/** queue.declare method fields */ +typedef struct amqp_queue_declare_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t passive; /**< passive */ + amqp_boolean_t durable; /**< durable */ + amqp_boolean_t exclusive; /**< exclusive */ + amqp_boolean_t auto_delete; /**< auto-delete */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_queue_declare_t; + +#define AMQP_QUEUE_DECLARE_OK_METHOD \ + ((amqp_method_number_t)0x0032000B) /**< queue.declare-ok method id \ + @internal 50, 11; 3276811 */ +/** queue.declare-ok method fields */ +typedef struct amqp_queue_declare_ok_t_ { + amqp_bytes_t queue; /**< queue */ + uint32_t message_count; /**< message-count */ + uint32_t consumer_count; /**< consumer-count */ +} amqp_queue_declare_ok_t; + +#define AMQP_QUEUE_BIND_METHOD \ + ((amqp_method_number_t)0x00320014) /**< queue.bind method id @internal 50, \ + 20; 3276820 */ +/** queue.bind method fields */ +typedef struct amqp_queue_bind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_queue_bind_t; + +#define AMQP_QUEUE_BIND_OK_METHOD \ + ((amqp_method_number_t)0x00320015) /**< queue.bind-ok method id @internal \ + 50, 21; 3276821 */ +/** queue.bind-ok method fields */ +typedef struct amqp_queue_bind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_queue_bind_ok_t; + +#define AMQP_QUEUE_PURGE_METHOD \ + ((amqp_method_number_t)0x0032001E) /**< queue.purge method id @internal \ + 50, 30; 3276830 */ +/** queue.purge method fields */ +typedef struct amqp_queue_purge_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_queue_purge_t; + +#define AMQP_QUEUE_PURGE_OK_METHOD \ + ((amqp_method_number_t)0x0032001F) /**< queue.purge-ok method id @internal \ + 50, 31; 3276831 */ +/** queue.purge-ok method fields */ +typedef struct amqp_queue_purge_ok_t_ { + uint32_t message_count; /**< message-count */ +} amqp_queue_purge_ok_t; + +#define AMQP_QUEUE_DELETE_METHOD \ + ((amqp_method_number_t)0x00320028) /**< queue.delete method id @internal \ + 50, 40; 3276840 */ +/** queue.delete method fields */ +typedef struct amqp_queue_delete_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t if_unused; /**< if-unused */ + amqp_boolean_t if_empty; /**< if-empty */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_queue_delete_t; + +#define AMQP_QUEUE_DELETE_OK_METHOD \ + ((amqp_method_number_t)0x00320029) /**< queue.delete-ok method id \ + @internal 50, 41; 3276841 */ +/** queue.delete-ok method fields */ +typedef struct amqp_queue_delete_ok_t_ { + uint32_t message_count; /**< message-count */ +} amqp_queue_delete_ok_t; + +#define AMQP_QUEUE_UNBIND_METHOD \ + ((amqp_method_number_t)0x00320032) /**< queue.unbind method id @internal \ + 50, 50; 3276850 */ +/** queue.unbind method fields */ +typedef struct amqp_queue_unbind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_table_t arguments; /**< arguments */ +} amqp_queue_unbind_t; + +#define AMQP_QUEUE_UNBIND_OK_METHOD \ + ((amqp_method_number_t)0x00320033) /**< queue.unbind-ok method id \ + @internal 50, 51; 3276851 */ +/** queue.unbind-ok method fields */ +typedef struct amqp_queue_unbind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_queue_unbind_ok_t; + +#define AMQP_BASIC_QOS_METHOD \ + ((amqp_method_number_t)0x003C000A) /**< basic.qos method id @internal 60, \ + 10; 3932170 */ +/** basic.qos method fields */ +typedef struct amqp_basic_qos_t_ { + uint32_t prefetch_size; /**< prefetch-size */ + uint16_t prefetch_count; /**< prefetch-count */ + amqp_boolean_t global; /**< global */ +} amqp_basic_qos_t; + +#define AMQP_BASIC_QOS_OK_METHOD \ + ((amqp_method_number_t)0x003C000B) /**< basic.qos-ok method id @internal \ + 60, 11; 3932171 */ +/** basic.qos-ok method fields */ +typedef struct amqp_basic_qos_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_basic_qos_ok_t; + +#define AMQP_BASIC_CONSUME_METHOD \ + ((amqp_method_number_t)0x003C0014) /**< basic.consume method id @internal \ + 60, 20; 3932180 */ +/** basic.consume method fields */ +typedef struct amqp_basic_consume_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_bytes_t consumer_tag; /**< consumer-tag */ + amqp_boolean_t no_local; /**< no-local */ + amqp_boolean_t no_ack; /**< no-ack */ + amqp_boolean_t exclusive; /**< exclusive */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_basic_consume_t; + +#define AMQP_BASIC_CONSUME_OK_METHOD \ + ((amqp_method_number_t)0x003C0015) /**< basic.consume-ok method id \ + @internal 60, 21; 3932181 */ +/** basic.consume-ok method fields */ +typedef struct amqp_basic_consume_ok_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ +} amqp_basic_consume_ok_t; + +#define AMQP_BASIC_CANCEL_METHOD \ + ((amqp_method_number_t)0x003C001E) /**< basic.cancel method id @internal \ + 60, 30; 3932190 */ +/** basic.cancel method fields */ +typedef struct amqp_basic_cancel_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_basic_cancel_t; + +#define AMQP_BASIC_CANCEL_OK_METHOD \ + ((amqp_method_number_t)0x003C001F) /**< basic.cancel-ok method id \ + @internal 60, 31; 3932191 */ +/** basic.cancel-ok method fields */ +typedef struct amqp_basic_cancel_ok_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ +} amqp_basic_cancel_ok_t; + +#define AMQP_BASIC_PUBLISH_METHOD \ + ((amqp_method_number_t)0x003C0028) /**< basic.publish method id @internal \ + 60, 40; 3932200 */ +/** basic.publish method fields */ +typedef struct amqp_basic_publish_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t mandatory; /**< mandatory */ + amqp_boolean_t immediate; /**< immediate */ +} amqp_basic_publish_t; + +#define AMQP_BASIC_RETURN_METHOD \ + ((amqp_method_number_t)0x003C0032) /**< basic.return method id @internal \ + 60, 50; 3932210 */ +/** basic.return method fields */ +typedef struct amqp_basic_return_t_ { + uint16_t reply_code; /**< reply-code */ + amqp_bytes_t reply_text; /**< reply-text */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ +} amqp_basic_return_t; + +#define AMQP_BASIC_DELIVER_METHOD \ + ((amqp_method_number_t)0x003C003C) /**< basic.deliver method id @internal \ + 60, 60; 3932220 */ +/** basic.deliver method fields */ +typedef struct amqp_basic_deliver_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t redelivered; /**< redelivered */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ +} amqp_basic_deliver_t; + +#define AMQP_BASIC_GET_METHOD \ + ((amqp_method_number_t)0x003C0046) /**< basic.get method id @internal 60, \ + 70; 3932230 */ +/** basic.get method fields */ +typedef struct amqp_basic_get_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t no_ack; /**< no-ack */ +} amqp_basic_get_t; + +#define AMQP_BASIC_GET_OK_METHOD \ + ((amqp_method_number_t)0x003C0047) /**< basic.get-ok method id @internal \ + 60, 71; 3932231 */ +/** basic.get-ok method fields */ +typedef struct amqp_basic_get_ok_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t redelivered; /**< redelivered */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + uint32_t message_count; /**< message-count */ +} amqp_basic_get_ok_t; + +#define AMQP_BASIC_GET_EMPTY_METHOD \ + ((amqp_method_number_t)0x003C0048) /**< basic.get-empty method id \ + @internal 60, 72; 3932232 */ +/** basic.get-empty method fields */ +typedef struct amqp_basic_get_empty_t_ { + amqp_bytes_t cluster_id; /**< cluster-id */ +} amqp_basic_get_empty_t; + +#define AMQP_BASIC_ACK_METHOD \ + ((amqp_method_number_t)0x003C0050) /**< basic.ack method id @internal 60, \ + 80; 3932240 */ +/** basic.ack method fields */ +typedef struct amqp_basic_ack_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t multiple; /**< multiple */ +} amqp_basic_ack_t; + +#define AMQP_BASIC_REJECT_METHOD \ + ((amqp_method_number_t)0x003C005A) /**< basic.reject method id @internal \ + 60, 90; 3932250 */ +/** basic.reject method fields */ +typedef struct amqp_basic_reject_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_reject_t; + +#define AMQP_BASIC_RECOVER_ASYNC_METHOD \ + ((amqp_method_number_t)0x003C0064) /**< basic.recover-async method id \ + @internal 60, 100; 3932260 */ +/** basic.recover-async method fields */ +typedef struct amqp_basic_recover_async_t_ { + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_recover_async_t; + +#define AMQP_BASIC_RECOVER_METHOD \ + ((amqp_method_number_t)0x003C006E) /**< basic.recover method id @internal \ + 60, 110; 3932270 */ +/** basic.recover method fields */ +typedef struct amqp_basic_recover_t_ { + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_recover_t; + +#define AMQP_BASIC_RECOVER_OK_METHOD \ + ((amqp_method_number_t)0x003C006F) /**< basic.recover-ok method id \ + @internal 60, 111; 3932271 */ +/** basic.recover-ok method fields */ +typedef struct amqp_basic_recover_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_basic_recover_ok_t; + +#define AMQP_BASIC_NACK_METHOD \ + ((amqp_method_number_t)0x003C0078) /**< basic.nack method id @internal 60, \ + 120; 3932280 */ +/** basic.nack method fields */ +typedef struct amqp_basic_nack_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t multiple; /**< multiple */ + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_nack_t; + +#define AMQP_TX_SELECT_METHOD \ + ((amqp_method_number_t)0x005A000A) /**< tx.select method id @internal 90, \ + 10; 5898250 */ +/** tx.select method fields */ +typedef struct amqp_tx_select_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_select_t; + +#define AMQP_TX_SELECT_OK_METHOD \ + ((amqp_method_number_t)0x005A000B) /**< tx.select-ok method id @internal \ + 90, 11; 5898251 */ +/** tx.select-ok method fields */ +typedef struct amqp_tx_select_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_select_ok_t; + +#define AMQP_TX_COMMIT_METHOD \ + ((amqp_method_number_t)0x005A0014) /**< tx.commit method id @internal 90, \ + 20; 5898260 */ +/** tx.commit method fields */ +typedef struct amqp_tx_commit_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_commit_t; + +#define AMQP_TX_COMMIT_OK_METHOD \ + ((amqp_method_number_t)0x005A0015) /**< tx.commit-ok method id @internal \ + 90, 21; 5898261 */ +/** tx.commit-ok method fields */ +typedef struct amqp_tx_commit_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_commit_ok_t; + +#define AMQP_TX_ROLLBACK_METHOD \ + ((amqp_method_number_t)0x005A001E) /**< tx.rollback method id @internal \ + 90, 30; 5898270 */ +/** tx.rollback method fields */ +typedef struct amqp_tx_rollback_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_rollback_t; + +#define AMQP_TX_ROLLBACK_OK_METHOD \ + ((amqp_method_number_t)0x005A001F) /**< tx.rollback-ok method id @internal \ + 90, 31; 5898271 */ +/** tx.rollback-ok method fields */ +typedef struct amqp_tx_rollback_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_rollback_ok_t; + +#define AMQP_CONFIRM_SELECT_METHOD \ + ((amqp_method_number_t)0x0055000A) /**< confirm.select method id @internal \ + 85, 10; 5570570 */ +/** confirm.select method fields */ +typedef struct amqp_confirm_select_t_ { + amqp_boolean_t nowait; /**< nowait */ +} amqp_confirm_select_t; + +#define AMQP_CONFIRM_SELECT_OK_METHOD \ + ((amqp_method_number_t)0x0055000B) /**< confirm.select-ok method id \ + @internal 85, 11; 5570571 */ +/** confirm.select-ok method fields */ +typedef struct amqp_confirm_select_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_confirm_select_ok_t; + +/* Class property records. */ +#define AMQP_CONNECTION_CLASS \ + (0x000A) /**< connection class id @internal 10 \ + */ +/** connection class properties */ +typedef struct amqp_connection_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_connection_properties_t; + +#define AMQP_CHANNEL_CLASS (0x0014) /**< channel class id @internal 20 */ +/** channel class properties */ +typedef struct amqp_channel_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_channel_properties_t; + +#define AMQP_ACCESS_CLASS (0x001E) /**< access class id @internal 30 */ +/** access class properties */ +typedef struct amqp_access_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_access_properties_t; + +#define AMQP_EXCHANGE_CLASS (0x0028) /**< exchange class id @internal 40 */ +/** exchange class properties */ +typedef struct amqp_exchange_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_properties_t; + +#define AMQP_QUEUE_CLASS (0x0032) /**< queue class id @internal 50 */ +/** queue class properties */ +typedef struct amqp_queue_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_queue_properties_t; + +#define AMQP_BASIC_CLASS (0x003C) /**< basic class id @internal 60 */ +#define AMQP_BASIC_CONTENT_TYPE_FLAG (1 << 15) +#define AMQP_BASIC_CONTENT_ENCODING_FLAG (1 << 14) +#define AMQP_BASIC_HEADERS_FLAG (1 << 13) +#define AMQP_BASIC_DELIVERY_MODE_FLAG (1 << 12) +#define AMQP_BASIC_PRIORITY_FLAG (1 << 11) +#define AMQP_BASIC_CORRELATION_ID_FLAG (1 << 10) +#define AMQP_BASIC_REPLY_TO_FLAG (1 << 9) +#define AMQP_BASIC_EXPIRATION_FLAG (1 << 8) +#define AMQP_BASIC_MESSAGE_ID_FLAG (1 << 7) +#define AMQP_BASIC_TIMESTAMP_FLAG (1 << 6) +#define AMQP_BASIC_TYPE_FLAG (1 << 5) +#define AMQP_BASIC_USER_ID_FLAG (1 << 4) +#define AMQP_BASIC_APP_ID_FLAG (1 << 3) +#define AMQP_BASIC_CLUSTER_ID_FLAG (1 << 2) +/** basic class properties */ +typedef struct amqp_basic_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + amqp_bytes_t content_type; /**< content-type */ + amqp_bytes_t content_encoding; /**< content-encoding */ + amqp_table_t headers; /**< headers */ + uint8_t delivery_mode; /**< delivery-mode */ + uint8_t priority; /**< priority */ + amqp_bytes_t correlation_id; /**< correlation-id */ + amqp_bytes_t reply_to; /**< reply-to */ + amqp_bytes_t expiration; /**< expiration */ + amqp_bytes_t message_id; /**< message-id */ + uint64_t timestamp; /**< timestamp */ + amqp_bytes_t type; /**< type */ + amqp_bytes_t user_id; /**< user-id */ + amqp_bytes_t app_id; /**< app-id */ + amqp_bytes_t cluster_id; /**< cluster-id */ +} amqp_basic_properties_t; + +#define AMQP_TX_CLASS (0x005A) /**< tx class id @internal 90 */ +/** tx class properties */ +typedef struct amqp_tx_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_properties_t; + +#define AMQP_CONFIRM_CLASS (0x0055) /**< confirm class id @internal 85 */ +/** confirm class properties */ +typedef struct amqp_confirm_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_confirm_properties_t; + +/* API functions for methods */ + +/** + * amqp_channel_open + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_channel_open_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_channel_open_ok_t *AMQP_CALL + amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel); +/** + * amqp_channel_flow + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] active active + * @returns amqp_channel_flow_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_channel_flow_ok_t *AMQP_CALL + amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, + amqp_boolean_t active); +/** + * amqp_exchange_declare + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] exchange exchange + * @param [in] type type + * @param [in] passive passive + * @param [in] durable durable + * @param [in] auto_delete auto_delete + * @param [in] internal internal + * @param [in] arguments arguments + * @returns amqp_exchange_declare_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_declare_ok_t *AMQP_CALL amqp_exchange_declare( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, + amqp_boolean_t durable, amqp_boolean_t auto_delete, amqp_boolean_t internal, + amqp_table_t arguments); +/** + * amqp_exchange_delete + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] exchange exchange + * @param [in] if_unused if_unused + * @returns amqp_exchange_delete_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_delete_ok_t *AMQP_CALL + amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_boolean_t if_unused); +/** + * amqp_exchange_bind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] destination destination + * @param [in] source source + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_exchange_bind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_bind_ok_t *AMQP_CALL + amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t destination, amqp_bytes_t source, + amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_exchange_unbind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] destination destination + * @param [in] source source + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_exchange_unbind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_unbind_ok_t *AMQP_CALL + amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t destination, amqp_bytes_t source, + amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_queue_declare + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] passive passive + * @param [in] durable durable + * @param [in] exclusive exclusive + * @param [in] auto_delete auto_delete + * @param [in] arguments arguments + * @returns amqp_queue_declare_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_declare_ok_t *AMQP_CALL amqp_queue_declare( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, + amqp_boolean_t auto_delete, amqp_table_t arguments); +/** + * amqp_queue_bind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] exchange exchange + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_queue_bind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_bind_ok_t *AMQP_CALL amqp_queue_bind( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_queue_purge + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @returns amqp_queue_purge_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_purge_ok_t *AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_bytes_t queue); +/** + * amqp_queue_delete + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] if_unused if_unused + * @param [in] if_empty if_empty + * @returns amqp_queue_delete_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_delete_ok_t *AMQP_CALL amqp_queue_delete( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t if_unused, amqp_boolean_t if_empty); +/** + * amqp_queue_unbind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] exchange exchange + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_queue_unbind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_unbind_ok_t *AMQP_CALL amqp_queue_unbind( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_basic_qos + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] prefetch_size prefetch_size + * @param [in] prefetch_count prefetch_count + * @param [in] global global + * @returns amqp_basic_qos_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_qos_ok_t *AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, + amqp_channel_t channel, + uint32_t prefetch_size, + uint16_t prefetch_count, + amqp_boolean_t global); +/** + * amqp_basic_consume + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] consumer_tag consumer_tag + * @param [in] no_local no_local + * @param [in] no_ack no_ack + * @param [in] exclusive exclusive + * @param [in] arguments arguments + * @returns amqp_basic_consume_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_consume_ok_t *AMQP_CALL amqp_basic_consume( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, + amqp_boolean_t exclusive, amqp_table_t arguments); +/** + * amqp_basic_cancel + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] consumer_tag consumer_tag + * @returns amqp_basic_cancel_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_cancel_ok_t *AMQP_CALL + amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t consumer_tag); +/** + * amqp_basic_recover + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] requeue requeue + * @returns amqp_basic_recover_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_recover_ok_t *AMQP_CALL + amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, + amqp_boolean_t requeue); +/** + * amqp_tx_select + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_select_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_select_ok_t *AMQP_CALL amqp_tx_select(amqp_connection_state_t state, + amqp_channel_t channel); +/** + * amqp_tx_commit + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_commit_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_commit_ok_t *AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, + amqp_channel_t channel); +/** + * amqp_tx_rollback + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_rollback_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_rollback_ok_t *AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, + amqp_channel_t channel); +/** + * amqp_confirm_select + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_confirm_select_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_confirm_select_ok_t *AMQP_CALL + amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel); + +AMQP_END_DECLS + +#endif /* AMQP_FRAMING_H */ diff --git a/ext/librabbitmq/macos/include/amqp_tcp_socket.h b/ext/librabbitmq/macos/include/amqp_tcp_socket.h new file mode 100644 index 000000000..3e9d82f54 --- /dev/null +++ b/ext/librabbitmq/macos/include/amqp_tcp_socket.h @@ -0,0 +1,68 @@ +/** \file */ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael + * Steinert. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * A TCP socket connection. + */ + +#ifndef AMQP_TCP_SOCKET_H +#define AMQP_TCP_SOCKET_H + +#include + +AMQP_BEGIN_DECLS + +/** + * Create a new TCP socket. + * + * Call amqp_connection_close() to release socket resources. + * + * \return A new socket object or NULL if an error occurred. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_socket_t *AMQP_CALL amqp_tcp_socket_new(amqp_connection_state_t state); + +/** + * Assign an open file descriptor to a socket object. + * + * This function must not be used in conjunction with amqp_socket_open(), i.e. + * the socket connection should already be open(2) when this function is + * called. + * + * \param [in,out] self A TCP socket object. + * \param [in] sockfd An open socket descriptor. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_tcp_socket_set_sockfd(amqp_socket_t *self, int sockfd); + +AMQP_END_DECLS + +#endif /* AMQP_TCP_SOCKET_H */ diff --git a/ext/librabbitmq/macos/lib/librabbitmq.a b/ext/librabbitmq/macos/lib/librabbitmq.a new file mode 100644 index 0000000000000000000000000000000000000000..f3d27b31dcda47dde6601e85aa5901ff1b3a66d0 GIT binary patch literal 95704 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

^GB9+OUh(Yw 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 literal 0 HcmV?d00001 diff --git a/make-mac.mk b/make-mac.mk index c71b3f778..545dabee8 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -22,8 +22,9 @@ include objects.mk ONE_OBJS+=osdep/MacEthernetTap.o osdep/MacKextEthernetTap.o ext/http-parser/http_parser.o ifeq ($(ZT_CONTROLLER),1) - LIBS+=-lpq -lrabbitmq + LIBS+=-L/usr/local/opt/libpq/lib -lpq -Lext/librabbitmq/macos/lib -lrabbitmq DEFS+=-DZT_CONTROLLER_USE_LIBPQ -DZT_CONTROLLER + INCLUDES+=-Iext/librabbitmq/macos/include -I/usr/local/opt/libpq/include endif # Official releases are signed with our Apple cert and apply software updates by default