Добавление Seastar, AMQP-CPP, fmt
This commit is contained in:
parent
5d66a3292f
commit
2da60debc0
2
builder/libs/AMQP-CPP/.clang_complete
Normal file
2
builder/libs/AMQP-CPP/.clang_complete
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-std=c++11
|
||||||
|
-Wno-pragma-once-outside-header
|
||||||
20
builder/libs/AMQP-CPP/.gitignore
vendored
Normal file
20
builder/libs/AMQP-CPP/.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.a.*
|
||||||
|
/build
|
||||||
|
/.vscode
|
||||||
|
.atom-build.cson
|
||||||
|
.atom-dbg.cson
|
||||||
|
/bin
|
||||||
119
builder/libs/AMQP-CPP/.travis.yml
Normal file
119
builder/libs/AMQP-CPP/.travis.yml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
################
|
||||||
|
# Config
|
||||||
|
################
|
||||||
|
|
||||||
|
# C++ project
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
group: edge
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
# Services
|
||||||
|
################
|
||||||
|
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
################
|
||||||
|
# Build matrix
|
||||||
|
################
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
|
||||||
|
################
|
||||||
|
# Linux / GCC
|
||||||
|
################
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=g++-7
|
||||||
|
- C_COMPILER=gcc-7
|
||||||
|
- CXX_COMPILER=g++-7
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=g++-8
|
||||||
|
- C_COMPILER=gcc-8
|
||||||
|
- CXX_COMPILER=g++-8
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=g++-9
|
||||||
|
- C_COMPILER=gcc-9
|
||||||
|
- CXX_COMPILER=g++-9
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=g++-10
|
||||||
|
- C_COMPILER=gcc-10
|
||||||
|
- CXX_COMPILER=g++-10
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
# Linux / Clang
|
||||||
|
################
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=clang-7
|
||||||
|
- C_COMPILER=clang-7
|
||||||
|
- CXX_COMPILER=clang++-7
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=clang-8
|
||||||
|
- C_COMPILER=clang-8
|
||||||
|
- CXX_COMPILER=clang++-8
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=clang-9
|
||||||
|
- C_COMPILER=clang-9
|
||||||
|
- CXX_COMPILER=clang++-9
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
env:
|
||||||
|
- COMPILER_PACKAGE=clang-10
|
||||||
|
- C_COMPILER=clang-10
|
||||||
|
- CXX_COMPILER=clang++-10
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
|
||||||
|
# Show OS/compiler version (this may not be the same OS as the Docker container)
|
||||||
|
- uname -a
|
||||||
|
|
||||||
|
# Use an artful container - gives us access to latest compilers.
|
||||||
|
- docker run -e "DEBIAN_FRONTEND=noninteractive" -d --name ubuntu-test-container -v $(pwd):/travis ubuntu:focal tail -f /dev/null
|
||||||
|
- docker ps
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
|
||||||
|
# Create our container
|
||||||
|
- docker exec -t ubuntu-test-container bash -c "apt-get update -y &&
|
||||||
|
apt-get --no-install-recommends install -y software-properties-common cmake
|
||||||
|
ninja-build libboost-all-dev libev-dev libuv1-dev ninja-build libssl-dev $COMPILER_PACKAGE &&
|
||||||
|
apt-get -y clean && rm -rf /var/lib/apt/lists/*"
|
||||||
|
|
||||||
|
################
|
||||||
|
# Build / Test
|
||||||
|
################
|
||||||
|
|
||||||
|
script:
|
||||||
|
|
||||||
|
# Run the container that we created and build the code
|
||||||
|
- docker exec -t ubuntu-test-container bash -c "cd /travis &&
|
||||||
|
export CC=/usr/bin/$C_COMPILER &&
|
||||||
|
export CXX=/usr/bin/$CXX_COMPILER &&
|
||||||
|
mkdir build.release && cd build.release &&
|
||||||
|
cmake ${CMAKE_OPTIONS} -DAMQP-CPP_BUILD_EXAMPLES=ON -DAMQP-CPP_LINUX_TCP=ON --config Release -GNinja .. &&
|
||||||
|
cmake --build . &&
|
||||||
|
cd .."
|
||||||
138
builder/libs/AMQP-CPP/CMakeLists.txt
Normal file
138
builder/libs/AMQP-CPP/CMakeLists.txt
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
# Builds AMQP-CPP
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
#
|
||||||
|
# - AMQP-CPP_BUILD_SHARED (default OFF)
|
||||||
|
# ON: Build shared lib
|
||||||
|
# OFF: Build static lib
|
||||||
|
#
|
||||||
|
# - AMQP-CPP_LINUX_TCP (default OFF)
|
||||||
|
# ON: Build posix handler implementation
|
||||||
|
# OFF: Don't build posix handler implementation
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
|
||||||
|
|
||||||
|
# project name
|
||||||
|
project(amqpcpp)
|
||||||
|
set (VERSION_MAJOR 4)
|
||||||
|
set (VERSION_MINOR 3)
|
||||||
|
set (VERSION_PATCH 26)
|
||||||
|
set (SO_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||||
|
|
||||||
|
# build options
|
||||||
|
option(AMQP-CPP_BUILD_SHARED "Build shared library. If off, build will be static." OFF)
|
||||||
|
option(AMQP-CPP_LINUX_TCP "Build linux sockets implementation." OFF)
|
||||||
|
option(AMQP-CPP_BUILD_EXAMPLES "Build amqpcpp examples" OFF)
|
||||||
|
|
||||||
|
# pass version number to source files as macro
|
||||||
|
add_compile_definitions(VERSION=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
|
||||||
|
|
||||||
|
# ensure c++11 on all compilers
|
||||||
|
set (CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
# add source files
|
||||||
|
# ------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# set include/ as include directory
|
||||||
|
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
# macro that adds a list of provided source files to a list called SRCS.
|
||||||
|
# if variable SRCS does not yet exist, it is created.
|
||||||
|
macro (add_sources)
|
||||||
|
file (RELATIVE_PATH _relPath "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
foreach (_src ${ARGN})
|
||||||
|
if (_relPath)
|
||||||
|
list (APPEND SRCS "${_relPath}/${_src}")
|
||||||
|
else()
|
||||||
|
list (APPEND SRCS "${_src}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if (_relPath)
|
||||||
|
# propagate SRCS to parent directory
|
||||||
|
set (SRCS ${SRCS} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# add source files
|
||||||
|
#add_subdirectory(src)
|
||||||
|
aux_source_directory(src src_MAIN)
|
||||||
|
if(AMQP-CPP_LINUX_TCP)
|
||||||
|
#add_subdirectory(src/linux_tcp)
|
||||||
|
aux_source_directory(src/linux_tcp src_LINUX_TCP)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# potentially build the examples
|
||||||
|
if(AMQP-CPP_BUILD_EXAMPLES)
|
||||||
|
add_subdirectory(examples)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# settings for specific compilers
|
||||||
|
# ------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# we have to prevent windows from defining the max macro.
|
||||||
|
if (WIN32)
|
||||||
|
add_definitions(-DNOMINMAX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# build targets
|
||||||
|
# ------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# set output directory
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
if(AMQP-CPP_BUILD_SHARED)
|
||||||
|
# create shared lib
|
||||||
|
#add_library(${PROJECT_NAME} SHARED ${SRCS})
|
||||||
|
add_library(${PROJECT_NAME} SHARED ${src_MAIN} ${src_LINUX_TCP})
|
||||||
|
# set shared lib version
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${SO_VERSION})
|
||||||
|
else()
|
||||||
|
# create static lib
|
||||||
|
#add_library(${PROJECT_NAME} STATIC ${SRCS})
|
||||||
|
add_library(${PROJECT_NAME} STATIC ${src_MAIN} ${src_LINUX_TCP})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# install rules
|
||||||
|
# ------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if(AMQP-CPP_BUILD_SHARED)
|
||||||
|
# copy shared lib and its static counter part
|
||||||
|
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
RUNTIME DESTINATION lib
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
# copy static lib
|
||||||
|
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# copy header files
|
||||||
|
install(DIRECTORY include/amqpcpp/ DESTINATION include/amqpcpp
|
||||||
|
FILES_MATCHING PATTERN "*.h")
|
||||||
|
install(FILES include/amqpcpp.h DESTINATION include)
|
||||||
|
|
||||||
|
install(EXPORT ${PROJECT_NAME}Config DESTINATION cmake)
|
||||||
|
export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}Config.cmake)
|
||||||
|
|
||||||
|
set(DEST_DIR "${CMAKE_INSTALL_PREFIX}")
|
||||||
|
set(PRIVATE_LIBS "-llibamqpcc")
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/amqpcpp.pc.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/amqpcpp.pc" @ONLY)
|
||||||
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/amqpcpp.pc" DESTINATION lib/pkgconfig)
|
||||||
|
|
||||||
|
# submodule support
|
||||||
|
# ------------------------------------------------------------------------------------------------------
|
||||||
|
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
|
||||||
|
$<INSTALL_INTERFACE:include/>
|
||||||
|
)
|
||||||
|
|
||||||
|
if(AMQP-CPP_LINUX_TCP)
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS})
|
||||||
|
# Find OpenSSL and provide include dirs
|
||||||
|
find_package(OpenSSL REQUIRED)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
202
builder/libs/AMQP-CPP/LICENSE
Normal file
202
builder/libs/AMQP-CPP/LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
37
builder/libs/AMQP-CPP/Makefile
Normal file
37
builder/libs/AMQP-CPP/Makefile
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
PREFIX ?= /usr
|
||||||
|
INCLUDE_DIR = ${PREFIX}/include
|
||||||
|
LIBRARY_DIR = ${PREFIX}/lib
|
||||||
|
export LIBRARY_NAME = amqpcpp
|
||||||
|
export SONAME = 4.3
|
||||||
|
export VERSION = 4.3.26
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(MAKE) VERSION=${VERSION} -C src all
|
||||||
|
|
||||||
|
pure:
|
||||||
|
$(MAKE) VERSION=${VERSION} -C src pure
|
||||||
|
|
||||||
|
release:
|
||||||
|
$(MAKE) VERSION=${VERSION} -C src release
|
||||||
|
|
||||||
|
static:
|
||||||
|
$(MAKE) VERSION=${VERSION} -C src static
|
||||||
|
|
||||||
|
shared:
|
||||||
|
$(MAKE) VERSION=${VERSION} -C src shared
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C src clean
|
||||||
|
|
||||||
|
install:
|
||||||
|
mkdir -p ${INCLUDE_DIR}/$(LIBRARY_NAME)
|
||||||
|
mkdir -p ${INCLUDE_DIR}/$(LIBRARY_NAME)/linux_tcp
|
||||||
|
mkdir -p ${LIBRARY_DIR}
|
||||||
|
cp -f include/$(LIBRARY_NAME).h ${INCLUDE_DIR}
|
||||||
|
cp -f include/amqpcpp/*.h ${INCLUDE_DIR}/$(LIBRARY_NAME)
|
||||||
|
cp -f include/amqpcpp/linux_tcp/*.h ${INCLUDE_DIR}/$(LIBRARY_NAME)/linux_tcp
|
||||||
|
-cp -f src/lib$(LIBRARY_NAME).so.$(VERSION) ${LIBRARY_DIR}
|
||||||
|
-cp -f src/lib$(LIBRARY_NAME).a.$(VERSION) ${LIBRARY_DIR}
|
||||||
|
ln -s -f lib$(LIBRARY_NAME).so.$(VERSION) $(LIBRARY_DIR)/lib$(LIBRARY_NAME).so.$(SONAME)
|
||||||
|
ln -s -f lib$(LIBRARY_NAME).so.$(VERSION) $(LIBRARY_DIR)/lib$(LIBRARY_NAME).so
|
||||||
|
ln -s -f lib$(LIBRARY_NAME).a.$(VERSION) $(LIBRARY_DIR)/lib$(LIBRARY_NAME).a
|
||||||
1475
builder/libs/AMQP-CPP/README.md
Normal file
1475
builder/libs/AMQP-CPP/README.md
Normal file
File diff suppressed because it is too large
Load Diff
10
builder/libs/AMQP-CPP/amqpcpp.pc.in
Normal file
10
builder/libs/AMQP-CPP/amqpcpp.pc.in
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
prefix=@DEST_DIR@
|
||||||
|
libdir=${prefix}/lib
|
||||||
|
includedir=${prefix}/include
|
||||||
|
|
||||||
|
Name: amqpcpp
|
||||||
|
Description: AMQP-CPP is a C++ library for communicating with a RabbitMQ message broker
|
||||||
|
Version: @VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@
|
||||||
|
|
||||||
|
Libs: -L${libdir} -lamqpcpp
|
||||||
|
Cflags: -I${includedir}
|
||||||
19
builder/libs/AMQP-CPP/appveyor.yml
Normal file
19
builder/libs/AMQP-CPP/appveyor.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
version: '1.0.{build}'
|
||||||
|
|
||||||
|
image: Visual Studio 2017
|
||||||
|
|
||||||
|
platform:
|
||||||
|
- x64
|
||||||
|
|
||||||
|
configuration:
|
||||||
|
- Release
|
||||||
|
- Debug
|
||||||
|
|
||||||
|
install:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
|
||||||
|
before_build:
|
||||||
|
- cmake -G "Visual Studio 15 2017 Win64" .
|
||||||
|
|
||||||
|
build:
|
||||||
|
project: $(APPVEYOR_BUILD_FOLDER)\amqpcpp.sln
|
||||||
1
builder/libs/AMQP-CPP/examples/.gitignore
vendored
Normal file
1
builder/libs/AMQP-CPP/examples/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
a.out
|
||||||
32
builder/libs/AMQP-CPP/examples/CMakeLists.txt
Normal file
32
builder/libs/AMQP-CPP/examples/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
# Boost
|
||||||
|
###################################
|
||||||
|
|
||||||
|
add_executable(amqpcpp_boost_example libboostasio.cpp)
|
||||||
|
|
||||||
|
add_dependencies(amqpcpp_boost_example amqpcpp)
|
||||||
|
|
||||||
|
target_link_libraries(amqpcpp_boost_example amqpcpp boost_system pthread dl ssl)
|
||||||
|
|
||||||
|
###################################
|
||||||
|
# Libev
|
||||||
|
###################################
|
||||||
|
|
||||||
|
add_executable(amqpcpp_libev_example libev.cpp)
|
||||||
|
|
||||||
|
add_dependencies(amqpcpp_libev_example amqpcpp)
|
||||||
|
|
||||||
|
target_link_libraries(amqpcpp_libev_example amqpcpp ev pthread dl ssl)
|
||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
# Libuv
|
||||||
|
###################################
|
||||||
|
|
||||||
|
add_executable(amqpcpp_libuv_example libuv.cpp)
|
||||||
|
|
||||||
|
add_dependencies(amqpcpp_libuv_example amqpcpp)
|
||||||
|
|
||||||
|
target_link_libraries(amqpcpp_libuv_example amqpcpp uv pthread dl ssl)
|
||||||
56
builder/libs/AMQP-CPP/examples/libboostasio.cpp
Normal file
56
builder/libs/AMQP-CPP/examples/libboostasio.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* LibBoostAsio.cpp
|
||||||
|
*
|
||||||
|
* Test program to check AMQP functionality based on Boost's asio io_service.
|
||||||
|
*
|
||||||
|
* @author Gavin Smith <gavin.smith@coralbay.tv>
|
||||||
|
*
|
||||||
|
* Compile with g++ -std=c++14 libboostasio.cpp -o boost_test -lpthread -lboost_system -lamqpcpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <boost/asio/io_service.hpp>
|
||||||
|
#include <boost/asio/strand.hpp>
|
||||||
|
#include <boost/asio/deadline_timer.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <amqpcpp.h>
|
||||||
|
#include <amqpcpp/libboostasio.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main program
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
// access to the boost asio handler
|
||||||
|
// note: we suggest use of 2 threads - normally one is fin (we are simply demonstrating thread safety).
|
||||||
|
boost::asio::io_service service(4);
|
||||||
|
|
||||||
|
// handler for libev
|
||||||
|
AMQP::LibBoostAsioHandler handler(service);
|
||||||
|
|
||||||
|
// make a connection
|
||||||
|
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://guest:guest@localhost/"));
|
||||||
|
|
||||||
|
// we need a channel too
|
||||||
|
AMQP::TcpChannel channel(&connection);
|
||||||
|
|
||||||
|
// create a temporary queue
|
||||||
|
channel.declareQueue(AMQP::exclusive).onSuccess([&connection](const std::string &name, uint32_t messagecount, uint32_t consumercount) {
|
||||||
|
|
||||||
|
// report the name of the temporary queue
|
||||||
|
std::cout << "declared queue " << name << std::endl;
|
||||||
|
|
||||||
|
// now we can close the connection
|
||||||
|
connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
// run the handler
|
||||||
|
// a t the moment, one will need SIGINT to stop. In time, should add signal handling through boost API.
|
||||||
|
return service.run();
|
||||||
|
}
|
||||||
|
|
||||||
235
builder/libs/AMQP-CPP/examples/libev.cpp
Normal file
235
builder/libs/AMQP-CPP/examples/libev.cpp
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/**
|
||||||
|
* LibEV.cpp
|
||||||
|
*
|
||||||
|
* Test program to check AMQP functionality based on LibEV
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2022 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <ev.h>
|
||||||
|
#include <amqpcpp.h>
|
||||||
|
#include <amqpcpp/libev.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom handler
|
||||||
|
*/
|
||||||
|
class MyHandler : public AMQP::LibEvHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Method that is called when a connection error occurs
|
||||||
|
* @param connection
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
virtual void onError(AMQP::TcpConnection *connection, const char *message) override
|
||||||
|
{
|
||||||
|
std::cout << "error: " << message << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection ends up in a connected state
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onConnected(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
std::cout << "connected" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection ends up in a ready
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onReady(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
std::cout << "ready" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection is closed
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onClosed(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
std::cout << "closed" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection is detached
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onDetached(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
std::cout << "detached" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param ev_loop
|
||||||
|
*/
|
||||||
|
MyHandler(struct ev_loop *loop) : AMQP::LibEvHandler(loop) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~MyHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that runs a timer
|
||||||
|
*/
|
||||||
|
class MyTimer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The actual watcher structure
|
||||||
|
* @var struct ev_io
|
||||||
|
*/
|
||||||
|
struct ev_timer _timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer towards the AMQP channel
|
||||||
|
* @var AMQP::TcpChannel
|
||||||
|
*/
|
||||||
|
AMQP::TcpChannel *_channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the queue
|
||||||
|
* @var std::string
|
||||||
|
*/
|
||||||
|
std::string _queue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method that is called by libev when the timer expires
|
||||||
|
* @param loop The loop in which the event was triggered
|
||||||
|
* @param timer Internal timer object
|
||||||
|
* @param revents The events that triggered this call
|
||||||
|
*/
|
||||||
|
static void callback(struct ev_loop *loop, struct ev_timer *timer, int revents)
|
||||||
|
{
|
||||||
|
// retrieve the this pointer
|
||||||
|
MyTimer *self = static_cast<MyTimer*>(timer->data);
|
||||||
|
|
||||||
|
// publish a message
|
||||||
|
self->_channel->publish("", self->_queue, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param loop
|
||||||
|
* @param channel
|
||||||
|
* @param queue
|
||||||
|
*/
|
||||||
|
MyTimer(struct ev_loop *loop, AMQP::TcpChannel *channel, std::string queue) :
|
||||||
|
_channel(channel), _queue(std::move(queue))
|
||||||
|
{
|
||||||
|
// initialize the libev structure
|
||||||
|
ev_timer_init(&_timer, callback, 0.005, 1.005);
|
||||||
|
|
||||||
|
// this object is the data
|
||||||
|
_timer.data = this;
|
||||||
|
|
||||||
|
// and start it
|
||||||
|
ev_timer_start(loop, &_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~MyTimer()
|
||||||
|
{
|
||||||
|
// @todo to be implemented
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main program
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// access to the event loop
|
||||||
|
auto *loop = EV_DEFAULT;
|
||||||
|
|
||||||
|
// handler for libev
|
||||||
|
MyHandler handler(loop);
|
||||||
|
|
||||||
|
// init the SSL library
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
SSL_library_init();
|
||||||
|
#else
|
||||||
|
OPENSSL_init_ssl(0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// make a connection
|
||||||
|
AMQP::Address address("amqp://guest:guest@localhost/");
|
||||||
|
// AMQP::Address address("amqps://guest:guest@localhost/");
|
||||||
|
AMQP::TcpConnection connection(&handler, address);
|
||||||
|
|
||||||
|
// we need a channel too
|
||||||
|
AMQP::TcpChannel channel(&connection);
|
||||||
|
|
||||||
|
// create a temporary queue
|
||||||
|
channel.declareQueue(AMQP::exclusive).onSuccess([&connection, &channel, loop](const std::string &queuename, uint32_t messagecount, uint32_t consumercount) {
|
||||||
|
|
||||||
|
// report the name of the temporary queue
|
||||||
|
std::cout << "declared queue " << queuename << std::endl;
|
||||||
|
|
||||||
|
// close the channel
|
||||||
|
//channel.close().onSuccess([&connection, &channel]() {
|
||||||
|
//
|
||||||
|
// // report that channel was closed
|
||||||
|
// std::cout << "channel closed" << std::endl;
|
||||||
|
//
|
||||||
|
// // close the connection
|
||||||
|
// connection.close();
|
||||||
|
//});
|
||||||
|
|
||||||
|
// construct a timer that is going to publish stuff
|
||||||
|
auto *timer = new MyTimer(loop, &channel, queuename);
|
||||||
|
|
||||||
|
// start a consumer
|
||||||
|
channel.consume(queuename).onSuccess([](const std::string &tag) {
|
||||||
|
|
||||||
|
// the consumer is ready
|
||||||
|
std::cout << "started consuming with tag " << tag << std::endl;
|
||||||
|
|
||||||
|
}).onCancelled([](const std::string &tag) {
|
||||||
|
|
||||||
|
// the consumer was cancelled by the server
|
||||||
|
std::cout << "consumer " << tag << " was cancelled" << std::endl;
|
||||||
|
|
||||||
|
}).onReceived([&channel, queuename](const AMQP::Message &message, uint64_t deliveryTag, bool redelivered) {
|
||||||
|
|
||||||
|
std::cout << "received " << deliveryTag << std::endl;
|
||||||
|
|
||||||
|
// we remove the queue -- to see if this indeed causes the onCancelled method to be called
|
||||||
|
if (deliveryTag > 3) channel.removeQueue(queuename);
|
||||||
|
|
||||||
|
// ack the message
|
||||||
|
channel.ack(deliveryTag);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
// run the loop
|
||||||
|
ev_run(loop, 0);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
53
builder/libs/AMQP-CPP/examples/libevent.cpp
Normal file
53
builder/libs/AMQP-CPP/examples/libevent.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Libevent.cpp
|
||||||
|
*
|
||||||
|
* Test program to check AMQP functionality based on Libevent
|
||||||
|
*
|
||||||
|
* @author Brent Dimmig <brentdimmig@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <amqpcpp.h>
|
||||||
|
#include <amqpcpp/libevent.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main program
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// access to the event loop
|
||||||
|
auto evbase = event_base_new();
|
||||||
|
|
||||||
|
// handler for libevent
|
||||||
|
AMQP::LibEventHandler handler(evbase);
|
||||||
|
|
||||||
|
// make a connection
|
||||||
|
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://localhost/"));
|
||||||
|
|
||||||
|
// we need a channel too
|
||||||
|
AMQP::TcpChannel channel(&connection);
|
||||||
|
|
||||||
|
// create a temporary queue
|
||||||
|
channel.declareQueue(AMQP::exclusive).onSuccess([&connection](const std::string &name, uint32_t messagecount, uint32_t consumercount) {
|
||||||
|
|
||||||
|
// report the name of the temporary queue
|
||||||
|
std::cout << "declared queue " << name << std::endl;
|
||||||
|
|
||||||
|
// now we can close the connection
|
||||||
|
connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
// run the loop
|
||||||
|
event_base_dispatch(evbase);
|
||||||
|
|
||||||
|
event_base_free(evbase);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
86
builder/libs/AMQP-CPP/examples/libuv.cpp
Normal file
86
builder/libs/AMQP-CPP/examples/libuv.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* LibUV.cpp
|
||||||
|
*
|
||||||
|
* Test program to check AMQP functionality based on LibUV
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <uv.h>
|
||||||
|
#include <amqpcpp.h>
|
||||||
|
#include <amqpcpp/libuv.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom handler
|
||||||
|
*/
|
||||||
|
class MyHandler : public AMQP::LibUvHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Method that is called when a connection error occurs
|
||||||
|
* @param connection
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
virtual void onError(AMQP::TcpConnection *connection, const char *message) override
|
||||||
|
{
|
||||||
|
std::cout << "error: " << message << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection ends up in a connected state
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onConnected(AMQP::TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
std::cout << "connected" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param uv_loop
|
||||||
|
*/
|
||||||
|
MyHandler(uv_loop_t *loop) : AMQP::LibUvHandler(loop) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~MyHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main program
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// access to the event loop
|
||||||
|
auto *loop = uv_default_loop();
|
||||||
|
|
||||||
|
// handler for libev
|
||||||
|
MyHandler handler(loop);
|
||||||
|
|
||||||
|
// make a connection
|
||||||
|
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://guest:guest@localhost/"));
|
||||||
|
|
||||||
|
// we need a channel too
|
||||||
|
AMQP::TcpChannel channel(&connection);
|
||||||
|
|
||||||
|
// create a temporary queue
|
||||||
|
channel.declareQueue(AMQP::exclusive).onSuccess([&connection](const std::string &name, uint32_t messagecount, uint32_t consumercount) {
|
||||||
|
|
||||||
|
// report the name of the temporary queue
|
||||||
|
std::cout << "declared queue " << name << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
// run the loop
|
||||||
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
87
builder/libs/AMQP-CPP/include/amqpcpp.h
Normal file
87
builder/libs/AMQP-CPP/include/amqpcpp.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* AMQP.h
|
||||||
|
*
|
||||||
|
* Starting point for all includes of the Copernica AMQP library
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// base C++ include files
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <queue>
|
||||||
|
#include <limits>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
// base C include files
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// fix strcasecmp on non linux platforms
|
||||||
|
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)) && !defined(__CYGWIN__)
|
||||||
|
#define strcasecmp _stricmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
#include "amqpcpp/classes.h"
|
||||||
|
|
||||||
|
// utility classes
|
||||||
|
#include "amqpcpp/endian.h"
|
||||||
|
#include "amqpcpp/buffer.h"
|
||||||
|
#include "amqpcpp/bytebuffer.h"
|
||||||
|
#include "amqpcpp/inbuffer.h"
|
||||||
|
#include "amqpcpp/outbuffer.h"
|
||||||
|
#include "amqpcpp/watchable.h"
|
||||||
|
#include "amqpcpp/monitor.h"
|
||||||
|
|
||||||
|
// amqp types
|
||||||
|
#include "amqpcpp/field.h"
|
||||||
|
#include "amqpcpp/numericfield.h"
|
||||||
|
#include "amqpcpp/decimalfield.h"
|
||||||
|
#include "amqpcpp/stringfield.h"
|
||||||
|
#include "amqpcpp/booleanset.h"
|
||||||
|
#include "amqpcpp/fieldproxy.h"
|
||||||
|
#include "amqpcpp/table.h"
|
||||||
|
#include "amqpcpp/array.h"
|
||||||
|
#include "amqpcpp/voidfield.h"
|
||||||
|
|
||||||
|
// envelope for publishing and consuming
|
||||||
|
#include "amqpcpp/metadata.h"
|
||||||
|
#include "amqpcpp/envelope.h"
|
||||||
|
#include "amqpcpp/message.h"
|
||||||
|
|
||||||
|
// mid level includes
|
||||||
|
#include "amqpcpp/exchangetype.h"
|
||||||
|
#include "amqpcpp/flags.h"
|
||||||
|
#include "amqpcpp/callbacks.h"
|
||||||
|
#include "amqpcpp/deferred.h"
|
||||||
|
#include "amqpcpp/deferredconsumer.h"
|
||||||
|
#include "amqpcpp/deferredqueue.h"
|
||||||
|
#include "amqpcpp/deferreddelete.h"
|
||||||
|
#include "amqpcpp/deferredcancel.h"
|
||||||
|
#include "amqpcpp/deferredconfirm.h"
|
||||||
|
#include "amqpcpp/deferredget.h"
|
||||||
|
#include "amqpcpp/deferredrecall.h"
|
||||||
|
#include "amqpcpp/channelimpl.h"
|
||||||
|
#include "amqpcpp/channel.h"
|
||||||
|
#include "amqpcpp/tagger.h"
|
||||||
|
#include "amqpcpp/throttle.h"
|
||||||
|
#include "amqpcpp/reliable.h"
|
||||||
|
#include "amqpcpp/login.h"
|
||||||
|
#include "amqpcpp/address.h"
|
||||||
|
#include "amqpcpp/connectionhandler.h"
|
||||||
|
#include "amqpcpp/connectionimpl.h"
|
||||||
|
#include "amqpcpp/connection.h"
|
||||||
|
#include "amqpcpp/openssl.h"
|
||||||
470
builder/libs/AMQP-CPP/include/amqpcpp/address.h
Normal file
470
builder/libs/AMQP-CPP/include/amqpcpp/address.h
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
/**
|
||||||
|
* Address.h
|
||||||
|
*
|
||||||
|
* An AMQP address in the "amqp://user:password@hostname:port/vhost" notation
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes
|
||||||
|
*/
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Address
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Helper class to do case insensitive comparison
|
||||||
|
*/
|
||||||
|
struct icasecmp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Comparison operator <. Should exhibit SWO.
|
||||||
|
* @param lhs
|
||||||
|
* @param rhs
|
||||||
|
* @return bool lhs < rhs
|
||||||
|
*/
|
||||||
|
bool operator() (const std::string& lhs, const std::string& rhs) const { return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The auth method
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _secure = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login data (username + password)
|
||||||
|
* @var Login
|
||||||
|
*/
|
||||||
|
Login _login;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hostname
|
||||||
|
* @var std::string
|
||||||
|
*/
|
||||||
|
std::string _hostname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port number
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _port = 5672;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The vhost
|
||||||
|
* @var std::string
|
||||||
|
*/
|
||||||
|
std::string _vhost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra provided options after the question mark /vhost?option=value
|
||||||
|
* @var std::map<std::string,std::string>
|
||||||
|
*/
|
||||||
|
std::map<std::string, std::string, icasecmp> _options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default port
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t defaultport() const
|
||||||
|
{
|
||||||
|
return _secure ? 5671 : 5672;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor to parse an address string
|
||||||
|
* The address should start with "amqp://
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Address(const char *data, size_t size) : _vhost("/")
|
||||||
|
{
|
||||||
|
// position of the last byte
|
||||||
|
const char *last = data + size;
|
||||||
|
|
||||||
|
// must start with ampqs:// to have a secure connection (and we also assign a different default port)
|
||||||
|
if (strncmp(data, "amqps://", 8) == 0) _secure = true;
|
||||||
|
|
||||||
|
// otherwise protocol must be amqp://
|
||||||
|
else if (strncmp(data, "amqp://", 7) != 0) throw std::runtime_error("AMQP address should start with \"amqp://\" or \"amqps://\"");
|
||||||
|
|
||||||
|
// assign default port (we may overwrite it later)
|
||||||
|
_port = defaultport();
|
||||||
|
|
||||||
|
// begin of the string was parsed
|
||||||
|
data += _secure ? 8 : 7;
|
||||||
|
|
||||||
|
// do we have a '@' to split user-data and hostname?
|
||||||
|
const char *at = (const char *)memchr(data, '@', last - data);
|
||||||
|
|
||||||
|
// do we have one?
|
||||||
|
if (at != nullptr)
|
||||||
|
{
|
||||||
|
// size of the user:password
|
||||||
|
size_t loginsize = at - data;
|
||||||
|
|
||||||
|
// colon could split username and password
|
||||||
|
const char *colon = (const char *)memchr(data, ':', loginsize);
|
||||||
|
|
||||||
|
// assign the login
|
||||||
|
_login = Login(
|
||||||
|
std::string(data, colon ? colon - data : loginsize),
|
||||||
|
std::string(colon ? colon + 1 : "", colon ? at - colon - 1 : 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// set data to the start of the hostname
|
||||||
|
data = at + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find out where the vhost is set (starts with a slash)
|
||||||
|
const char *slash = (const char *)memchr(data, '/', last - data);
|
||||||
|
|
||||||
|
// where to start looking for the question mark, we also want to support urls where the
|
||||||
|
// hostname does not have a slash.
|
||||||
|
const char *start = slash ? slash : data;
|
||||||
|
|
||||||
|
// we search for the ? for extra options
|
||||||
|
const char *qm = static_cast<const char *>(memchr(start, '?', last - start));
|
||||||
|
|
||||||
|
// if there is a questionmark, we need to parse all options
|
||||||
|
if (qm != nullptr && last - qm > 1)
|
||||||
|
{
|
||||||
|
// we start at question mark now
|
||||||
|
start = qm;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// find the next equals sign and start of the next parameter
|
||||||
|
const char *equals = (const char *)memchr(start + 1, '=', last - start - 1);
|
||||||
|
const char *next = (const char *)memchr(start + 1, '&', last - start - 1);
|
||||||
|
|
||||||
|
// assign it to the options if we found an equals sign
|
||||||
|
if (equals) _options[std::string(start + 1, equals - start - 1)] = std::string(equals + 1, (next ? next - equals : last - equals) - 1);
|
||||||
|
|
||||||
|
// we now have a new start, the next '&...'
|
||||||
|
start = next;
|
||||||
|
|
||||||
|
// keep iterating as long as there are more vars
|
||||||
|
} while (start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// was a vhost set?
|
||||||
|
if (slash != nullptr && last - slash > 1) _vhost.assign(slash + 1, (qm ? qm - slash : last - slash) - 1);
|
||||||
|
|
||||||
|
// the hostname is everything until the slash, check is portnumber was set
|
||||||
|
const char *colon = (const char *)memchr(data, ':', last - data);
|
||||||
|
|
||||||
|
// was a portnumber specified (colon must appear before the slash of the vhost)
|
||||||
|
if (colon && (!slash || colon < slash))
|
||||||
|
{
|
||||||
|
// a portnumber was set to
|
||||||
|
_hostname.assign(data, colon - data);
|
||||||
|
|
||||||
|
// calculate the port
|
||||||
|
_port = atoi(std::string(colon + 1, slash ? slash - colon - 1 : last - colon - 1).data());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no portnumber was set
|
||||||
|
_hostname.assign(data, slash ? slash - data : last - data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor to parse an address string
|
||||||
|
* The address should start with amqp:// or amqps://
|
||||||
|
* @param data
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Address(const char *data) : Address(data, strlen(data)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on std::string
|
||||||
|
* @param address
|
||||||
|
*/
|
||||||
|
Address(const std::string &address) : Address(address.data(), address.size()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on already known properties
|
||||||
|
* @param host
|
||||||
|
* @param port
|
||||||
|
* @param login
|
||||||
|
* @param vhost
|
||||||
|
* @param secure
|
||||||
|
*/
|
||||||
|
Address(std::string host, uint16_t port, Login login, std::string vhost, bool secure = false) :
|
||||||
|
_secure(secure),
|
||||||
|
_login(std::move(login)),
|
||||||
|
_hostname(std::move(host)),
|
||||||
|
_port(port),
|
||||||
|
_vhost(std::move(vhost)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Address() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we open a secure connection?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool secure() const
|
||||||
|
{
|
||||||
|
return _secure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose the login data
|
||||||
|
* @return Login
|
||||||
|
*/
|
||||||
|
const Login &login() const
|
||||||
|
{
|
||||||
|
return _login;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host name
|
||||||
|
* @return std::string
|
||||||
|
*/
|
||||||
|
const std::string &hostname() const
|
||||||
|
{
|
||||||
|
return _hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port number
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t port() const
|
||||||
|
{
|
||||||
|
return _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The vhost to connect to
|
||||||
|
* @return std::string
|
||||||
|
*/
|
||||||
|
const std::string &vhost() const
|
||||||
|
{
|
||||||
|
return _vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to the options
|
||||||
|
* @return std::map<std::string,std::string>
|
||||||
|
*/
|
||||||
|
const decltype(_options) &options() const
|
||||||
|
{
|
||||||
|
return _options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to a string
|
||||||
|
* @return std::string
|
||||||
|
*/
|
||||||
|
operator std::string () const
|
||||||
|
{
|
||||||
|
// result object
|
||||||
|
std::string str(_secure ? "amqps://" : "amqp://");
|
||||||
|
|
||||||
|
// append login
|
||||||
|
str.append(_login.user()).append(":").append(_login.password()).append("@").append(_hostname);
|
||||||
|
|
||||||
|
// do we need a special portnumber?
|
||||||
|
if (_port != 5672) str.append(":").append(std::to_string(_port));
|
||||||
|
|
||||||
|
// append default vhost
|
||||||
|
str.append("/");
|
||||||
|
|
||||||
|
// do we have a special vhost?
|
||||||
|
if (_vhost != "/") str.append(_vhost);
|
||||||
|
|
||||||
|
// iterate over all options, appending them
|
||||||
|
if (!_options.empty())
|
||||||
|
{
|
||||||
|
// first append a question mark
|
||||||
|
str.push_back('?');
|
||||||
|
|
||||||
|
// iterate over all the options
|
||||||
|
for (const auto &kv : _options) str.append(kv.first).append("=").append(kv.second).append("&");
|
||||||
|
|
||||||
|
// remove the extra &
|
||||||
|
str.erase(str.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator
|
||||||
|
* @param that
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator==(const Address &that) const
|
||||||
|
{
|
||||||
|
// security setting should match
|
||||||
|
if (_secure != that._secure) return false;
|
||||||
|
|
||||||
|
// logins must match
|
||||||
|
if (_login != that._login) return false;
|
||||||
|
|
||||||
|
// hostname must match, but are not case sensitive
|
||||||
|
if (strcasecmp(_hostname.data(), that._hostname.data()) != 0) return false;
|
||||||
|
|
||||||
|
// portnumber must match
|
||||||
|
if (_port != that._port) return false;
|
||||||
|
|
||||||
|
// and the vhosts, they must match too
|
||||||
|
if (_vhost != that._vhost) return false;
|
||||||
|
|
||||||
|
// and the options as well
|
||||||
|
return _options == that._options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator
|
||||||
|
* @param that
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator!=(const Address &that) const
|
||||||
|
{
|
||||||
|
// the opposite of operator==
|
||||||
|
return !operator==(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator that is useful if addresses have to be ordered
|
||||||
|
* @param that
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator<(const Address &that) const
|
||||||
|
{
|
||||||
|
// compare auth methods (amqp comes before amqps)
|
||||||
|
if (_secure != that._secure) return !_secure;
|
||||||
|
|
||||||
|
// compare logins
|
||||||
|
if (_login != that._login) return _login < that._login;
|
||||||
|
|
||||||
|
// hostname must match, but are not case sensitive
|
||||||
|
int result = strcasecmp(_hostname.data(), that._hostname.data());
|
||||||
|
|
||||||
|
// if hostnames are not equal, we know the result
|
||||||
|
if (result != 0) return result < 0;
|
||||||
|
|
||||||
|
// portnumber must match
|
||||||
|
if (_port != that._port) return _port < that._port;
|
||||||
|
|
||||||
|
// and finally compare the vhosts
|
||||||
|
if (_vhost < that._vhost) return _vhost < that._vhost;
|
||||||
|
|
||||||
|
// and finally lexicographically compare the options
|
||||||
|
return _options < that._options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Friend function to allow writing the address to a stream
|
||||||
|
* @param stream
|
||||||
|
* @param address
|
||||||
|
* @return std::ostream
|
||||||
|
*/
|
||||||
|
friend std::ostream &operator<<(std::ostream &stream, const Address &address)
|
||||||
|
{
|
||||||
|
// start with the protocol and login
|
||||||
|
stream << (address._secure ? "amqps://" : "amqp://");
|
||||||
|
|
||||||
|
// do we have a login?
|
||||||
|
if (address._login) stream << address._login << "@";
|
||||||
|
|
||||||
|
// write hostname
|
||||||
|
stream << address._hostname;
|
||||||
|
|
||||||
|
// do we need a special portnumber?
|
||||||
|
if (address._port != address.defaultport()) stream << ":" << address._port;
|
||||||
|
|
||||||
|
// append default vhost
|
||||||
|
stream << "/";
|
||||||
|
|
||||||
|
// do we have a special vhost or options?
|
||||||
|
if (address._vhost != "/") stream << address._vhost;
|
||||||
|
|
||||||
|
// iterate over all options, appending them
|
||||||
|
if (!address._options.empty())
|
||||||
|
{
|
||||||
|
// first append a question mark
|
||||||
|
stream << '?';
|
||||||
|
|
||||||
|
// is this the first option?
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
// iterate over all the options
|
||||||
|
for (const auto &kv : address._options)
|
||||||
|
{
|
||||||
|
// write the pair to the stream
|
||||||
|
stream << (first ? "" : "&") << kv.first << "=" << kv.second;
|
||||||
|
|
||||||
|
// no longer on first option
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer option
|
||||||
|
* @param name
|
||||||
|
* @param fallback
|
||||||
|
* @return T
|
||||||
|
*/
|
||||||
|
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
|
||||||
|
T option(const char *name, T fallback) const
|
||||||
|
{
|
||||||
|
// find the const char* version of the option
|
||||||
|
const char *value = option(name);
|
||||||
|
|
||||||
|
// if there is a value, convert it to integral, otherwise return the fallback
|
||||||
|
return value ? static_cast<T>(atoll(value)) : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a const char * option, returns nullptr if it does not exist.
|
||||||
|
* @return const char *
|
||||||
|
*/
|
||||||
|
const char *option(const char *name) const
|
||||||
|
{
|
||||||
|
// find the option
|
||||||
|
auto iter = _options.find(name);
|
||||||
|
|
||||||
|
// if not found, we return the default
|
||||||
|
if (iter == _options.end()) return nullptr;
|
||||||
|
|
||||||
|
// return the value in the map
|
||||||
|
return iter->second.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
119
builder/libs/AMQP-CPP/include/amqpcpp/addresses.h
Normal file
119
builder/libs/AMQP-CPP/include/amqpcpp/addresses.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* Addresses.h
|
||||||
|
*
|
||||||
|
* Class that contains multiple addresses
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Addresses
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The actual addresses
|
||||||
|
* @var std::vector<Address>
|
||||||
|
*/
|
||||||
|
std::vector<Address> _addresses;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for a comma separated list
|
||||||
|
* @param buffer
|
||||||
|
* @param size
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Addresses(const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
// keep looping
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// look for the comma
|
||||||
|
const char *comma = memchr(buffer, ',', size);
|
||||||
|
|
||||||
|
// stop if there is no comma
|
||||||
|
if (comma == nullptr) break;
|
||||||
|
|
||||||
|
// size of the address
|
||||||
|
size_t addresssize = comma - buffer - 1;
|
||||||
|
|
||||||
|
// add address
|
||||||
|
_addresses.emplace_back(buffer, addresssize);
|
||||||
|
|
||||||
|
// update for next iteration
|
||||||
|
buffer += addresssize + 1;
|
||||||
|
size -= addresssize + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have more?
|
||||||
|
if (size > 0) _addresses.emplace_back(buffer, size);
|
||||||
|
|
||||||
|
// was anything found?
|
||||||
|
if (_addresses.size() > 0) return;
|
||||||
|
|
||||||
|
// no addresses found
|
||||||
|
throw std::runtime_error("no addresses");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for a comma separated list
|
||||||
|
* @param buffer
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Addresses(const char *buffer) : Addresses(buffer, strlen(buffer)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for a comma separated list
|
||||||
|
* @param buffer
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Addresses(const std::string &buffer) : Addresses(buffer.data(), buffer.size()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructed
|
||||||
|
*/
|
||||||
|
virtual ~Addresses() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of addresses
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return _addresses.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose an address by index
|
||||||
|
* @param index
|
||||||
|
* @return Address
|
||||||
|
*/
|
||||||
|
const Address &operator[](size_t index) const
|
||||||
|
{
|
||||||
|
return _addresses.at(index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
258
builder/libs/AMQP-CPP/include/amqpcpp/array.h
Normal file
258
builder/libs/AMQP-CPP/include/amqpcpp/array.h
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
/**
|
||||||
|
* AMQP field array
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "field.h"
|
||||||
|
#include "fieldproxy.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AMQP field array
|
||||||
|
*/
|
||||||
|
class Array : public Field
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Definition of an array as a vector
|
||||||
|
* @typedef
|
||||||
|
*/
|
||||||
|
typedef std::vector<std::unique_ptr<Field>> FieldArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual fields
|
||||||
|
* @var FieldArray
|
||||||
|
*/
|
||||||
|
FieldArray _fields;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor to construct an array from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
Array(InBuffer &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param array
|
||||||
|
*/
|
||||||
|
Array(const Array &array);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor
|
||||||
|
* @param array
|
||||||
|
*/
|
||||||
|
Array(Array &&array) : _fields(std::move(array._fields)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for an empty Array
|
||||||
|
*/
|
||||||
|
Array() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Array() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of this object
|
||||||
|
* @return Field*
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
return std::unique_ptr<Array>(new Array(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a field
|
||||||
|
*
|
||||||
|
* @param index field index
|
||||||
|
* @param value field value
|
||||||
|
* @return Array
|
||||||
|
*/
|
||||||
|
Array set(uint8_t index, const Field &value)
|
||||||
|
{
|
||||||
|
// make a copy
|
||||||
|
auto ptr = value.clone();
|
||||||
|
|
||||||
|
// should we overwrite an existing record?
|
||||||
|
if (index >= _fields.size())
|
||||||
|
{
|
||||||
|
// append index
|
||||||
|
_fields.push_back(std::move(ptr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// overwrite pointer
|
||||||
|
_fields[index] = std::move(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field
|
||||||
|
*
|
||||||
|
* If the field does not exist, an empty string is returned
|
||||||
|
*
|
||||||
|
* @param index field index
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
|
const Field &get(uint8_t index) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get number of elements on this array
|
||||||
|
*
|
||||||
|
* @return array size
|
||||||
|
*/
|
||||||
|
uint32_t count() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove last element from array
|
||||||
|
*/
|
||||||
|
void pop_back();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add field to end of array
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
void push_back(const Field &value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field
|
||||||
|
*
|
||||||
|
* @param index field index
|
||||||
|
* @return ArrayFieldProxy
|
||||||
|
*/
|
||||||
|
ArrayFieldProxy operator[](uint8_t index)
|
||||||
|
{
|
||||||
|
return ArrayFieldProxy(this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a const field
|
||||||
|
* @param index field index
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
|
const Field &operator[](uint8_t index) const
|
||||||
|
{
|
||||||
|
return get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
* @return char
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are an array field
|
||||||
|
*
|
||||||
|
* @return true, because we are an array
|
||||||
|
*/
|
||||||
|
bool isArray() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// prefix
|
||||||
|
stream << "array(";
|
||||||
|
|
||||||
|
// is this the first iteration
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
// loop through all members
|
||||||
|
for (auto &iter : _fields)
|
||||||
|
{
|
||||||
|
// split with comma
|
||||||
|
if (!first) stream << ",";
|
||||||
|
|
||||||
|
// show output
|
||||||
|
stream << *iter;
|
||||||
|
|
||||||
|
// no longer first iter
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// postfix
|
||||||
|
stream << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to array.
|
||||||
|
*
|
||||||
|
* @note: This function may look silly and unnecessary. We are, after all, already
|
||||||
|
* an array. The whole reason we still have this function is that it is virtual
|
||||||
|
* and if we do not declare a cast to array on a pointer to base (i.e. Field)
|
||||||
|
* will return an empty field instead of the expected array.
|
||||||
|
*
|
||||||
|
* Yes, clang gets this wrong and gives incorrect warnings here. See
|
||||||
|
* https://llvm.org/bugs/show_bug.cgi?id=28263 for more information
|
||||||
|
*
|
||||||
|
* @return Ourselves
|
||||||
|
*/
|
||||||
|
virtual operator const Array& () const override
|
||||||
|
{
|
||||||
|
// this already is an array, so no cast is necessary
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom output stream operator
|
||||||
|
* @param stream
|
||||||
|
* @param field
|
||||||
|
* @return ostream
|
||||||
|
*/
|
||||||
|
inline std::ostream &operator<<(std::ostream &stream, const ArrayFieldProxy &field)
|
||||||
|
{
|
||||||
|
// get underlying field, and output that
|
||||||
|
return stream << field.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
202
builder/libs/AMQP-CPP/include/amqpcpp/booleanset.h
Normal file
202
builder/libs/AMQP-CPP/include/amqpcpp/booleanset.h
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/**
|
||||||
|
* BooleanSet.h
|
||||||
|
*
|
||||||
|
* AMQP can store eight booleans in a single byte. This class
|
||||||
|
* is a utility class for setting and getting the eight
|
||||||
|
* booleans
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <ostream>
|
||||||
|
#include "field.h"
|
||||||
|
#include "outbuffer.h"
|
||||||
|
#include "inbuffer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class BooleanSet : public Field
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The actual byte
|
||||||
|
* @var uint8_t
|
||||||
|
*/
|
||||||
|
uint8_t _byte;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param first the first bool to set
|
||||||
|
* @param second the second bool to set
|
||||||
|
* @param third the third bool to set
|
||||||
|
* @param fourth the fourth bool to set
|
||||||
|
* @param fifth the fifth bool to set
|
||||||
|
* @param sixth the sixth bool to set
|
||||||
|
* @param seventh the seventh bool to set
|
||||||
|
* @param eigth the eigth bool to set
|
||||||
|
*/
|
||||||
|
BooleanSet(bool first = false, bool second = false, bool third = false, bool fourth = false, bool fifth = false, bool sixth = false, bool seventh = false, bool eigth = false)
|
||||||
|
{
|
||||||
|
_byte = 0;
|
||||||
|
set(0, first);
|
||||||
|
set(1, second);
|
||||||
|
set(2, third);
|
||||||
|
set(3, fourth);
|
||||||
|
set(4, fifth);
|
||||||
|
set(5, sixth);
|
||||||
|
set(6, seventh);
|
||||||
|
set(7, eigth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on incoming data
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BooleanSet(InBuffer &frame)
|
||||||
|
{
|
||||||
|
_byte = frame.nextUint8();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
BooleanSet(const BooleanSet &that)
|
||||||
|
{
|
||||||
|
_byte = that._byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BooleanSet() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extending from field forces us to implement a clone function.
|
||||||
|
* @return unique_ptr
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
return std::unique_ptr<Field>(new BooleanSet(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// prefix
|
||||||
|
stream << "booleanset(";
|
||||||
|
|
||||||
|
// the members
|
||||||
|
for (int i=0; i<8; i++) stream << (i == 0 ? "" : ",") << (get(i) ? 1 : 0);
|
||||||
|
|
||||||
|
// postfix
|
||||||
|
stream << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get one of the booleans
|
||||||
|
* @param index from 0 to 7, where 0 is rightmost bit
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool get(uint32_t index) const
|
||||||
|
{
|
||||||
|
// bigger than seven is not an option
|
||||||
|
if (index > 7) return false;
|
||||||
|
|
||||||
|
// magic bit manipulation...
|
||||||
|
return 0 != ((1 << index) & _byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a boolean in the set
|
||||||
|
* @param index
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
void set(uint32_t index, bool value)
|
||||||
|
{
|
||||||
|
// index must be valid
|
||||||
|
if (index > 7) return;
|
||||||
|
|
||||||
|
// are we setting or unsetting
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
// magic bit manipulation...
|
||||||
|
_byte |= (1 << index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// magic bit manipulation...
|
||||||
|
_byte &= ~(1 << index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill the buffer
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
buffer.add(_byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the byte value
|
||||||
|
* @return value
|
||||||
|
*/
|
||||||
|
uint8_t value() const
|
||||||
|
{
|
||||||
|
return _byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type ID
|
||||||
|
* @return char
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return 't';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are a boolean field
|
||||||
|
*
|
||||||
|
* @return true, because we are a boolean
|
||||||
|
*/
|
||||||
|
bool isBoolean() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override
|
||||||
|
{
|
||||||
|
// booleanset takes up a single byte.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
84
builder/libs/AMQP-CPP/include/amqpcpp/buffer.h
Normal file
84
builder/libs/AMQP-CPP/include/amqpcpp/buffer.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Buffer.h
|
||||||
|
*
|
||||||
|
* Interface that can be implemented by client applications and that
|
||||||
|
* is passed to the Connection::parse() method.
|
||||||
|
*
|
||||||
|
* Normally, the Connection::parse() method is fed with a byte
|
||||||
|
* array. However, if you're receiving big frames, it may be inconvenient
|
||||||
|
* to copy these big frames into continguous byte arrays, and you
|
||||||
|
* prefer using objects that internally use linked lists or other
|
||||||
|
* ways to store the bytes. In such sitations, you can implement this
|
||||||
|
* interface and pass that to the connection.
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Buffer() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total size of the buffer
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to a single byte
|
||||||
|
*
|
||||||
|
* No safety checks are necessary: this method will only be called
|
||||||
|
* for bytes that actually exist
|
||||||
|
*
|
||||||
|
* @param pos position in the buffer
|
||||||
|
* @return char value of the byte in the buffer
|
||||||
|
*/
|
||||||
|
virtual char byte(size_t pos) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to the raw data
|
||||||
|
* @param pos position in the buffer
|
||||||
|
* @param size number of continuous bytes
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
virtual const char *data(size_t pos, size_t size) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy bytes to a buffer
|
||||||
|
*
|
||||||
|
* No safety checks are necessary: this method will only be called
|
||||||
|
* for bytes that actually exist
|
||||||
|
*
|
||||||
|
* @param pos position in the buffer
|
||||||
|
* @param size number of bytes to copy
|
||||||
|
* @param buffer buffer to copy into
|
||||||
|
* @return void* pointer to buffer
|
||||||
|
*/
|
||||||
|
virtual void *copy(size_t pos, size_t size, void *buffer) const = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
140
builder/libs/AMQP-CPP/include/amqpcpp/bytebuffer.h
Normal file
140
builder/libs/AMQP-CPP/include/amqpcpp/bytebuffer.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
* ByteByffer.h
|
||||||
|
*
|
||||||
|
* Very simple implementation of the buffer class that simply wraps
|
||||||
|
* around a buffer of bytes
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class ByteBuffer : public Buffer
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The actual byte buffer
|
||||||
|
* @var const char *
|
||||||
|
*/
|
||||||
|
const char *_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the buffer
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
ByteBuffer(const char *data, size_t size) : _data(data), _size(size) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No copy'ing
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
ByteBuffer(const ByteBuffer &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
ByteBuffer(ByteBuffer &&that) : _data(that._data), _size(that._size)
|
||||||
|
{
|
||||||
|
// reset other object
|
||||||
|
that._data = nullptr;
|
||||||
|
that._size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~ByteBuffer() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move assignment operator
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
ByteBuffer &operator=(ByteBuffer &&that)
|
||||||
|
{
|
||||||
|
// skip self-assignment
|
||||||
|
if (this == &that) return *this;
|
||||||
|
|
||||||
|
// copy members
|
||||||
|
_data = that._data;
|
||||||
|
_size = that._size;
|
||||||
|
|
||||||
|
// reset other object
|
||||||
|
that._data = nullptr;
|
||||||
|
that._size = 0;
|
||||||
|
|
||||||
|
// done
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total size of the buffer
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override
|
||||||
|
{
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to a single byte
|
||||||
|
* @param pos position in the buffer
|
||||||
|
* @return char value of the byte in the buffer
|
||||||
|
*/
|
||||||
|
virtual char byte(size_t pos) const override
|
||||||
|
{
|
||||||
|
return _data[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to the raw data
|
||||||
|
* @param pos position in the buffer
|
||||||
|
* @param size number of continuous bytes
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
virtual const char *data(size_t pos, size_t size) const override
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) size;
|
||||||
|
|
||||||
|
// expose the data
|
||||||
|
return _data + pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy bytes to a buffer
|
||||||
|
* @param pos position in the buffer
|
||||||
|
* @param size number of bytes to copy
|
||||||
|
* @param buffer buffer to copy into
|
||||||
|
* @return size_t pointer to buffer
|
||||||
|
*/
|
||||||
|
virtual void *copy(size_t pos, size_t size, void *buffer) const override
|
||||||
|
{
|
||||||
|
return memcpy(buffer, _data + pos, size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
98
builder/libs/AMQP-CPP/include/amqpcpp/callbacks.h
Normal file
98
builder/libs/AMQP-CPP/include/amqpcpp/callbacks.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* Callbacks.h
|
||||||
|
*
|
||||||
|
* Class storing deferred callbacks of different type.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Message;
|
||||||
|
class MetaData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic callbacks that are used by many deferred objects
|
||||||
|
*/
|
||||||
|
using SuccessCallback = std::function<void()>;
|
||||||
|
using ErrorCallback = std::function<void(const char *message)>;
|
||||||
|
using FinalizeCallback = std::function<void()>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declaring and deleting a queue
|
||||||
|
*/
|
||||||
|
using QueueCallback = std::function<void(const std::string &name, uint32_t messagecount, uint32_t consumercount)>;
|
||||||
|
using DeleteCallback = std::function<void(uint32_t deletedmessages)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When retrieving the size of a queue in some way
|
||||||
|
*/
|
||||||
|
using EmptyCallback = std::function<void()>;
|
||||||
|
using CountCallback = std::function<void(uint32_t messagecount)>;
|
||||||
|
using SizeCallback = std::function<void(uint64_t messagesize)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starting and stopping a consumer
|
||||||
|
*/
|
||||||
|
using ConsumeCallback = std::function<void(const std::string &consumer)>;
|
||||||
|
using CancelCallback = std::function<void(const std::string &consumer)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receiving messages, either via consume(), get() or as returned messages
|
||||||
|
* The following methods receive the returned message in multiple parts
|
||||||
|
*/
|
||||||
|
using StartCallback = std::function<void(const std::string &exchange, const std::string &routingkey)>;
|
||||||
|
using HeaderCallback = std::function<void(const MetaData &metaData)>;
|
||||||
|
using DataCallback = std::function<void(const char *data, size_t size)>;
|
||||||
|
using DeliveredCallback = std::function<void(uint64_t deliveryTag, bool redelivered)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For returned messages amqp-cpp first calls a return-callback before the start,
|
||||||
|
* header and data callbacks are called. Instead of the deliver-callback, a
|
||||||
|
* returned-callback is called.
|
||||||
|
*/
|
||||||
|
using ReturnCallback = std::function<void(int16_t code, const std::string &message)>;
|
||||||
|
using ReturnedCallback = std::function<void()>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If you do not want to merge all data into a single string, you can als
|
||||||
|
* implement callbacks that return the collected message.
|
||||||
|
*/
|
||||||
|
using MessageCallback = std::function<void(const Message &message, uint64_t deliveryTag, bool redelivered)>;
|
||||||
|
using BounceCallback = std::function<void(const Message &message, int16_t code, const std::string &description)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When using publisher confirms, AckCallback is called when server confirms that message is received
|
||||||
|
* and processed. NackCallback is called otherwise.
|
||||||
|
*/
|
||||||
|
using AckCallback = std::function<void(uint64_t deliveryTag, bool multiple)>;
|
||||||
|
using NackCallback = std::function<void(uint64_t deliveryTag, bool multiple, bool requeue)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When using a confirm wrapped channel, these callbacks are called when a message is acknowledged/nacked.
|
||||||
|
*/
|
||||||
|
using PublishAckCallback = std::function<void()>;
|
||||||
|
using PublishNackCallback = std::function<void()>;
|
||||||
|
using PublishLostCallback = std::function<void()>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
616
builder/libs/AMQP-CPP/include/amqpcpp/channel.h
Normal file
616
builder/libs/AMQP-CPP/include/amqpcpp/channel.h
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a (mid-level) AMQP channel implementation
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Channel
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The implementation for the channel
|
||||||
|
* @var std::shared_ptr<ChannelImpl>
|
||||||
|
*/
|
||||||
|
std::shared_ptr<ChannelImpl> _implementation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a channel object
|
||||||
|
*
|
||||||
|
* The passed in connection pointer must remain valid for the
|
||||||
|
* lifetime of the channel. Watch out: this method throws an error
|
||||||
|
* if the channel could not be constructed (for example because the
|
||||||
|
* max number of AMQP channels has been reached)
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Channel(Connection *connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy'ing of channel objects is not supported
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
Channel(const Channel &channel) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* But movement _is_ allowed
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
Channel(Channel &&channel) : _implementation(std::move(channel._implementation)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Channel()
|
||||||
|
{
|
||||||
|
// close the channel (this will eventually destruct the channel)
|
||||||
|
// note that the channel may be in an invalid state in case it was moved, hence the "if"
|
||||||
|
if (_implementation) _implementation->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No assignments of other channels
|
||||||
|
* @param channel
|
||||||
|
* @return Channel
|
||||||
|
*/
|
||||||
|
Channel &operator=(const Channel &channel) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when the channel was succesfully created.
|
||||||
|
*
|
||||||
|
* Only one callback can be registered. Calling this function multiple
|
||||||
|
* times will remove the old callback.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline void onReady(const SuccessCallback& callback) { return onReady(SuccessCallback(callback)); }
|
||||||
|
void onReady(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
_implementation->onReady(std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when an error occurs.
|
||||||
|
*
|
||||||
|
* Only one error callback can be registered. Calling this function
|
||||||
|
* multiple times will remove the old callback.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline void onError(const ErrorCallback& callback) { return onError(ErrorCallback(callback)); }
|
||||||
|
void onError(ErrorCallback&& callback)
|
||||||
|
{
|
||||||
|
_implementation->onError(std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause deliveries on a channel
|
||||||
|
*
|
||||||
|
* This will stop all incoming messages
|
||||||
|
*
|
||||||
|
* Note that this function does *not* work using RabbitMQ. For more info
|
||||||
|
* @see https://www.rabbitmq.com/specification.html#method-status-channel.flow
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &pause()
|
||||||
|
{
|
||||||
|
return _implementation->pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume a paused channel
|
||||||
|
*
|
||||||
|
* This will resume incoming messages
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &resume()
|
||||||
|
{
|
||||||
|
return _implementation->resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the channel ready / has it passed the initial handshake?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ready() const
|
||||||
|
{
|
||||||
|
return _implementation->ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the channel usable / not yet closed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool usable() const
|
||||||
|
{
|
||||||
|
return _implementation->usable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the channel connected?
|
||||||
|
* This method is deprecated: use Channel::usable()
|
||||||
|
* @return bool
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
bool connected() const
|
||||||
|
{
|
||||||
|
return usable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put channel in a confirm mode (RabbitMQ specific)
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
DeferredConfirm &confirmSelect()
|
||||||
|
{
|
||||||
|
return _implementation->confirmSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a transaction
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &startTransaction()
|
||||||
|
{
|
||||||
|
return _implementation->startTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit the current transaction
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &commitTransaction()
|
||||||
|
{
|
||||||
|
return _implementation->commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback the current transaction
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &rollbackTransaction()
|
||||||
|
{
|
||||||
|
return _implementation->rollbackTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare an exchange
|
||||||
|
*
|
||||||
|
* If an empty name is supplied, a name will be assigned by the server.
|
||||||
|
*
|
||||||
|
* The following flags can be used for the exchange:
|
||||||
|
*
|
||||||
|
* - durable exchange survives a broker restart
|
||||||
|
* - autodelete exchange is automatically removed when all connected queues are removed
|
||||||
|
* - passive only check if the exchange exist
|
||||||
|
* - internal create an internal exchange
|
||||||
|
*
|
||||||
|
* @param name name of the exchange
|
||||||
|
* @param type exchange type
|
||||||
|
* @param flags exchange flags
|
||||||
|
* @param arguments additional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &declareExchange(const std::string_view &name, ExchangeType type, int flags, const Table &arguments) { return _implementation->declareExchange(name, type, flags, arguments); }
|
||||||
|
Deferred &declareExchange(const std::string_view &name, ExchangeType type, const Table &arguments) { return _implementation->declareExchange(name, type, 0, arguments); }
|
||||||
|
Deferred &declareExchange(const std::string_view &name, ExchangeType type = fanout, int flags = 0) { return _implementation->declareExchange(name, type, flags, Table()); }
|
||||||
|
Deferred &declareExchange(ExchangeType type, int flags, const Table &arguments) { return _implementation->declareExchange(std::string_view(), type, flags, arguments); }
|
||||||
|
Deferred &declareExchange(ExchangeType type, const Table &arguments) { return _implementation->declareExchange(std::string_view(), type, 0, arguments); }
|
||||||
|
Deferred &declareExchange(ExchangeType type = fanout, int flags = 0) { return _implementation->declareExchange(std::string_view(), type, flags, Table()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an exchange
|
||||||
|
*
|
||||||
|
* The following flags can be used for the exchange:
|
||||||
|
*
|
||||||
|
* - ifunused only delete if no queues are connected
|
||||||
|
|
||||||
|
* @param name name of the exchange to remove
|
||||||
|
* @param flags optional flags
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &removeExchange(const std::string_view &name, int flags = 0) { return _implementation->removeExchange(name, flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind two exchanges to each other
|
||||||
|
*
|
||||||
|
* @param source the source exchange
|
||||||
|
* @param target the target exchange
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param arguments additional bind arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &bindExchange(const std::string_view &source, const std::string_view &target, const std::string_view &routingkey, const Table &arguments) { return _implementation->bindExchange(source, target, routingkey, arguments); }
|
||||||
|
Deferred &bindExchange(const std::string_view &source, const std::string_view &target, const std::string_view &routingkey) { return _implementation->bindExchange(source, target, routingkey, Table()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unbind two exchanges from one another
|
||||||
|
*
|
||||||
|
* @param target the target exchange
|
||||||
|
* @param source the source exchange
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param arguments additional unbind arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &unbindExchange(const std::string_view &target, const std::string_view &source, const std::string_view &routingkey, const Table &arguments) { return _implementation->unbindExchange(target, source, routingkey, arguments); }
|
||||||
|
Deferred &unbindExchange(const std::string_view &target, const std::string_view &source, const std::string_view &routingkey) { return _implementation->unbindExchange(target, source, routingkey, Table()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare a queue
|
||||||
|
*
|
||||||
|
* If you do not supply a name, a name will be assigned by the server.
|
||||||
|
*
|
||||||
|
* The flags can be a combination of the following values:
|
||||||
|
*
|
||||||
|
* - durable queue survives a broker restart
|
||||||
|
* - autodelete queue is automatically removed when all connected consumers are gone
|
||||||
|
* - passive only check if the queue exist
|
||||||
|
* - exclusive the queue only exists for this connection, and is automatically removed when connection is gone
|
||||||
|
*
|
||||||
|
* @param name name of the queue
|
||||||
|
* @param flags combination of flags
|
||||||
|
* @param arguments optional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(const std::string &name, uint32_t messageCount, uint32_t consumerCount);
|
||||||
|
*
|
||||||
|
* For example: channel.declareQueue("myqueue").onSuccess([](const std::string &name, uint32_t messageCount, uint32_t consumerCount) {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue '" << name << "' has been declared with " << messageCount << " messages and " << consumerCount << " consumers" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredQueue &declareQueue(const std::string_view &name, int flags, const Table &arguments) { return _implementation->declareQueue(name, flags, arguments); }
|
||||||
|
DeferredQueue &declareQueue(const std::string_view &name, const Table &arguments) { return _implementation->declareQueue(name, 0, arguments); }
|
||||||
|
DeferredQueue &declareQueue(const std::string_view &name, int flags = 0) { return _implementation->declareQueue(name, flags, Table()); }
|
||||||
|
DeferredQueue &declareQueue(int flags, const Table &arguments) { return _implementation->declareQueue(std::string_view(), flags, arguments); }
|
||||||
|
DeferredQueue &declareQueue(const Table &arguments) { return _implementation->declareQueue(std::string_view(), 0, arguments); }
|
||||||
|
DeferredQueue &declareQueue(int flags = 0) { return _implementation->declareQueue(std::string_view(), flags, Table()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a queue to an exchange
|
||||||
|
*
|
||||||
|
* @param exchange the source exchange
|
||||||
|
* @param queue the target queue
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param arguments additional bind arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &bindQueue(const std::string_view &exchange, const std::string_view &queue, const std::string_view &routingkey, const Table &arguments) { return _implementation->bindQueue(exchange, queue, routingkey, arguments); }
|
||||||
|
Deferred &bindQueue(const std::string_view &exchange, const std::string_view &queue, const std::string_view &routingkey) { return _implementation->bindQueue(exchange, queue, routingkey, Table()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unbind a queue from an exchange
|
||||||
|
* @param exchange the source exchange
|
||||||
|
* @param queue the target queue
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param arguments additional bind arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &unbindQueue(const std::string_view &exchange, const std::string_view &queue, const std::string_view &routingkey, const Table &arguments) { return _implementation->unbindQueue(exchange, queue, routingkey, arguments); }
|
||||||
|
Deferred &unbindQueue(const std::string_view &exchange, const std::string_view &queue, const std::string_view &routingkey) { return _implementation->unbindQueue(exchange, queue, routingkey, Table()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purge a queue
|
||||||
|
*
|
||||||
|
* @param name name of the queue
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(uint32_t messageCount);
|
||||||
|
*
|
||||||
|
* For example: channel.purgeQueue("myqueue").onSuccess([](uint32_t messageCount) {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue purged, all " << messageCount << " messages removed" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredDelete &purgeQueue(const std::string_view &name){ return _implementation->purgeQueue(name); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a queue
|
||||||
|
*
|
||||||
|
* The following flags can be used for the exchange:
|
||||||
|
*
|
||||||
|
* - ifunused only delete if no consumers are connected
|
||||||
|
* - ifempty only delete if the queue is empty
|
||||||
|
*
|
||||||
|
* @param name name of the queue to remove
|
||||||
|
* @param flags optional flags
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(uint32_t messageCount);
|
||||||
|
*
|
||||||
|
* For example: channel.removeQueue("myqueue").onSuccess([](uint32_t messageCount) {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue deleted, along with " << messageCount << " messages" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredDelete &removeQueue(const std::string_view &name, int flags = 0) { return _implementation->removeQueue(name, flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a message to an exchange
|
||||||
|
*
|
||||||
|
* You have to supply the name of an exchange and a routing key. RabbitMQ will then try
|
||||||
|
* to send the message to one or more queues. With the optional flags parameter you can
|
||||||
|
* specify what should happen if the message could not be routed to a queue. By default,
|
||||||
|
* unroutable message are silently discarded.
|
||||||
|
*
|
||||||
|
* If you set the 'mandatory' and/or 'immediate' flag, messages that could not be handled
|
||||||
|
* are returned to the application. Make sure that you have called the recall()-method and
|
||||||
|
* have set up all appropriate handlers to process these returned messages before you start
|
||||||
|
* publishing.
|
||||||
|
*
|
||||||
|
* The following flags can be supplied:
|
||||||
|
*
|
||||||
|
* - mandatory If set, server returns messages that are not sent to a queue
|
||||||
|
* - immediate If set, server returns messages that can not immediately be forwarded to a consumer.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange to publish to
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param envelope the full envelope to send
|
||||||
|
* @param message the message to send
|
||||||
|
* @param size size of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
*/
|
||||||
|
bool publish(const std::string_view &exchange, const std::string_view &routingKey, const Envelope &envelope, int flags = 0) { return _implementation->publish(exchange, routingKey, envelope, flags); }
|
||||||
|
bool publish(const std::string_view &exchange, const std::string_view &routingKey, const std::string &message, int flags = 0) { return _implementation->publish(exchange, routingKey, Envelope(message.data(), message.size()), flags); }
|
||||||
|
bool publish(const std::string_view &exchange, const std::string_view &routingKey, const char *message, size_t size, int flags = 0) { return _implementation->publish(exchange, routingKey, Envelope(message, size), flags); }
|
||||||
|
bool publish(const std::string_view &exchange, const std::string_view &routingKey, const char *message, int flags = 0) { return _implementation->publish(exchange, routingKey, Envelope(message, strlen(message)), flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Quality of Service (QOS) for this channel
|
||||||
|
*
|
||||||
|
* When you consume messages, every single message needs to be ack'ed to inform
|
||||||
|
* the RabbitMQ server that is has been received. The Qos setting specifies the
|
||||||
|
* number of unacked messages that may exist in the client application. The server
|
||||||
|
* stops delivering more messages if the number of unack'ed messages has reached
|
||||||
|
* the prefetchCount
|
||||||
|
*
|
||||||
|
* @param prefetchCount maximum number of messages to prefetch
|
||||||
|
* @param global share counter between all consumers on the same channel
|
||||||
|
* @return bool whether the Qos frame is sent.
|
||||||
|
*/
|
||||||
|
Deferred &setQos(uint16_t prefetchCount, bool global = false)
|
||||||
|
{
|
||||||
|
return _implementation->setQos(prefetchCount, global);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the RabbitMQ server that we're ready to consume messages
|
||||||
|
*
|
||||||
|
* After this method is called, RabbitMQ starts delivering messages to the client
|
||||||
|
* application. The consume tag is a string identifier that you can use to identify
|
||||||
|
* the consumer if you later want to stop it with with a channel::cancel() call.
|
||||||
|
* If you do not specify a consumer tag, the server will assign one for you.
|
||||||
|
*
|
||||||
|
* The following flags are supported:
|
||||||
|
*
|
||||||
|
* - nolocal if set, messages published on this channel are not also consumed
|
||||||
|
* - noack if set, consumed messages do not have to be acked, this happens automatically
|
||||||
|
* - exclusive request exclusive access, only this consumer can access the queue
|
||||||
|
*
|
||||||
|
* @param queue the queue from which you want to consume
|
||||||
|
* @param tag a consumer tag that will be associated with this consume operation
|
||||||
|
* @param flags additional flags
|
||||||
|
* @param arguments additional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(const std::string_view& tag);
|
||||||
|
*
|
||||||
|
* For example: channel.consume("myqueue").onSuccess([](const std::string_view& tag) {
|
||||||
|
*
|
||||||
|
* std::cout << "Started consuming under tag " << tag << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredConsumer &consume(const std::string_view &queue, const std::string_view &tag, int flags, const Table &arguments) { return _implementation->consume(queue, tag, flags, arguments); }
|
||||||
|
DeferredConsumer &consume(const std::string_view &queue, const std::string_view &tag, int flags = 0) { return _implementation->consume(queue, tag, flags, Table()); }
|
||||||
|
DeferredConsumer &consume(const std::string_view &queue, const std::string_view &tag, const Table &arguments) { return _implementation->consume(queue, tag, 0, arguments); }
|
||||||
|
DeferredConsumer &consume(const std::string_view &queue, int flags, const Table &arguments) { return _implementation->consume(queue, std::string_view(), flags, arguments); }
|
||||||
|
DeferredConsumer &consume(const std::string_view &queue, int flags = 0) { return _implementation->consume(queue, std::string_view(), flags, Table()); }
|
||||||
|
DeferredConsumer &consume(const std::string_view &queue, const Table &arguments) { return _implementation->consume(queue, std::string_view(), 0, arguments); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the messages that you are ready to recall/take back messages that messages thar are unroutable.
|
||||||
|
*
|
||||||
|
* When you use the publish() method in combination with the 'immediate' or 'mandatory' flag, rabbitmq
|
||||||
|
* sends back unroutable messages. With this recall() method you can install a sort of pseudo-consumer
|
||||||
|
* that defines how such returned-messages are processed.
|
||||||
|
*
|
||||||
|
* Watch out: when you call this method more than once, you always get access to the same object. You
|
||||||
|
* can thus not install multiple callbacks for the same event.
|
||||||
|
*/
|
||||||
|
DeferredRecall &recall() { return _implementation->recall(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a running consume call
|
||||||
|
*
|
||||||
|
* If you want to stop a running consumer, you can use this method with the consumer tag
|
||||||
|
*
|
||||||
|
* @param tag the consumer tag
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(const std::string& tag);
|
||||||
|
*
|
||||||
|
* For example: channel.cancel("myqueue").onSuccess([](const std::string& tag) {
|
||||||
|
*
|
||||||
|
* std::cout << "Stopped consuming under tag " << tag << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredCancel &cancel(const std::string_view &tag) { return _implementation->cancel(tag); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a single message from RabbitMQ
|
||||||
|
*
|
||||||
|
* When you call this method, you can get one single message from the queue (or none
|
||||||
|
* at all if the queue is empty). The deferred object that is returned, should be used
|
||||||
|
* to install a onEmpty() and onSuccess() callback function that will be called
|
||||||
|
* when the message is consumed and/or when the message could not be consumed.
|
||||||
|
*
|
||||||
|
* The following flags are supported:
|
||||||
|
*
|
||||||
|
* - noack if set, consumed messages do not have to be acked, this happens automatically
|
||||||
|
*
|
||||||
|
* @param queue name of the queue to consume from
|
||||||
|
* @param flags optional flags
|
||||||
|
*
|
||||||
|
* The object returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onEmpty(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback has the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(const Message &message, uint64_t deliveryTag, bool redelivered);
|
||||||
|
*
|
||||||
|
* For example: channel.get("myqueue").onSuccess([](const Message &message, uint64_t deliveryTag, bool redelivered) {
|
||||||
|
*
|
||||||
|
* std::cout << "Message fetched" << std::endl;
|
||||||
|
*
|
||||||
|
* }).onEmpty([]() {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue is empty" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredGet &get(const std::string_view &queue, int flags = 0) { return _implementation->get(queue, flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acknoldge a received message
|
||||||
|
*
|
||||||
|
* When a message is received in the DeferredConsumer::onReceived() method,
|
||||||
|
* you must acknowledge it so that RabbitMQ removes it from the queue (unless
|
||||||
|
* you are consuming with the noack option). This method can be used for
|
||||||
|
* this acknowledging.
|
||||||
|
*
|
||||||
|
* The following flags are supported:
|
||||||
|
*
|
||||||
|
* - multiple acknowledge multiple messages: all un-acked messages that were earlier delivered are acknowledged too
|
||||||
|
*
|
||||||
|
* @param deliveryTag the unique delivery tag of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ack(uint64_t deliveryTag, int flags=0) { return _implementation->ack(deliveryTag, flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject or nack a message
|
||||||
|
*
|
||||||
|
* When a message was received in the DeferredConsumer::onReceived() method,
|
||||||
|
* and you don't want to acknowledge it, you can also choose to reject it by
|
||||||
|
* calling this reject method.
|
||||||
|
*
|
||||||
|
* The following flags are supported:
|
||||||
|
*
|
||||||
|
* - multiple reject multiple messages: all un-acked messages that were earlier delivered are unacked too
|
||||||
|
* - requeue if set, the message is put back in the queue, otherwise it is dead-lettered/removed
|
||||||
|
*
|
||||||
|
* @param deliveryTag the unique delivery tag of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool reject(uint64_t deliveryTag, int flags=0) { return _implementation->reject(deliveryTag, flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recover all messages that were not yet acked
|
||||||
|
*
|
||||||
|
* This method asks the server to redeliver all unacknowledged messages on a specified
|
||||||
|
* channel. Zero or more messages may be redelivered.
|
||||||
|
*
|
||||||
|
* The following flags are supported:
|
||||||
|
*
|
||||||
|
* - requeue if set, the server will requeue the messages, so the could also end up with at different consumer
|
||||||
|
*
|
||||||
|
* @param flags
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &recover(int flags = 0) { return _implementation->recover(flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current channel
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &close() { return _implementation->close(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channel we're working on
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t id() const
|
||||||
|
{
|
||||||
|
return _implementation->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some internal classes may touch our implementation
|
||||||
|
*/
|
||||||
|
friend class Tagger;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
803
builder/libs/AMQP-CPP/include/amqpcpp/channelimpl.h
Normal file
803
builder/libs/AMQP-CPP/include/amqpcpp/channelimpl.h
Normal file
@ -0,0 +1,803 @@
|
|||||||
|
/**
|
||||||
|
* ChannelImpl.h
|
||||||
|
*
|
||||||
|
* Extended channel object that is used internally by the library, but
|
||||||
|
* that has a private constructor so that it can not be used from outside
|
||||||
|
* the AMQP library
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "exchangetype.h"
|
||||||
|
#include "watchable.h"
|
||||||
|
#include "callbacks.h"
|
||||||
|
#include "copiedbuffer.h"
|
||||||
|
#include "deferred.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class DeferredReceiver;
|
||||||
|
class BasicDeliverFrame;
|
||||||
|
class DeferredConsumer;
|
||||||
|
class BasicGetOKFrame;
|
||||||
|
class ConsumedMessage;
|
||||||
|
class ConnectionImpl;
|
||||||
|
class DeferredDelete;
|
||||||
|
class DeferredCancel;
|
||||||
|
class DeferredConfirm;
|
||||||
|
class DeferredQueue;
|
||||||
|
class DeferredGet;
|
||||||
|
class DeferredRecall;
|
||||||
|
class Connection;
|
||||||
|
class Envelope;
|
||||||
|
class Table;
|
||||||
|
class Frame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class ChannelImpl : public Watchable, public std::enable_shared_from_this<ChannelImpl>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Pointer to the connection
|
||||||
|
* @var ConnectionImpl
|
||||||
|
*/
|
||||||
|
ConnectionImpl *_connection = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback when the channel is ready
|
||||||
|
* @var SuccessCallback
|
||||||
|
*/
|
||||||
|
SuccessCallback _readyCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback when the channel errors out
|
||||||
|
* @var ErrorCallback
|
||||||
|
*/
|
||||||
|
ErrorCallback _errorCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler that deals with incoming messages as a result of publish operations
|
||||||
|
* @var DeferredRecall
|
||||||
|
*/
|
||||||
|
std::shared_ptr<DeferredRecall> _recall;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler that deals with publisher confirms frames
|
||||||
|
* @var std::shared_ptr<DeferredConfirm>
|
||||||
|
*/
|
||||||
|
std::shared_ptr<DeferredConfirm> _confirm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handlers for all consumers that are active
|
||||||
|
* @var std::map<std::string,std::shared_ptr<DeferredConsumer>
|
||||||
|
*/
|
||||||
|
std::map<std::string,std::shared_ptr<DeferredConsumer>> _consumers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the oldest deferred result (the first one that is going
|
||||||
|
* to be executed)
|
||||||
|
*
|
||||||
|
* @var Deferred
|
||||||
|
*/
|
||||||
|
std::shared_ptr<Deferred> _oldestCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the newest deferred result (the last one to be added).
|
||||||
|
*
|
||||||
|
* @var Deferred
|
||||||
|
*/
|
||||||
|
std::shared_ptr<Deferred> _newestCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel number
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _id = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State of the channel object
|
||||||
|
* @var enum
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
state_connected,
|
||||||
|
state_ready,
|
||||||
|
state_closing,
|
||||||
|
state_closed
|
||||||
|
} _state = state_closed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The frames that still need to be send out
|
||||||
|
*
|
||||||
|
* We store the data as well as whether they
|
||||||
|
* should be handled synchronously.
|
||||||
|
*
|
||||||
|
* @var std::queue
|
||||||
|
*/
|
||||||
|
std::queue<CopiedBuffer> _queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we currently operating in synchronous mode? Meaning: do we first have
|
||||||
|
* to wait for the answer to previous instructions before we send a new instruction?
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _synchronous = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current object that is busy receiving a message
|
||||||
|
* @var std::shared_ptr<DeferredReceiver>
|
||||||
|
*/
|
||||||
|
std::shared_ptr<DeferredReceiver> _receiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach the connection
|
||||||
|
* @param connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool attach(Connection *connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push a deferred result
|
||||||
|
* @param result The deferred result
|
||||||
|
* @return Deferred The object just pushed
|
||||||
|
*/
|
||||||
|
Deferred &push(const std::shared_ptr<Deferred> &deferred);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a framen and push a deferred result
|
||||||
|
* @param frame The frame to send
|
||||||
|
* @return Deferred The object just pushed
|
||||||
|
*/
|
||||||
|
Deferred &push(const Frame &frame);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Construct a channel object
|
||||||
|
*
|
||||||
|
* Note that the constructor is private, and that the Channel class is
|
||||||
|
* a friend. By doing this we ensure that nobody can instantiate this
|
||||||
|
* object, and that it can thus only be used inside the library.
|
||||||
|
*/
|
||||||
|
ChannelImpl();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Copy'ing of channel objects is not supported
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
ChannelImpl(const ChannelImpl &channel) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~ChannelImpl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No assignments of other channels
|
||||||
|
* @param channel
|
||||||
|
* @return Channel
|
||||||
|
*/
|
||||||
|
ChannelImpl &operator=(const ChannelImpl &channel) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate the channel
|
||||||
|
* This method is called when the connection is destructed
|
||||||
|
*/
|
||||||
|
void detach()
|
||||||
|
{
|
||||||
|
// connection is gone
|
||||||
|
_connection = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose the currently installed callbacks
|
||||||
|
* @return ErrorCallback
|
||||||
|
*/
|
||||||
|
const ErrorCallback &onError() const { return _errorCallback; }
|
||||||
|
const SuccessCallback &onReady() const { return _readyCallback; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when the channel was succesfully created.
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline void onReady(const SuccessCallback& callback) { return onReady(SuccessCallback(callback)); }
|
||||||
|
void onReady(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_readyCallback = std::move(callback);
|
||||||
|
|
||||||
|
// direct call if channel is already ready
|
||||||
|
if (_state == state_ready && _readyCallback) _readyCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when an error occurs.
|
||||||
|
*
|
||||||
|
* Only one error callback can be registered. Calling this function
|
||||||
|
* multiple times will remove the old callback.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline void onError(const ErrorCallback& callback) { return onError(ErrorCallback(callback)); }
|
||||||
|
void onError(ErrorCallback&& callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause deliveries on a channel
|
||||||
|
*
|
||||||
|
* This will stop all incoming messages
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &pause();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume a paused channel
|
||||||
|
*
|
||||||
|
* This will resume incoming messages
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &resume();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the channel usable / not yet closed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool usable() const
|
||||||
|
{
|
||||||
|
return _state == state_connected || _state == state_ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the channel ready / has it passed the initial handshake?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ready() const
|
||||||
|
{
|
||||||
|
return _state == state_ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put channel in a confirm mode (RabbitMQ specific)
|
||||||
|
*/
|
||||||
|
DeferredConfirm &confirmSelect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a transaction
|
||||||
|
*/
|
||||||
|
Deferred &startTransaction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit the current transaction
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &commitTransaction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback the current transaction
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &rollbackTransaction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* declare an exchange
|
||||||
|
*
|
||||||
|
* @param name name of the exchange to declare
|
||||||
|
* @param type type of exchange
|
||||||
|
* @param flags additional settings for the exchange
|
||||||
|
* @param arguments additional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &declareExchange(const std::string_view &name, ExchangeType type, int flags, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bind two exchanges
|
||||||
|
|
||||||
|
* @param source exchange which binds to target
|
||||||
|
* @param target exchange to bind to
|
||||||
|
* @param routingKey routing key
|
||||||
|
* @param arguments additional arguments for binding
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &bindExchange(const std::string_view &source, const std::string_view &target, const std::string_view &routingkey, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unbind two exchanges
|
||||||
|
|
||||||
|
* @param source the source exchange
|
||||||
|
* @param target the target exchange
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param arguments additional unbind arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &unbindExchange(const std::string_view &source, const std::string_view &target, const std::string_view &routingkey, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove an exchange
|
||||||
|
*
|
||||||
|
* @param name name of the exchange to remove
|
||||||
|
* @param flags additional settings for deleting the exchange
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &removeExchange(const std::string_view &name, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* declare a queue
|
||||||
|
* @param name queue name
|
||||||
|
* @param flags additional settings for the queue
|
||||||
|
* @param arguments additional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
DeferredQueue &declareQueue(const std::string_view &name, int flags, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a queue to an exchange
|
||||||
|
*
|
||||||
|
* @param exchangeName name of the exchange to bind to
|
||||||
|
* @param queueName name of the queue
|
||||||
|
* @param routingkey routingkey
|
||||||
|
* @param arguments additional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &bindQueue(const std::string_view &exchangeName, const std::string_view &queueName, const std::string_view &routingkey, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unbind a queue from an exchange
|
||||||
|
*
|
||||||
|
* @param exchange the source exchange
|
||||||
|
* @param queue the target queue
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param arguments additional bind arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &unbindQueue(const std::string_view &exchangeName, const std::string_view &queueName, const std::string_view &routingkey, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purge a queue
|
||||||
|
* @param queue queue to purge
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(AMQP::Channel *channel, uint32_t messageCount);
|
||||||
|
*
|
||||||
|
* For example: channel.purgeQueue("myqueue").onSuccess([](AMQP::Channel *channel, uint32_t messageCount) {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue purged, all " << messageCount << " messages removed" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredDelete &purgeQueue(const std::string_view &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a queue
|
||||||
|
* @param queue queue to remove
|
||||||
|
* @param flags additional flags
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(AMQP::Channel *channel, uint32_t messageCount);
|
||||||
|
*
|
||||||
|
* For example: channel.declareQueue("myqueue").onSuccess([](AMQP::Channel *channel, uint32_t messageCount) {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue deleted, along with " << messageCount << " messages" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredDelete &removeQueue(const std::string_view &name, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a message to an exchange
|
||||||
|
*
|
||||||
|
* If the mandatory or immediate flag is set, and the message could not immediately
|
||||||
|
* be published, the message will be returned to the client.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange to publish to
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param envelope the full envelope to send
|
||||||
|
* @param message the message to send
|
||||||
|
* @param size size of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool publish(const std::string_view &exchange, const std::string_view &routingKey, const Envelope &envelope, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Quality of Service (QOS) of the entire connection
|
||||||
|
* @param prefetchCount maximum number of messages to prefetch
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* @param count number of messages to pre-fetch
|
||||||
|
* @param global share count between all consumers on the same channel
|
||||||
|
*/
|
||||||
|
Deferred &setQos(uint16_t prefetchCount, bool global = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the RabbitMQ server that we're ready to consume messages
|
||||||
|
* @param queue the queue from which you want to consume
|
||||||
|
* @param tag a consumer tag that will be associated with this consume operation
|
||||||
|
* @param flags additional flags
|
||||||
|
* @param arguments additional arguments
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(AMQP::Channel *channel, const std::string& tag);
|
||||||
|
*
|
||||||
|
* For example: channel.declareQueue("myqueue").onSuccess([](AMQP::Channel *channel, const std::string& tag) {
|
||||||
|
*
|
||||||
|
* std::cout << "Started consuming under tag " << tag << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredConsumer& consume(const std::string_view &queue, const std::string_view &tag, int flags, const Table &arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell that you are prepared to recall/take back messages that could not be
|
||||||
|
* published. This is only meaningful if you pass the 'immediate' or 'mandatory'
|
||||||
|
* flag to publish() operations.
|
||||||
|
*
|
||||||
|
* THis function returns a deferred handler more or less similar to the object
|
||||||
|
* return by the consume() method and that can be used to install callbacks that
|
||||||
|
* handle the recalled messages.
|
||||||
|
*/
|
||||||
|
DeferredRecall &recall();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a running consumer
|
||||||
|
* @param tag the consumer tag
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback that you can install should have the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(const std::string& tag);
|
||||||
|
*
|
||||||
|
* For example: channel.declareQueue("myqueue").onSuccess([](const std::string& tag) {
|
||||||
|
*
|
||||||
|
* std::cout << "Started consuming under tag " << tag << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredCancel &cancel(const std::string_view &tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a single message from RabbitMQ
|
||||||
|
*
|
||||||
|
* When you call this method, you can get one single message from the queue (or none
|
||||||
|
* at all if the queue is empty). The deferred object that is returned, should be used
|
||||||
|
* to install a onEmpty() and onSuccess() callback function that will be called
|
||||||
|
* when the message is consumed and/or when the message could not be consumed.
|
||||||
|
*
|
||||||
|
* The following flags are supported:
|
||||||
|
*
|
||||||
|
* - noack if set, consumed messages do not have to be acked, this happens automatically
|
||||||
|
*
|
||||||
|
* @param queue name of the queue to consume from
|
||||||
|
* @param flags optional flags
|
||||||
|
*
|
||||||
|
* The object returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onEmpty(), onError() and onFinalize() methods.
|
||||||
|
*
|
||||||
|
* The onSuccess() callback has the following signature:
|
||||||
|
*
|
||||||
|
* void myCallback(const Message &message, uint64_t deliveryTag, bool redelivered);
|
||||||
|
*
|
||||||
|
* For example: channel.get("myqueue").onSuccess([](const Message &message, uint64_t deliveryTag, bool redelivered) {
|
||||||
|
*
|
||||||
|
* std::cout << "Message fetched" << std::endl;
|
||||||
|
*
|
||||||
|
* }).onEmpty([]() {
|
||||||
|
*
|
||||||
|
* std::cout << "Queue is empty" << std::endl;
|
||||||
|
*
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
DeferredGet &get(const std::string_view &queue, int flags = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acknowledge a message
|
||||||
|
* @param deliveryTag the delivery tag
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ack(uint64_t deliveryTag, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject a message
|
||||||
|
* @param deliveryTag the delivery tag
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool reject(uint64_t deliveryTag, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recover messages that were not yet ack'ed
|
||||||
|
* @param flags optional flags
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &recover(int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current channel
|
||||||
|
*
|
||||||
|
* This function returns a deferred handler. Callbacks can be installed
|
||||||
|
* using onSuccess(), onError() and onFinalize() methods.
|
||||||
|
*/
|
||||||
|
Deferred &close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channel we're working on
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t id() const
|
||||||
|
{
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a frame over the channel
|
||||||
|
* @param frame frame to send
|
||||||
|
* @return bool was frame succesfully sent?
|
||||||
|
*/
|
||||||
|
bool send(CopiedBuffer &&frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a frame over the channel
|
||||||
|
* @param frame frame to send
|
||||||
|
* @return bool was frame succesfully sent?
|
||||||
|
*/
|
||||||
|
bool send(const Frame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this channel waiting for an answer before it can send furher instructions
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool waiting() const
|
||||||
|
{
|
||||||
|
return _synchronous || !_queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max payload size for frames
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t maxPayload() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal the channel that a synchronous operation was completed, and that any
|
||||||
|
* queued frames can be sent out.
|
||||||
|
* @return false if an error on the connection level occurred, true if not
|
||||||
|
*/
|
||||||
|
bool flush();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report to the handler that the channel is opened
|
||||||
|
*/
|
||||||
|
void reportReady()
|
||||||
|
{
|
||||||
|
// if we are still in connected state we are now ready
|
||||||
|
if (_state == state_connected) _state = state_ready;
|
||||||
|
|
||||||
|
// send out more instructions if there is a queue
|
||||||
|
flush();
|
||||||
|
|
||||||
|
// inform handler
|
||||||
|
if (_readyCallback) _readyCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report to the handler that the channel is closed
|
||||||
|
*
|
||||||
|
* Returns whether the channel object is still valid
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool reportClosed()
|
||||||
|
{
|
||||||
|
// change state
|
||||||
|
_state = state_closed;
|
||||||
|
|
||||||
|
// create a monitor, because the callbacks could destruct the current object
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// and pass on to the reportSuccess() method which will call the
|
||||||
|
// appropriate deferred object to report the successful operation
|
||||||
|
bool result = reportSuccess();
|
||||||
|
|
||||||
|
// leap out if object no longer exists
|
||||||
|
if (!monitor.valid()) return result;
|
||||||
|
|
||||||
|
// all later deferred objects should report an error, because it
|
||||||
|
// was not possible to complete the instruction as the channel is
|
||||||
|
// now closed (but the channel onError does not have to run)
|
||||||
|
reportError("Channel has been closed", false);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success
|
||||||
|
*
|
||||||
|
* Returns whether the channel object is still valid
|
||||||
|
*
|
||||||
|
* @param mixed
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
template <typename... Arguments>
|
||||||
|
bool reportSuccess(Arguments ...parameters)
|
||||||
|
{
|
||||||
|
// skip if there is no oldest callback
|
||||||
|
if (!_oldestCallback) return true;
|
||||||
|
|
||||||
|
// we are going to call callbacks that could destruct the channel
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// flush the queue, which will send the next operation if the current operation was synchronous
|
||||||
|
flush();
|
||||||
|
|
||||||
|
// the call to flush may have resulted in a call to reportError
|
||||||
|
if (!monitor.valid()) return false;
|
||||||
|
|
||||||
|
// copy the callback (so that it will not be destructed during
|
||||||
|
// the "reportSuccess" call, if the channel is destructed during the call)
|
||||||
|
auto cb = _oldestCallback;
|
||||||
|
|
||||||
|
// the call to flush might have caused the callback to have been invoked; check once more
|
||||||
|
if (!cb) return true;
|
||||||
|
|
||||||
|
// call the callback
|
||||||
|
auto next = cb->reportSuccess(std::forward<Arguments>(parameters)...);
|
||||||
|
|
||||||
|
// leap out if channel no longer exist
|
||||||
|
if (!monitor.valid()) return false;
|
||||||
|
|
||||||
|
// in case the callback-shared-pointer is still kept in scope (for example because it
|
||||||
|
// is stored in the list of consumers), we do want to ensure that it no longer maintains
|
||||||
|
// a chain of queued deferred objects
|
||||||
|
cb->unchain();
|
||||||
|
|
||||||
|
// set the oldest callback
|
||||||
|
_oldestCallback = next;
|
||||||
|
|
||||||
|
// if there was no next callback, the newest callback was just used
|
||||||
|
if (!next) _newestCallback = nullptr;
|
||||||
|
|
||||||
|
// we are still valid
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report that a consumer was cancelled by the server (for example because the
|
||||||
|
* queue was removed or the node on which the queue was stored was terminated)
|
||||||
|
* @param tag the consumer tag
|
||||||
|
*/
|
||||||
|
void reportCancelled(const std::string &tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report an error message on a channel
|
||||||
|
* @param message the error message
|
||||||
|
* @param notifyhandler should the channel-wide handler also be called?
|
||||||
|
*/
|
||||||
|
void reportError(const char *message, bool notifyhandler = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a consumer
|
||||||
|
* @param consumertag The consumer tag
|
||||||
|
* @param consumer The consumer object
|
||||||
|
*/
|
||||||
|
void install(const std::string &consumertag, const std::shared_ptr<DeferredConsumer> &consumer)
|
||||||
|
{
|
||||||
|
// install the consumer handler
|
||||||
|
_consumers[consumertag] = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install the current consumer
|
||||||
|
* @param receiver The receiver object
|
||||||
|
*/
|
||||||
|
void install(const std::shared_ptr<DeferredReceiver> &receiver)
|
||||||
|
{
|
||||||
|
// store object as current receiver
|
||||||
|
_receiver = receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall a consumer callback
|
||||||
|
* @param consumertag The consumer tag
|
||||||
|
*/
|
||||||
|
void uninstall(const std::string &consumertag)
|
||||||
|
{
|
||||||
|
// erase the callback
|
||||||
|
_consumers.erase(consumertag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the receiver for a specific consumer tag
|
||||||
|
* @param consumertag the consumer tag
|
||||||
|
* @return the receiver object
|
||||||
|
*/
|
||||||
|
DeferredConsumer *consumer(const std::string &consumertag) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the current object that is receiving a message
|
||||||
|
* @return The handler responsible for the current message
|
||||||
|
*/
|
||||||
|
DeferredReceiver *receiver() const { return _receiver.get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the recalls-object that handles bounces
|
||||||
|
* @return The deferred recall object
|
||||||
|
*/
|
||||||
|
DeferredRecall *recalls() const { return _recall.get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the deferred confirm that handles publisher confirms
|
||||||
|
* @return The deferred confirm object
|
||||||
|
*/
|
||||||
|
DeferredConfirm *confirm() const { return _confirm.get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel class is its friend, thus can it instantiate this object
|
||||||
|
*/
|
||||||
|
friend class Channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
47
builder/libs/AMQP-CPP/include/amqpcpp/classes.h
Normal file
47
builder/libs/AMQP-CPP/include/amqpcpp/classes.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Classes.h
|
||||||
|
*
|
||||||
|
* List of all declared classes
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All classes defined by this library
|
||||||
|
*/
|
||||||
|
class Array;
|
||||||
|
class BasicDeliverFrame;
|
||||||
|
class BasicGetOKFrame;
|
||||||
|
class BasicHeaderFrame;
|
||||||
|
class BasicReturnFrame;
|
||||||
|
class BasicAckFrame;
|
||||||
|
class BasicNackFrame;
|
||||||
|
class BodyFrame;
|
||||||
|
class Channel;
|
||||||
|
class Connection;
|
||||||
|
class ConnectionHandler;
|
||||||
|
class ConnectionImpl;
|
||||||
|
class CopiedBuffer;
|
||||||
|
class Exchange;
|
||||||
|
class Frame;
|
||||||
|
class Login;
|
||||||
|
class Monitor;
|
||||||
|
class OutBuffer;
|
||||||
|
class InBuffer;
|
||||||
|
class Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
266
builder/libs/AMQP-CPP/include/amqpcpp/connection.h
Normal file
266
builder/libs/AMQP-CPP/include/amqpcpp/connection.h
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a mid-level Amqp connection
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Connection
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The actual implementation
|
||||||
|
* @var ConnectionImpl
|
||||||
|
*/
|
||||||
|
ConnectionImpl _implementation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct an AMQP object based on full login data
|
||||||
|
*
|
||||||
|
* The first parameter is a handler object. This handler class is
|
||||||
|
* an interface that should be implemented by the caller.
|
||||||
|
*
|
||||||
|
* @param handler Connection handler
|
||||||
|
* @param login Login data
|
||||||
|
* @param vhost Vhost to use
|
||||||
|
*/
|
||||||
|
Connection(ConnectionHandler *handler, const Login &login, const std::string &vhost) : _implementation(this, handler, login, vhost) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct with default vhost
|
||||||
|
* @param handler Connection handler
|
||||||
|
* @param login Login data
|
||||||
|
*/
|
||||||
|
Connection(ConnectionHandler *handler, const Login &login) : _implementation(this, handler, login, "/") {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an AMQP object with default login data and default vhost
|
||||||
|
* @param handler Connection handler
|
||||||
|
*/
|
||||||
|
Connection(ConnectionHandler *handler, const std::string &vhost) : _implementation(this, handler, Login(), vhost) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an AMQP object with default login data and default vhost
|
||||||
|
* @param handler Connection handler
|
||||||
|
*/
|
||||||
|
Connection(ConnectionHandler *handler) : _implementation(this, handler, Login(), "/") {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No copy'ing, we do not support having two identical connection objects
|
||||||
|
* @param connection
|
||||||
|
*/
|
||||||
|
Connection(const Connection &connection) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Connection() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No assignments of other connections
|
||||||
|
* @param connection
|
||||||
|
* @return Connection
|
||||||
|
*/
|
||||||
|
Connection &operator=(const Connection &connection) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the login data
|
||||||
|
* @return Login
|
||||||
|
*/
|
||||||
|
const Login &login() const
|
||||||
|
{
|
||||||
|
return _implementation.login();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the vhost
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string &vhost() const
|
||||||
|
{
|
||||||
|
return _implementation.vhost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a ping/heartbeat to the channel to keep it alive
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool heartbeat()
|
||||||
|
{
|
||||||
|
return _implementation.heartbeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse data that was recevied from RabbitMQ
|
||||||
|
*
|
||||||
|
* Every time that data comes in from RabbitMQ, you should call this method to parse
|
||||||
|
* the incoming data, and let it handle by the AMQP library. This method returns the number
|
||||||
|
* of bytes that were processed.
|
||||||
|
*
|
||||||
|
* If not all bytes could be processed because it only contained a partial frame, you should
|
||||||
|
* call this same method later on when more data is available. The AMQP library does not do
|
||||||
|
* any buffering, so it is up to the caller to ensure that the old data is also passed in that
|
||||||
|
* later call.
|
||||||
|
*
|
||||||
|
* @param buffer buffer to decode
|
||||||
|
* @param size size of the buffer to decode
|
||||||
|
* @return number of bytes that were processed
|
||||||
|
*/
|
||||||
|
uint64_t parse(const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
return _implementation.parse(ByteBuffer(buffer, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse data that was recevied from RabbitMQ
|
||||||
|
*
|
||||||
|
* Every time that data comes in from RabbitMQ, you should call this method to parse
|
||||||
|
* the incoming data, and let it handle by the AMQP library. This method returns the number
|
||||||
|
* of bytes that were processed.
|
||||||
|
*
|
||||||
|
* If not all bytes could be processed because it only contained a partial frame, you should
|
||||||
|
* call this same method later on when more data is available. The AMQP library does not do
|
||||||
|
* any buffering, so it is up to the caller to ensure that the old data is also passed in that
|
||||||
|
* later call.
|
||||||
|
*
|
||||||
|
* This method accepts a buffer object. This is an interface that is defined by the AMQP
|
||||||
|
* library, that can be implemented by you to allow faster access to a buffer.
|
||||||
|
*
|
||||||
|
* @param buffer buffer to decode
|
||||||
|
* @return number of bytes that were processed
|
||||||
|
*/
|
||||||
|
uint64_t parse(const Buffer &buffer)
|
||||||
|
{
|
||||||
|
return _implementation.parse(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report that the connection was lost in the middle of an operation
|
||||||
|
*
|
||||||
|
* The AMQP protocol normally has a nice closing handshake, and a connection
|
||||||
|
* is elegantly closed via calls to the close() and parse() methods. The parse()
|
||||||
|
* methods recognizes the close-confirmation and will report this to the handler.
|
||||||
|
* However, if you notice yourself that the connection is lost in the middle of
|
||||||
|
* an operation (for example due to a crashing RabbitMQ server), you should
|
||||||
|
* explicitly tell the connection object about it, so that it can cancel all
|
||||||
|
* pending operations. For all pending operations the error and finalize callbacks
|
||||||
|
* will be called. The ConnectionHandler::onError() method will however _not_ be
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* @param message the message that has to be passed to all error handlers
|
||||||
|
* @return bool false if the connection already was failed
|
||||||
|
*/
|
||||||
|
bool fail(const char *message)
|
||||||
|
{
|
||||||
|
return _implementation.fail(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max frame size
|
||||||
|
*
|
||||||
|
* If you allocate memory to receive data that you are going to pass to the parse() method,
|
||||||
|
* it might be useful to have an insight in the max frame size. The parse() method process
|
||||||
|
* one frame at a time, so you must at least be able to read in buffers of this specific
|
||||||
|
* frame size.
|
||||||
|
*
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
uint32_t maxFrame() const
|
||||||
|
{
|
||||||
|
return _implementation.maxFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected number of bytes for the next parse() call.
|
||||||
|
*
|
||||||
|
* This method returns the number of bytes that the next call to parse() at least expects to
|
||||||
|
* do something meaningful with it.
|
||||||
|
*
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
uint32_t expected() const
|
||||||
|
{
|
||||||
|
return _implementation.expected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection ready to accept instructions / has passed the login handshake and not closed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ready() const
|
||||||
|
{
|
||||||
|
return _implementation.ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is (or was) the connection initialized
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool initialized() const
|
||||||
|
{
|
||||||
|
return _implementation.initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection in a usable state, or is it already closed or
|
||||||
|
* in the process of being closed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool usable() const
|
||||||
|
{
|
||||||
|
return _implementation.usable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the connection
|
||||||
|
* This will close all channels
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool close()
|
||||||
|
{
|
||||||
|
return _implementation.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the number of channels that are active for this connection
|
||||||
|
* @return std::size_t
|
||||||
|
*/
|
||||||
|
std::size_t channels() const
|
||||||
|
{
|
||||||
|
return _implementation.channels();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection busy waiting for an answer from the server? (in the
|
||||||
|
* meantime you can already send more instructions over it)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool waiting() const
|
||||||
|
{
|
||||||
|
return _implementation.waiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some classes have access to private properties
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
234
builder/libs/AMQP-CPP/include/amqpcpp/connectionhandler.h
Normal file
234
builder/libs/AMQP-CPP/include/amqpcpp/connectionhandler.h
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/**
|
||||||
|
* ConnectionHandler.h
|
||||||
|
*
|
||||||
|
* Interface that should be implemented by the caller of the library and
|
||||||
|
* that is passed to the AMQP connection. This interface contains all sorts
|
||||||
|
* of methods that are called when data needs to be sent, or when the
|
||||||
|
* AMQP connection ends up in a broken state.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <cstdint>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class ConnectionHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~ConnectionHandler() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the connection is being set up, the client and server exchange
|
||||||
|
* some information. This includes for example their name and version,
|
||||||
|
* copyright statement and the operating system name. Nothing in this
|
||||||
|
* exchange of information is very relevant for the actual AMQP protocol,
|
||||||
|
* but by overriding this method you can read out the information that
|
||||||
|
* was sent by the server, and you can decide which information you
|
||||||
|
* want to send back that describe the client. In RabbitMQ's management
|
||||||
|
* console the client-properties are visible on the "connections" tab,
|
||||||
|
* which could be helpful in certain scenarios, like debugging.
|
||||||
|
*
|
||||||
|
* The read-only "server" parameter contains the information sent by
|
||||||
|
* the server, while the "client" table may be filled with information
|
||||||
|
* about your application. The AMQP protocol says that this table should
|
||||||
|
* at least be filled with data for the "product", "version", "platform",
|
||||||
|
* "copyright" and "information" keys. However, you do not have to
|
||||||
|
* override this method, and even when you do, you do not have to ensure
|
||||||
|
* that these properties are indeed set, because the AMQP-CPP library
|
||||||
|
* takes care of filling in properties that were not explicitly set.
|
||||||
|
*
|
||||||
|
* @param connection The connection about which information is exchanged
|
||||||
|
* @param server Properties sent by the server
|
||||||
|
* @param client Properties that are to be sent back
|
||||||
|
*/
|
||||||
|
virtual void onProperties(Connection *connection, const Table &server, Table &client)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complaint about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) server;
|
||||||
|
(void) client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the heartbeat frequency is negotiated
|
||||||
|
* between the server and the client durion connection setup. You
|
||||||
|
* normally do not have to override this method, because in the default
|
||||||
|
* implementation the suggested heartbeat is simply rejected by the client.
|
||||||
|
*
|
||||||
|
* However, if you want to enable heartbeats you can override this
|
||||||
|
* method. You should "return interval" if you want to accept the
|
||||||
|
* heartbeat interval that was suggested by the server, or you can
|
||||||
|
* return an alternative value if you want a shorter or longer interval.
|
||||||
|
* Return 0 if you want to disable heartbeats.
|
||||||
|
*
|
||||||
|
* If heartbeats are enabled, you yourself are responsible to send
|
||||||
|
* out a heartbeat every *interval / 2* number of seconds by calling
|
||||||
|
* the Connection::heartbeat() method.
|
||||||
|
*
|
||||||
|
* @param connection The connection that suggested a heartbeat interval
|
||||||
|
* @param interval The suggested interval from the server
|
||||||
|
* @return uint16_t The interval to use
|
||||||
|
*/
|
||||||
|
virtual uint16_t onNegotiate(Connection *connection, uint16_t interval)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) interval;
|
||||||
|
|
||||||
|
// default implementation, disable heartbeats
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by AMQP-CPP when data has to be sent over the
|
||||||
|
* network. You must implement this method and send the data over a
|
||||||
|
* socket that is connected with RabbitMQ.
|
||||||
|
*
|
||||||
|
* Note that the AMQP library does no buffering by itself. This means
|
||||||
|
* that this method should always send out all data or do the buffering
|
||||||
|
* itself.
|
||||||
|
*
|
||||||
|
* @param connection The connection that created this output
|
||||||
|
* @param buffer Data to send
|
||||||
|
* @param size Size of the buffer
|
||||||
|
*/
|
||||||
|
virtual void onData(Connection *connection, const char *buffer, size_t size) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP-CPP library received a heartbeat
|
||||||
|
* frame that was sent by the server to the client.
|
||||||
|
*
|
||||||
|
* You do not have to do anything here, the client sends back a heartbeat
|
||||||
|
* frame automatically, but if you like, you can implement/override this
|
||||||
|
* method if you want to be notified of such heartbeats
|
||||||
|
*
|
||||||
|
* @param connection The connection over which the heartbeat was received
|
||||||
|
*/
|
||||||
|
virtual void onHeartbeat(Connection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the connection ends up in an error state this method is called.
|
||||||
|
* This happens when data comes in that does not match the AMQP protocol,
|
||||||
|
* or when an error message was sent by the server to the client.
|
||||||
|
*
|
||||||
|
* After this method is called, the connection no longer is in a valid
|
||||||
|
* state and can no longer be used.
|
||||||
|
*
|
||||||
|
* This method has an empty default implementation, although you are very
|
||||||
|
* much advised to implement it. When an error occurs, the connection
|
||||||
|
* is no longer usable, so you probably want to know.
|
||||||
|
*
|
||||||
|
* @param connection The connection that entered the error state
|
||||||
|
* @param message Error message
|
||||||
|
*/
|
||||||
|
virtual void onError(Connection *connection, const char *message)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the login attempt succeeded. After this method
|
||||||
|
* is called, the connection is ready to use, and the RabbitMQ server is
|
||||||
|
* ready to receive instructions.
|
||||||
|
*
|
||||||
|
* According to the AMQP protocol, you must wait for the connection to become
|
||||||
|
* ready (and this onConnected method to be called) before you can start
|
||||||
|
* sending instructions to RabbitMQ. However, if you prematurely do send
|
||||||
|
* instructions, this AMQP-CPP library caches all methods that you call
|
||||||
|
* before the connection is ready and flushes them the moment the connection
|
||||||
|
* has been set up, so technically there is no real reason to wait for this
|
||||||
|
* method to be called before you send the first instructions.
|
||||||
|
*
|
||||||
|
* @param connection The connection that can now be used
|
||||||
|
*/
|
||||||
|
virtual void onReady(Connection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection was closed.
|
||||||
|
*
|
||||||
|
* This is the counter part of a call to Connection::close() and it confirms
|
||||||
|
* that the connection was _correctly_ closed. Note that this only applies
|
||||||
|
* to the AMQP connection, the underlying TCP connection is not managed by
|
||||||
|
* AMQP-CPP and is still active.
|
||||||
|
*
|
||||||
|
* @param connection The connection that was closed and that is now unusable
|
||||||
|
*/
|
||||||
|
virtual void onClosed(Connection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection was blocked.
|
||||||
|
*
|
||||||
|
* This method is called, when the server connection gets blocked for the first
|
||||||
|
* time due to the broker running low on a resource (memory or disk). For
|
||||||
|
* example, when a RabbitMQ node detects that it is low on RAM, it sends a
|
||||||
|
* notification to all connected publishing clients supporting this feature.
|
||||||
|
* If before the connections are unblocked the node also starts running low on
|
||||||
|
* disk space, another notification will not be sent.
|
||||||
|
*
|
||||||
|
* @param connection The connection that was blocked
|
||||||
|
* @param reason Why was the connection blocked
|
||||||
|
*/
|
||||||
|
virtual void onBlocked(Connection *connection, const char *reason)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection is no longer blocked.
|
||||||
|
*
|
||||||
|
* This method is called when all resource alarms have cleared and the
|
||||||
|
* connection is fully unblocked.
|
||||||
|
*
|
||||||
|
* @param connection The connection that is no longer blocked
|
||||||
|
*/
|
||||||
|
virtual void onUnblocked(Connection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
496
builder/libs/AMQP-CPP/include/amqpcpp/connectionimpl.h
Normal file
496
builder/libs/AMQP-CPP/include/amqpcpp/connectionimpl.h
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
/**
|
||||||
|
* Connection implementation
|
||||||
|
*
|
||||||
|
* This is the implementation of the connection - a class that can only be
|
||||||
|
* constructed by the connection class itselves and that has all sorts of
|
||||||
|
* methods that are only useful inside the library
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "watchable.h"
|
||||||
|
#include "connectionhandler.h"
|
||||||
|
#include "channelimpl.h"
|
||||||
|
#include "copiedbuffer.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
#include "login.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Connection;
|
||||||
|
class Buffer;
|
||||||
|
class Frame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class ConnectionImpl : public Watchable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The parent connection object
|
||||||
|
* @var Connection
|
||||||
|
*/
|
||||||
|
Connection *_parent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection handler
|
||||||
|
* @var ConnectionHandler
|
||||||
|
*/
|
||||||
|
ConnectionHandler *_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State of the connection
|
||||||
|
* The current state is the last frame sent to the server
|
||||||
|
* @var enum
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
state_protocol, // protocol headers are being passed
|
||||||
|
state_handshake, // busy with the handshake to open the connection
|
||||||
|
state_connected, // connection is set up and ready for communication
|
||||||
|
state_closing, // connection is busy closing (we have sent the close frame)
|
||||||
|
state_closed, // connection is closed
|
||||||
|
} _state = state_protocol;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has the close() method been called? If this is true, we automatically
|
||||||
|
* send a close-frame after all pending operations are finsihed.
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _closed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All channels that are active
|
||||||
|
* @var std::unordered_map<uint16_t, std::shared_ptr<ChannelImpl>>
|
||||||
|
*/
|
||||||
|
std::unordered_map<uint16_t, std::shared_ptr<ChannelImpl>> _channels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last unused channel ID
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _nextFreeChannel = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max number of channels (0 for unlimited)
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _maxChannels = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max frame size
|
||||||
|
* @var uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t _maxFrame = 4096;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of expected bytes that will hold the next incoming frame
|
||||||
|
* We start with seven because that is the header of a frame
|
||||||
|
* @var uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t _expected = 7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The login for the server (login, password)
|
||||||
|
* @var Login
|
||||||
|
*/
|
||||||
|
Login _login;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vhost to connect to
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _vhost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queued messages that should be sent after the connection has been established
|
||||||
|
* @var queue
|
||||||
|
*/
|
||||||
|
std::queue<CopiedBuffer> _queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to send the close frame
|
||||||
|
* Return value tells if the connection is still valid
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool sendClose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is any channel waiting for an answer on a synchronous call?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool waitingChannels() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the channel waiting for a response from the peer (server)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool waiting() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for the fail() method
|
||||||
|
* @param monitor
|
||||||
|
* @param message
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool fail(const Monitor &monitor, const char *message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Construct an AMQP object based on full login data
|
||||||
|
*
|
||||||
|
* The first parameter is a handler object. This handler class is
|
||||||
|
* an interface that should be implemented by the caller.
|
||||||
|
*
|
||||||
|
* Note that the constructor is private to ensure that nobody can construct
|
||||||
|
* this class, only the real Connection class via a friend construct
|
||||||
|
*
|
||||||
|
* @param parent Parent connection object
|
||||||
|
* @param handler Connection handler
|
||||||
|
* @param login Login data
|
||||||
|
*/
|
||||||
|
ConnectionImpl(Connection *parent, ConnectionHandler *handler, const Login &login, const std::string &vhost);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Copy'ing connections is impossible
|
||||||
|
* @param connection
|
||||||
|
*/
|
||||||
|
ConnectionImpl(const ConnectionImpl &connection) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~ConnectionImpl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No assignments of other connections
|
||||||
|
* @param connection
|
||||||
|
* @return ConnectionImpl
|
||||||
|
*/
|
||||||
|
ConnectionImpl &operator=(const ConnectionImpl &connection) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What is the state of the connection - is the protocol handshake completed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool protocolOk() const
|
||||||
|
{
|
||||||
|
// must be busy doing the connection handshake, or already connected
|
||||||
|
return _state == state_handshake || _state == state_connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the protocol as being ok
|
||||||
|
* @param server properties sent by the server
|
||||||
|
* @param client properties to be send back
|
||||||
|
*/
|
||||||
|
void setProtocolOk(const Table &server, Table &client)
|
||||||
|
{
|
||||||
|
// if object is destructed
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// check if user-space wants to set these properties
|
||||||
|
_handler->onProperties(_parent, server, client);
|
||||||
|
|
||||||
|
// leap out if userspace destructed the object
|
||||||
|
if (!monitor.valid()) return;
|
||||||
|
|
||||||
|
// move on to handshake state
|
||||||
|
if (_state == state_protocol) _state = state_handshake;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we fully connected and ready for instructions? This is true after the initial
|
||||||
|
* protocol and login handshake were completed and the connection is not closed.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ready() const
|
||||||
|
{
|
||||||
|
// state must be connected
|
||||||
|
return _state == state_connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is (or was) the connection initialized
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool initialized() const
|
||||||
|
{
|
||||||
|
// We are initalized if we have passed the initialized state. So we are in
|
||||||
|
// a connected, closing, or closed state.
|
||||||
|
return _state == state_connected || _state == state_closing || _state == state_closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we closing down?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool closing() const
|
||||||
|
{
|
||||||
|
// state must be connected
|
||||||
|
return _state == state_closing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we closed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool closed() const
|
||||||
|
{
|
||||||
|
// state must be connected
|
||||||
|
return _state == state_closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection in a usable state / not yet closed?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool usable() const
|
||||||
|
{
|
||||||
|
return (_state == state_protocol || _state == state_handshake || _state == state_connected) && !_closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the connection as ready
|
||||||
|
*/
|
||||||
|
void setReady();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the login data
|
||||||
|
* @return Login
|
||||||
|
*/
|
||||||
|
const Login &login() const
|
||||||
|
{
|
||||||
|
return _login;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the vhost
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string &vhost() const
|
||||||
|
{
|
||||||
|
return _vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the max number of channels and max number of frames
|
||||||
|
* @param channels max number of channels
|
||||||
|
* @param size max frame size
|
||||||
|
*/
|
||||||
|
void setCapacity(uint16_t channels, uint32_t size)
|
||||||
|
{
|
||||||
|
_maxChannels = channels;
|
||||||
|
_maxFrame = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max frame size
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t maxFrame() const
|
||||||
|
{
|
||||||
|
return _maxFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max payload size for body frames
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t maxPayload() const
|
||||||
|
{
|
||||||
|
// 8 bytes for header and end-of-frame byte
|
||||||
|
return _maxFrame - 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes that can best be passed to the next call to the parse() method
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t expected() const
|
||||||
|
{
|
||||||
|
return _expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a channel to the connection, and return the channel ID that it
|
||||||
|
* is allowed to use, or 0 when no more ID's are available
|
||||||
|
* @param channel
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t add(const std::shared_ptr<ChannelImpl> &channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a channel
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
void remove(const ChannelImpl *channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the buffer into a recognized frame
|
||||||
|
*
|
||||||
|
* Every time that data comes in on the connection, you should call this method to parse
|
||||||
|
* the incoming data, and let it handle by the AMQP library. This method returns the number
|
||||||
|
* of bytes that were processed.
|
||||||
|
*
|
||||||
|
* If not all bytes could be processed because it only contained a partial frame, you should
|
||||||
|
* call this same method later on when more data is available. The AMQP library does not do
|
||||||
|
* any buffering, so it is up to the caller to ensure that the old data is also passed in that
|
||||||
|
* later call.
|
||||||
|
*
|
||||||
|
* @param buffer buffer to decode
|
||||||
|
* @return number of bytes that were processed
|
||||||
|
*/
|
||||||
|
uint64_t parse(const Buffer &buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fail all pending - this can be called by user-space when it is recognized that the
|
||||||
|
* underlying connection is lost. All error-handlers for all operations and open
|
||||||
|
* channels will be called. This will _not_ call ConnectionHandler::onError() method.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool fail(const char *message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the connection
|
||||||
|
* This will also close all channels
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a frame over the connection
|
||||||
|
*
|
||||||
|
* This is an internal method that you normally do not have to call yourself
|
||||||
|
*
|
||||||
|
* @param frame the frame to send
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool send(const Frame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send buffered data over the connection
|
||||||
|
*
|
||||||
|
* @param buffer the buffer with data to send
|
||||||
|
*/
|
||||||
|
bool send(CopiedBuffer &&buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a channel by its identifier
|
||||||
|
*
|
||||||
|
* This method only works if you had already created the channel before.
|
||||||
|
* This is an internal method that you will not need if you cache the channel
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @param number channel identifier
|
||||||
|
* @return channel the channel object, or nullptr if not yet created
|
||||||
|
*/
|
||||||
|
std::shared_ptr<ChannelImpl> channel(int number)
|
||||||
|
{
|
||||||
|
auto iter = _channels.find(number);
|
||||||
|
return iter == _channels.end() ? nullptr : iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report an error message
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void reportError(const char *message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report that the connection is closed
|
||||||
|
*/
|
||||||
|
void reportClosed()
|
||||||
|
{
|
||||||
|
// change state
|
||||||
|
_state = state_closed;
|
||||||
|
|
||||||
|
// inform the handler
|
||||||
|
_handler->onClosed(_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report that the connection is blocked
|
||||||
|
* @param reason
|
||||||
|
*/
|
||||||
|
void reportBlocked(const char *reason)
|
||||||
|
{
|
||||||
|
// inform the handler
|
||||||
|
_handler->onBlocked(_parent, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report that the connection is unblocked
|
||||||
|
*/
|
||||||
|
void reportUnblocked()
|
||||||
|
{
|
||||||
|
// inform the handler
|
||||||
|
_handler->onUnblocked(_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the amount of channels this connection has
|
||||||
|
* @return std::size_t
|
||||||
|
*/
|
||||||
|
std::size_t channels() const
|
||||||
|
{
|
||||||
|
return _channels.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the heartbeat timeout
|
||||||
|
* @param heartbeat suggested heartbeat timeout by server
|
||||||
|
* @return uint16_t accepted heartbeat timeout from client
|
||||||
|
*/
|
||||||
|
uint16_t setHeartbeat(uint16_t heartbeat)
|
||||||
|
{
|
||||||
|
// pass to the handler
|
||||||
|
return _handler->onNegotiate(_parent, heartbeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report a heartbeat to the connection handler
|
||||||
|
*/
|
||||||
|
void reportHeartbeat()
|
||||||
|
{
|
||||||
|
// pass to handler
|
||||||
|
_handler->onHeartbeat(_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a heartbeat to keep the connection alive
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool heartbeat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual connection is a friend and can construct this class
|
||||||
|
*/
|
||||||
|
friend class Connection;
|
||||||
|
friend class ChannelImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
156
builder/libs/AMQP-CPP/include/amqpcpp/copiedbuffer.h
Normal file
156
builder/libs/AMQP-CPP/include/amqpcpp/copiedbuffer.h
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
* CopiedBuffer.h
|
||||||
|
*
|
||||||
|
* If an output buffer (frame) cannot immediately be sent, we copy it to
|
||||||
|
* memory using this CopiedBuffer class
|
||||||
|
*
|
||||||
|
* @copyright 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include "endian.h"
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class CopiedBuffer : public OutBuffer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The total capacity of the out buffer
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _capacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the beginning of the buffer
|
||||||
|
* @var const char *
|
||||||
|
*/
|
||||||
|
char *_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current size of the buffer
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _size = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the frame is synchronous
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _synchronous = false;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The method that adds the actual data
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
virtual void append(const void *data, size_t size) override
|
||||||
|
{
|
||||||
|
// copy into the buffer
|
||||||
|
memcpy(_buffer + _size, data, size);
|
||||||
|
|
||||||
|
// update the size
|
||||||
|
_size += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
CopiedBuffer(const Frame &frame) :
|
||||||
|
_capacity(frame.totalSize()),
|
||||||
|
_buffer((char *)malloc(_capacity)),
|
||||||
|
_synchronous(frame.synchronous())
|
||||||
|
{
|
||||||
|
// tell the frame to fill this buffer
|
||||||
|
frame.fill(*this);
|
||||||
|
|
||||||
|
// append an end of frame byte (but not when still negotiating the protocol)
|
||||||
|
if (frame.needsSeparator()) add((uint8_t)206);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disabled copy constructor to prevent expensive copy operations
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
CopiedBuffer(const CopiedBuffer &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
CopiedBuffer(CopiedBuffer &&that) :
|
||||||
|
_capacity(that._capacity),
|
||||||
|
_buffer(that._buffer),
|
||||||
|
_size(that._size),
|
||||||
|
_synchronous(that._synchronous)
|
||||||
|
{
|
||||||
|
// reset the other object
|
||||||
|
that._buffer = nullptr;
|
||||||
|
that._size = 0;
|
||||||
|
that._capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~CopiedBuffer()
|
||||||
|
{
|
||||||
|
// deallocate the buffer
|
||||||
|
free(_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to the internal buffer
|
||||||
|
* @return const char*
|
||||||
|
*/
|
||||||
|
const char *data() const
|
||||||
|
{
|
||||||
|
// expose member
|
||||||
|
return _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current size of the output buffer
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
// expose member
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the frame is to be sent synchronously
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool synchronous() const noexcept
|
||||||
|
{
|
||||||
|
// expose member
|
||||||
|
return _synchronous;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
242
builder/libs/AMQP-CPP/include/amqpcpp/decimalfield.h
Normal file
242
builder/libs/AMQP-CPP/include/amqpcpp/decimalfield.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
/**
|
||||||
|
* Decimal field type for AMQP
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <cmath>
|
||||||
|
#include <ostream>
|
||||||
|
#include "field.h"
|
||||||
|
#include "outbuffer.h"
|
||||||
|
#include "inbuffer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class DecimalField : public Field
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* To preserve precision the decision is made to work with the places and number.
|
||||||
|
* These values are sent in the framedata, so no precision will be lost.
|
||||||
|
* Other options, such as floats, doubles, Decimal32 etc result in loss of precision
|
||||||
|
* and this is something which is not acceptable.
|
||||||
|
*
|
||||||
|
* Only (in)equality and assignment operators are implemented since the decimalfield
|
||||||
|
* is not supposed to be altered.
|
||||||
|
* e.q. ==, != and =
|
||||||
|
*
|
||||||
|
* When requesting the value of this object there are 3 choices;
|
||||||
|
* float, double or DecimalField
|
||||||
|
* e.g. valueFloat(), valueDouble() and value()
|
||||||
|
*/
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The number of places, which means the number of decimals
|
||||||
|
* e.g. number = 1234, places = 2, true value is 12.34
|
||||||
|
*/
|
||||||
|
uint8_t _places;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number without the decimals
|
||||||
|
*/
|
||||||
|
uint32_t _number;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// encode fields
|
||||||
|
buffer.add(_places);
|
||||||
|
buffer.add(_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct decimal field
|
||||||
|
*
|
||||||
|
* @param places the number of places
|
||||||
|
* @param number the integer number
|
||||||
|
*/
|
||||||
|
DecimalField(uint8_t places = 0, uint32_t number = 0) :
|
||||||
|
_places(places),
|
||||||
|
_number(number)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on incoming data
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
DecimalField(InBuffer &frame)
|
||||||
|
{
|
||||||
|
_places = frame.nextUint8();
|
||||||
|
_number = frame.nextUint32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~DecimalField() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new identical instance of this object
|
||||||
|
* @return unique_ptr
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
return std::unique_ptr<Field>(new DecimalField(_places, _number));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// output floating point value
|
||||||
|
stream << "decimal(" << _number / pow(10.0f, _places) << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
*
|
||||||
|
* @param value new value for field
|
||||||
|
* @return DecimalField
|
||||||
|
*/
|
||||||
|
DecimalField& operator=(const DecimalField& value)
|
||||||
|
{
|
||||||
|
// if it's the same object, skip assignment and just return *this
|
||||||
|
if (this == &value) return *this;
|
||||||
|
|
||||||
|
// not the same object, copy values to this object.
|
||||||
|
_places = value._places;
|
||||||
|
_number = value._number;
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts decimalfield to double
|
||||||
|
* e.g. "double x = decimalfield" will work
|
||||||
|
*
|
||||||
|
* @return double value of decimalfield in double format
|
||||||
|
*/
|
||||||
|
virtual operator double() const override
|
||||||
|
{
|
||||||
|
return _number / pow(10.0f, _places);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts decimalfield to float
|
||||||
|
* e.g. "float x = decimalfield" will work
|
||||||
|
*
|
||||||
|
* @return float value of decimalfield in float format
|
||||||
|
*/
|
||||||
|
virtual operator float() const override
|
||||||
|
{
|
||||||
|
return static_cast<float>(_number / pow(10.0f, _places));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for equality between this and another DecimalField
|
||||||
|
*
|
||||||
|
* @param value value to be checked for equality
|
||||||
|
* @return boolean whether values are equal
|
||||||
|
*/
|
||||||
|
bool operator==(const DecimalField& value) const
|
||||||
|
{
|
||||||
|
// check if everything is the same
|
||||||
|
// precision is taken into account, e.q. 1.0 != 1.00
|
||||||
|
// meaning number:10, places:1 is not equal to number:100, places:2
|
||||||
|
return _number == value.number() && _places == value.places();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for inequality between this and another DecimalField
|
||||||
|
*
|
||||||
|
* @param value value to be checked for inequality
|
||||||
|
* @return boolean whether values are inequal
|
||||||
|
*/
|
||||||
|
bool operator!=(const DecimalField& value) const
|
||||||
|
{
|
||||||
|
return !(*this == value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override
|
||||||
|
{
|
||||||
|
// the sum of all fields
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of places
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
uint8_t places() const
|
||||||
|
{
|
||||||
|
return _places;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number without decimals
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t number() const
|
||||||
|
{
|
||||||
|
return _number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the DecimalField
|
||||||
|
* To preserve precision DecimalField is returned, containing the number and places.
|
||||||
|
* @return return DecimalField
|
||||||
|
*/
|
||||||
|
DecimalField value() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are a decimal field
|
||||||
|
*
|
||||||
|
* @return true, because we are a decimal field
|
||||||
|
*/
|
||||||
|
bool isDecimal() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return 'D';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
311
builder/libs/AMQP-CPP/include/amqpcpp/deferred.h
Normal file
311
builder/libs/AMQP-CPP/include/amqpcpp/deferred.h
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
/**
|
||||||
|
* Deferred.h
|
||||||
|
*
|
||||||
|
* Class describing a set of actions that could
|
||||||
|
* possibly happen in the future that can be
|
||||||
|
* caught.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "callbacks.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
// forward declaration
|
||||||
|
class ChannelImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback to execute either way
|
||||||
|
* @var FinalizeCallback
|
||||||
|
*/
|
||||||
|
FinalizeCallback _finalizeCallback;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Callback to execute on success
|
||||||
|
* @var SuccessCallback
|
||||||
|
*/
|
||||||
|
SuccessCallback _successCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to execute on failure
|
||||||
|
* @var ErrorCallback
|
||||||
|
*/
|
||||||
|
ErrorCallback _errorCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the next deferred object
|
||||||
|
* @var Deferred
|
||||||
|
*/
|
||||||
|
std::shared_ptr<Deferred> _next;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we already know we failed?
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _failed;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next deferred object
|
||||||
|
* @return Deferred
|
||||||
|
*/
|
||||||
|
const std::shared_ptr<Deferred> &next() const
|
||||||
|
{
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate success
|
||||||
|
* @return Deferred Next deferred result
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess() const
|
||||||
|
{
|
||||||
|
// execute callbacks if registered
|
||||||
|
if (_successCallback) _successCallback();
|
||||||
|
|
||||||
|
// return the next deferred result
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for queue declared messages
|
||||||
|
* @param name Name of the new queue
|
||||||
|
* @param messagecount Number of messages in the queue
|
||||||
|
* @param consumercount Number of consumers linked to the queue
|
||||||
|
* @return Deferred Next deferred result
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(const std::string &name, uint32_t messagecount, uint32_t consumercount) const
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) name;
|
||||||
|
(void) messagecount;
|
||||||
|
(void) consumercount;
|
||||||
|
|
||||||
|
// this is the same as a regular success message
|
||||||
|
return reportSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for frames that report delete operations
|
||||||
|
* @param messagecount Number of messages that were deleted
|
||||||
|
* @return Deferred
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(uint32_t messagecount) const
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) messagecount;
|
||||||
|
|
||||||
|
// this is the same as a regular success message
|
||||||
|
return reportSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for a get operation
|
||||||
|
*
|
||||||
|
* @param messagecount Number of messages left in the queue
|
||||||
|
* @param deliveryTag Delivery tag of the message coming in
|
||||||
|
* @param redelivered Was the message redelivered?
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(uint32_t messagecount, uint64_t deliveryTag, bool redelivered)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) messagecount;
|
||||||
|
(void) deliveryTag;
|
||||||
|
(void) redelivered;
|
||||||
|
|
||||||
|
// this is the same as a regular success message
|
||||||
|
return reportSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for frames that report cancel operations
|
||||||
|
* @param name Consumer tag that is cancelled
|
||||||
|
* @return Deferred
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(const std::string &name)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) name;
|
||||||
|
|
||||||
|
// this is the same as a regular success message
|
||||||
|
return reportSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate failure
|
||||||
|
* @param error Description of the error that occured
|
||||||
|
* @return Deferred Next deferred result
|
||||||
|
*/
|
||||||
|
const std::shared_ptr<Deferred> &reportError(const char *error)
|
||||||
|
{
|
||||||
|
// from this moment on the object should be listed as failed
|
||||||
|
_failed = true;
|
||||||
|
|
||||||
|
// execute callbacks if registered
|
||||||
|
if (_errorCallback) _errorCallback(error);
|
||||||
|
|
||||||
|
// return the next deferred result
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a pointer to the next deferred result
|
||||||
|
* @param deferred
|
||||||
|
*/
|
||||||
|
void add(const std::shared_ptr<Deferred> &deferred)
|
||||||
|
{
|
||||||
|
// store pointer
|
||||||
|
_next = deferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove this object from the chain of deferreds
|
||||||
|
*/
|
||||||
|
void unchain()
|
||||||
|
{
|
||||||
|
// we no longer need the next pointer
|
||||||
|
_next = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class Tagger;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param failed are we already failed?
|
||||||
|
*/
|
||||||
|
Deferred(bool failed = false) : _failed(failed) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Deleted copy and move constructors
|
||||||
|
*/
|
||||||
|
Deferred(const Deferred &that) = delete;
|
||||||
|
Deferred(Deferred &&that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Deferred()
|
||||||
|
{
|
||||||
|
// report to the finalize callback
|
||||||
|
if (_finalizeCallback) _finalizeCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to a boolean
|
||||||
|
*/
|
||||||
|
operator bool () const
|
||||||
|
{
|
||||||
|
return !_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called
|
||||||
|
* if and when the operation succesfully
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* Only one callback can be registered at a time.
|
||||||
|
* Successive calls to this function will clear
|
||||||
|
* callbacks registered before.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline Deferred &onSuccess(const SuccessCallback& callback) { return onSuccess(SuccessCallback(callback)); }
|
||||||
|
Deferred &onSuccess(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_successCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called
|
||||||
|
* if and when the operation fails.
|
||||||
|
*
|
||||||
|
* Only one callback can be registered at a time.
|
||||||
|
* Successive calls to this function will clear
|
||||||
|
* callbacks registered before.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline Deferred &onError(const ErrorCallback& callback) { return onError(ErrorCallback(callback)); }
|
||||||
|
Deferred &onError(ErrorCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_errorCallback = std::move(callback);
|
||||||
|
|
||||||
|
// if the object is already in a failed state, we call the callback right away
|
||||||
|
if (_failed) _errorCallback("Frame could not be sent");
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called
|
||||||
|
* if and when the operation completes
|
||||||
|
* or fails. This function will be called
|
||||||
|
* either way.
|
||||||
|
*
|
||||||
|
* In the case of success, the provided
|
||||||
|
* error parameter will be an empty string.
|
||||||
|
*
|
||||||
|
* Only one callback can be registered at at time.
|
||||||
|
* Successive calls to this function will clear
|
||||||
|
* callbacks registered before.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline Deferred &onFinalize(const FinalizeCallback& callback) { return onFinalize(FinalizeCallback(callback)); }
|
||||||
|
Deferred &onFinalize(FinalizeCallback&& callback)
|
||||||
|
{
|
||||||
|
// if the object is already in a failed state, we call the callback right away
|
||||||
|
if (_failed) callback();
|
||||||
|
|
||||||
|
// otherwise we store callback until it's time for the call
|
||||||
|
else _finalizeCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
105
builder/libs/AMQP-CPP/include/amqpcpp/deferredcancel.h
Normal file
105
builder/libs/AMQP-CPP/include/amqpcpp/deferredcancel.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* DeferredCancel.h
|
||||||
|
*
|
||||||
|
* Deferred callback for instructions that cancel a running consumer. This
|
||||||
|
* deferred object allows one to register a callback that also gets the
|
||||||
|
* consumer tag as one of its parameters.
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We extend from the default deferred and add extra functionality
|
||||||
|
*/
|
||||||
|
class DeferredCancel : public Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Pointer to the channel
|
||||||
|
* @var ChannelImpl
|
||||||
|
*/
|
||||||
|
ChannelImpl *_channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to execute when the instruction is completed
|
||||||
|
* @var CancelCallback
|
||||||
|
*/
|
||||||
|
CancelCallback _cancelCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for frames that report cancel operations
|
||||||
|
* @param name Consumer tag that is cancelled
|
||||||
|
* @return Deferred
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(const std::string &name) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class ConsumedMessage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param channel Pointer to the channel
|
||||||
|
* @param failed Are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredCancel(ChannelImpl *channel, bool failed = false) :
|
||||||
|
Deferred(failed), _channel(channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register a function to be called when the cancel operation succeeded
|
||||||
|
*
|
||||||
|
* Only one callback can be registered. Successive calls
|
||||||
|
* to this function will clear callbacks registered before.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredCancel &onSuccess(const CancelCallback& callback) { return onSuccess(CancelCallback(callback)); }
|
||||||
|
DeferredCancel &onSuccess(CancelCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_cancelCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the cancel operation succeeded
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredCancel &onSuccess(const SuccessCallback& callback) { return onSuccess(SuccessCallback(callback)); }
|
||||||
|
DeferredCancel &onSuccess(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
Deferred::onSuccess(std::move(callback));
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
121
builder/libs/AMQP-CPP/include/amqpcpp/deferredconfirm.h
Normal file
121
builder/libs/AMQP-CPP/include/amqpcpp/deferredconfirm.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* DeferredConfirm.h
|
||||||
|
*
|
||||||
|
* Deferred callback for RabbitMQ-specific publisher confirms mechanism.
|
||||||
|
*
|
||||||
|
* @author Marcin Gibula <m.gibula@gmail.com>
|
||||||
|
* @copyright 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We extend from the default deferred and add extra functionality
|
||||||
|
*/
|
||||||
|
class DeferredConfirm : public Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback to execute when server confirms that message is processed
|
||||||
|
* @var AckCallback
|
||||||
|
*/
|
||||||
|
AckCallback _ackCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to execute when server sends negative acknowledgement
|
||||||
|
* @var NackCallback
|
||||||
|
*/
|
||||||
|
NackCallback _nackCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an ACK frame
|
||||||
|
*
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
void process(BasicAckFrame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an ACK frame
|
||||||
|
*
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
void process(BasicNackFrame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class BasicAckFrame;
|
||||||
|
friend class BasicNackFrame;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param boolean are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredConfirm(bool failed = false) : Deferred(failed) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register the function that is called when channel is put in publisher
|
||||||
|
* confirmed mode
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredConfirm &onSuccess(const SuccessCallback& callback) { return onSuccess(SuccessCallback(callback)); }
|
||||||
|
DeferredConfirm &onSuccess(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
Deferred::onSuccess(std::move(callback));
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when the broker confirmed message publication
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredConfirm &onAck(const AckCallback& callback) { return onAck(AckCallback(callback)); }
|
||||||
|
DeferredConfirm &onAck(AckCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_ackCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when the broker denied message publication
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredConfirm &onNack(const NackCallback& callback) { return onNack(NackCallback(callback)); }
|
||||||
|
DeferredConfirm &onNack(NackCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_nackCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
323
builder/libs/AMQP-CPP/include/amqpcpp/deferredconsumer.h
Normal file
323
builder/libs/AMQP-CPP/include/amqpcpp/deferredconsumer.h
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/**
|
||||||
|
* DeferredConsumer.h
|
||||||
|
*
|
||||||
|
* Deferred callback for consumers
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2022 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "deferredextreceiver.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declararions
|
||||||
|
*/
|
||||||
|
class BasicDeliverFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We extend from the default deferred and add extra functionality
|
||||||
|
*/
|
||||||
|
class DeferredConsumer : public DeferredExtReceiver, public std::enable_shared_from_this<DeferredConsumer>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback to execute when consumption has started
|
||||||
|
* @var ConsumeCallback
|
||||||
|
*/
|
||||||
|
ConsumeCallback _consumeCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to excute when the server has cancelled the consumer
|
||||||
|
* @var CancelCallback
|
||||||
|
*/
|
||||||
|
CancelCallback _cancelCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a delivery frame
|
||||||
|
*
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
void process(BasicDeliverFrame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for frames that report start consumer operations
|
||||||
|
* @param name Consumer tag that is started
|
||||||
|
* @return Deferred
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(const std::string &name) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report that the server has cancelled this consumer
|
||||||
|
* @param namae The consumer tag
|
||||||
|
*/
|
||||||
|
void reportCancelled(const std::string &name)
|
||||||
|
{
|
||||||
|
// report
|
||||||
|
if (_cancelCallback) _cancelCallback(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reference to self to prevent that object falls out of scope
|
||||||
|
* @return std::shared_ptr
|
||||||
|
*/
|
||||||
|
virtual std::shared_ptr<DeferredReceiver> lock() override { return shared_from_this(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class ConsumedMessage;
|
||||||
|
friend class BasicDeliverFrame;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor that should only be called from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param channel the channel implementation
|
||||||
|
* @param failed are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredConsumer(ChannelImpl *channel, bool failed = false) :
|
||||||
|
DeferredExtReceiver(failed, channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register a callback function that gets called when the consumer is
|
||||||
|
* started. In the callback you will for receive the consumer-tag
|
||||||
|
* that you need to later stop the consumer
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onSuccess(const ConsumeCallback& callback) { return onSuccess(ConsumeCallback(callback)); }
|
||||||
|
DeferredConsumer &onSuccess(ConsumeCallback&& callback)
|
||||||
|
{
|
||||||
|
// store the callback
|
||||||
|
_consumeCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the consumer starts.
|
||||||
|
* It is recommended to use the onSuccess() method mentioned above
|
||||||
|
* since that will also pass the consumer-tag as parameter.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onSuccess(const SuccessCallback& callback) { return onSuccess(SuccessCallback(callback)); }
|
||||||
|
DeferredConsumer &onSuccess(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
Deferred::onSuccess(std::move(std::move(callback)));
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called when a full message is received
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onReceived(const MessageCallback& callback) { return onReceived(MessageCallback(callback)); }
|
||||||
|
DeferredConsumer &onReceived(MessageCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_messageCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for onReceived() (see above)
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onMessage(const MessageCallback& callback) { return onMessage(MessageCallback(callback)); }
|
||||||
|
DeferredConsumer &onMessage(MessageCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_messageCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RabbitMQ sends a message in multiple frames to its consumers.
|
||||||
|
* The AMQP-CPP library collects these frames and merges them into a
|
||||||
|
* single AMQP::Message object that is passed to the callback that
|
||||||
|
* you can set with the onReceived() or onMessage() methods (see above).
|
||||||
|
*
|
||||||
|
* However, you can also write your own algorithm to merge the frames.
|
||||||
|
* In that case you can install callbacks to handle the frames. Every
|
||||||
|
* message is sent in a number of frames:
|
||||||
|
*
|
||||||
|
* - a begin frame that marks the start of the message
|
||||||
|
* - an optional header if the message was sent with an envelope
|
||||||
|
* - zero or more data frames (usually 1, but more for large messages)
|
||||||
|
* - an end frame to mark the end of the message.
|
||||||
|
*
|
||||||
|
* To install handlers for these frames, you can use the onBegin(),
|
||||||
|
* onHeaders(), onData() and onComplete() methods.
|
||||||
|
*
|
||||||
|
* If you just rely on the onReceived() or onMessage() callbacks, you
|
||||||
|
* do not need any of the methods below this line.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the start frame of a new
|
||||||
|
* consumed message is received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onBegin(const StartCallback& callback) { return onBegin(StartCallback(callback)); }
|
||||||
|
DeferredConsumer &onBegin(StartCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_startCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the start frame of a new
|
||||||
|
* consumed message is received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onStart(const StartCallback& callback) { return onStart(StartCallback(callback)); }
|
||||||
|
DeferredConsumer &onStart(StartCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_startCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function that is called when the message size is known
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for message headers
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onSize(const SizeCallback& callback) { return onSize(SizeCallback(callback)); }
|
||||||
|
DeferredConsumer &onSize(SizeCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_sizeCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when message headers come in
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for message headers
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onHeaders(const HeaderCallback& callback) { return onHeaders(HeaderCallback(callback)); }
|
||||||
|
DeferredConsumer &onHeaders(HeaderCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_headerCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function to be called when a chunk of data comes in
|
||||||
|
*
|
||||||
|
* Note that this function may be called zero, one or multiple times
|
||||||
|
* for each incoming message depending on the size of the message data.
|
||||||
|
*
|
||||||
|
* If you install this callback you very likely also want to install
|
||||||
|
* the onComplete callback so you know when the last data part was
|
||||||
|
* received.
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for chunks of message data
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onData(const DataCallback& callback) { return onData(DataCallback(callback)); }
|
||||||
|
DeferredConsumer &onData(DataCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_dataCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a funtion to be called when a message was completely received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onComplete(const DeliveredCallback& callback) { return onComplete(DeliveredCallback(callback)); }
|
||||||
|
DeferredConsumer &onComplete(DeliveredCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_deliveredCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a funtion to be called when a message was completely received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onDelivered(const DeliveredCallback& callback) { return onDelivered(DeliveredCallback(callback)); }
|
||||||
|
DeferredConsumer &onDelivered(DeliveredCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_deliveredCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a funtion to be called when the server cancelled the consumer
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredConsumer &onCancelled(const CancelCallback& callback) { return onCancelled(CancelCallback(callback)); }
|
||||||
|
DeferredConsumer &onCancelled(CancelCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_cancelCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
107
builder/libs/AMQP-CPP/include/amqpcpp/deferreddelete.h
Normal file
107
builder/libs/AMQP-CPP/include/amqpcpp/deferreddelete.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* DeferredDelete.h
|
||||||
|
*
|
||||||
|
* Deferred callback for instructions that delete or purge queues, and that
|
||||||
|
* want to report the number of deleted messages.
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We extend from the default deferred and add extra functionality
|
||||||
|
*/
|
||||||
|
class DeferredDelete : public Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback to execute when the instruction is completed
|
||||||
|
* @var DeleteCallback
|
||||||
|
*/
|
||||||
|
DeleteCallback _deleteCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for queue delete and queue purge messages
|
||||||
|
* @param messagecount Number of messages that were deleted
|
||||||
|
* @return Deferred Next deferred result
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(uint32_t messagecount) const override
|
||||||
|
{
|
||||||
|
// skip if no special callback was installed
|
||||||
|
if (!_deleteCallback) return Deferred::reportSuccess();
|
||||||
|
|
||||||
|
// call the callback
|
||||||
|
_deleteCallback(messagecount);
|
||||||
|
|
||||||
|
// return next object
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class ConsumedMessage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param boolean are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredDelete(bool failed = false) : Deferred(failed) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register a function to be called when the queue is deleted or purged
|
||||||
|
*
|
||||||
|
* Only one callback can be registered. Successive calls
|
||||||
|
* to this function will clear callbacks registered before.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredDelete &onSuccess(const DeleteCallback& callback) { return onSuccess(DeleteCallback(callback)); }
|
||||||
|
DeferredDelete &onSuccess(DeleteCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_deleteCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the queue is deleted or purged
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredDelete &onSuccess(const SuccessCallback& callback) { return onSuccess(SuccessCallback(callback)); }
|
||||||
|
DeferredDelete &onSuccess(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
Deferred::onSuccess(std::move(callback));
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
91
builder/libs/AMQP-CPP/include/amqpcpp/deferredextreceiver.h
Normal file
91
builder/libs/AMQP-CPP/include/amqpcpp/deferredextreceiver.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* DeferredExtReceiver.h
|
||||||
|
*
|
||||||
|
* Extended receiver that _wants_ to receive message (because it is
|
||||||
|
* consuming or get'ting messages. This is the base class for both
|
||||||
|
* the DeferredConsumer as well as the DeferredGet classes, but not
|
||||||
|
* the base of the DeferredRecall (which can also receive returned
|
||||||
|
* messages, but not as a result of an explicit request)
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2018 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "deferredreceiver.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class DeferredExtReceiver : public DeferredReceiver
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The delivery tag for the current message
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _deliveryTag = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a redelivered message
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _redelivered = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for incoming messages
|
||||||
|
* @var MessageCallback
|
||||||
|
*/
|
||||||
|
MessageCallback _messageCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for when a message was complete finished
|
||||||
|
* @var DeliveredCallback
|
||||||
|
*/
|
||||||
|
DeliveredCallback _deliveredCallback;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the object to send out a message
|
||||||
|
* @param exchange the exchange to which the message was published
|
||||||
|
* @param routingkey the routing key that was used to publish the message
|
||||||
|
*/
|
||||||
|
virtual void initialize(const std::string &exchange, const std::string &routingkey) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that a message was done
|
||||||
|
*/
|
||||||
|
virtual void complete() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param failed Have we already failed?
|
||||||
|
* @param channel The channel we are consuming on
|
||||||
|
*/
|
||||||
|
DeferredExtReceiver(bool failed, ChannelImpl *channel) :
|
||||||
|
DeferredReceiver(failed, channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~DeferredExtReceiver() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
304
builder/libs/AMQP-CPP/include/amqpcpp/deferredget.h
Normal file
304
builder/libs/AMQP-CPP/include/amqpcpp/deferredget.h
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
/**
|
||||||
|
* DeferredGet.h
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "deferredextreceiver.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*
|
||||||
|
* This class implements the 'shared_from_this' functionality, because
|
||||||
|
* it grabs a self-pointer when the callback is running, otherwise the onFinalize()
|
||||||
|
* is called before the actual message is consumed.
|
||||||
|
*/
|
||||||
|
class DeferredGet : public DeferredExtReceiver, public std::enable_shared_from_this<DeferredGet>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback in case the queue is empty
|
||||||
|
* @var EmptyCallback
|
||||||
|
*/
|
||||||
|
EmptyCallback _emptyCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback with the number of messages still in the queue
|
||||||
|
* @var CountCallback
|
||||||
|
*/
|
||||||
|
CountCallback _countCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for a get operation
|
||||||
|
* @param messagecount Number of messages left in the queue
|
||||||
|
* @param deliveryTag Delivery tag of the message coming in
|
||||||
|
* @param redelivered Was the message redelivered?
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(uint32_t messagecount, uint64_t deliveryTag, bool redelivered) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success when queue was empty
|
||||||
|
* @return Deferred
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reference to self to prevent that object falls out of scope
|
||||||
|
* @return std::shared_ptr
|
||||||
|
*/
|
||||||
|
virtual std::shared_ptr<DeferredReceiver> lock() override { return shared_from_this(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended implementation of the complete method that is called when a message was fully received
|
||||||
|
*/
|
||||||
|
virtual void complete() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class ConsumedMessage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param channel the channel implementation
|
||||||
|
* @param failed are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredGet(ChannelImpl *channel, bool failed = false) :
|
||||||
|
DeferredExtReceiver(failed, channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register a function to be called when a message arrives
|
||||||
|
* This fuction is also available as onReceived() and onMessage() because I always forget which name I gave to it
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onSuccess(const MessageCallback& callback) { return onSuccess(MessageCallback(callback)); }
|
||||||
|
DeferredGet &onSuccess(MessageCallback&& callback)
|
||||||
|
{
|
||||||
|
// store the callback
|
||||||
|
_messageCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called when an error occurs. This should be defined, otherwise the base methods are used.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onError(const ErrorCallback& callback) { return onError(ErrorCallback(callback)); }
|
||||||
|
DeferredGet &onError(ErrorCallback&& callback)
|
||||||
|
{
|
||||||
|
// store the callback
|
||||||
|
_errorCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called when a message arrives
|
||||||
|
* This fuction is also available as onSuccess() and onMessage() because I always forget which name I gave to it
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onReceived(const MessageCallback& callback) { return onReceived(MessageCallback(callback)); }
|
||||||
|
DeferredGet &onReceived(MessageCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_messageCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called when a message arrives
|
||||||
|
* This fuction is also available as onSuccess() and onReceived() because I always forget which name I gave to it
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onMessage(const MessageCallback& callback) { return onMessage(MessageCallback(callback)); }
|
||||||
|
DeferredGet &onMessage(MessageCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_messageCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called if no message could be fetched
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onEmpty(const EmptyCallback& callback) { return onEmpty(EmptyCallback(callback)); }
|
||||||
|
DeferredGet &onEmpty(EmptyCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_emptyCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called when queue size information is known
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onCount(const CountCallback& callback) { return onCount(CountCallback(callback)); }
|
||||||
|
DeferredGet &onCount(CountCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_countCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function to be called when a new message is expected
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onBegin(const StartCallback& callback) { return onBegin(StartCallback(callback)); }
|
||||||
|
DeferredGet &onBegin(StartCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_startCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function to be called when a new message is expected
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onStart(const StartCallback& callback) { return onStart(StartCallback(callback)); }
|
||||||
|
DeferredGet &onStart(StartCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_startCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function that is called when the message size is known
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for message headers
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onSize(const SizeCallback& callback) { return onSize(SizeCallback(callback)); }
|
||||||
|
DeferredGet &onSize(SizeCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_sizeCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function to be called when message headers come in
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for message headers
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onHeaders(const HeaderCallback& callback) { return onHeaders(HeaderCallback(callback)); }
|
||||||
|
DeferredGet &onHeaders(HeaderCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_headerCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function to be called when a chunk of data comes in
|
||||||
|
*
|
||||||
|
* Note that this function may be called zero, one or multiple times
|
||||||
|
* for each incoming message depending on the size of the message data.
|
||||||
|
*
|
||||||
|
* If you install this callback you very likely also want to install
|
||||||
|
* the onComplete callback so you know when the last data part was
|
||||||
|
* received.
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for chunks of message data
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onData(const DataCallback& callback) { return onData(DataCallback(callback)); }
|
||||||
|
DeferredGet &onData(DataCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_dataCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a funtion to be called when a message was completely received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onComplete(const DeliveredCallback& callback) { return onComplete(DeliveredCallback(callback)); }
|
||||||
|
DeferredGet &onComplete(DeliveredCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_deliveredCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a funtion to be called when a message was completely received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredGet &onDelivered(const DeliveredCallback& callback) { return onDelivered(DeliveredCallback(callback)); }
|
||||||
|
DeferredGet &onDelivered(DeliveredCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_deliveredCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
150
builder/libs/AMQP-CPP/include/amqpcpp/deferredpublish.h
Normal file
150
builder/libs/AMQP-CPP/include/amqpcpp/deferredpublish.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/**
|
||||||
|
* DeferredPublish.h
|
||||||
|
*
|
||||||
|
* Deferred callback for RabbitMQ-specific publisher confirms mechanism per-message.
|
||||||
|
*
|
||||||
|
* @author Michael van der Werve <michael.vanderwerve@mailerq.com>
|
||||||
|
* @copyright 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We extend from the default deferred and add extra functionality
|
||||||
|
*/
|
||||||
|
class DeferredPublish : public Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback to execute when server confirms that message is processed
|
||||||
|
* @var AckCallback
|
||||||
|
*/
|
||||||
|
PublishAckCallback _ackCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to execute when server sends negative acknowledgement
|
||||||
|
* @var NackCallback
|
||||||
|
*/
|
||||||
|
PublishNackCallback _nackCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to execute when message is lost (nack / error)
|
||||||
|
* @var LostCallback
|
||||||
|
*/
|
||||||
|
PublishLostCallback _lostCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report an ack, calls the callback.
|
||||||
|
*/
|
||||||
|
void reportAck()
|
||||||
|
{
|
||||||
|
// check if the callback is set
|
||||||
|
if (_ackCallback) _ackCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report an nack, calls the callback if set.
|
||||||
|
*/
|
||||||
|
void reportNack()
|
||||||
|
{
|
||||||
|
// check if the callback is set
|
||||||
|
if (_nackCallback) _nackCallback();
|
||||||
|
|
||||||
|
// message is 'lost'
|
||||||
|
if (_lostCallback) _lostCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate failure
|
||||||
|
* @param error Description of the error that occured
|
||||||
|
*/
|
||||||
|
void reportError(const char *error)
|
||||||
|
{
|
||||||
|
// from this moment on the object should be listed as failed
|
||||||
|
_failed = true;
|
||||||
|
|
||||||
|
// message is lost
|
||||||
|
if (_lostCallback) _lostCallback();
|
||||||
|
|
||||||
|
// execute callbacks if registered
|
||||||
|
if (_errorCallback) _errorCallback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wrapped confirmed channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
friend class Reliable;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param boolean are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredPublish(bool failed = false) : Deferred(failed) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Callback that is called when the broker confirmed message publication
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredPublish &onAck(const PublishAckCallback& callback) { return onAck(PublishAckCallback(callback)); }
|
||||||
|
DeferredPublish &onAck(PublishAckCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_ackCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when the broker denied message publication
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredPublish &onNack(const PublishNackCallback& callback) { return onNack(PublishNackCallback(callback)); }
|
||||||
|
DeferredPublish &onNack(PublishNackCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_nackCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when a message is lost, either through RabbitMQ
|
||||||
|
* rejecting it or because of a channel error
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredPublish &onLost(const PublishLostCallback& callback) { return onLost(PublishLostCallback(callback)); }
|
||||||
|
DeferredPublish &onLost(PublishLostCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_lostCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
107
builder/libs/AMQP-CPP/include/amqpcpp/deferredqueue.h
Normal file
107
builder/libs/AMQP-CPP/include/amqpcpp/deferredqueue.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* DeferredQueue.h
|
||||||
|
*
|
||||||
|
* Deferred callback for "declare-queue" instructions.
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We extend from the default deferred and add extra functionality
|
||||||
|
*/
|
||||||
|
class DeferredQueue : public Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Callback to execute when the queue is declared
|
||||||
|
* @var QueueCallback
|
||||||
|
*/
|
||||||
|
QueueCallback _queueCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report success for queue declared messages
|
||||||
|
* @param name Name of the new queue
|
||||||
|
* @param messagecount Number of messages in the queue
|
||||||
|
* @param consumercount Number of consumers linked to the queue
|
||||||
|
* @return Deferred Next deferred result
|
||||||
|
*/
|
||||||
|
virtual const std::shared_ptr<Deferred> &reportSuccess(const std::string &name, uint32_t messagecount, uint32_t consumercount) const override
|
||||||
|
{
|
||||||
|
// skip if no special callback was installed
|
||||||
|
if (!_queueCallback) return Deferred::reportSuccess();
|
||||||
|
|
||||||
|
// call the queue callback
|
||||||
|
_queueCallback(name, messagecount, consumercount);
|
||||||
|
|
||||||
|
// return next object
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel implementation may call our
|
||||||
|
* private members and construct us
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class ConsumedMessage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Protected constructor that can only be called
|
||||||
|
* from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param bool are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredQueue(bool failed = false) : Deferred(failed) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register a function to be called when the queue is declared
|
||||||
|
*
|
||||||
|
* Only one callback can be registered. Successive calls
|
||||||
|
* to this function will clear callbacks registered before.
|
||||||
|
*
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredQueue &onSuccess(const QueueCallback& callback) { return onSuccess(QueueCallback(callback)); }
|
||||||
|
DeferredQueue &onSuccess(QueueCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_queueCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the queue is declared
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline DeferredQueue &onSuccess(const SuccessCallback& callback) { return onSuccess(SuccessCallback(callback)); }
|
||||||
|
DeferredQueue &onSuccess(SuccessCallback&& callback)
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
Deferred::onSuccess(std::move(callback));
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
249
builder/libs/AMQP-CPP/include/amqpcpp/deferredrecall.h
Normal file
249
builder/libs/AMQP-CPP/include/amqpcpp/deferredrecall.h
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/**
|
||||||
|
* DeferredRecall.h
|
||||||
|
*
|
||||||
|
* Class that an be used to install callback methods that define how
|
||||||
|
* returned messages should be handled.
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2018 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class ChannelImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class DeferredRecall : public DeferredReceiver, public std::enable_shared_from_this<DeferredRecall>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The error code
|
||||||
|
* @var int16_t
|
||||||
|
*/
|
||||||
|
int16_t _code = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error message
|
||||||
|
* @var std::string
|
||||||
|
*/
|
||||||
|
std::string _description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when a message is returned
|
||||||
|
* @var BounceCallback
|
||||||
|
*/
|
||||||
|
BounceCallback _bounceCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of a bounced message
|
||||||
|
* @var ReturnCallback
|
||||||
|
*/
|
||||||
|
ReturnCallback _beginCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of a bounced message
|
||||||
|
* @var ReturnedCallback
|
||||||
|
*/
|
||||||
|
ReturnedCallback _completeCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a return frame
|
||||||
|
*
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
void process(BasicReturnFrame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reference to self to prevent that object falls out of scope
|
||||||
|
* @return std::shared_ptr
|
||||||
|
*/
|
||||||
|
virtual std::shared_ptr<DeferredReceiver> lock() override { return shared_from_this(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended implementation of the complete method that is called when a message was fully received
|
||||||
|
*/
|
||||||
|
virtual void complete() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classes that can access private members
|
||||||
|
*/
|
||||||
|
friend class BasicReturnFrame;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor that should only be called from within the channel implementation
|
||||||
|
*
|
||||||
|
* Note: this constructor _should_ be protected, but because make_shared
|
||||||
|
* will then not work, we have decided to make it public after all,
|
||||||
|
* because the work-around would result in not-so-easy-to-read code.
|
||||||
|
*
|
||||||
|
* @param channel the channel implementation
|
||||||
|
* @param failed are we already failed?
|
||||||
|
*/
|
||||||
|
DeferredRecall(ChannelImpl *channel, bool failed = false) :
|
||||||
|
DeferredReceiver(failed, channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Register a function to be called when a full message is returned
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onReceived(const BounceCallback& callback) { return onReceived(BounceCallback(callback)); }
|
||||||
|
DeferredRecall &onReceived(BounceCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_bounceCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for onReceived() (see above)
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onMessage(const BounceCallback& callback) { return onMessage(BounceCallback(callback)); }
|
||||||
|
DeferredRecall &onMessage(BounceCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_bounceCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for onReceived() (see above)
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onReturned(const BounceCallback& callback) { return onReturned(BounceCallback(callback)); }
|
||||||
|
DeferredRecall &onReturned(BounceCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_bounceCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for onReceived() (see above)
|
||||||
|
* @param callback the callback to execute
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onBounced(const BounceCallback& callback) { return onBounced(BounceCallback(callback)); }
|
||||||
|
DeferredRecall &onBounced(BounceCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_bounceCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when the start frame of a new
|
||||||
|
* consumed message is received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onBegin(const ReturnCallback& callback) { return onBegin(ReturnCallback(callback)); }
|
||||||
|
DeferredRecall &onBegin(ReturnCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_beginCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function that is called when the message size is known
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for message headers
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onSize(const SizeCallback& callback) { return onSize(SizeCallback(callback)); }
|
||||||
|
DeferredRecall &onSize(SizeCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_sizeCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function that is called when message headers come in
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for message headers
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onHeaders(const HeaderCallback& callback) { return onHeaders(HeaderCallback(callback)); }
|
||||||
|
DeferredRecall &onHeaders(HeaderCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_headerCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the function to be called when a chunk of data comes in
|
||||||
|
*
|
||||||
|
* Note that this function may be called zero, one or multiple times
|
||||||
|
* for each incoming message depending on the size of the message data.
|
||||||
|
*
|
||||||
|
* If you install this callback you very likely also want to install
|
||||||
|
* the onComplete callback so you know when the last data part was
|
||||||
|
* received.
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke for chunks of message data
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onData(const DataCallback& callback) { return onData(DataCallback(callback)); }
|
||||||
|
DeferredRecall &onData(DataCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_dataCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a funtion to be called when a message was completely received
|
||||||
|
*
|
||||||
|
* @param callback The callback to invoke
|
||||||
|
* @return Same object for chaining
|
||||||
|
*/
|
||||||
|
inline DeferredRecall &onComplete(const ReturnedCallback& callback) { return onComplete(ReturnedCallback(callback)); }
|
||||||
|
DeferredRecall &onComplete(ReturnedCallback&& callback)
|
||||||
|
{
|
||||||
|
// store callback
|
||||||
|
_completeCallback = std::move(callback);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
145
builder/libs/AMQP-CPP/include/amqpcpp/deferredreceiver.h
Normal file
145
builder/libs/AMQP-CPP/include/amqpcpp/deferredreceiver.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* DeferredReceiver.h
|
||||||
|
*
|
||||||
|
* Base class for the deferred consumer, the deferred get and the
|
||||||
|
* deferred publisher (that may receive returned messages)
|
||||||
|
*
|
||||||
|
* @copyright 2016 - 2018 Copernica B.V.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "deferred.h"
|
||||||
|
#include "stack_ptr.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class BasicDeliverFrame;
|
||||||
|
class BasicGetOKFrame;
|
||||||
|
class BasicHeaderFrame;
|
||||||
|
class BodyFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for deferred consumers
|
||||||
|
*/
|
||||||
|
class DeferredReceiver : public Deferred
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Size of the body of the current message
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _bodySize = 0;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Initialize the object to send out a message
|
||||||
|
* @param exchange the exchange to which the message was published
|
||||||
|
* @param routingkey the routing key that was used to publish the message
|
||||||
|
*/
|
||||||
|
virtual void initialize(const std::string &exchange, const std::string &routingkey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reference to self to prevent that object falls out of scope
|
||||||
|
* @return std::shared_ptr
|
||||||
|
*/
|
||||||
|
virtual std::shared_ptr<DeferredReceiver> lock() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that a message was done
|
||||||
|
*/
|
||||||
|
virtual void complete() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Process the message headers
|
||||||
|
*
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
void process(BasicHeaderFrame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the message data
|
||||||
|
*
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
void process(BodyFrame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frames may be processed
|
||||||
|
*/
|
||||||
|
friend class ChannelImpl;
|
||||||
|
friend class BasicGetOKFrame;
|
||||||
|
friend class BasicHeaderFrame;
|
||||||
|
friend class BodyFrame;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The channel to which the consumer is linked
|
||||||
|
* @var ChannelImpl
|
||||||
|
*/
|
||||||
|
ChannelImpl *_channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for new message
|
||||||
|
* @var StartCallback
|
||||||
|
*/
|
||||||
|
StartCallback _startCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called when size of the message is known
|
||||||
|
* @var SizeCallback
|
||||||
|
*/
|
||||||
|
SizeCallback _sizeCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for incoming headers
|
||||||
|
* @var HeaderCallback
|
||||||
|
*/
|
||||||
|
HeaderCallback _headerCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for when a chunk of data comes in
|
||||||
|
* @var DataCallback
|
||||||
|
*/
|
||||||
|
DataCallback _dataCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message that we are currently receiving
|
||||||
|
* @var stack_ptr<Message>
|
||||||
|
*/
|
||||||
|
stack_ptr<Message> _message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param failed Have we already failed?
|
||||||
|
* @param channel The channel we are consuming on
|
||||||
|
*/
|
||||||
|
DeferredReceiver(bool failed, ChannelImpl *channel) :
|
||||||
|
Deferred(failed), _channel(channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~DeferredReceiver() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
153
builder/libs/AMQP-CPP/include/amqpcpp/endian.h
Normal file
153
builder/libs/AMQP-CPP/include/amqpcpp/endian.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/**
|
||||||
|
* Endian.h
|
||||||
|
*
|
||||||
|
* On Apple systems, there are no macro's to convert between little
|
||||||
|
* and big endian byte orders. This header file adds the missing macros
|
||||||
|
*
|
||||||
|
* @author madmongo1 <https://github.com/madmongo1>
|
||||||
|
*
|
||||||
|
* And we have also copied code from the "portable_endian.h" file by
|
||||||
|
* Mathias Panzenböck. His license:
|
||||||
|
*
|
||||||
|
* "License": Public Domain
|
||||||
|
* I, Mathias Panzenböck, place this file hereby into the public
|
||||||
|
* domain. Use it at your own risk for whatever you like. In case
|
||||||
|
* there are jurisdictions that don't support putting things in the
|
||||||
|
* public domain you can also consider it to be "dual licensed"
|
||||||
|
* under the BSD, MIT and Apache licenses, if you want to. This
|
||||||
|
* code is trivial anyway. Consider it an example on how to get the
|
||||||
|
* endian conversion functions on different platforms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The contents of the file are only relevant for Apple
|
||||||
|
*/
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
|
||||||
|
// dependencies
|
||||||
|
#include <machine/endian.h>
|
||||||
|
#include <libkern/OSByteOrder.h>
|
||||||
|
|
||||||
|
// define 16 bit macros
|
||||||
|
#define htobe16(x) OSSwapHostToBigInt16(x)
|
||||||
|
#define htole16(x) OSSwapHostToLittleInt16(x)
|
||||||
|
#define be16toh(x) OSSwapBigToHostInt16(x)
|
||||||
|
#define le16toh(x) OSSwapLittleToHostInt16(x)
|
||||||
|
|
||||||
|
// define 32 bit macros
|
||||||
|
#define htobe32(x) OSSwapHostToBigInt32(x)
|
||||||
|
#define htole32(x) OSSwapHostToLittleInt32(x)
|
||||||
|
#define be32toh(x) OSSwapBigToHostInt32(x)
|
||||||
|
#define le32toh(x) OSSwapLittleToHostInt32(x)
|
||||||
|
|
||||||
|
// define 64 but macros
|
||||||
|
#define htobe64(x) OSSwapHostToBigInt64(x)
|
||||||
|
#define htole64(x) OSSwapHostToLittleInt64(x)
|
||||||
|
#define be64toh(x) OSSwapBigToHostInt64(x)
|
||||||
|
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* And on Windows systems weird things are going on as well
|
||||||
|
*/
|
||||||
|
#elif (defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)) && !defined(__CYGWIN__)
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#pragma comment(lib,"Ws2_32.lib")
|
||||||
|
//# include <sys/param.h>
|
||||||
|
|
||||||
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
|
||||||
|
#define htobe16(x) htons(x)
|
||||||
|
#define htole16(x) (x)
|
||||||
|
#define be16toh(x) ntohs(x)
|
||||||
|
#define le16toh(x) (x)
|
||||||
|
|
||||||
|
#define htobe32(x) htonl(x)
|
||||||
|
#define htole32(x) (x)
|
||||||
|
#define be32toh(x) ntohl(x)
|
||||||
|
#define le32toh(x) (x)
|
||||||
|
|
||||||
|
#define htobe64(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
|
||||||
|
#define htole64(x) (x)
|
||||||
|
#define be64toh(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
|
||||||
|
#define le64toh(x) (x)
|
||||||
|
|
||||||
|
#elif BYTE_ORDER == BIG_ENDIAN
|
||||||
|
|
||||||
|
/* that would be xbox 360 */
|
||||||
|
#define htobe16(x) (x)
|
||||||
|
#define htole16(x) __builtin_bswap16(x)
|
||||||
|
#define be16toh(x) (x)
|
||||||
|
#define le16toh(x) __builtin_bswap16(x)
|
||||||
|
|
||||||
|
#define htobe32(x) (x)
|
||||||
|
#define htole32(x) __builtin_bswap32(x)
|
||||||
|
#define be32toh(x) (x)
|
||||||
|
#define le32toh(x) __builtin_bswap32(x)
|
||||||
|
|
||||||
|
#define htobe64(x) (x)
|
||||||
|
#define htole64(x) __builtin_bswap64(x)
|
||||||
|
#define be64toh(x) (x)
|
||||||
|
#define le64toh(x) __builtin_bswap64(x)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error byte order not supported
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __BYTE_ORDER BYTE_ORDER
|
||||||
|
#define __BIG_ENDIAN BIG_ENDIAN
|
||||||
|
#define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
|
#define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenBSD handling
|
||||||
|
*/
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
|
#include <sys/endian.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NetBSD handling
|
||||||
|
*/
|
||||||
|
#elif defined(__NetBSD__) || defined(__DragonFly__)
|
||||||
|
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#define be16toh(x) betoh16(x)
|
||||||
|
#define le16toh(x) letoh16(x)
|
||||||
|
#define be32toh(x) betoh32(x)
|
||||||
|
#define le32toh(x) letoh32(x)
|
||||||
|
#define be64toh(x) betoh64(x)
|
||||||
|
#define le64toh(x) letoh64(x)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FreeBSD handling
|
||||||
|
*/
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
|
||||||
|
#include <sys/endian.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QNX Neutrino handling
|
||||||
|
*/
|
||||||
|
#elif defined(__QNXNTO__)
|
||||||
|
|
||||||
|
#include <net/netbyte.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not on apple, and not on windows
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
|
||||||
|
// this is the normal linux way of doing things
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
|
// end of "#if defined(__APPLE__)"
|
||||||
|
#endif
|
||||||
|
|
||||||
208
builder/libs/AMQP-CPP/include/amqpcpp/entityimpl.h
Normal file
208
builder/libs/AMQP-CPP/include/amqpcpp/entityimpl.h
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/**
|
||||||
|
* EntityImpl.h
|
||||||
|
*
|
||||||
|
* Common base class for exchanges and queues.
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class EntityImpl
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The channel on which we communicate
|
||||||
|
* @var Channel
|
||||||
|
*/
|
||||||
|
Channel *_channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the queue/exchange
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a durable queue/exchange?
|
||||||
|
* A durable queue/exchange survives a broker restart
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _durable = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a passive queue/exchange?
|
||||||
|
* If set, only check if the queue/exchange exists without actually creating it
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _passive = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this an auto-delete queue/exchange?
|
||||||
|
* If set, the entity is removed when it is no longer used (for queues
|
||||||
|
* when all consumers are gone, for exchanges when all queues are gone)
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
bool _autoDelete = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional arguments
|
||||||
|
* @var Table
|
||||||
|
*/
|
||||||
|
Table _arguments;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor is protected and can only be accessed by derived classes
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
EntityImpl(Channel *channel) : _channel(channel) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~EntityImpl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
std::string &name()
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the name
|
||||||
|
* You must declare the entity before this has effect
|
||||||
|
* @param string
|
||||||
|
*/
|
||||||
|
void setName(const std::string &name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the queue or exchange durable
|
||||||
|
* The entity survives a broker restart if it is durable
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool durable()
|
||||||
|
{
|
||||||
|
return _durable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the object as durable
|
||||||
|
* @param bool
|
||||||
|
*/
|
||||||
|
void setDurable(bool durable)
|
||||||
|
{
|
||||||
|
_durable = durable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the passive bit set
|
||||||
|
* If set, the declare method only checks if the queue/exchange exists without actually creating it
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool passive()
|
||||||
|
{
|
||||||
|
return _passive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the passive bit
|
||||||
|
* @param bool
|
||||||
|
*/
|
||||||
|
void setPassive(bool passive)
|
||||||
|
{
|
||||||
|
_passive = passive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the auto-delete property set?
|
||||||
|
* The entity is removed when the consumers and/or queues are unlinked from it
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool autoDelete()
|
||||||
|
{
|
||||||
|
return _autoDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the auto-delete bit
|
||||||
|
* @param bool
|
||||||
|
*/
|
||||||
|
void setAutoDelete(bool autoDelete)
|
||||||
|
{
|
||||||
|
_autoDelete = autoDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a custom argument
|
||||||
|
* @param name Name of the argument
|
||||||
|
* @param value Value of the argument
|
||||||
|
*/
|
||||||
|
void setArgument(const std::string &name, const std::string &value)
|
||||||
|
{
|
||||||
|
_arguments[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a argument
|
||||||
|
* @param name Name of the argument
|
||||||
|
* @return The value of the argument
|
||||||
|
*/
|
||||||
|
std::string &argument(const std::string &name)
|
||||||
|
{
|
||||||
|
return _arguments[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind to a different exchange
|
||||||
|
* @param exchange The exchange to bind to
|
||||||
|
* @param key The routing key
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool bind(const std::string &exchange, const std::string &key) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unbind from an exchange
|
||||||
|
* @param exchange Exchange to unbind from
|
||||||
|
* @param key The routing key
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool unbind(const std::string &exchange, const std::string &key) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare the queue/exchange
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool declare() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the queue/exchange
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool remove() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
145
builder/libs/AMQP-CPP/include/amqpcpp/envelope.h
Normal file
145
builder/libs/AMQP-CPP/include/amqpcpp/envelope.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* Envelope.h
|
||||||
|
*
|
||||||
|
* When you send or receive a message to the rabbitMQ server, it is encapsulated
|
||||||
|
* in an envelope that contains additional meta information as well.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "metadata.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
* The envelope extends from MetaData, although this is conceptually not entirely
|
||||||
|
* correct: and envelope _holds_ meta data and a body, so it would have been more
|
||||||
|
* correct to make the MetaData instance a member. But by extending we automatically
|
||||||
|
* make all meta-data properties accesible.
|
||||||
|
*/
|
||||||
|
class Envelope : public MetaData
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Pointer to the body data (the memory is not managed by the AMQP library!)
|
||||||
|
* @var const char *
|
||||||
|
*/
|
||||||
|
const char *_body;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the data
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _bodySize;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* The data buffer that you pass to this constructor must be valid during
|
||||||
|
* the lifetime of the Envelope object.
|
||||||
|
* @param body
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
Envelope(const char *body, uint64_t size) : MetaData(), _body(body), _bodySize(size) {}
|
||||||
|
Envelope(const std::string_view &body) : Envelope(body.data(), body.size()) {}
|
||||||
|
Envelope(const char *body) : Envelope(body, strlen(body)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that preserves meta-data, but installs different body
|
||||||
|
* @param metadata
|
||||||
|
* @param body
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
Envelope(const MetaData &metadata, const char *body, uint64_t size) : MetaData(metadata), _body(body), _bodySize(size) {}
|
||||||
|
Envelope(const MetaData &metadata, const std::string_view &body) : Envelope(metadata, body.data(), body.size()) {}
|
||||||
|
Envelope(const MetaData &metadata, const char *body) : Envelope(metadata, body, strlen(body)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read envelope frmo an input-buffer
|
||||||
|
* This method is the counterpart of the Envelope::fill() method, and is not used
|
||||||
|
* by the library itself, but might be useful for applications that want to store
|
||||||
|
* envelopes.
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
Envelope(InBuffer &buffer) : MetaData(buffer)
|
||||||
|
{
|
||||||
|
// extract the properties
|
||||||
|
_bodySize = buffer.nextUint64();
|
||||||
|
_body = buffer.nextData(_bodySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disabled copy constructor
|
||||||
|
* @param envelope the envelope to copy
|
||||||
|
*/
|
||||||
|
Envelope(const Envelope &envelope) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Envelope() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the full message data
|
||||||
|
* @return buffer
|
||||||
|
*/
|
||||||
|
const char *body() const
|
||||||
|
{
|
||||||
|
return _body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the body
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t bodySize() const
|
||||||
|
{
|
||||||
|
return _bodySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the envelope, this is the size of the meta+data plus the number of bytes
|
||||||
|
* required to store the size of the body + the actual body. This method is not used
|
||||||
|
* by the AMQP-CPP library, but could be useful if you feel the need to store
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
// this is the size of the meta-data + the size of the body
|
||||||
|
return MetaData::size() + _bodySize + sizeof(uint64_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill an output buffer
|
||||||
|
* This method is not used by this library, but could be useful if you want to store
|
||||||
|
* the meta-data + message contents (
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
void fill(OutBuffer &buffer) const
|
||||||
|
{
|
||||||
|
// first we store the meta-data
|
||||||
|
MetaData::fill(buffer);
|
||||||
|
|
||||||
|
// now the size of the message body + the actual body
|
||||||
|
buffer.add(_bodySize);
|
||||||
|
buffer.add(_body, _bodySize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
40
builder/libs/AMQP-CPP/include/amqpcpp/exception.h
Normal file
40
builder/libs/AMQP-CPP/include/amqpcpp/exception.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Exception.h
|
||||||
|
*
|
||||||
|
* Base class for all AMQP exceptions
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base exception class
|
||||||
|
*/
|
||||||
|
class Exception : public std::runtime_error
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param what
|
||||||
|
*/
|
||||||
|
explicit Exception(const std::string &what) : runtime_error(what) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
36
builder/libs/AMQP-CPP/include/amqpcpp/exchangetype.h
Normal file
36
builder/libs/AMQP-CPP/include/amqpcpp/exchangetype.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* ExchangeType.h
|
||||||
|
*
|
||||||
|
* The various exchange types that are supported
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class
|
||||||
|
*/
|
||||||
|
enum ExchangeType
|
||||||
|
{
|
||||||
|
fanout,
|
||||||
|
direct,
|
||||||
|
topic,
|
||||||
|
headers,
|
||||||
|
consistent_hash,
|
||||||
|
message_deduplication
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
134
builder/libs/AMQP-CPP/include/amqpcpp/field.h
Normal file
134
builder/libs/AMQP-CPP/include/amqpcpp/field.h
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/**
|
||||||
|
* Available field types for AMQP
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class InBuffer;
|
||||||
|
class OutBuffer;
|
||||||
|
class Array;
|
||||||
|
class Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base field class
|
||||||
|
*
|
||||||
|
* This class cannot be constructed, but serves
|
||||||
|
* as the base class for all AMQP field types
|
||||||
|
*/
|
||||||
|
class Field
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Decode a field by fetching a type and full field from a frame
|
||||||
|
* The returned field is allocated on the heap!
|
||||||
|
* @param frame
|
||||||
|
* @return std::unique_ptr<Field>
|
||||||
|
*/
|
||||||
|
static std::unique_ptr<Field> decode(InBuffer &frame);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Field() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance on the heap of this object, identical to the object passed
|
||||||
|
* @return Field*
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
* @return char
|
||||||
|
*/
|
||||||
|
virtual char typeID() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casting operators
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
virtual operator const std::string& () const;
|
||||||
|
virtual operator const char * () const { return nullptr; }
|
||||||
|
virtual operator uint8_t () const { return 0; }
|
||||||
|
virtual operator uint16_t () const { return 0; }
|
||||||
|
virtual operator uint32_t () const { return 0; }
|
||||||
|
virtual operator uint64_t () const { return 0; }
|
||||||
|
virtual operator int8_t () const { return 0; }
|
||||||
|
virtual operator int16_t () const { return 0; }
|
||||||
|
virtual operator int32_t () const { return 0; }
|
||||||
|
virtual operator int64_t () const { return 0; }
|
||||||
|
virtual operator float () const { return 0; }
|
||||||
|
virtual operator double () const { return 0; }
|
||||||
|
virtual operator const Array& () const;
|
||||||
|
virtual operator const Table& () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the field type
|
||||||
|
*
|
||||||
|
* @return Is the field a specific type?
|
||||||
|
*/
|
||||||
|
virtual bool isInteger() const { return false; }
|
||||||
|
virtual bool isDecimal() const { return false; }
|
||||||
|
virtual bool isArray() const { return false; }
|
||||||
|
virtual bool isTable() const { return false; }
|
||||||
|
virtual bool isBoolean() const { return false; }
|
||||||
|
virtual bool isString() const { return false; }
|
||||||
|
virtual bool isVoid() const { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom output stream operator
|
||||||
|
* @param stream
|
||||||
|
* @param field
|
||||||
|
* @return ostream
|
||||||
|
*/
|
||||||
|
inline std::ostream &operator<<(std::ostream &stream, const Field &field)
|
||||||
|
{
|
||||||
|
field.output(stream);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
275
builder/libs/AMQP-CPP/include/amqpcpp/fieldproxy.h
Normal file
275
builder/libs/AMQP-CPP/include/amqpcpp/fieldproxy.h
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/**
|
||||||
|
* Field proxy. Returned by the table. Can be casted to the
|
||||||
|
* relevant native type (std::string or numeric)
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include "stringfield.h"
|
||||||
|
#include "booleanset.h"
|
||||||
|
#include "decimalfield.h"
|
||||||
|
#include "numericfield.h"
|
||||||
|
#include "voidfield.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Table;
|
||||||
|
class Array;
|
||||||
|
class Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
template <typename T, typename I>
|
||||||
|
class FieldProxy
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The table or array possibly holding the requested field
|
||||||
|
*/
|
||||||
|
T *_source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key in the table
|
||||||
|
*/
|
||||||
|
I _index;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct the field proxy
|
||||||
|
*
|
||||||
|
* @param table the table possibly holding the field
|
||||||
|
* @oaram index key in table map
|
||||||
|
*/
|
||||||
|
FieldProxy(T *source, I index) :
|
||||||
|
_source(source),
|
||||||
|
_index(index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a boolean value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(bool value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, BooleanSet(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(uint8_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, UOctet(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(int8_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, Octet(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(uint16_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, UShort(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(int16_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, Short(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(uint32_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, ULong(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(int32_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, Long(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(uint64_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, ULongLong(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a numeric value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(int64_t value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, LongLong(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a decimal value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy& operator=(const DecimalField &value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, DecimalField(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a string value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy &operator=(const std::string &value)
|
||||||
|
{
|
||||||
|
// in theory we should make a distinction between short and long string,
|
||||||
|
// but in practive only long strings are accepted
|
||||||
|
_source->set(_index, LongString(value));
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a string value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy &operator=(const char *value)
|
||||||
|
{
|
||||||
|
// cast to a string
|
||||||
|
return operator=(std::string(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign an array value
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy &operator=(const Array &value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a table value
|
||||||
|
* @param value
|
||||||
|
* @return FieldProxy
|
||||||
|
*/
|
||||||
|
FieldProxy &operator=(const Table &value)
|
||||||
|
{
|
||||||
|
// assign value and allow chaining
|
||||||
|
_source->set(_index, value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the underlying field
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
|
const Field &get() const
|
||||||
|
{
|
||||||
|
return _source->get(_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a boolean
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
template <typename TARGET>
|
||||||
|
operator TARGET () const
|
||||||
|
{
|
||||||
|
// retrieve the value
|
||||||
|
return _source->get(_index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// define types for array- and table-based field proxy
|
||||||
|
using AssociativeFieldProxy = FieldProxy<Table, std::string>;
|
||||||
|
using ArrayFieldProxy = FieldProxy<Array, uint8_t>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
47
builder/libs/AMQP-CPP/include/amqpcpp/flags.h
Normal file
47
builder/libs/AMQP-CPP/include/amqpcpp/flags.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* AmqpFlags.h
|
||||||
|
*
|
||||||
|
* The various flags that are supported
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All bit flags
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
extern const int durable;
|
||||||
|
extern const int autodelete;
|
||||||
|
extern const int active;
|
||||||
|
extern const int passive;
|
||||||
|
extern const int ifunused;
|
||||||
|
extern const int ifempty;
|
||||||
|
extern const int global;
|
||||||
|
extern const int nolocal;
|
||||||
|
extern const int noack;
|
||||||
|
extern const int exclusive;
|
||||||
|
extern const int nowait;
|
||||||
|
extern const int mandatory;
|
||||||
|
extern const int immediate;
|
||||||
|
extern const int redelivered;
|
||||||
|
extern const int multiple;
|
||||||
|
extern const int requeue;
|
||||||
|
extern const int readable;
|
||||||
|
extern const int writable;
|
||||||
|
extern const int internal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
108
builder/libs/AMQP-CPP/include/amqpcpp/frame.h
Normal file
108
builder/libs/AMQP-CPP/include/amqpcpp/frame.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* Frame.h
|
||||||
|
*
|
||||||
|
* Base class for frames. This base class can not be constructed from outside
|
||||||
|
* the library, and is only used internally.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "protocolexception.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class ConnectionImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Frame
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Protected constructor to ensure that no objects are created from
|
||||||
|
* outside the library
|
||||||
|
*/
|
||||||
|
Frame() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Frame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the total size of the frame
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
virtual uint32_t totalSize() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill an output buffer
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer &buffer) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a frame that is part of the connection setup?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool partOfHandshake() const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a frame that is part of the connection close operation?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool partOfShutdown() const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this frame need an end-of-frame seperator?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool needsSeparator() const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
virtual bool synchronous() const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
|
||||||
|
// this is an exception
|
||||||
|
throw ProtocolException("unimplemented frame");
|
||||||
|
|
||||||
|
// unreachable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
143
builder/libs/AMQP-CPP/include/amqpcpp/inbuffer.h
Normal file
143
builder/libs/AMQP-CPP/include/amqpcpp/inbuffer.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* InBuffer.h
|
||||||
|
*
|
||||||
|
* The InBuffer class is a wrapper around a data buffer and that adds
|
||||||
|
* some safety checks so that the rest of the library can safely read
|
||||||
|
* from it.
|
||||||
|
*
|
||||||
|
* This is a class that is used internally by the AMQP library. As a user
|
||||||
|
* of this library, you normally do not have to instantiate it. However,
|
||||||
|
* if you do want to store or safe messages yourself, it sometimes can
|
||||||
|
* be useful to implement it.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class InBuffer
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The buffer we are reading from
|
||||||
|
* @var Buffer
|
||||||
|
*/
|
||||||
|
const Buffer &_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes already processed
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _skip = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param buffer Binary buffer
|
||||||
|
*/
|
||||||
|
InBuffer(const Buffer &buffer) : _buffer(buffer) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~InBuffer() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint8_t from the buffer
|
||||||
|
* @return uint8_t value read
|
||||||
|
*/
|
||||||
|
uint8_t nextUint8();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int8_t from the buffer
|
||||||
|
* @return int8_t value read
|
||||||
|
*/
|
||||||
|
int8_t nextInt8();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint16_t from the buffer
|
||||||
|
* @return uint16_t value read
|
||||||
|
*/
|
||||||
|
uint16_t nextUint16();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int16_t from the buffer
|
||||||
|
* @return int16_t value read
|
||||||
|
*/
|
||||||
|
int16_t nextInt16();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint32_t from the buffer
|
||||||
|
* @return uint32_t value read
|
||||||
|
*/
|
||||||
|
uint32_t nextUint32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int32_t from the buffer
|
||||||
|
* @return int32_t value read
|
||||||
|
*/
|
||||||
|
int32_t nextInt32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next uint64_t from the buffer
|
||||||
|
* @return uint64_t value read
|
||||||
|
*/
|
||||||
|
uint64_t nextUint64();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next int64_t from the buffer
|
||||||
|
* @return int64_t value read
|
||||||
|
*/
|
||||||
|
int64_t nextInt64();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a float from the buffer
|
||||||
|
* @return float float read from buffer.
|
||||||
|
*/
|
||||||
|
float nextFloat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a double from the buffer
|
||||||
|
* @return double double read from buffer
|
||||||
|
*/
|
||||||
|
double nextDouble();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a pointer to the next binary buffer of a certain size
|
||||||
|
* @param size
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
const char *nextData(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The checker may access private data
|
||||||
|
*/
|
||||||
|
friend class BufferCheck;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
539
builder/libs/AMQP-CPP/include/amqpcpp/libboostasio.h
Normal file
539
builder/libs/AMQP-CPP/include/amqpcpp/libboostasio.h
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
/**
|
||||||
|
* LibBoostAsio.h
|
||||||
|
*
|
||||||
|
* Implementation for the AMQP::TcpHandler for boost::asio. You can use this class
|
||||||
|
* instead of a AMQP::TcpHandler class, just pass the boost asio service to the
|
||||||
|
* constructor and you're all set. See tests/libboostasio.cpp for example.
|
||||||
|
*
|
||||||
|
* Watch out: this class was not implemented or reviewed by the original author of
|
||||||
|
* AMQP-CPP. However, we do get a lot of questions and issues from users of this class,
|
||||||
|
* so we cannot guarantee its quality. If you run into such issues too, it might be
|
||||||
|
* better to implement your own handler that interact with boost.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Gavin Smith <gavin.smith@coralbay.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <boost/asio/strand.hpp>
|
||||||
|
#include <boost/asio/deadline_timer.hpp>
|
||||||
|
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||||
|
#include <boost/asio/dispatch.hpp>
|
||||||
|
#include <boost/bind/bind.hpp>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
|
#include "amqpcpp/linux_tcp.h"
|
||||||
|
|
||||||
|
// C++17 has 'weak_from_this()' support.
|
||||||
|
#if __cplusplus >= 201701L
|
||||||
|
#define PTR_FROM_THIS(T) weak_from_this()
|
||||||
|
#else
|
||||||
|
#define PTR_FROM_THIS(T) std::weak_ptr<T>(shared_from_this())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
* @note Because of a limitation on Windows, this will only work on POSIX based systems - see https://github.com/chriskohlhoff/asio/issues/70
|
||||||
|
*/
|
||||||
|
class LibBoostAsioHandler : public virtual TcpHandler
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that wraps a boost io_context socket monitor.
|
||||||
|
*/
|
||||||
|
class Watcher : public virtual std::enable_shared_from_this<Watcher>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boost asio io_context which is responsible for detecting events.
|
||||||
|
* @var class boost::asio::io_context&
|
||||||
|
*/
|
||||||
|
boost::asio::io_context & _iocontext;
|
||||||
|
|
||||||
|
using strand_weak_ptr = std::weak_ptr<boost::asio::io_context::strand>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boost asio io_context::strand managed pointer.
|
||||||
|
* @var class std::shared_ptr<boost::asio::io_context>
|
||||||
|
*/
|
||||||
|
strand_weak_ptr _wpstrand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boost tcp socket.
|
||||||
|
* @var class boost::asio::ip::tcp::socket
|
||||||
|
* @note https://stackoverflow.com/questions/38906711/destroying-boost-asio-socket-without-closing-native-handler
|
||||||
|
*/
|
||||||
|
boost::asio::posix::stream_descriptor _socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boost asynchronous deadline timer.
|
||||||
|
* @var class boost::asio::deadline_timer
|
||||||
|
*/
|
||||||
|
boost::asio::deadline_timer _timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean that indicates if the watcher is monitoring for read events.
|
||||||
|
* @var _read True if reads are being monitored else false.
|
||||||
|
*/
|
||||||
|
bool _read{false};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean that indicates if the watcher has a pending read event.
|
||||||
|
* @var _read True if read is pending else false.
|
||||||
|
*/
|
||||||
|
bool _read_pending{false};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean that indicates if the watcher is monitoring for write events.
|
||||||
|
* @var _read True if writes are being monitored else false.
|
||||||
|
*/
|
||||||
|
bool _write{false};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean that indicates if the watcher has a pending write event.
|
||||||
|
* @var _read True if read is pending else false.
|
||||||
|
*/
|
||||||
|
bool _write_pending{false};
|
||||||
|
|
||||||
|
using handler_cb = boost::function<void(boost::system::error_code,std::size_t)>;
|
||||||
|
using io_handler = boost::function<void(const boost::system::error_code&, const std::size_t)>;
|
||||||
|
using timer_handler = boost::function<void(boost::system::error_code)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a io handler callback that executes the io callback in a strand.
|
||||||
|
* @param io_handler The handler callback to dispatch
|
||||||
|
* @return handler_cb A function wrapping the execution of the handler function in a io_context::strand.
|
||||||
|
*/
|
||||||
|
handler_cb get_dispatch_wrapper(io_handler fn)
|
||||||
|
{
|
||||||
|
const strand_weak_ptr wpstrand = _wpstrand;
|
||||||
|
|
||||||
|
return [fn, wpstrand](const boost::system::error_code &ec, const std::size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
const strand_shared_ptr strand = wpstrand.lock();
|
||||||
|
if (!strand)
|
||||||
|
{
|
||||||
|
fn(boost::system::errc::make_error_code(boost::system::errc::operation_canceled), std::size_t{0});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boost::asio::dispatch(strand->context().get_executor(), boost::bind(fn, ec, bytes_transferred));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds and returns a read handler for the io operation.
|
||||||
|
* @param connection The connection being watched.
|
||||||
|
* @param fd The file descripter being watched.
|
||||||
|
* @return handler callback
|
||||||
|
*/
|
||||||
|
handler_cb get_read_handler(TcpConnection *const connection, const int fd)
|
||||||
|
{
|
||||||
|
auto fn = boost::bind(&Watcher::read_handler,
|
||||||
|
this,
|
||||||
|
boost::placeholders::_1,
|
||||||
|
boost::placeholders::_2,
|
||||||
|
PTR_FROM_THIS(Watcher),
|
||||||
|
connection,
|
||||||
|
fd);
|
||||||
|
return get_dispatch_wrapper(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds and returns a read handler for the io operation.
|
||||||
|
* @param connection The connection being watched.
|
||||||
|
* @param fd The file descripter being watched.
|
||||||
|
* @return handler callback
|
||||||
|
*/
|
||||||
|
handler_cb get_write_handler(TcpConnection *const connection, const int fd)
|
||||||
|
{
|
||||||
|
auto fn = boost::bind(&Watcher::write_handler,
|
||||||
|
this,
|
||||||
|
boost::placeholders::_1,
|
||||||
|
boost::placeholders::_2,
|
||||||
|
PTR_FROM_THIS(Watcher),
|
||||||
|
connection,
|
||||||
|
fd);
|
||||||
|
return get_dispatch_wrapper(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds and returns a lamba function handler for the io operation.
|
||||||
|
* @param connection The connection being watched.
|
||||||
|
* @param timeout The file descripter being watched.
|
||||||
|
* @return handler callback
|
||||||
|
*/
|
||||||
|
timer_handler get_timer_handler(TcpConnection *const connection, const uint16_t timeout)
|
||||||
|
{
|
||||||
|
const auto fn = boost::bind(&Watcher::timeout_handler,
|
||||||
|
this,
|
||||||
|
boost::placeholders::_1,
|
||||||
|
PTR_FROM_THIS(Watcher),
|
||||||
|
connection,
|
||||||
|
timeout);
|
||||||
|
|
||||||
|
const strand_weak_ptr wpstrand = _wpstrand;
|
||||||
|
|
||||||
|
return [fn, wpstrand](const boost::system::error_code &ec)
|
||||||
|
{
|
||||||
|
const strand_shared_ptr strand = wpstrand.lock();
|
||||||
|
if (!strand)
|
||||||
|
{
|
||||||
|
fn(boost::system::errc::make_error_code(boost::system::errc::operation_canceled));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boost::asio::dispatch(strand->context().get_executor(), boost::bind(fn, ec));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler method that is called by boost's io_context when the socket pumps a read event.
|
||||||
|
* @param ec The status of the callback.
|
||||||
|
* @param bytes_transferred The number of bytes transferred.
|
||||||
|
* @param awpWatcher A weak pointer to this object.
|
||||||
|
* @param connection The connection being watched.
|
||||||
|
* @param fd The file descriptor being watched.
|
||||||
|
* @note The handler will get called if a read is cancelled.
|
||||||
|
*/
|
||||||
|
void read_handler(const boost::system::error_code &ec,
|
||||||
|
const std::size_t bytes_transferred,
|
||||||
|
const std::weak_ptr<Watcher> awpWatcher,
|
||||||
|
TcpConnection *const connection,
|
||||||
|
const int fd)
|
||||||
|
{
|
||||||
|
// Resolve any potential problems with dangling pointers
|
||||||
|
// (remember we are using async).
|
||||||
|
const std::shared_ptr<Watcher> apWatcher = awpWatcher.lock();
|
||||||
|
if (!apWatcher) { return; }
|
||||||
|
|
||||||
|
_read_pending = false;
|
||||||
|
|
||||||
|
if ((!ec || ec == boost::asio::error::would_block) && _read)
|
||||||
|
{
|
||||||
|
connection->process(fd, AMQP::readable);
|
||||||
|
|
||||||
|
_read_pending = true;
|
||||||
|
|
||||||
|
_socket.async_read_some(
|
||||||
|
boost::asio::null_buffers(),
|
||||||
|
get_read_handler(connection, fd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler method that is called by boost's io_context when the socket pumps a write event.
|
||||||
|
* @param ec The status of the callback.
|
||||||
|
* @param bytes_transferred The number of bytes transferred.
|
||||||
|
* @param awpWatcher A weak pointer to this object.
|
||||||
|
* @param connection The connection being watched.
|
||||||
|
* @param fd The file descriptor being watched.
|
||||||
|
* @note The handler will get called if a write is cancelled.
|
||||||
|
*/
|
||||||
|
void write_handler(const boost::system::error_code ec,
|
||||||
|
const std::size_t bytes_transferred,
|
||||||
|
const std::weak_ptr<Watcher> awpWatcher,
|
||||||
|
TcpConnection *const connection,
|
||||||
|
const int fd)
|
||||||
|
{
|
||||||
|
// Resolve any potential problems with dangling pointers
|
||||||
|
// (remember we are using async).
|
||||||
|
const std::shared_ptr<Watcher> apWatcher = awpWatcher.lock();
|
||||||
|
if (!apWatcher) { return; }
|
||||||
|
|
||||||
|
_write_pending = false;
|
||||||
|
|
||||||
|
if ((!ec || ec == boost::asio::error::would_block) && _write)
|
||||||
|
{
|
||||||
|
connection->process(fd, AMQP::writable);
|
||||||
|
|
||||||
|
_write_pending = true;
|
||||||
|
|
||||||
|
_socket.async_write_some(
|
||||||
|
boost::asio::null_buffers(),
|
||||||
|
get_write_handler(connection, fd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method that is called by libev when the timer expires
|
||||||
|
* @param ec error code returned from loop
|
||||||
|
* @param loop The loop in which the event was triggered
|
||||||
|
* @param connection
|
||||||
|
* @param timeout
|
||||||
|
*/
|
||||||
|
void timeout_handler(const boost::system::error_code &ec,
|
||||||
|
std::weak_ptr<Watcher> awpThis,
|
||||||
|
TcpConnection *const connection,
|
||||||
|
const uint16_t timeout)
|
||||||
|
{
|
||||||
|
// Resolve any potential problems with dangling pointers
|
||||||
|
// (remember we are using async).
|
||||||
|
const std::shared_ptr<Watcher> apTimer = awpThis.lock();
|
||||||
|
if (!apTimer) { return; }
|
||||||
|
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
if (connection)
|
||||||
|
{
|
||||||
|
// send the heartbeat
|
||||||
|
connection->heartbeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reschedule the timer for the future:
|
||||||
|
_timer.expires_at(_timer.expires_at() + boost::posix_time::seconds(timeout));
|
||||||
|
|
||||||
|
// Posts the timer event
|
||||||
|
_timer.async_wait(get_timer_handler(connection, timeout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor- initialises the watcher and assigns the filedescriptor to
|
||||||
|
* a boost socket for monitoring.
|
||||||
|
* @param io_context The boost io_context
|
||||||
|
* @param wpstrand A weak pointer to a io_context::strand instance.
|
||||||
|
* @param fd The filedescriptor being watched
|
||||||
|
*/
|
||||||
|
Watcher(boost::asio::io_context &io_context,
|
||||||
|
const strand_weak_ptr wpstrand,
|
||||||
|
const int fd) :
|
||||||
|
_iocontext(io_context),
|
||||||
|
_wpstrand(wpstrand),
|
||||||
|
_socket(io_context),
|
||||||
|
_timer(io_context)
|
||||||
|
{
|
||||||
|
_socket.assign(fd);
|
||||||
|
|
||||||
|
_socket.non_blocking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watchers cannot be copied or moved
|
||||||
|
*
|
||||||
|
* @param that The object to not move or copy
|
||||||
|
*/
|
||||||
|
Watcher(Watcher &&that) = delete;
|
||||||
|
Watcher(const Watcher &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
~Watcher()
|
||||||
|
{
|
||||||
|
_read = false;
|
||||||
|
_write = false;
|
||||||
|
_socket.release();
|
||||||
|
stop_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the events for which the filedescriptor is monitored
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
void events(TcpConnection *connection, int fd, int events)
|
||||||
|
{
|
||||||
|
// 1. Handle reads?
|
||||||
|
_read = ((events & AMQP::readable) != 0);
|
||||||
|
|
||||||
|
// Read requsted but no read pending?
|
||||||
|
if (_read && !_read_pending)
|
||||||
|
{
|
||||||
|
_read_pending = true;
|
||||||
|
|
||||||
|
_socket.async_read_some(
|
||||||
|
boost::asio::null_buffers(),
|
||||||
|
get_read_handler(connection, fd));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Handle writes?
|
||||||
|
_write = ((events & AMQP::writable) != 0);
|
||||||
|
|
||||||
|
// Write requested but no write pending?
|
||||||
|
if (_write && !_write_pending)
|
||||||
|
{
|
||||||
|
_write_pending = true;
|
||||||
|
|
||||||
|
_socket.async_write_some(
|
||||||
|
boost::asio::null_buffers(),
|
||||||
|
get_write_handler(connection, fd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the expire time
|
||||||
|
* @param connection
|
||||||
|
* @param timeout
|
||||||
|
*/
|
||||||
|
void set_timer(TcpConnection *connection, uint16_t timeout)
|
||||||
|
{
|
||||||
|
// stop timer in case it was already set
|
||||||
|
stop_timer();
|
||||||
|
|
||||||
|
// Reschedule the timer for the future:
|
||||||
|
_timer.expires_from_now(boost::posix_time::seconds(timeout));
|
||||||
|
|
||||||
|
// Posts the timer event
|
||||||
|
_timer.async_wait(get_timer_handler(connection, timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the timer
|
||||||
|
*/
|
||||||
|
void stop_timer()
|
||||||
|
{
|
||||||
|
// do nothing if it was never set
|
||||||
|
_timer.cancel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boost asio io_context.
|
||||||
|
* @var class boost::asio::io_context&
|
||||||
|
*/
|
||||||
|
boost::asio::io_context & _iocontext;
|
||||||
|
|
||||||
|
using strand_shared_ptr = std::shared_ptr<boost::asio::io_context::strand>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boost asio io_context::strand managed pointer.
|
||||||
|
* @var class std::shared_ptr<boost::asio::io_context>
|
||||||
|
*/
|
||||||
|
strand_shared_ptr _strand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All I/O watchers that are active, indexed by their filedescriptor
|
||||||
|
* @var std::map<int,Watcher>
|
||||||
|
*/
|
||||||
|
std::map<int, std::shared_ptr<Watcher> > _watchers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by AMQP-CPP to register a filedescriptor for readability or writability
|
||||||
|
* @param connection The TCP connection object that is reporting
|
||||||
|
* @param fd The filedescriptor to be monitored
|
||||||
|
* @param flags Should the object be monitored for readability or writability?
|
||||||
|
*/
|
||||||
|
void monitor(TcpConnection *const connection,
|
||||||
|
const int fd,
|
||||||
|
const int flags) override
|
||||||
|
{
|
||||||
|
// do we already have this filedescriptor
|
||||||
|
auto iter = _watchers.find(fd);
|
||||||
|
|
||||||
|
// was it found?
|
||||||
|
if (iter == _watchers.end())
|
||||||
|
{
|
||||||
|
// we did not yet have this watcher - but that is ok if no filedescriptor was registered
|
||||||
|
if (flags == 0){ return; }
|
||||||
|
|
||||||
|
// construct a new pair (watcher/timer), and put it in the map
|
||||||
|
const std::shared_ptr<Watcher> apWatcher =
|
||||||
|
std::make_shared<Watcher>(_iocontext, _strand, fd);
|
||||||
|
|
||||||
|
_watchers[fd] = apWatcher;
|
||||||
|
|
||||||
|
// explicitly set the events to monitor
|
||||||
|
apWatcher->events(connection, fd, flags);
|
||||||
|
}
|
||||||
|
else if (flags == 0)
|
||||||
|
{
|
||||||
|
// the watcher does already exist, but we no longer have to watch this watcher
|
||||||
|
_watchers.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Change the events on which to act.
|
||||||
|
iter->second->events(connection,fd,flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Method that is called when the heartbeat frequency is negotiated between the server and the client.
|
||||||
|
* @param connection The connection that suggested a heartbeat interval
|
||||||
|
* @param interval The suggested interval from the server
|
||||||
|
* @return uint16_t The interval to use
|
||||||
|
*/
|
||||||
|
virtual uint16_t onNegotiate(TcpConnection *connection, uint16_t interval) override
|
||||||
|
{
|
||||||
|
// skip if no heartbeats are needed
|
||||||
|
if (interval == 0) return 0;
|
||||||
|
|
||||||
|
const auto fd = connection->fileno();
|
||||||
|
|
||||||
|
auto iter = _watchers.find(fd);
|
||||||
|
if (iter == _watchers.end()) return 0;
|
||||||
|
|
||||||
|
// set the timer
|
||||||
|
iter->second->set_timer(connection, interval);
|
||||||
|
|
||||||
|
// we agree with the interval
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler cannot be default constructed.
|
||||||
|
*
|
||||||
|
* @param that The object to not move or copy
|
||||||
|
*/
|
||||||
|
LibBoostAsioHandler() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param io_context The boost io_context to wrap
|
||||||
|
*/
|
||||||
|
explicit LibBoostAsioHandler(boost::asio::io_context &io_context) :
|
||||||
|
_iocontext(io_context),
|
||||||
|
_strand(std::make_shared<boost::asio::io_context::strand>(_iocontext))
|
||||||
|
//_timer(std::make_shared<Timer>(_iocontext,_strand))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler cannot be copied or moved
|
||||||
|
*
|
||||||
|
* @param that The object to not move or copy
|
||||||
|
*/
|
||||||
|
LibBoostAsioHandler(LibBoostAsioHandler &&that) = delete;
|
||||||
|
LibBoostAsioHandler(const LibBoostAsioHandler &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the boost io_context object that is being used.
|
||||||
|
* @return The boost io_context object.
|
||||||
|
*/
|
||||||
|
boost::asio::io_context &service()
|
||||||
|
{
|
||||||
|
return _iocontext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
~LibBoostAsioHandler() override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
531
builder/libs/AMQP-CPP/include/amqpcpp/libev.h
Normal file
531
builder/libs/AMQP-CPP/include/amqpcpp/libev.h
Normal file
@ -0,0 +1,531 @@
|
|||||||
|
/**
|
||||||
|
* LibEV.h
|
||||||
|
*
|
||||||
|
* Implementation for the AMQP::TcpHandler that is optimized for libev. You can
|
||||||
|
* use this class instead of a AMQP::TcpHandler class, just pass the event loop
|
||||||
|
* to the constructor and you're all set
|
||||||
|
*
|
||||||
|
* Compile with: "g++ -std=c++11 libev.cpp -lamqpcpp -lev -lpthread"
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <ev.h>
|
||||||
|
#include <list>
|
||||||
|
#include "amqpcpp/linux_tcp.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class LibEvHandler : public TcpHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Internal interface for the object that is being watched
|
||||||
|
*/
|
||||||
|
class Watchable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The method that is called when a filedescriptor becomes active
|
||||||
|
* @param fd
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
virtual void onActive(int fd, int events) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the timer expires
|
||||||
|
*/
|
||||||
|
virtual void onExpired() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that wraps a libev I/O watcher
|
||||||
|
*/
|
||||||
|
class Watcher
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The event loop to which it is attached
|
||||||
|
* @var struct ev_loop
|
||||||
|
*/
|
||||||
|
struct ev_loop *_loop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual watcher structure
|
||||||
|
* @var struct ev_io
|
||||||
|
*/
|
||||||
|
struct ev_io _io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method that is called by libev when a filedescriptor becomes active
|
||||||
|
* @param loop The loop in which the event was triggered
|
||||||
|
* @param w Internal watcher object
|
||||||
|
* @param revents Events triggered
|
||||||
|
*/
|
||||||
|
static void callback(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||||
|
{
|
||||||
|
// retrieve the watched object
|
||||||
|
Watchable *object = static_cast<Watchable*>(watcher->data);
|
||||||
|
|
||||||
|
// tell the object that its filedescriptor is active
|
||||||
|
object->onActive(watcher->fd, revents);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param loop The current event loop
|
||||||
|
* @param object The object being watched
|
||||||
|
* @param fd The filedescriptor being watched
|
||||||
|
* @param events The events that should be monitored
|
||||||
|
* @param priority The priority for the watcher
|
||||||
|
*/
|
||||||
|
Watcher(struct ev_loop *loop, Watchable *object, int fd, int events, int priority) : _loop(loop)
|
||||||
|
{
|
||||||
|
// initialize the libev structure
|
||||||
|
ev_io_init(&_io, callback, fd, events);
|
||||||
|
|
||||||
|
// install a priority
|
||||||
|
ev_set_priority(&_io, priority);
|
||||||
|
|
||||||
|
// store the object in the data "void*"
|
||||||
|
_io.data = object;
|
||||||
|
|
||||||
|
// start the watcher
|
||||||
|
ev_io_start(_loop, &_io);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watchers cannot be copied or moved
|
||||||
|
*
|
||||||
|
* @param that The object to not move or copy
|
||||||
|
*/
|
||||||
|
Watcher(Watcher &&that) = delete;
|
||||||
|
Watcher(const Watcher &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Watcher()
|
||||||
|
{
|
||||||
|
// stop the watcher
|
||||||
|
ev_io_stop(_loop, &_io);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a filedescriptor is covered by the watcher
|
||||||
|
* @param fd
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool contains(int fd) const { return _io.fd == fd; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the events for which the filedescriptor is monitored
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
void events(int events)
|
||||||
|
{
|
||||||
|
// stop the watcher if it was active
|
||||||
|
ev_io_stop(_loop, &_io);
|
||||||
|
|
||||||
|
// set the events
|
||||||
|
ev_io_set(&_io, _io.fd, events);
|
||||||
|
|
||||||
|
// and restart it
|
||||||
|
ev_io_start(_loop, &_io);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around a connection, this will monitor the filedescriptors
|
||||||
|
* and run a timer to send out heartbeats
|
||||||
|
*/
|
||||||
|
class Wrapper : private Watchable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The connection that is monitored
|
||||||
|
* @var TcpConnection
|
||||||
|
*/
|
||||||
|
TcpConnection *_connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The event loop to which it is attached
|
||||||
|
* @var struct ev_loop
|
||||||
|
*/
|
||||||
|
struct ev_loop *_loop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The watcher for the timer
|
||||||
|
* @var struct ev_io
|
||||||
|
*/
|
||||||
|
struct ev_timer _timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IO-watchers to monitor filedescriptors
|
||||||
|
* @var std::list
|
||||||
|
*/
|
||||||
|
std::list<Watcher> _watchers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When should we send the next heartbeat?
|
||||||
|
* @var ev_tstamp
|
||||||
|
*/
|
||||||
|
ev_tstamp _next = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When does the connection expire / was the server for a too longer period of time idle?
|
||||||
|
* During connection setup, this member is used as the connect-timeout.
|
||||||
|
* @var ev_tstamp
|
||||||
|
*/
|
||||||
|
ev_tstamp _expire;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout after which the connection is no longer considered alive.
|
||||||
|
* A heartbeat must be sent every _timeout / 2 seconds.
|
||||||
|
* Value zero means heartbeats are disabled, or not yet negotiated.
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _timeout = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method that is called by libev when the timer expires
|
||||||
|
* @param loop The loop in which the event was triggered
|
||||||
|
* @param timer Internal timer object
|
||||||
|
* @param revents The events that triggered this call
|
||||||
|
*/
|
||||||
|
static void callback(struct ev_loop *loop, struct ev_timer *timer, int revents)
|
||||||
|
{
|
||||||
|
// retrieve the object
|
||||||
|
Watchable *object = static_cast<Watchable*>(timer->data);
|
||||||
|
|
||||||
|
// tell the object that it expired
|
||||||
|
object->onExpired();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we need timers / is this a timed monitor?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool timed() const
|
||||||
|
{
|
||||||
|
// if neither timers are set
|
||||||
|
return _expire > 0.0 || _next > 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the timer expired
|
||||||
|
*/
|
||||||
|
virtual void onExpired() override
|
||||||
|
{
|
||||||
|
// get the current time
|
||||||
|
ev_tstamp now = ev_now(_loop);
|
||||||
|
|
||||||
|
// timer is no longer active, so the refcounter in the loop is restored
|
||||||
|
ev_ref(_loop);
|
||||||
|
|
||||||
|
// if the onNegotiate method was not yet called, and no heartbeat timeout was negotiated
|
||||||
|
if (_timeout == 0)
|
||||||
|
{
|
||||||
|
// this can happen in three situations: 1. a connect-timeout, 2. user space has
|
||||||
|
// told us that we're not interested in heartbeats, 3. rabbitmq does not want heartbeats,
|
||||||
|
// in either case we're no longer going to run further timers.
|
||||||
|
_next = _expire = 0.0;
|
||||||
|
|
||||||
|
// if we have an initialized connection, user-space must have overridden the onNegotiate
|
||||||
|
// method, so we keep using the connection
|
||||||
|
if (_connection->initialized()) return;
|
||||||
|
|
||||||
|
// this is a connection timeout, close the connection from our side too
|
||||||
|
return (void)_connection->close(true);
|
||||||
|
}
|
||||||
|
else if (now >= _expire)
|
||||||
|
{
|
||||||
|
// the server was inactive for a too long period of time, reset state
|
||||||
|
_next = _expire = 0.0; _timeout = 0;
|
||||||
|
|
||||||
|
// close the connection because server was inactive (we close it with immediate effect,
|
||||||
|
// because it was inactive so we cannot trust it to respect the AMQP close handshake)
|
||||||
|
return (void)_connection->close(true);
|
||||||
|
}
|
||||||
|
else if (now >= _next)
|
||||||
|
{
|
||||||
|
// it's time for the next heartbeat
|
||||||
|
_connection->heartbeat();
|
||||||
|
|
||||||
|
// remember when we should send out the next one, so the next one should be
|
||||||
|
// sent only after _timout/2 seconds again _from now_ (no catching up)
|
||||||
|
_next = now + std::max(_timeout / 2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset the timer to trigger again later
|
||||||
|
ev_timer_set(&_timer, std::min(_next, _expire) - now, 0.0);
|
||||||
|
|
||||||
|
// and start it again
|
||||||
|
ev_timer_start(_loop, &_timer);
|
||||||
|
|
||||||
|
// and because the timer is running again, we restore the refcounter
|
||||||
|
ev_unref(_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when a filedescriptor becomes active
|
||||||
|
* @param fd the filedescriptor that is active
|
||||||
|
* @param events the events that are active (readable/writable)
|
||||||
|
*/
|
||||||
|
virtual void onActive(int fd, int events) override
|
||||||
|
{
|
||||||
|
// if the server is readable, we have some extra time before it expires, the expire time
|
||||||
|
// is set to 1.5 * _timeout to close the connection when the third heartbeat is about to be sent
|
||||||
|
if (_timeout != 0 && (events & EV_READ)) _expire = ev_now(_loop) + _timeout * 1.5;
|
||||||
|
|
||||||
|
// pass on to the connection
|
||||||
|
_connection->process(fd, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param loop The current event loop
|
||||||
|
* @param connection The TCP connection
|
||||||
|
* @param timeout Connect timeout
|
||||||
|
* @param priority The priority (high priorities are invoked earlier
|
||||||
|
*/
|
||||||
|
Wrapper(struct ev_loop *loop, AMQP::TcpConnection *connection, uint16_t timeout, int priority) :
|
||||||
|
_connection(connection),
|
||||||
|
_loop(loop),
|
||||||
|
_next(0.0),
|
||||||
|
_expire(ev_now(loop) + timeout),
|
||||||
|
_timeout(0)
|
||||||
|
{
|
||||||
|
// store the object in the data "void*"
|
||||||
|
_timer.data = this;
|
||||||
|
|
||||||
|
// initialize the libev structure, it should expire after the connection timeout
|
||||||
|
ev_timer_init(&_timer, callback, timeout, 0.0);
|
||||||
|
|
||||||
|
// set a priority
|
||||||
|
ev_set_priority(&_timer, priority);
|
||||||
|
|
||||||
|
// start the timer (this is the time that we reserve for setting up the connection)
|
||||||
|
ev_timer_start(_loop, &_timer);
|
||||||
|
|
||||||
|
// the timer should not keep the event loop active
|
||||||
|
ev_unref(_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watchers cannot be copied or moved
|
||||||
|
*
|
||||||
|
* @param that The object to not move or copy
|
||||||
|
*/
|
||||||
|
Wrapper(Wrapper &&that) = delete;
|
||||||
|
Wrapper(const Wrapper &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Wrapper()
|
||||||
|
{
|
||||||
|
// the timer was already stopped
|
||||||
|
if (!timed()) return;
|
||||||
|
|
||||||
|
// stop the timer
|
||||||
|
ev_timer_stop(_loop, &_timer);
|
||||||
|
|
||||||
|
// restore loop refcount
|
||||||
|
ev_ref(_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the timer (and expose the interval)
|
||||||
|
* @param interval the heartbeat interval proposed by the server
|
||||||
|
* @return uint16_t the heartbeat interval that we accepted
|
||||||
|
*/
|
||||||
|
uint16_t start(uint16_t timeout)
|
||||||
|
{
|
||||||
|
// we now know for sure that the connection was set up
|
||||||
|
_timeout = timeout;
|
||||||
|
|
||||||
|
// if heartbeats are disabled we do not have to set it
|
||||||
|
if (_timeout == 0) return 0;
|
||||||
|
|
||||||
|
// calculate current time
|
||||||
|
auto now = ev_now(_loop);
|
||||||
|
|
||||||
|
// we also know when the next heartbeat should be sent
|
||||||
|
_next = now + std::max(_timeout / 2, 1);
|
||||||
|
|
||||||
|
// because the server has just sent us some data, we will update the expire time too
|
||||||
|
_expire = now + _timeout * 1.5;
|
||||||
|
|
||||||
|
// stop the existing timer (we have to stop it and restart it, because ev_timer_set()
|
||||||
|
// on its own does not change the running timer) (note that we assume that the timer
|
||||||
|
// is already running and keeps on running, so no calls to ev_ref()/en_unref() here)
|
||||||
|
ev_timer_stop(_loop, &_timer);
|
||||||
|
|
||||||
|
// find the earliest thing that expires
|
||||||
|
ev_timer_set(&_timer, std::min(_next, _expire) - now, 0.0);
|
||||||
|
|
||||||
|
// and start it again
|
||||||
|
ev_timer_start(_loop, &_timer);
|
||||||
|
|
||||||
|
// expose the accepted interval
|
||||||
|
return _timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the timer is associated with a certain connection
|
||||||
|
* @param connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool contains(const AMQP::TcpConnection *connection) const
|
||||||
|
{
|
||||||
|
// compare the connections
|
||||||
|
return _connection == connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor a filedescriptor
|
||||||
|
* @param fd
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
void monitor(int fd, int events)
|
||||||
|
{
|
||||||
|
// should we remove?
|
||||||
|
if (events == 0)
|
||||||
|
{
|
||||||
|
// remove the io-watcher
|
||||||
|
_watchers.remove_if([fd](const Watcher &watcher) -> bool {
|
||||||
|
|
||||||
|
// compare filedescriptors
|
||||||
|
return watcher.contains(fd);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// look in the array for this filedescriptor
|
||||||
|
for (auto &watcher : _watchers)
|
||||||
|
{
|
||||||
|
// do we have a match?
|
||||||
|
if (watcher.contains(fd)) return watcher.events(events);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need a watcher
|
||||||
|
Watchable *watchable = this;
|
||||||
|
|
||||||
|
// we should monitor a new filedescriptor
|
||||||
|
_watchers.emplace_back(_loop, watchable, fd, events, ev_priority(&_timer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The event loop
|
||||||
|
* @var struct ev_loop*
|
||||||
|
*/
|
||||||
|
struct ev_loop *_loop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each connection is wrapped
|
||||||
|
* @var std::list
|
||||||
|
*/
|
||||||
|
std::list<Wrapper> _wrappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The priority that watchers should have (higher prio means libev gives more prio to this eveht)
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
int _priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup a connection-wrapper, when the wrapper is not found, we construct one
|
||||||
|
* @param connection
|
||||||
|
* @return Wrapper
|
||||||
|
*/
|
||||||
|
Wrapper &lookup(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// look for the appropriate connection
|
||||||
|
for (auto &wrapper : _wrappers)
|
||||||
|
{
|
||||||
|
// do we have a match?
|
||||||
|
if (wrapper.contains(connection)) return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to the wrappers
|
||||||
|
_wrappers.emplace_back(_loop, connection, 60, _priority);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return _wrappers.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Method that is called by AMQP-CPP to register a filedescriptor for readability or writability
|
||||||
|
* @param connection The TCP connection object that is reporting
|
||||||
|
* @param fd The filedescriptor to be monitored
|
||||||
|
* @param flags Should the object be monitored for readability or writability?
|
||||||
|
*/
|
||||||
|
virtual void monitor(TcpConnection *connection, int fd, int flags) override
|
||||||
|
{
|
||||||
|
// lookup the appropriate wrapper and start monitoring
|
||||||
|
lookup(connection).monitor(fd, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the heartbeat timeout is negotiated between the server and the client.
|
||||||
|
* @param connection The connection that suggested a heartbeat timeout
|
||||||
|
* @param timeout The suggested timeout from the server
|
||||||
|
* @return uint16_t The timeout to use
|
||||||
|
*/
|
||||||
|
virtual uint16_t onNegotiate(TcpConnection *connection, uint16_t timeout) override
|
||||||
|
{
|
||||||
|
// lookup the wrapper, and start the timer to check for activity and send heartbeats
|
||||||
|
return lookup(connection).start(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection is destructed
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onDetached(TcpConnection *connection) override
|
||||||
|
{
|
||||||
|
// remove from the array
|
||||||
|
_wrappers.remove_if([connection](const Wrapper &wrapper) -> bool {
|
||||||
|
return wrapper.contains(connection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param loop The event loop to wrap
|
||||||
|
* @param priority The libev priority (higher priorities are invoked earlier)
|
||||||
|
*/
|
||||||
|
LibEvHandler(struct ev_loop *loop, int priority = 0) : _loop(loop), _priority(priority) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~LibEvHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
191
builder/libs/AMQP-CPP/include/amqpcpp/libevent.h
Normal file
191
builder/libs/AMQP-CPP/include/amqpcpp/libevent.h
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/**
|
||||||
|
* LibEvent.h
|
||||||
|
*
|
||||||
|
* Implementation for the AMQP::TcpHandler that is optimized for libevent. You can
|
||||||
|
* use this class instead of a AMQP::TcpHandler class, just pass the event loop
|
||||||
|
* to the constructor and you're all set
|
||||||
|
*
|
||||||
|
* Compile with: "g++ -std=c++11 libevent.cpp -lamqpcpp -levent -lpthread"
|
||||||
|
*
|
||||||
|
* @author Brent Dimmig <brentdimmig@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <amqpcpp/flags.h>
|
||||||
|
#include <amqpcpp/linux_tcp.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class LibEventHandler : public TcpHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Helper class that wraps a libev I/O watcher
|
||||||
|
*/
|
||||||
|
class Watcher
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The actual event structure
|
||||||
|
* @var struct event
|
||||||
|
*/
|
||||||
|
struct event * _event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method that is called by libevent when a filedescriptor becomes active
|
||||||
|
* @param fd The filedescriptor with an event
|
||||||
|
* @param what Events triggered
|
||||||
|
* @param connection_arg void * to the connection
|
||||||
|
*/
|
||||||
|
static void callback(evutil_socket_t fd, short what, void *connection_arg)
|
||||||
|
{
|
||||||
|
// retrieve the connection
|
||||||
|
TcpConnection *connection = static_cast<TcpConnection*>(connection_arg);
|
||||||
|
|
||||||
|
// setup amqp flags
|
||||||
|
int amqp_flags = 0;
|
||||||
|
if (what & EV_READ)
|
||||||
|
amqp_flags |= AMQP::readable;
|
||||||
|
if (what & EV_WRITE)
|
||||||
|
amqp_flags |= AMQP::writable;
|
||||||
|
|
||||||
|
// tell the connection that its filedescriptor is active
|
||||||
|
connection->process(fd, amqp_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param evbase The current event loop
|
||||||
|
* @param connection The connection being watched
|
||||||
|
* @param fd The filedescriptor being watched
|
||||||
|
* @param events The events that should be monitored
|
||||||
|
*/
|
||||||
|
Watcher(struct event_base *evbase, TcpConnection *connection, int fd, int events)
|
||||||
|
{
|
||||||
|
// setup libevent flags
|
||||||
|
short event_flags = EV_PERSIST;
|
||||||
|
if (events & AMQP::readable)
|
||||||
|
event_flags |= EV_READ;
|
||||||
|
if (events & AMQP::writable)
|
||||||
|
event_flags |= EV_WRITE;
|
||||||
|
|
||||||
|
// initialize the event
|
||||||
|
|
||||||
|
_event = event_new(evbase, fd, event_flags, callback, connection);
|
||||||
|
event_add(_event, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Watcher()
|
||||||
|
{
|
||||||
|
// stop the event
|
||||||
|
event_del(_event);
|
||||||
|
// free the event
|
||||||
|
event_free(_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the events for which the filedescriptor is monitored
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
void events(int events)
|
||||||
|
{
|
||||||
|
// stop the event if it was active
|
||||||
|
event_del(_event);
|
||||||
|
|
||||||
|
// setup libevent flags
|
||||||
|
short event_flags = EV_PERSIST;
|
||||||
|
if (events & AMQP::readable)
|
||||||
|
event_flags |= EV_READ;
|
||||||
|
if (events & AMQP::writable)
|
||||||
|
event_flags |= EV_WRITE;
|
||||||
|
|
||||||
|
// set the events
|
||||||
|
event_assign(_event, event_get_base(_event), event_get_fd(_event), event_flags,
|
||||||
|
event_get_callback(_event), event_get_callback_arg(_event));
|
||||||
|
|
||||||
|
// and restart it
|
||||||
|
event_add(_event, nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The event loop
|
||||||
|
* @var struct event_base*
|
||||||
|
*/
|
||||||
|
struct event_base *_evbase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All I/O watchers that are active, indexed by their filedescriptor
|
||||||
|
* @var std::map<int,Watcher>
|
||||||
|
*/
|
||||||
|
std::map<int,std::unique_ptr<Watcher>> _watchers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by AMQP-CPP to register a filedescriptor for readability or writability
|
||||||
|
* @param connection The TCP connection object that is reporting
|
||||||
|
* @param fd The filedescriptor to be monitored
|
||||||
|
* @param flags Should the object be monitored for readability or writability?
|
||||||
|
*/
|
||||||
|
virtual void monitor(TcpConnection *connection, int fd, int flags) override
|
||||||
|
{
|
||||||
|
// do we already have this filedescriptor
|
||||||
|
auto iter = _watchers.find(fd);
|
||||||
|
|
||||||
|
// was it found?
|
||||||
|
if (iter == _watchers.end())
|
||||||
|
{
|
||||||
|
// we did not yet have this watcher - but that is ok if no filedescriptor was registered
|
||||||
|
if (flags == 0) return;
|
||||||
|
|
||||||
|
// construct a new watcher, and put it in the map
|
||||||
|
_watchers[fd] = std::unique_ptr<Watcher>(new Watcher(_evbase, connection, fd, flags));
|
||||||
|
}
|
||||||
|
else if (flags == 0)
|
||||||
|
{
|
||||||
|
// the watcher does already exist, but we no longer have to watch this watcher
|
||||||
|
_watchers.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// change the events
|
||||||
|
iter->second->events(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param evbase The event loop to wrap
|
||||||
|
*/
|
||||||
|
LibEventHandler(struct event_base *evbase) : _evbase(evbase) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~LibEventHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
224
builder/libs/AMQP-CPP/include/amqpcpp/libuv.h
Normal file
224
builder/libs/AMQP-CPP/include/amqpcpp/libuv.h
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/**
|
||||||
|
* LibUV.h
|
||||||
|
*
|
||||||
|
* Implementation for the AMQP::TcpHandler that is optimized for libuv. You can
|
||||||
|
* use this class instead of a AMQP::TcpHandler class, just pass the event loop
|
||||||
|
* to the constructor and you're all set.
|
||||||
|
*
|
||||||
|
* Based heavily on the libev.h implementation by Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
*
|
||||||
|
* @author David Nikdel <david@nikdel.com>
|
||||||
|
* @copyright 2015 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
#include "amqpcpp/linux_tcp.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class LibUvHandler : public TcpHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Helper class that wraps a libev I/O watcher
|
||||||
|
*/
|
||||||
|
class Watcher
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The event loop to which it is attached
|
||||||
|
* @var uv_loop_t
|
||||||
|
*/
|
||||||
|
uv_loop_t *_loop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual watcher structure
|
||||||
|
* @var uv_poll_t
|
||||||
|
*/
|
||||||
|
uv_poll_t *_poll;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method that is called by libuv when a filedescriptor becomes active
|
||||||
|
* @param handle Internal poll handle
|
||||||
|
* @param status LibUV error code UV_*
|
||||||
|
* @param events Events triggered
|
||||||
|
*/
|
||||||
|
static void callback(uv_poll_t *handle, int status, int events)
|
||||||
|
{
|
||||||
|
// retrieve the connection
|
||||||
|
TcpConnection *connection = static_cast<TcpConnection*>(handle->data);
|
||||||
|
|
||||||
|
// tell the connection that its filedescriptor is active
|
||||||
|
int fd = -1;
|
||||||
|
uv_fileno(reinterpret_cast<uv_handle_t*>(handle), &fd);
|
||||||
|
connection->process(fd, uv_to_amqp_events(status, events));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param loop The current event loop
|
||||||
|
* @param connection The connection being watched
|
||||||
|
* @param fd The filedescriptor being watched
|
||||||
|
* @param events The events that should be monitored
|
||||||
|
*/
|
||||||
|
Watcher(uv_loop_t *loop, TcpConnection *connection, int fd, int events) : _loop(loop)
|
||||||
|
{
|
||||||
|
// create a new poll
|
||||||
|
_poll = new uv_poll_t();
|
||||||
|
|
||||||
|
// initialize the libev structure
|
||||||
|
uv_poll_init(_loop, _poll, fd);
|
||||||
|
|
||||||
|
// store the connection in the data "void*"
|
||||||
|
_poll->data = connection;
|
||||||
|
|
||||||
|
// start the watcher
|
||||||
|
uv_poll_start(_poll, amqp_to_uv_events(events), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watchers cannot be copied or moved
|
||||||
|
*
|
||||||
|
* @param that The object to not move or copy
|
||||||
|
*/
|
||||||
|
Watcher(Watcher &&that) = delete;
|
||||||
|
Watcher(const Watcher &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Watcher()
|
||||||
|
{
|
||||||
|
// stop the watcher
|
||||||
|
uv_poll_stop(_poll);
|
||||||
|
|
||||||
|
// close the handle
|
||||||
|
uv_close(reinterpret_cast<uv_handle_t*>(_poll), [](uv_handle_t* handle) {
|
||||||
|
// delete memory once closed
|
||||||
|
delete reinterpret_cast<uv_poll_t*>(handle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the events for which the filedescriptor is monitored
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
void events(int events)
|
||||||
|
{
|
||||||
|
// update the events being watched for
|
||||||
|
uv_poll_start(_poll, amqp_to_uv_events(events), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert event flags from UV format to AMQP format
|
||||||
|
*/
|
||||||
|
static int uv_to_amqp_events(int status, int events)
|
||||||
|
{
|
||||||
|
// if the socket is closed report both so we pick up the error
|
||||||
|
if (status != 0)
|
||||||
|
return AMQP::readable | AMQP::writable;
|
||||||
|
|
||||||
|
// map read or write
|
||||||
|
int amqp_events = 0;
|
||||||
|
if (events & UV_READABLE)
|
||||||
|
amqp_events |= AMQP::readable;
|
||||||
|
if (events & UV_WRITABLE)
|
||||||
|
amqp_events |= AMQP::writable;
|
||||||
|
return amqp_events;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert event flags from AMQP format to UV format
|
||||||
|
*/
|
||||||
|
static int amqp_to_uv_events(int events)
|
||||||
|
{
|
||||||
|
int uv_events = 0;
|
||||||
|
if (events & AMQP::readable)
|
||||||
|
uv_events |= UV_READABLE;
|
||||||
|
if (events & AMQP::writable)
|
||||||
|
uv_events |= UV_WRITABLE;
|
||||||
|
return uv_events;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The event loop
|
||||||
|
* @var uv_loop_t*
|
||||||
|
*/
|
||||||
|
uv_loop_t *_loop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All I/O watchers that are active, indexed by their filedescriptor
|
||||||
|
* @var std::map<int,Watcher>
|
||||||
|
*/
|
||||||
|
std::map<int,std::unique_ptr<Watcher>> _watchers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by AMQP-CPP to register a filedescriptor for readability or writability
|
||||||
|
* @param connection The TCP connection object that is reporting
|
||||||
|
* @param fd The filedescriptor to be monitored
|
||||||
|
* @param flags Should the object be monitored for readability or writability?
|
||||||
|
*/
|
||||||
|
virtual void monitor(TcpConnection *connection, int fd, int flags) override
|
||||||
|
{
|
||||||
|
// do we already have this filedescriptor
|
||||||
|
auto iter = _watchers.find(fd);
|
||||||
|
|
||||||
|
// was it found?
|
||||||
|
if (iter == _watchers.end())
|
||||||
|
{
|
||||||
|
// we did not yet have this watcher - but that is ok if no filedescriptor was registered
|
||||||
|
if (flags == 0) return;
|
||||||
|
|
||||||
|
// construct a new watcher, and put it in the map
|
||||||
|
_watchers[fd] = std::unique_ptr<Watcher>(new Watcher(_loop, connection, fd, flags));
|
||||||
|
}
|
||||||
|
else if (flags == 0)
|
||||||
|
{
|
||||||
|
// the watcher does already exist, but we no longer have to watch this watcher
|
||||||
|
_watchers.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// change the events
|
||||||
|
iter->second->events(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param loop The event loop to wrap
|
||||||
|
*/
|
||||||
|
LibUvHandler(uv_loop_t *loop) : _loop(loop) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~LibUvHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
4
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp.h
Normal file
4
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "linux_tcp/tcpparent.h"
|
||||||
|
#include "linux_tcp/tcphandler.h"
|
||||||
|
#include "linux_tcp/tcpconnection.h"
|
||||||
|
#include "linux_tcp/tcpchannel.h"
|
||||||
62
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpchannel.h
Normal file
62
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpchannel.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* TcpChannel.h
|
||||||
|
*
|
||||||
|
* Extended channel that can be constructed on top of a TCP connection
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class TcpChannel : public Channel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* The passed in connection pointer must remain valid for the
|
||||||
|
* lifetime of the channel. A constructor is thrown if the channel
|
||||||
|
* cannot be connected (because the connection is already closed or
|
||||||
|
* because max number of channels has been reached)
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
TcpChannel(TcpConnection *connection) :
|
||||||
|
Channel(&connection->_connection) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~TcpChannel() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copying is not allowed.
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
TcpChannel(const TcpChannel &other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* But movement is allowed
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
TcpChannel(TcpChannel &&other) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
357
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpconnection.h
Normal file
357
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpconnection.h
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
/**
|
||||||
|
* TcpConnection.h
|
||||||
|
*
|
||||||
|
* Extended Connection object that creates a TCP connection for the
|
||||||
|
* IO between the client application and the RabbitMQ server.
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2021 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class TcpState;
|
||||||
|
class TcpChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class TcpConnection :
|
||||||
|
private ConnectionHandler,
|
||||||
|
private Watchable,
|
||||||
|
private TcpParent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* User-space handler object
|
||||||
|
* @var TcpHandler
|
||||||
|
*/
|
||||||
|
TcpHandler *_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the TCP connection - this state objecs changes based on
|
||||||
|
* the state of the connection (resolving, connected or closed)
|
||||||
|
* @var std::unique_ptr<TcpState>
|
||||||
|
*/
|
||||||
|
std::unique_ptr<TcpState> _state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The underlying AMQP connection
|
||||||
|
* @var Connection
|
||||||
|
*/
|
||||||
|
Connection _connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel may access out _connection
|
||||||
|
* @friend
|
||||||
|
*/
|
||||||
|
friend TcpChannel;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the RabbitMQ server and your client application
|
||||||
|
* exchange some properties that describe their identity.
|
||||||
|
* @param connection The connection about which information is exchanged
|
||||||
|
* @param server Properties sent by the server
|
||||||
|
* @param client Properties that are to be sent back
|
||||||
|
*/
|
||||||
|
virtual void onProperties(Connection *connection, const Table &server, Table &client) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the heartbeat frequency is negotiated.
|
||||||
|
* @param connection The connection that suggested a heartbeat interval
|
||||||
|
* @param interval The suggested interval from the server
|
||||||
|
* @return uint16_t The interval to use
|
||||||
|
*/
|
||||||
|
virtual uint16_t onNegotiate(Connection *connection, uint16_t interval) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called by the connection when data needs to be sent over the network
|
||||||
|
* @param connection The connection that created this output
|
||||||
|
* @param buffer Data to send
|
||||||
|
* @param size Size of the buffer
|
||||||
|
*/
|
||||||
|
virtual void onData(Connection *connection, const char *buffer, size_t size) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the server sends a heartbeat to the client
|
||||||
|
* @param connection The connection over which the heartbeat was received
|
||||||
|
*/
|
||||||
|
virtual void onHeartbeat(Connection *connection) override
|
||||||
|
{
|
||||||
|
// pass on to tcp handler
|
||||||
|
if (_handler) _handler->onHeartbeat(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called when the connection ends up in an error state
|
||||||
|
* @param connection The connection that entered the error state
|
||||||
|
* @param message Error message
|
||||||
|
*/
|
||||||
|
virtual void onError(Connection *connection, const char *message) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection is established
|
||||||
|
* @param connection The connection that can now be used
|
||||||
|
*/
|
||||||
|
virtual void onReady(Connection *connection) override
|
||||||
|
{
|
||||||
|
// pass on to the handler
|
||||||
|
if (_handler) _handler->onReady(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the connection was closed.
|
||||||
|
* @param connection The connection that was closed and that is now unusable
|
||||||
|
*/
|
||||||
|
virtual void onClosed(Connection *connection) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection was blocked.
|
||||||
|
* @param connection The connection that was blocked
|
||||||
|
* @param reason Why was the connection blocked
|
||||||
|
*/
|
||||||
|
virtual void onBlocked(Connection *connection, const char *reason) override
|
||||||
|
{
|
||||||
|
// pass to user space
|
||||||
|
if (_handler) _handler->onBlocked(this, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection is no longer blocked.
|
||||||
|
* @param connection The connection that is no longer blocked
|
||||||
|
*/
|
||||||
|
virtual void onUnblocked(Connection *connection)
|
||||||
|
{
|
||||||
|
// pass to user space
|
||||||
|
if (_handler) _handler->onUnblocked(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the tcp connection has been established
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
virtual void onConnected(TcpState *state) override
|
||||||
|
{
|
||||||
|
// pass on to the handler
|
||||||
|
if (_handler) _handler->onConnected(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when right before connection is being secured
|
||||||
|
* @param state
|
||||||
|
* @param ssl
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool onSecuring(TcpState *state, SSL *ssl) override
|
||||||
|
{
|
||||||
|
// pass on to user-space
|
||||||
|
return _handler && _handler->onSecuring(this, ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the connection is secured
|
||||||
|
* @param state
|
||||||
|
* @param ssl
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool onSecured(TcpState *state, const SSL *ssl) override
|
||||||
|
{
|
||||||
|
// pass on to user-space
|
||||||
|
return _handler && _handler->onSecured(this, ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when data was received
|
||||||
|
* @param state
|
||||||
|
* @param buffer
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t onReceived(TcpState *state, const Buffer &buffer) override
|
||||||
|
{
|
||||||
|
// pass on to the connection
|
||||||
|
return _connection.parse(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when we need to monitor a different filedescriptor
|
||||||
|
* @param state
|
||||||
|
* @param fd
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
virtual void onIdle(TcpState *state, int socket, int events) override
|
||||||
|
{
|
||||||
|
// pass on to user-space
|
||||||
|
if (_handler) _handler->monitor(this, socket, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when an error occurs (the connection is lost)
|
||||||
|
* @param state
|
||||||
|
* @param error
|
||||||
|
* @param connected
|
||||||
|
*/
|
||||||
|
virtual void onError(TcpState *state, const char *message, bool connected) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when it is detected that the connection was lost
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
virtual void onLost(TcpState *state) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The expected number of bytes
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t expected() override
|
||||||
|
{
|
||||||
|
// pass on to the connection
|
||||||
|
return _connection.expected();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param handler User implemented handler object
|
||||||
|
* @param hostname The address to connect to
|
||||||
|
*/
|
||||||
|
TcpConnection(TcpHandler *handler, const Address &address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No copying
|
||||||
|
* @param that
|
||||||
|
*/
|
||||||
|
TcpConnection(const TcpConnection &that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~TcpConnection() noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filedescriptor that is used for this connection
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int fileno() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the TCP connection
|
||||||
|
*
|
||||||
|
* This method should be called when the filedescriptor that is registered
|
||||||
|
* in the event loop becomes active. You should pass in a flag holding the
|
||||||
|
* flags AMQP::readable or AMQP::writable to indicate whether the descriptor
|
||||||
|
* was readable or writable, or bitwise-or if it was both
|
||||||
|
*
|
||||||
|
* @param fd The filedescriptor that became readable or writable
|
||||||
|
* @param events What sort of events occured?
|
||||||
|
*/
|
||||||
|
void process(int fd, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the connection in an elegant fashion. This closes all channels and the
|
||||||
|
* TCP connection. Note that the connection is not immediately closed: first all
|
||||||
|
* pending operations are completed, and then an AMQP closing-handshake is
|
||||||
|
* performed. If you pass a parameter "immediate=true" the connection is
|
||||||
|
* immediately closed, without waiting for earlier commands (and your handler's
|
||||||
|
* onError() method is called about the premature close, including the onLost() and
|
||||||
|
* onDetached()).
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool close(bool immediate = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection connected, meaning: it has passed the login handshake
|
||||||
|
* and isn't closed yet?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool ready() const
|
||||||
|
{
|
||||||
|
return _connection.ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection initialized, meaning: it has passed the login handshake?
|
||||||
|
* It may be closing or closed
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool initialized() const
|
||||||
|
{
|
||||||
|
return _connection.initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection in a usable state / not yet closed or being closed
|
||||||
|
* When a connection is usable, you can send further commands over it. When it is
|
||||||
|
* unusable, it may still be connected and finished queued commands.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool usable() const
|
||||||
|
{
|
||||||
|
return _connection.usable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection closed and full dead? The entire TCP connection has been discarded.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool closed() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max frame size. Useful if you set up a buffer to parse incoming data: it does not have to exceed this size.
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t maxFrame() const
|
||||||
|
{
|
||||||
|
return _connection.maxFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes that can best be passed to the next call to the parse() method.
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t expected() const
|
||||||
|
{
|
||||||
|
return _connection.expected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of channels this connection has.
|
||||||
|
* @return std::size_t
|
||||||
|
*/
|
||||||
|
std::size_t channels() const
|
||||||
|
{
|
||||||
|
// return the number of channels this connection has
|
||||||
|
return _connection.channels();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of outgoing bytes queued on this connection.
|
||||||
|
* @return std::size_t
|
||||||
|
*/
|
||||||
|
std::size_t queued() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a heartbeat
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool heartbeat()
|
||||||
|
{
|
||||||
|
return _connection.heartbeat();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
27
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpdefines.h
Normal file
27
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpdefines.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No MSG_NOSIGNAL on OS X.
|
||||||
|
* Avoid SIGPIPE by using sockopt call.
|
||||||
|
*/
|
||||||
|
#ifdef MSG_NOSIGNAL
|
||||||
|
# define AMQP_CPP_MSG_NOSIGNAL MSG_NOSIGNAL
|
||||||
|
#else
|
||||||
|
# define AMQP_CPP_MSG_NOSIGNAL 0
|
||||||
|
# ifdef SO_NOSIGPIPE
|
||||||
|
# define AMQP_CPP_USE_SO_NOSIGPIPE
|
||||||
|
# else
|
||||||
|
# error "Cannot block SIGPIPE!"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AMQP_CPP_USE_SO_NOSIGPIPE
|
||||||
|
/**
|
||||||
|
* Ignore SIGPIPE when there is no MSG_NOSIGNAL.
|
||||||
|
*/
|
||||||
|
inline void set_sockopt_nosigpipe(int socket)
|
||||||
|
{
|
||||||
|
int optval = 1;
|
||||||
|
setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
275
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcphandler.h
Normal file
275
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcphandler.h
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/**
|
||||||
|
* TcpHandler.h
|
||||||
|
*
|
||||||
|
* Interface to be implemented by the caller of the AMQP library in case
|
||||||
|
* the "Tcp" class is being used as alternative for the ConnectionHandler
|
||||||
|
* class.
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2015 - 2021 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class TcpConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class TcpHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~TcpHandler() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called immediately after a connection has been constructed.
|
||||||
|
* @param connection The connection object that was just constructed
|
||||||
|
*/
|
||||||
|
virtual void onAttached(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection ends up in a connected state
|
||||||
|
* This method is called after the TCP connection has been set up, but before
|
||||||
|
* the (optional) secure TLS connection is ready, and before the AMQP login
|
||||||
|
* handshake has been completed. If this step has been set, the onLost()
|
||||||
|
* method will also always be called when the connection is closed.
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onConnected(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called after a TCP connection has been set up, and right before
|
||||||
|
* the SSL handshake is going to be performed to secure the connection (only for
|
||||||
|
* amqps:// connections). This method can be overridden in user space to load
|
||||||
|
* client side certificates.
|
||||||
|
* @param connection The connection for which TLS was just started
|
||||||
|
* @param ssl Pointer to the SSL structure that can be modified
|
||||||
|
* @return bool True to proceed / accept the connection, false to break up
|
||||||
|
*/
|
||||||
|
virtual bool onSecuring(TcpConnection *connection, SSL *ssl)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) ssl;
|
||||||
|
|
||||||
|
// default implementation: do not do anything, just allow the connection
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called after a TCP connection has been set up and the initial
|
||||||
|
* TLS handshake is finished too, but right before the AMQP login handshake is
|
||||||
|
* going to take place and the first data is going to be sent over the connection.
|
||||||
|
* This method allows you to inspect the TLS certificate and other connection
|
||||||
|
* properties, and to break up the connection if you find it not secure enough.
|
||||||
|
* The default implementation considers all connections to be secure, even if the
|
||||||
|
* connection has a self-signed or even invalid certificate. To be more strict,
|
||||||
|
* override this method, inspect the certificate and return false if you do not
|
||||||
|
* want to use the connection. The passed in SSL pointer is a pointer to a SSL
|
||||||
|
* structure from the openssl library. This method is only called for secure
|
||||||
|
* connections (connection with an amqps:// address).
|
||||||
|
* @param connection The connection for which TLS was just started
|
||||||
|
* @param ssl Pointer to the SSL structure that can be inspected
|
||||||
|
* @return bool True to proceed / accept the connection, false to break up
|
||||||
|
*/
|
||||||
|
virtual bool onSecured(TcpConnection *connection, const SSL *ssl)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) ssl;
|
||||||
|
|
||||||
|
// default implementation: do not inspect anything, just allow the connection
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the RabbitMQ server and your client application
|
||||||
|
* exchange some properties that describe their identity.
|
||||||
|
* @param connection The connection about which information is exchanged
|
||||||
|
* @param server Properties sent by the server
|
||||||
|
* @param client Properties that are to be sent back
|
||||||
|
*/
|
||||||
|
virtual void onProperties(TcpConnection *connection, const Table &server, Table &client)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complaint about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) server;
|
||||||
|
(void) client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the heartbeat frequency is negotiated
|
||||||
|
* between the server and the client. Applications can override this method
|
||||||
|
* if they want to use a different heartbeat interval (for example: return 0
|
||||||
|
* to disable heartbeats)
|
||||||
|
* @param connection The connection that suggested a heartbeat interval
|
||||||
|
* @param interval The suggested interval from the server
|
||||||
|
* @return uint16_t The interval to use
|
||||||
|
*
|
||||||
|
* @see ConnectionHandler::onNegotiate
|
||||||
|
*/
|
||||||
|
virtual uint16_t onNegotiate(TcpConnection *connection, uint16_t interval)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) interval;
|
||||||
|
|
||||||
|
// default implementation, suggested heartbeat is ok
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called after the AMQP login handshake has been completed
|
||||||
|
* and the connection object is ready for sending out actual AMQP instructions
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onReady(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the server sends a heartbeat to the client
|
||||||
|
* @param connection The connection over which the heartbeat was received
|
||||||
|
* @see ConnectionHandler::onHeartbeat
|
||||||
|
*/
|
||||||
|
virtual void onHeartbeat(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the connection ends up in an error state
|
||||||
|
* This could either be an error at the AMQP level, but could also
|
||||||
|
* be an error at the TCP of SSL level (like a broken connection).
|
||||||
|
* If the connection is connected (the onConnected() method was called
|
||||||
|
* before), the onLost() method is going to be called too.
|
||||||
|
* @param connection The TCP connection
|
||||||
|
* @param message Error message
|
||||||
|
*/
|
||||||
|
virtual void onError(TcpConnection *connection, const char *message)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
(void) message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP protocol was gracefully ended.
|
||||||
|
* This is the counter-part of a call to connection.close(). Note that
|
||||||
|
* the underlying TCP connection is still alive, and onLost() and
|
||||||
|
* onDetached() (see below) are going to be called too.
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onClosed(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection was blocked.
|
||||||
|
*
|
||||||
|
* This method is called, when the server connection gets blocked for the first
|
||||||
|
* time due to the broker running low on a resource (memory or disk). For
|
||||||
|
* example, when a RabbitMQ node detects that it is low on RAM, it sends a
|
||||||
|
* notification to all connected publishing clients supporting this feature.
|
||||||
|
* If before the connections are unblocked the node also starts running low on
|
||||||
|
* disk space, another notification will not be sent.
|
||||||
|
*
|
||||||
|
* @param connection The connection that was blocked
|
||||||
|
* @param reason Why was the connection blocked
|
||||||
|
*/
|
||||||
|
virtual void onBlocked(TcpConnection *connection, const char *reason)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the AMQP connection is no longer blocked.
|
||||||
|
*
|
||||||
|
* This method is called when all resource alarms have cleared and the
|
||||||
|
* connection is fully unblocked.
|
||||||
|
*
|
||||||
|
* @param connection The connection that is no longer blocked
|
||||||
|
*/
|
||||||
|
virtual void onUnblocked(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection is lost or closed. This
|
||||||
|
* is always called if you have also received a call to onConnected().
|
||||||
|
* @param connection The TCP connection
|
||||||
|
*/
|
||||||
|
virtual void onLost(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the handler will no longer be notified.
|
||||||
|
* This is the last call to your handler, and it is typically used
|
||||||
|
* to clean up stuff.
|
||||||
|
* @param connection The connection that is being destructed
|
||||||
|
*/
|
||||||
|
virtual void onDetached(TcpConnection *connection)
|
||||||
|
{
|
||||||
|
// make sure compilers dont complain about unused parameters
|
||||||
|
(void) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor a filedescriptor for readability or writability
|
||||||
|
*
|
||||||
|
* When a TCP connection is opened, it creates a non-blocking socket
|
||||||
|
* connection. This method is called to inform you about this socket,
|
||||||
|
* so that you can include it in the event loop. When the socket becomes
|
||||||
|
* active, you should call the "process()" method in the Tcp class.
|
||||||
|
*
|
||||||
|
* The flags is AMQP::readable if the filedescriptor should be monitored
|
||||||
|
* for readability, AMQP::writable if it is to be monitored for writability,
|
||||||
|
* or AMQP::readable | AMQP::writable if it has to be checked for both.
|
||||||
|
* If flags has value 0, the filedescriptor should be removed from the
|
||||||
|
* event loop.
|
||||||
|
*
|
||||||
|
* @param connection The TCP connection object that is reporting
|
||||||
|
* @param fd The filedescriptor to be monitored
|
||||||
|
* @param flags Should the object be monitored for readability or writability?
|
||||||
|
*/
|
||||||
|
virtual void monitor(TcpConnection *connection, int fd, int flags) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
106
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpparent.h
Normal file
106
builder/libs/AMQP-CPP/include/amqpcpp/linux_tcp/tcpparent.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* TcpParent.h
|
||||||
|
*
|
||||||
|
* Interface to be implemented by the parent of a tcp-state. This is
|
||||||
|
* an _internal_ interface that is not relevant for user-space applications.
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2018 - 2021 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class TcpState;
|
||||||
|
class Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class TcpParent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~TcpParent() = default;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the TCP connection has been established
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
virtual void onConnected(TcpState *state) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called right before a connection is secured and that allows userspac to change SSL
|
||||||
|
* @param state
|
||||||
|
* @param ssl
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool onSecuring(TcpState *state, SSL *ssl) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when the connection is secured
|
||||||
|
* @param state
|
||||||
|
* @param ssl
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
virtual bool onSecured(TcpState *state, const SSL *ssl) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when data was received
|
||||||
|
* @param state
|
||||||
|
* @param buffer
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t onReceived(TcpState *state, const Buffer &buffer) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when we need to monitor a different filedescriptor
|
||||||
|
* @param state
|
||||||
|
* @param fd
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
virtual void onIdle(TcpState *state, int socket, int events) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called when an error occurs (the connection is lost)
|
||||||
|
* @param state
|
||||||
|
* @param error
|
||||||
|
* @param connected
|
||||||
|
*/
|
||||||
|
virtual void onError(TcpState *state, const char *message, bool connected = true) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to be called when it is detected that the connection was lost
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
virtual void onLost(TcpState *state) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The expected number of bytes
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t expected() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
173
builder/libs/AMQP-CPP/include/amqpcpp/login.h
Normal file
173
builder/libs/AMQP-CPP/include/amqpcpp/login.h
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* The login information to access a server
|
||||||
|
*
|
||||||
|
* This class combines login, password and vhost
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Login
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The username
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The password
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _password;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
Login() : _user("guest"), _password("guest") {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param user
|
||||||
|
* @param password
|
||||||
|
*/
|
||||||
|
Login(std::string user, std::string password) :
|
||||||
|
_user(std::move(user)), _password(std::move(password)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param user
|
||||||
|
* @param password
|
||||||
|
*/
|
||||||
|
Login(const char *user, const char *password) :
|
||||||
|
_user(user), _password(password) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Login() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to boolean: is the login set?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
operator bool () const
|
||||||
|
{
|
||||||
|
return !_user.empty() || !_password.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate operator: is it not set
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator! () const
|
||||||
|
{
|
||||||
|
return _user.empty() && _password.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the user name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string &user() const
|
||||||
|
{
|
||||||
|
return _user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the password
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string &password() const
|
||||||
|
{
|
||||||
|
return _password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String representation in SASL PLAIN mode
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
std::string saslPlain() const
|
||||||
|
{
|
||||||
|
// we need an initial string
|
||||||
|
std::string result("\0", 1);
|
||||||
|
|
||||||
|
// append other elements
|
||||||
|
return result.append(_user).append("\0",1).append(_password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator
|
||||||
|
* @param that
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator==(const Login &that) const
|
||||||
|
{
|
||||||
|
// username and password must match
|
||||||
|
return _user == that._user && _password == that._password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator
|
||||||
|
* @param that
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator!=(const Login &that) const
|
||||||
|
{
|
||||||
|
// the opposite of operator==
|
||||||
|
return !operator==(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison operator
|
||||||
|
* @param that
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator<(const Login &that) const
|
||||||
|
{
|
||||||
|
// compare users
|
||||||
|
if (_user != that._user) return _user < that._user;
|
||||||
|
|
||||||
|
// compare passwords
|
||||||
|
return _password < that._password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Friend function to allow writing the login to a stream
|
||||||
|
* @param stream
|
||||||
|
* @param login
|
||||||
|
* @return std::ostream
|
||||||
|
*/
|
||||||
|
friend std::ostream &operator<<(std::ostream &stream, const Login &login)
|
||||||
|
{
|
||||||
|
// write username and password
|
||||||
|
return stream << login._user << ":" << login._password;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
182
builder/libs/AMQP-CPP/include/amqpcpp/message.h
Normal file
182
builder/libs/AMQP-CPP/include/amqpcpp/message.h
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/**
|
||||||
|
* Message.h
|
||||||
|
*
|
||||||
|
* An incoming message has the same sort of information as an outgoing
|
||||||
|
* message, plus some additional information.
|
||||||
|
*
|
||||||
|
* Message objects can not be constructed by end users, they are only constructed
|
||||||
|
* by the AMQP library, and passed to user callbacks.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "envelope.h"
|
||||||
|
#include <limits>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class DeferredReceiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Message : public Envelope
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* An allocated and mutable block of memory underlying _body
|
||||||
|
* @var char *
|
||||||
|
*/
|
||||||
|
char *_mutableBody = nullptr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The exchange to which it was originally published
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _exchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The routing key that was originally used
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _routingkey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes already filled
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _filled = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are an open book to the consumer handler
|
||||||
|
*/
|
||||||
|
friend class DeferredReceiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the body size
|
||||||
|
* This field is set when the header is received
|
||||||
|
* @param uint64_t
|
||||||
|
*/
|
||||||
|
void setBodySize(uint64_t size)
|
||||||
|
{
|
||||||
|
// safety-check: on 32-bit platforms size_t is obviously also a 32-bit dword
|
||||||
|
// in which case casting the uint64_t to a size_t could result in truncation
|
||||||
|
// here we check whether the given size fits inside a size_t
|
||||||
|
if (std::numeric_limits<size_t>::max() < size) throw std::runtime_error("message is too big for this system");
|
||||||
|
|
||||||
|
// store the new size
|
||||||
|
_bodySize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append data
|
||||||
|
* @param buffer incoming data
|
||||||
|
* @param size size of the data
|
||||||
|
* @return bool true if the message is now complete
|
||||||
|
*/
|
||||||
|
bool append(const char *buffer, uint64_t size)
|
||||||
|
{
|
||||||
|
// is the body already allocated?
|
||||||
|
if (_mutableBody)
|
||||||
|
{
|
||||||
|
// prevent overflow
|
||||||
|
size = std::min(size, _bodySize - _filled);
|
||||||
|
|
||||||
|
// append more data
|
||||||
|
memcpy(_mutableBody + _filled, buffer, (size_t)size);
|
||||||
|
|
||||||
|
// update filled data
|
||||||
|
_filled += (size_t)size;
|
||||||
|
}
|
||||||
|
else if (size >= _bodySize)
|
||||||
|
{
|
||||||
|
// we do not have to combine multiple frames, so we can store
|
||||||
|
// the buffer pointer in the message
|
||||||
|
_body = buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// allocate the buffer
|
||||||
|
_mutableBody = (char *)malloc((size_t)_bodySize);
|
||||||
|
|
||||||
|
// expose the body in its immutable form
|
||||||
|
_body = _mutableBody;
|
||||||
|
|
||||||
|
// store the initial data
|
||||||
|
_filled = std::min((size_t)size, (size_t)_bodySize);
|
||||||
|
memcpy(_mutableBody, buffer, _filled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we're done
|
||||||
|
return _filled >= _bodySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param exchange
|
||||||
|
* @param routingKey
|
||||||
|
*/
|
||||||
|
Message(std::string exchange, std::string routingkey) :
|
||||||
|
Envelope(nullptr, 0), _exchange(std::move(exchange)), _routingkey(std::move(routingkey))
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disabled copy constructor
|
||||||
|
* @param message the message to copy
|
||||||
|
*/
|
||||||
|
Message(const Message &message) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Message()
|
||||||
|
{
|
||||||
|
if (_mutableBody) free(_mutableBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange to which it was originally published
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const std::string &exchange() const
|
||||||
|
{
|
||||||
|
// expose member
|
||||||
|
return _exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The routing key that was originally used
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const std::string &routingkey() const
|
||||||
|
{
|
||||||
|
// expose member
|
||||||
|
return _routingkey;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
402
builder/libs/AMQP-CPP/include/amqpcpp/metadata.h
Normal file
402
builder/libs/AMQP-CPP/include/amqpcpp/metadata.h
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
/**
|
||||||
|
* MetaData.h
|
||||||
|
*
|
||||||
|
* With every published message a set of meta data is passed to. This class
|
||||||
|
* holds all that meta data.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "booleanset.h"
|
||||||
|
#include "stringfield.h"
|
||||||
|
#include "table.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class MetaData
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* First set of booleans
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _bools1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second set of booleans
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _bools2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME content type
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _contentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME content encoding
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _contentEncoding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message header field table
|
||||||
|
* @var Table
|
||||||
|
*/
|
||||||
|
Table _headers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delivery mode (non-persistent (1) or persistent (2))
|
||||||
|
* @var UOctet
|
||||||
|
*/
|
||||||
|
UOctet _deliveryMode = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean whether field was sent to us
|
||||||
|
* @var UOctet
|
||||||
|
*/
|
||||||
|
UOctet _priority = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* application correlation identifier
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _correlationID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* address to reply to
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _replyTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message expiration identifier
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _expiration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* application message identifier
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _messageID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message timestamp
|
||||||
|
* @var Timestamp
|
||||||
|
*/
|
||||||
|
Timestamp _timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message type name
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _typeName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creating user id
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _userID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creating application id
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _appID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated cluster ID
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _clusterID;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for empty meta data. Can be useful when user-space wants to preserve all meta-data
|
||||||
|
*/
|
||||||
|
MetaData() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read incoming frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
MetaData(InBuffer &frame) :
|
||||||
|
_bools1(frame),
|
||||||
|
_bools2(frame)
|
||||||
|
{
|
||||||
|
// only copy the properties that were sent
|
||||||
|
if (hasContentType()) _contentType = ShortString(frame);
|
||||||
|
if (hasContentEncoding()) _contentEncoding = ShortString(frame);
|
||||||
|
if (hasHeaders()) _headers = Table(frame);
|
||||||
|
if (hasDeliveryMode()) _deliveryMode = UOctet(frame);
|
||||||
|
if (hasPriority()) _priority = UOctet(frame);
|
||||||
|
if (hasCorrelationID()) _correlationID = ShortString(frame);
|
||||||
|
if (hasReplyTo()) _replyTo = ShortString(frame);
|
||||||
|
if (hasExpiration()) _expiration = ShortString(frame);
|
||||||
|
if (hasMessageID()) _messageID = ShortString(frame);
|
||||||
|
if (hasTimestamp()) _timestamp = Timestamp(frame);
|
||||||
|
if (hasTypeName()) _typeName = ShortString(frame);
|
||||||
|
if (hasUserID()) _userID = ShortString(frame);
|
||||||
|
if (hasAppID()) _appID = ShortString(frame);
|
||||||
|
if (hasClusterID()) _clusterID = ShortString(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~MetaData() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set all meta data
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
void set(const MetaData &data)
|
||||||
|
{
|
||||||
|
// simply copy all fields
|
||||||
|
_bools1 = data._bools1;
|
||||||
|
_bools2 = data._bools2;
|
||||||
|
_contentType = data._contentType;
|
||||||
|
_contentEncoding = data._contentEncoding;
|
||||||
|
_headers = data._headers;
|
||||||
|
_deliveryMode = data._deliveryMode;
|
||||||
|
_priority = data._priority;
|
||||||
|
_correlationID = data._correlationID;
|
||||||
|
_replyTo = data._replyTo;
|
||||||
|
_expiration = data._expiration;
|
||||||
|
_messageID = data._messageID;
|
||||||
|
_timestamp = data._timestamp;
|
||||||
|
_typeName = data._typeName;
|
||||||
|
_userID = data._userID;
|
||||||
|
_appID = data._appID;
|
||||||
|
_clusterID = data._clusterID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a certain field is set
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool hasExpiration () const { return _bools1.get(0); }
|
||||||
|
bool hasReplyTo () const { return _bools1.get(1); }
|
||||||
|
bool hasCorrelationID () const { return _bools1.get(2); }
|
||||||
|
bool hasPriority () const { return _bools1.get(3); }
|
||||||
|
bool hasDeliveryMode () const { return _bools1.get(4); }
|
||||||
|
bool hasHeaders () const { return _bools1.get(5); }
|
||||||
|
bool hasContentEncoding () const { return _bools1.get(6); }
|
||||||
|
bool hasContentType () const { return _bools1.get(7); }
|
||||||
|
bool hasClusterID () const { return _bools2.get(2); }
|
||||||
|
bool hasAppID () const { return _bools2.get(3); }
|
||||||
|
bool hasUserID () const { return _bools2.get(4); }
|
||||||
|
bool hasTypeName () const { return _bools2.get(5); }
|
||||||
|
bool hasTimestamp () const { return _bools2.get(6); }
|
||||||
|
bool hasMessageID () const { return _bools2.get(7); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the various supported fields
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
void setExpiration (const std::string &value) { _expiration = value; _bools1.set(0,true); }
|
||||||
|
void setReplyTo (const std::string &value) { _replyTo = value; _bools1.set(1,true); }
|
||||||
|
void setCorrelationID (const std::string &value) { _correlationID = value; _bools1.set(2,true); }
|
||||||
|
void setPriority (uint8_t value) { _priority = value; _bools1.set(3,true); }
|
||||||
|
void setDeliveryMode (uint8_t value) { _deliveryMode = value; _bools1.set(4,true); }
|
||||||
|
void setHeaders (const Table &value) { _headers = value; _bools1.set(5,true); }
|
||||||
|
void setContentEncoding (const std::string &value) { _contentEncoding = value; _bools1.set(6,true); }
|
||||||
|
void setContentType (const std::string &value) { _contentType = value; _bools1.set(7,true); }
|
||||||
|
void setClusterID (const std::string &value) { _clusterID = value; _bools2.set(2,true); }
|
||||||
|
void setAppID (const std::string &value) { _appID = value; _bools2.set(3,true); }
|
||||||
|
void setUserID (const std::string &value) { _userID = value; _bools2.set(4,true); }
|
||||||
|
void setTypeName (const std::string &value) { _typeName = value; _bools2.set(5,true); }
|
||||||
|
void setTimestamp (uint64_t value) { _timestamp = value; _bools2.set(6,true); }
|
||||||
|
void setMessageID (const std::string &value) { _messageID = value; _bools2.set(7,true); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the various supported fields using r-value references
|
||||||
|
* @param value moveable value
|
||||||
|
*/
|
||||||
|
void setExpiration (std::string &&value) { _expiration = std::move(value); _bools1.set(0,true); }
|
||||||
|
void setReplyTo (std::string &&value) { _replyTo = std::move(value); _bools1.set(1,true); }
|
||||||
|
void setCorrelationID (std::string &&value) { _correlationID = std::move(value); _bools1.set(2,true); }
|
||||||
|
void setHeaders (Table &&value) { _headers = std::move(value); _bools1.set(5,true); }
|
||||||
|
void setContentEncoding (std::string &&value) { _contentEncoding = std::move(value); _bools1.set(6,true); }
|
||||||
|
void setContentType (std::string &&value) { _contentType = std::move(value); _bools1.set(7,true); }
|
||||||
|
void setClusterID (std::string &&value) { _clusterID = std::move(value); _bools2.set(2,true); }
|
||||||
|
void setAppID (std::string &&value) { _appID = std::move(value); _bools2.set(3,true); }
|
||||||
|
void setUserID (std::string &&value) { _userID = std::move(value); _bools2.set(4,true); }
|
||||||
|
void setTypeName (std::string &&value) { _typeName = std::move(value); _bools2.set(5,true); }
|
||||||
|
void setMessageID (std::string &&value) { _messageID = std::move(value); _bools2.set(7,true); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the various supported fields using data buffers
|
||||||
|
* @param value data buffer
|
||||||
|
* @param size size of the buffer
|
||||||
|
*/
|
||||||
|
void setExpiration (const char *value, size_t size) { _expiration.assign(value, size); _bools1.set(0,true); }
|
||||||
|
void setReplyTo (const char *value, size_t size) { _replyTo.assign(value, size); _bools1.set(1,true); }
|
||||||
|
void setCorrelationID (const char *value, size_t size) { _correlationID.assign(value, size); _bools1.set(2,true); }
|
||||||
|
void setContentEncoding (const char *value, size_t size) { _contentEncoding.assign(value, size); _bools1.set(6,true); }
|
||||||
|
void setContentType (const char *value, size_t size) { _contentType.assign(value, size); _bools1.set(7,true); }
|
||||||
|
void setClusterID (const char *value, size_t size) { _clusterID.assign(value, size); _bools2.set(2,true); }
|
||||||
|
void setAppID (const char *value, size_t size) { _appID.assign(value, size); _bools2.set(3,true); }
|
||||||
|
void setUserID (const char *value, size_t size) { _userID.assign(value, size); _bools2.set(4,true); }
|
||||||
|
void setTypeName (const char *value, size_t size) { _typeName.assign(value, size); _bools2.set(5,true); }
|
||||||
|
void setMessageID (const char *value, size_t size) { _messageID.assign(value, size); _bools2.set(7,true); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the various supported fields using c strings
|
||||||
|
* @param value data buffer
|
||||||
|
*/
|
||||||
|
void setExpiration (const char *value) { _expiration.assign(value); _bools1.set(0,true); }
|
||||||
|
void setReplyTo (const char *value) { _replyTo.assign(value); _bools1.set(1,true); }
|
||||||
|
void setCorrelationID (const char *value) { _correlationID.assign(value); _bools1.set(2,true); }
|
||||||
|
void setContentEncoding (const char *value) { _contentEncoding.assign(value); _bools1.set(6,true); }
|
||||||
|
void setContentType (const char *value) { _contentType.assign(value); _bools1.set(7,true); }
|
||||||
|
void setClusterID (const char *value) { _clusterID.assign(value); _bools2.set(2,true); }
|
||||||
|
void setAppID (const char *value) { _appID.assign(value); _bools2.set(3,true); }
|
||||||
|
void setUserID (const char *value) { _userID.assign(value); _bools2.set(4,true); }
|
||||||
|
void setTypeName (const char *value) { _typeName.assign(value); _bools2.set(5,true); }
|
||||||
|
void setMessageID (const char *value) { _messageID.assign(value); _bools2.set(7,true); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods to remove properties from the header
|
||||||
|
*/
|
||||||
|
void removeExpiration () { _expiration .clear(); _bools1.set(0,false); }
|
||||||
|
void removeReplyTo () { _replyTo .clear(); _bools1.set(1,false); }
|
||||||
|
void removeCorrelationID () { _correlationID .clear(); _bools1.set(2,false); }
|
||||||
|
void removePriority () { _priority .clear(); _bools1.set(3,false); }
|
||||||
|
void removeDeliveryMode () { _deliveryMode .clear(); _bools1.set(4,false); }
|
||||||
|
void removeHeaders () { _headers .clear(); _bools1.set(5,false); }
|
||||||
|
void removeContentEncoding () { _contentEncoding.clear(); _bools1.set(6,false); }
|
||||||
|
void removeContentType () { _contentType .clear(); _bools1.set(7,false); }
|
||||||
|
void removeClusterID () { _clusterID .clear(); _bools2.set(2,false); }
|
||||||
|
void removeAppID () { _appID .clear(); _bools2.set(3,false); }
|
||||||
|
void removeUserID () { _userID .clear(); _bools2.set(4,false); }
|
||||||
|
void removeTypeName () { _typeName .clear(); _bools2.set(5,false); }
|
||||||
|
void removeTimestamp () { _timestamp .clear(); _bools2.set(6,false); }
|
||||||
|
void removeMessageID () { _messageID .clear(); _bools2.set(7,false); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the fields
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string &expiration () const { return _expiration; }
|
||||||
|
const std::string &replyTo () const { return _replyTo; }
|
||||||
|
const std::string &correlationID () const { return _correlationID; }
|
||||||
|
uint8_t priority () const { return _priority; }
|
||||||
|
uint8_t deliveryMode () const { return _deliveryMode; }
|
||||||
|
const Table &headers () const { return _headers; }
|
||||||
|
const std::string &contentEncoding() const { return _contentEncoding; }
|
||||||
|
const std::string &contentType () const { return _contentType; }
|
||||||
|
const std::string &clusterID () const { return _clusterID; }
|
||||||
|
const std::string &appID () const { return _appID; }
|
||||||
|
const std::string &userID () const { return _userID; }
|
||||||
|
const std::string &typeName () const { return _typeName; }
|
||||||
|
uint64_t timestamp () const { return _timestamp; }
|
||||||
|
const std::string &messageID () const { return _messageID; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a message with persistent storage
|
||||||
|
* This is an alias for retrieving the delivery mode and checking if it is set to 2
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool persistent() const
|
||||||
|
{
|
||||||
|
return hasDeliveryMode() && deliveryMode() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether storage should be persistent or not
|
||||||
|
* @param bool
|
||||||
|
*/
|
||||||
|
void setPersistent(bool value = true)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
// simply set the delivery mode
|
||||||
|
setDeliveryMode(2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we remove the field from the header
|
||||||
|
_deliveryMode = 0;
|
||||||
|
_bools1.set(4,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total size
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t size() const
|
||||||
|
{
|
||||||
|
// the result (2 for the two boolean sets)
|
||||||
|
uint32_t result = 2;
|
||||||
|
|
||||||
|
if (hasExpiration()) result += (uint32_t)_expiration.size();
|
||||||
|
if (hasReplyTo()) result += (uint32_t)_replyTo.size();
|
||||||
|
if (hasCorrelationID()) result += (uint32_t)_correlationID.size();
|
||||||
|
if (hasPriority()) result += (uint32_t)_priority.size();
|
||||||
|
if (hasDeliveryMode()) result += (uint32_t)_deliveryMode.size();
|
||||||
|
if (hasHeaders()) result += (uint32_t)_headers.size();
|
||||||
|
if (hasContentEncoding()) result += (uint32_t)_contentEncoding.size();
|
||||||
|
if (hasContentType()) result += (uint32_t)_contentType.size();
|
||||||
|
if (hasClusterID()) result += (uint32_t)_clusterID.size();
|
||||||
|
if (hasAppID()) result += (uint32_t)_appID.size();
|
||||||
|
if (hasUserID()) result += (uint32_t)_userID.size();
|
||||||
|
if (hasTypeName()) result += (uint32_t)_typeName.size();
|
||||||
|
if (hasTimestamp()) result += (uint32_t)_timestamp.size();
|
||||||
|
if (hasMessageID()) result += (uint32_t)_messageID.size();
|
||||||
|
|
||||||
|
// done
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill an output buffer
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
void fill(OutBuffer &buffer) const
|
||||||
|
{
|
||||||
|
// the two boolean sets are always present
|
||||||
|
_bools1.fill(buffer);
|
||||||
|
_bools2.fill(buffer);
|
||||||
|
|
||||||
|
// only copy the properties that were sent
|
||||||
|
if (hasContentType()) _contentType.fill(buffer);
|
||||||
|
if (hasContentEncoding()) _contentEncoding.fill(buffer);
|
||||||
|
if (hasHeaders()) _headers.fill(buffer);
|
||||||
|
if (hasDeliveryMode()) _deliveryMode.fill(buffer);
|
||||||
|
if (hasPriority()) _priority.fill(buffer);
|
||||||
|
if (hasCorrelationID()) _correlationID.fill(buffer);
|
||||||
|
if (hasReplyTo()) _replyTo.fill(buffer);
|
||||||
|
if (hasExpiration()) _expiration.fill(buffer);
|
||||||
|
if (hasMessageID()) _messageID.fill(buffer);
|
||||||
|
if (hasTimestamp()) _timestamp.fill(buffer);
|
||||||
|
if (hasTypeName()) _typeName.fill(buffer);
|
||||||
|
if (hasUserID()) _userID.fill(buffer);
|
||||||
|
if (hasAppID()) _appID.fill(buffer);
|
||||||
|
if (hasClusterID()) _clusterID.fill(buffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
138
builder/libs/AMQP-CPP/include/amqpcpp/monitor.h
Normal file
138
builder/libs/AMQP-CPP/include/amqpcpp/monitor.h
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/**
|
||||||
|
* Monitor.h
|
||||||
|
*
|
||||||
|
* A monitor object monitors if the connection is still valid. When the
|
||||||
|
* connection is parsing incoming data, it calls the user handler for each
|
||||||
|
* incoming frame. However, it is unknown what this handler is going to do,
|
||||||
|
* it could for example decide to destruct the connection object. In that
|
||||||
|
* case the connection object should stop further handling the data. This
|
||||||
|
* monitor class is used to check if the connection has been destructed.
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "watchable.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Monitor
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The object being watched
|
||||||
|
* @var Watchable
|
||||||
|
*/
|
||||||
|
Watchable *_watchable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate the object
|
||||||
|
*/
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_watchable = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param watchable
|
||||||
|
*/
|
||||||
|
Monitor(Watchable *watchable) : _watchable(watchable)
|
||||||
|
{
|
||||||
|
// register with the watchable
|
||||||
|
_watchable->add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param monitor
|
||||||
|
*/
|
||||||
|
Monitor(const Monitor &monitor) : _watchable(monitor._watchable)
|
||||||
|
{
|
||||||
|
// register with the watchable
|
||||||
|
if (_watchable) _watchable->add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator
|
||||||
|
* @param monitor
|
||||||
|
*/
|
||||||
|
Monitor& operator= (const Monitor &monitor)
|
||||||
|
{
|
||||||
|
// remove from watchable
|
||||||
|
if (_watchable) _watchable->remove(this);
|
||||||
|
|
||||||
|
// replace watchable
|
||||||
|
_watchable = monitor._watchable;
|
||||||
|
|
||||||
|
// register with the watchable
|
||||||
|
if (_watchable) _watchable->add(this);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Monitor()
|
||||||
|
{
|
||||||
|
// remove from watchable
|
||||||
|
if (_watchable) _watchable->remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to boolean: is object in valid state?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
operator bool () const
|
||||||
|
{
|
||||||
|
return _watchable != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate operator: is the object in an invalid state?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool operator! () const
|
||||||
|
{
|
||||||
|
return _watchable == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the object is valid
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool valid() const
|
||||||
|
{
|
||||||
|
return _watchable != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The watchable can access private data
|
||||||
|
*/
|
||||||
|
friend class Watchable;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
228
builder/libs/AMQP-CPP/include/amqpcpp/numericfield.h
Normal file
228
builder/libs/AMQP-CPP/include/amqpcpp/numericfield.h
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/**
|
||||||
|
* Numeric field types for AMQP
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#include "inbuffer.h"
|
||||||
|
#include "outbuffer.h"
|
||||||
|
#include "field.h"
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template for numeric field types
|
||||||
|
*/
|
||||||
|
template<
|
||||||
|
typename T,
|
||||||
|
char F,
|
||||||
|
typename = typename std::enable_if<std::is_arithmetic<T>::value, T>
|
||||||
|
>
|
||||||
|
class NumericField : public Field
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Field value
|
||||||
|
*/
|
||||||
|
T _value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Type = T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor, assign 0
|
||||||
|
*/
|
||||||
|
NumericField() : _value(0) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct numeric field from
|
||||||
|
* one of numeric types
|
||||||
|
*
|
||||||
|
* @param value field value
|
||||||
|
*/
|
||||||
|
NumericField(T value) : _value(value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse based on incoming buffer
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
NumericField(InBuffer &frame)
|
||||||
|
{
|
||||||
|
// The Microsoft Visual Studio compiler thinks that there is an issue
|
||||||
|
// with the following code, so we temporarily disable a specific warning
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (std::is_same<int8_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt8();
|
||||||
|
else if (std::is_same<int16_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt16();
|
||||||
|
else if (std::is_same<int32_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt32();
|
||||||
|
else if (std::is_same<int64_t, typename std::remove_cv<T>::type>::value) _value = frame.nextInt64();
|
||||||
|
else if (std::is_same<uint8_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint8();
|
||||||
|
else if (std::is_same<uint16_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint16();
|
||||||
|
else if (std::is_same<uint32_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint32();
|
||||||
|
else if (std::is_same<uint64_t, typename std::remove_cv<T>::type>::value) _value = frame.nextUint64();
|
||||||
|
else if (std::is_same<float, typename std::remove_cv<T>::type>::value) _value = frame.nextFloat();
|
||||||
|
else if (std::is_same<double, typename std::remove_cv<T>::type>::value) _value = frame.nextDouble();
|
||||||
|
|
||||||
|
// re-enable the warning
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning( pop )
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~NumericField() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of this object
|
||||||
|
* @return unique_ptr
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
// create a new copy of ourselves and return it
|
||||||
|
return std::unique_ptr<Field>(new NumericField(_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
*
|
||||||
|
* @param value new value for field
|
||||||
|
* @return NumericField
|
||||||
|
*/
|
||||||
|
NumericField& operator=(T value)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the field
|
||||||
|
* @return NumericField
|
||||||
|
*/
|
||||||
|
NumericField& clear()
|
||||||
|
{
|
||||||
|
_value = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
operator uint8_t () const override { return (uint8_t)_value; }
|
||||||
|
operator uint16_t() const override { return (uint16_t)_value; }
|
||||||
|
operator uint32_t() const override { return (uint32_t)_value; }
|
||||||
|
operator uint64_t() const override { return (uint64_t)_value; }
|
||||||
|
operator int8_t () const override { return (int8_t)_value; }
|
||||||
|
operator int16_t () const override { return (int16_t)_value; }
|
||||||
|
operator int32_t () const override { return (int32_t)_value; }
|
||||||
|
operator int64_t () const override { return (int64_t)_value; }
|
||||||
|
operator float () const override { return (float)_value; }
|
||||||
|
operator double () const override { return (double)_value; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
T value() const
|
||||||
|
{
|
||||||
|
// return internal value
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are an integer field
|
||||||
|
*
|
||||||
|
* @return true, because we are an integer
|
||||||
|
*/
|
||||||
|
bool isInteger() const override
|
||||||
|
{
|
||||||
|
return std::is_integral<T>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override
|
||||||
|
{
|
||||||
|
// numeric types have no extra storage requirements
|
||||||
|
return sizeof(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer OutBuffer to write to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// store converted value
|
||||||
|
T value = _value;
|
||||||
|
|
||||||
|
// write to buffer
|
||||||
|
// adding a value takes care of host to network byte order
|
||||||
|
buffer.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// show
|
||||||
|
stream << "numeric(" << value() << ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete numeric types for AMQP
|
||||||
|
*/
|
||||||
|
typedef NumericField<int8_t, 'b'> Octet;
|
||||||
|
typedef NumericField<uint8_t, 'B'> UOctet;
|
||||||
|
typedef NumericField<int16_t, 'U'> Short;
|
||||||
|
typedef NumericField<uint16_t, 'u'> UShort;
|
||||||
|
typedef NumericField<int32_t, 'I'> Long;
|
||||||
|
typedef NumericField<uint32_t, 'i'> ULong;
|
||||||
|
typedef NumericField<int64_t, 'L'> LongLong;
|
||||||
|
typedef NumericField<uint64_t, 'l'> ULongLong;
|
||||||
|
typedef NumericField<uint64_t, 'T'> Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete floating-point types for AMQP
|
||||||
|
*/
|
||||||
|
typedef NumericField<float, 'f'> Float;
|
||||||
|
typedef NumericField<double, 'd'> Double;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
37
builder/libs/AMQP-CPP/include/amqpcpp/openssl.h
Normal file
37
builder/libs/AMQP-CPP/include/amqpcpp/openssl.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* OpenSSL.h
|
||||||
|
*
|
||||||
|
* Function to set openssl features
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To make secure "amqps://" connections, AMQP-CPP relies on functions from the
|
||||||
|
* openssl library. It your application is dynamically linked to openssl (because
|
||||||
|
* it was compiled with the "-lssl" flag), this works flawlessly because AMQPCPP
|
||||||
|
* can then locate the openssl symbols in its own project space. However, if the
|
||||||
|
* openssl library was not linked, you either cannot use amqps:// connections,
|
||||||
|
* or you have to supply a handle to the openssl library yourself, using the
|
||||||
|
* following method.
|
||||||
|
*
|
||||||
|
* @param handle Handle returned by dlopen() that has access to openssl
|
||||||
|
*/
|
||||||
|
void openssl(void *handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
192
builder/libs/AMQP-CPP/include/amqpcpp/outbuffer.h
Normal file
192
builder/libs/AMQP-CPP/include/amqpcpp/outbuffer.h
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
* OutBuffer.h
|
||||||
|
*
|
||||||
|
* This is a utility class for writing various data types to a binary
|
||||||
|
* string, and converting the values to network byte order
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include "endian.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class OutBuffer
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The method that adds the actual data
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
virtual void append(const void *data, size_t size) = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~OutBuffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a binary buffer to the buffer
|
||||||
|
* @param string char* to the string
|
||||||
|
* @param size size of string
|
||||||
|
*/
|
||||||
|
void add(const char *string, size_t size)
|
||||||
|
{
|
||||||
|
// append data
|
||||||
|
append(string, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a binary buffer to the buffer
|
||||||
|
* @param string char* to the string
|
||||||
|
* @param size size of string
|
||||||
|
*/
|
||||||
|
void add(const std::string &string)
|
||||||
|
{
|
||||||
|
// add data
|
||||||
|
append(string.c_str(), string.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a uint8_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(uint8_t value)
|
||||||
|
{
|
||||||
|
// append one byte
|
||||||
|
append(&value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a uint16_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(uint16_t value)
|
||||||
|
{
|
||||||
|
// convert to network byte order
|
||||||
|
uint16_t v = htobe16(value);
|
||||||
|
|
||||||
|
// append the data
|
||||||
|
append(&v, sizeof(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a uint32_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(uint32_t value)
|
||||||
|
{
|
||||||
|
// convert to network byte order
|
||||||
|
uint32_t v = htobe32(value);
|
||||||
|
|
||||||
|
// append the data
|
||||||
|
append(&v, sizeof(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a uint64_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(uint64_t value)
|
||||||
|
{
|
||||||
|
// convert to network byte order
|
||||||
|
uint64_t v = htobe64(value);
|
||||||
|
|
||||||
|
// append the data
|
||||||
|
append(&v, sizeof(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a int8_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(int8_t value)
|
||||||
|
{
|
||||||
|
// append the data
|
||||||
|
append(&value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a int16_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(int16_t value)
|
||||||
|
{
|
||||||
|
// convert to network byte order
|
||||||
|
int16_t v = htobe16(value);
|
||||||
|
|
||||||
|
// append the data
|
||||||
|
append(&v, sizeof(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a int32_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(int32_t value)
|
||||||
|
{
|
||||||
|
// convert into network byte order
|
||||||
|
int32_t v = htobe32(value);
|
||||||
|
|
||||||
|
// append the data
|
||||||
|
append(&v, sizeof(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a int64_t to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(int64_t value)
|
||||||
|
{
|
||||||
|
// copy into the buffer
|
||||||
|
int64_t v = htobe64(value);
|
||||||
|
|
||||||
|
// append the data
|
||||||
|
append(&v, sizeof(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a float to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(float value)
|
||||||
|
{
|
||||||
|
// append the data
|
||||||
|
append(&value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a double to the buffer
|
||||||
|
* @param value value to add
|
||||||
|
*/
|
||||||
|
void add(double value)
|
||||||
|
{
|
||||||
|
// append the data
|
||||||
|
append(&value, sizeof(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
42
builder/libs/AMQP-CPP/include/amqpcpp/protocolexception.h
Normal file
42
builder/libs/AMQP-CPP/include/amqpcpp/protocolexception.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* ProtocolException.h
|
||||||
|
*
|
||||||
|
* This exception is thrown internally in the library when invalid data is
|
||||||
|
* received from the server. The best remedy is to close the connection
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "exception.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class ProtocolException : public Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param what
|
||||||
|
*/
|
||||||
|
explicit ProtocolException(const std::string &what) : Exception(what) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
287
builder/libs/AMQP-CPP/include/amqpcpp/reliable.h
Normal file
287
builder/libs/AMQP-CPP/include/amqpcpp/reliable.h
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/**
|
||||||
|
* Reliable.h
|
||||||
|
*
|
||||||
|
* A channel wrapper based on AMQP::Tagger that allows message callbacks to be installed
|
||||||
|
* on the publish-confirms, to be called when they a confirmation is received from RabbitMQ.
|
||||||
|
*
|
||||||
|
* You can also change the base class and use Reliable<Throttle> if you not only
|
||||||
|
* want to be notified about the publish-confirms, but want to use it for automatic
|
||||||
|
* throttling at the same time.
|
||||||
|
*
|
||||||
|
* @author Michael van der Werve <michael.vanderwerve@mailerq.com>
|
||||||
|
* @copyright 2020 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes
|
||||||
|
*/
|
||||||
|
#include "deferredpublish.h"
|
||||||
|
#include "tagger.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespaces
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
template <typename BASE=Tagger>
|
||||||
|
class Reliable : public BASE
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// make sure it is a proper channel
|
||||||
|
static_assert(std::is_base_of<Tagger, BASE>::value, "base should be derived from a confirmed channel.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of open deliverytags. We want a normal set (not unordered_set) because
|
||||||
|
* removal will be cheaper for whole ranges.
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
std::map<size_t, std::shared_ptr<DeferredPublish>> _handlers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the deliverytag(s) are acked
|
||||||
|
* @param deliveryTag
|
||||||
|
* @param multiple
|
||||||
|
*/
|
||||||
|
void onAck(uint64_t deliveryTag, bool multiple) override
|
||||||
|
{
|
||||||
|
// monitor the object, watching for destruction since these ack/nack handlers
|
||||||
|
// could destruct the object
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// single element is simple
|
||||||
|
if (!multiple)
|
||||||
|
{
|
||||||
|
// find the element
|
||||||
|
auto iter = _handlers.find(deliveryTag);
|
||||||
|
|
||||||
|
// we did not find it (this should not be possible, unless somebody explicitly called)
|
||||||
|
// the base-class publish methods for some reason.
|
||||||
|
if (iter == _handlers.end()) return BASE::onAck(deliveryTag, multiple);
|
||||||
|
|
||||||
|
// get the handler (we store it first so that we can remove it)
|
||||||
|
auto handler = iter->second;
|
||||||
|
|
||||||
|
// erase it from the map (we remove it before the call, because the callback might update
|
||||||
|
// the _handlers and invalidate the iterator)
|
||||||
|
_handlers.erase(iter);
|
||||||
|
|
||||||
|
// call the ack handler
|
||||||
|
handler->reportAck();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// do multiple at once
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// keep looping for as long as the object is in a valid state
|
||||||
|
while (monitor && !_handlers.empty())
|
||||||
|
{
|
||||||
|
// get the first handler
|
||||||
|
auto iter = _handlers.begin();
|
||||||
|
|
||||||
|
// make sure this is the right deliverytag, if we've passed it we leap out
|
||||||
|
if (iter->first > deliveryTag) break;
|
||||||
|
|
||||||
|
// get the handler
|
||||||
|
auto handler = iter->second;
|
||||||
|
|
||||||
|
// remove it from the map (before we make a call to userspace, so that user space
|
||||||
|
// can add even more handlers, without invalidating iterators)
|
||||||
|
_handlers.erase(iter);
|
||||||
|
|
||||||
|
// call the ack handler
|
||||||
|
handler->reportAck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the object is still valid
|
||||||
|
if (!monitor) return;
|
||||||
|
|
||||||
|
// call base handler as well
|
||||||
|
BASE::onAck(deliveryTag, multiple);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the deliverytag(s) are nacked
|
||||||
|
* @param deliveryTag
|
||||||
|
* @param multiple
|
||||||
|
*/
|
||||||
|
void onNack(uint64_t deliveryTag, bool multiple) override
|
||||||
|
{
|
||||||
|
// monitor the object, watching for destruction since these ack/nack handlers
|
||||||
|
// could destruct the object
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// single element is simple
|
||||||
|
if (!multiple)
|
||||||
|
{
|
||||||
|
// find the element
|
||||||
|
auto iter = _handlers.find(deliveryTag);
|
||||||
|
|
||||||
|
// we did not find it (this should not be possible, unless somebody explicitly called)
|
||||||
|
// the base-class publish methods for some reason.
|
||||||
|
if (iter == _handlers.end()) return BASE::onNack(deliveryTag, multiple);
|
||||||
|
|
||||||
|
// get the handler (we store it first so that we can remove it)
|
||||||
|
auto handler = iter->second;
|
||||||
|
|
||||||
|
// erase it from the map (we remove it before the call, because the callback might update
|
||||||
|
// the _handlers and invalidate the iterator)
|
||||||
|
_handlers.erase(iter);
|
||||||
|
|
||||||
|
// call the ack handler
|
||||||
|
handler->reportNack();
|
||||||
|
}
|
||||||
|
|
||||||
|
// nack multiple elements
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// keep looping for as long as the object is in a valid state
|
||||||
|
while (monitor && !_handlers.empty())
|
||||||
|
{
|
||||||
|
// get the first handler
|
||||||
|
auto iter = _handlers.begin();
|
||||||
|
|
||||||
|
// make sure this is the right deliverytag, if we've passed it we leap out
|
||||||
|
if (iter->first > deliveryTag) break;
|
||||||
|
|
||||||
|
// get the handler
|
||||||
|
auto handler = iter->second;
|
||||||
|
|
||||||
|
// remove it from the map (before we make a call to userspace, so that user space
|
||||||
|
// can add even more handlers, without invalidating iterators)
|
||||||
|
_handlers.erase(iter);
|
||||||
|
|
||||||
|
// call the ack handler
|
||||||
|
handler->reportNack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the object is no longer valid, return
|
||||||
|
if (!monitor) return;
|
||||||
|
|
||||||
|
// call the base handler
|
||||||
|
BASE::onNack(deliveryTag, multiple);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called to report an error
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void reportError(const char *message) override
|
||||||
|
{
|
||||||
|
// monitor the object, watching for destruction since these ack/nack handlers
|
||||||
|
// could destruct the object
|
||||||
|
Monitor monitor(this);
|
||||||
|
|
||||||
|
// move the handlers out
|
||||||
|
auto handlers = std::move(_handlers);
|
||||||
|
|
||||||
|
// iterate over all the messages
|
||||||
|
// call the handlers
|
||||||
|
for (const auto &iter : handlers)
|
||||||
|
{
|
||||||
|
// call the handler
|
||||||
|
iter.second->reportError(message);
|
||||||
|
|
||||||
|
// if we were destructed in the meantime, we leap out
|
||||||
|
if (!monitor) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the monitor is no longer valid, leap out
|
||||||
|
if (!monitor) return;
|
||||||
|
|
||||||
|
// call the base handler
|
||||||
|
BASE::reportError(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param channel
|
||||||
|
* @param throttle
|
||||||
|
*/
|
||||||
|
template <typename ...Args>
|
||||||
|
Reliable(Args &&...args) : BASE(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted copy constructor, deleted move constructor
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Reliable(const Reliable &other) = delete;
|
||||||
|
Reliable(Reliable &&other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted copy assignment, deleted move assignment
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Reliable &operator=(const Reliable &other) = delete;
|
||||||
|
Reliable &operator=(Reliable &&other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Virtual destructor
|
||||||
|
*/
|
||||||
|
virtual ~Reliable() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to check how many messages are still unacked.
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t unacknowledged() const override { return _handlers.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a message to an exchange. See amqpcpp/channel.h for more details on the flags.
|
||||||
|
* Delays actual publishing depending on the publisher confirms sent by RabbitMQ.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange to publish to
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param envelope the full envelope to send
|
||||||
|
* @param message the message to send
|
||||||
|
* @param size size of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
DeferredPublish &publish(const std::string_view &exchange, const std::string_view &routingKey, const std::string_view &message, int flags = 0) { return publish(exchange, routingKey, Envelope(message.data(), message.size()), flags); }
|
||||||
|
DeferredPublish &publish(const std::string_view &exchange, const std::string_view &routingKey, const char *message, size_t size, int flags = 0) { return publish(exchange, routingKey, Envelope(message, size), flags); }
|
||||||
|
DeferredPublish &publish(const std::string_view &exchange, const std::string_view &routingKey, const char *message, int flags = 0) { return publish(exchange, routingKey, Envelope(message, strlen(message)), flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a message to an exchange. See amqpcpp/channel.h for more details on the flags.
|
||||||
|
* Delays actual publishing depending on the publisher confirms sent by RabbitMQ.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange to publish to
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param envelope the full envelope to send
|
||||||
|
* @param message the message to send
|
||||||
|
* @param size size of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
*/
|
||||||
|
DeferredPublish &publish(const std::string_view &exchange, const std::string_view &routingKey, const Envelope &envelope, int flags = 0)
|
||||||
|
{
|
||||||
|
// publish the entire thing, and remember if it failed at any point
|
||||||
|
uint64_t tag = BASE::publish(exchange, routingKey, envelope, flags);
|
||||||
|
|
||||||
|
// create the publish deferred object, if we got no tag we failed
|
||||||
|
auto handler = std::make_shared<DeferredPublish>(tag == 0);
|
||||||
|
|
||||||
|
// add it to the open handlers
|
||||||
|
_handlers[tag] = handler;
|
||||||
|
|
||||||
|
// return the dereferenced handler
|
||||||
|
return *handler;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespaces
|
||||||
|
*/
|
||||||
|
}
|
||||||
146
builder/libs/AMQP-CPP/include/amqpcpp/stack_ptr.h
Normal file
146
builder/libs/AMQP-CPP/include/amqpcpp/stack_ptr.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
* stack_ptr.h
|
||||||
|
*
|
||||||
|
* Implementation of an object that behaves like a
|
||||||
|
* smart pointer but is actually managed on the stack
|
||||||
|
*
|
||||||
|
* @copyright 2016 Copernica B.V.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack-based smart pointer
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class stack_ptr
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Storage for the object
|
||||||
|
* @var typename std::aligned_storage<sizeof(T), alignof(T)>::type
|
||||||
|
*/
|
||||||
|
typename std::aligned_storage<sizeof(T), alignof(T)>::type _data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the pointer initialized?
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
bool _initialized = false;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
stack_ptr() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy and moving is disabled
|
||||||
|
*
|
||||||
|
* @param that The stack_ptr we refuse to copy/move
|
||||||
|
*/
|
||||||
|
stack_ptr(const stack_ptr &that) = delete;
|
||||||
|
stack_ptr(stack_ptr &&that) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
~stack_ptr()
|
||||||
|
{
|
||||||
|
// reset the pointer
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the pointer
|
||||||
|
*/
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
// are we initialized?
|
||||||
|
if (!_initialized) return;
|
||||||
|
|
||||||
|
// destroy the object
|
||||||
|
reinterpret_cast<T*>(&_data)->~T();
|
||||||
|
|
||||||
|
// the object is not currently initialized
|
||||||
|
_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the object
|
||||||
|
*
|
||||||
|
* @param ... Zero or more constructor arguments for T
|
||||||
|
*/
|
||||||
|
template <typename... Arguments>
|
||||||
|
void construct(Arguments&&... parameters)
|
||||||
|
{
|
||||||
|
// first reset the current object
|
||||||
|
reset();
|
||||||
|
|
||||||
|
// initialize new object
|
||||||
|
new (&_data) T(std::forward<Arguments>(parameters)...);
|
||||||
|
|
||||||
|
// we are now initialized
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the object initialized?
|
||||||
|
*
|
||||||
|
* @return Are we currently managing an object?
|
||||||
|
*/
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
// are we initialized with an object?
|
||||||
|
return _initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a pointer to the object
|
||||||
|
*
|
||||||
|
* @return Pointer to the object or nullptr if no object is managed
|
||||||
|
*/
|
||||||
|
T *get() const
|
||||||
|
{
|
||||||
|
// do we have a managed object
|
||||||
|
if (!_initialized) return nullptr;
|
||||||
|
|
||||||
|
// return pointer to the managed object
|
||||||
|
return const_cast<T*>(reinterpret_cast<const T*>(&_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a reference to the object
|
||||||
|
*
|
||||||
|
* @return Reference to the object, undefined if no object is managed
|
||||||
|
*/
|
||||||
|
T &operator*() const
|
||||||
|
{
|
||||||
|
// dereference the pointer
|
||||||
|
return *operator->();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a pointer to the object
|
||||||
|
*
|
||||||
|
* @return Pointer to the object, undefined if no object is managed
|
||||||
|
*/
|
||||||
|
T *operator->() const
|
||||||
|
{
|
||||||
|
// return pointer to the managed object
|
||||||
|
return const_cast<T*>(reinterpret_cast<const T*>(&_data));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
309
builder/libs/AMQP-CPP/include/amqpcpp/stringfield.h
Normal file
309
builder/libs/AMQP-CPP/include/amqpcpp/stringfield.h
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/**
|
||||||
|
* String field types for amqp
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "field.h"
|
||||||
|
#include "outbuffer.h"
|
||||||
|
#include "numericfield.h"
|
||||||
|
#include "inbuffer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for string types
|
||||||
|
*/
|
||||||
|
template <typename T, char F>
|
||||||
|
class StringField : public Field
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Pointer to string data
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
std::string _data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initialize empty string
|
||||||
|
*/
|
||||||
|
StringField() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on a std::string
|
||||||
|
* @param value string value
|
||||||
|
*/
|
||||||
|
StringField(const std::string &value) : _data(value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on a std::string
|
||||||
|
* @param value string value
|
||||||
|
*/
|
||||||
|
StringField(const std::string_view &value) : _data(value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on a std::string
|
||||||
|
* @param value string value
|
||||||
|
*/
|
||||||
|
StringField(std::string &&value) : _data(std::move(value)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on a buffer
|
||||||
|
* @param buffer buffer value
|
||||||
|
* @param size size of the buffer
|
||||||
|
*/
|
||||||
|
StringField(const char *buffer, size_t size) : _data(buffer, size) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on a c-string
|
||||||
|
* @param buffer buffer value
|
||||||
|
*/
|
||||||
|
StringField(const char *buffer) : _data(buffer) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on received data
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
StringField(InBuffer &frame)
|
||||||
|
{
|
||||||
|
// get the size
|
||||||
|
T size(frame);
|
||||||
|
|
||||||
|
// allocate string
|
||||||
|
_data = std::string(frame.nextData(size.value()), (size_t) size.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up memory used
|
||||||
|
*/
|
||||||
|
virtual ~StringField() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of this object
|
||||||
|
* @return std::unique_ptr<Field>
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
// create a new copy of ourselves and return it
|
||||||
|
return std::unique_ptr<Field>(new StringField(_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value new value
|
||||||
|
*/
|
||||||
|
StringField& operator=(const std::string &value)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data = value;
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value new value
|
||||||
|
*/
|
||||||
|
StringField& operator=(std::string &&value)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data = std::move(value);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value new value
|
||||||
|
*/
|
||||||
|
StringField& operator=(const char *value)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data.assign(value);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value
|
||||||
|
* @return StringField
|
||||||
|
*/
|
||||||
|
StringField& assign(const std::string &value)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data = value;
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value new value
|
||||||
|
* @return StringField
|
||||||
|
*/
|
||||||
|
StringField& assign(std::string &&value)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data = std::move(value);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value new value
|
||||||
|
* @return StringField
|
||||||
|
*/
|
||||||
|
StringField& assign(const char *value)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data.assign(value);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new value
|
||||||
|
* @param value new value
|
||||||
|
* @return StringField
|
||||||
|
*/
|
||||||
|
StringField& assign(const char *value, size_t size)
|
||||||
|
{
|
||||||
|
// overwrite data
|
||||||
|
_data.assign(value, size);
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the field empty
|
||||||
|
* @return StringField
|
||||||
|
*/
|
||||||
|
StringField &clear()
|
||||||
|
{
|
||||||
|
// clear internal dta
|
||||||
|
_data.clear();
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override
|
||||||
|
{
|
||||||
|
// find out size of the size parameter
|
||||||
|
T size((typename T::Type)_data.size());
|
||||||
|
|
||||||
|
// size of the uint8 or uint32 + the actual string size
|
||||||
|
return size.size() + _data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
virtual operator const std::string& () const override
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& value() const
|
||||||
|
{
|
||||||
|
// get data
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the maximum allowed string length for this field
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
constexpr static size_t maxLength()
|
||||||
|
{
|
||||||
|
return T::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// create size
|
||||||
|
T size((typename T::Type)_data.size());
|
||||||
|
|
||||||
|
// first, write down the size of the string
|
||||||
|
size.fill(buffer);
|
||||||
|
|
||||||
|
// write down the string content
|
||||||
|
buffer.add(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
* @return char
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are a string
|
||||||
|
*
|
||||||
|
* @return true, because we are a string
|
||||||
|
*/
|
||||||
|
bool isString() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// show
|
||||||
|
stream << "string(" << value() << ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete string types for AMQP
|
||||||
|
*/
|
||||||
|
typedef StringField<UOctet, 's'> ShortString;
|
||||||
|
typedef StringField<ULong, 'S'> LongString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
304
builder/libs/AMQP-CPP/include/amqpcpp/table.h
Normal file
304
builder/libs/AMQP-CPP/include/amqpcpp/table.h
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
/**
|
||||||
|
* AMQP field table
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "field.h"
|
||||||
|
#include "fieldproxy.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AMQP field table
|
||||||
|
*/
|
||||||
|
class Table : public Field
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* We define a custom type for storing fields
|
||||||
|
* @typedef FieldMap
|
||||||
|
*/
|
||||||
|
typedef std::map<std::string, std::unique_ptr<Field> > FieldMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the fields
|
||||||
|
* @var FieldMap
|
||||||
|
*/
|
||||||
|
FieldMap _fields;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor that creates an empty table
|
||||||
|
*/
|
||||||
|
Table() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode the data from a received frame into a table
|
||||||
|
*
|
||||||
|
* @param frame received frame to decode
|
||||||
|
*/
|
||||||
|
Table(InBuffer &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param table
|
||||||
|
*/
|
||||||
|
Table(const Table &table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor
|
||||||
|
* @param table
|
||||||
|
*/
|
||||||
|
Table(Table &&table) : _fields(std::move(table._fields)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Table() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator
|
||||||
|
* @param table
|
||||||
|
* @return Table
|
||||||
|
*/
|
||||||
|
Table &operator=(const Table &table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move assignment operator
|
||||||
|
* @param table
|
||||||
|
* @return Table
|
||||||
|
*/
|
||||||
|
Table &operator=(Table &&table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all keys in the table
|
||||||
|
*
|
||||||
|
* @return Vector with all keys in the table
|
||||||
|
*/
|
||||||
|
std::vector<std::string> keys() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance on the heap of this object, identical to the object passed
|
||||||
|
* @return Field*
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
return std::unique_ptr<Table>(new Table(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a field
|
||||||
|
* @param name field name
|
||||||
|
* @param value field value
|
||||||
|
* @return Table
|
||||||
|
*/
|
||||||
|
Table &set(const std::string& name, const Field &value)
|
||||||
|
{
|
||||||
|
// copy to a new pointer and store it
|
||||||
|
_fields[name] = value.clone();
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aliases for setting values
|
||||||
|
* @param name
|
||||||
|
* @param value
|
||||||
|
* @return Table&
|
||||||
|
*/
|
||||||
|
Table &set(const std::string &name, bool value) { return set(name, BooleanSet(value)); }
|
||||||
|
Table &set(const std::string &name, uint8_t value) { return set(name, UOctet(value)); }
|
||||||
|
Table &set(const std::string &name, int8_t value) { return set(name, Octet(value)); }
|
||||||
|
Table &set(const std::string &name, uint16_t value) { return set(name, UShort(value)); }
|
||||||
|
Table &set(const std::string &name, int16_t value) { return set(name, Short(value)); }
|
||||||
|
Table &set(const std::string &name, uint32_t value) { return set(name, ULong(value)); }
|
||||||
|
Table &set(const std::string &name, int32_t value) { return set(name, Long(value)); }
|
||||||
|
Table &set(const std::string &name, uint64_t value) { return set(name, ULongLong(value)); }
|
||||||
|
Table &set(const std::string &name, int64_t value) { return set(name, LongLong(value)); }
|
||||||
|
Table &set(const std::string &name, const std::string &value) { return set(name, LongString(value)); }
|
||||||
|
Table &set(const std::string &name, const char *value) { return set(name, LongString(std::string(value))); }
|
||||||
|
Table &set(const std::string &name, std::nullptr_t) { return set(name, VoidField()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the entire table
|
||||||
|
* @return Table
|
||||||
|
*/
|
||||||
|
Table &clear()
|
||||||
|
{
|
||||||
|
_fields.clear();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a certain field set in the table
|
||||||
|
* @param name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool contains(const std::string &name) const
|
||||||
|
{
|
||||||
|
return _fields.find(name) != _fields.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field
|
||||||
|
*
|
||||||
|
* If the field does not exist, an empty string field is returned
|
||||||
|
*
|
||||||
|
* @param name field name
|
||||||
|
* @return the field value
|
||||||
|
*/
|
||||||
|
const Field &get(const std::string &name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field
|
||||||
|
*
|
||||||
|
* @param name field name
|
||||||
|
*/
|
||||||
|
AssociativeFieldProxy operator[](const std::string& name)
|
||||||
|
{
|
||||||
|
return AssociativeFieldProxy(this, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field
|
||||||
|
*
|
||||||
|
* @param name field name
|
||||||
|
*/
|
||||||
|
AssociativeFieldProxy operator[](const char *name)
|
||||||
|
{
|
||||||
|
return AssociativeFieldProxy(this, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a const field
|
||||||
|
*
|
||||||
|
* @param name field name
|
||||||
|
*/
|
||||||
|
const Field &operator[](const std::string& name) const
|
||||||
|
{
|
||||||
|
return get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a const field
|
||||||
|
*
|
||||||
|
* @param name field name
|
||||||
|
*/
|
||||||
|
const Field &operator[](const char *name) const
|
||||||
|
{
|
||||||
|
return get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return 'F';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are a table
|
||||||
|
*
|
||||||
|
* @return true, because we are a table
|
||||||
|
*/
|
||||||
|
bool isTable() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// prefix
|
||||||
|
stream << "table(";
|
||||||
|
|
||||||
|
// is this the first iteration
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
// loop through all members
|
||||||
|
for (auto &iter : _fields)
|
||||||
|
{
|
||||||
|
// split with comma
|
||||||
|
if (!first) stream << ",";
|
||||||
|
|
||||||
|
// show output
|
||||||
|
stream << iter.first << ":" << *iter.second;
|
||||||
|
|
||||||
|
// no longer first iter
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// postfix
|
||||||
|
stream << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to table.
|
||||||
|
*
|
||||||
|
* @note: This function may look silly and unnecessary. We are, after all, already
|
||||||
|
* a table. The whole reason we still have this function is that it is virtual
|
||||||
|
* and if we do not declare a cast to table on a pointer to base (i.e. Field)
|
||||||
|
* will return an empty field instead of the expected table.
|
||||||
|
*
|
||||||
|
* Yes, clang gets this wrong and gives incorrect warnings here. See
|
||||||
|
* https://llvm.org/bugs/show_bug.cgi?id=28263 for more information
|
||||||
|
*
|
||||||
|
* @return Ourselves
|
||||||
|
*/
|
||||||
|
virtual operator const Table& () const override
|
||||||
|
{
|
||||||
|
// this already is a table, so no cast is necessary
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom output stream operator
|
||||||
|
* @param stream
|
||||||
|
* @param field
|
||||||
|
* @return ostream
|
||||||
|
*/
|
||||||
|
inline std::ostream &operator<<(std::ostream &stream, const AssociativeFieldProxy &field)
|
||||||
|
{
|
||||||
|
// get underlying field, and output that
|
||||||
|
return stream << field.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
153
builder/libs/AMQP-CPP/include/amqpcpp/tagger.h
Normal file
153
builder/libs/AMQP-CPP/include/amqpcpp/tagger.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/**
|
||||||
|
* Tagger.h
|
||||||
|
*
|
||||||
|
* Base class that enables publisher confirms and keeps track of the sent
|
||||||
|
* messages. You can wrap this class around a AMQP::Channel object and use
|
||||||
|
* this object for publishing instead. This is a base class that you cannot
|
||||||
|
* use directly. You should instead use:
|
||||||
|
*
|
||||||
|
* - Throttle: to throttle traffic to prevent flooding RabbitMQ
|
||||||
|
* - Reliable<Tagger>: to be notified about publish-confirms via callbacks
|
||||||
|
* - Reliable<Throttle>: to have throttle + notifications via callbacks
|
||||||
|
*
|
||||||
|
* @author Michael van der Werve <michael.vanderwerve@mailerq.com>
|
||||||
|
* @copyright 2020 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes
|
||||||
|
*/
|
||||||
|
#include "deferredpublish.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespaces
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Tagger : public Watchable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The implementation for the channel
|
||||||
|
* @var std::shared_ptr<ChannelImpl>
|
||||||
|
*/
|
||||||
|
std::shared_ptr<ChannelImpl> _implementation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current id, always starts at 1.
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _current = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deferred to set up on the close
|
||||||
|
* @var std::shared_ptr<Deferred>
|
||||||
|
*/
|
||||||
|
std::shared_ptr<Deferred> _close;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to call when an error occurred
|
||||||
|
* @var ErrorCallback
|
||||||
|
*/
|
||||||
|
ErrorCallback _errorCallback;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Send method for a frame
|
||||||
|
* @param id
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
virtual bool send(uint64_t id, const Frame &frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called to report an error.
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
virtual void reportError(const char *message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that gets called on ack/nack. If these methods are overridden, make sure
|
||||||
|
* to also call the base class methods.
|
||||||
|
* @param deliveryTag
|
||||||
|
* @param multiple
|
||||||
|
*/
|
||||||
|
virtual void onAck(uint64_t deliveryTag, bool multiple);
|
||||||
|
virtual void onNack(uint64_t deliveryTag, bool multiple);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
Tagger(AMQP::Channel &channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted copy constructor, deleted move constructor
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Tagger(const Tagger &other) = delete;
|
||||||
|
Tagger(Tagger &&other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted copy assignment, deleted move assignment
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Tagger &operator=(const Tagger &other) = delete;
|
||||||
|
Tagger &operator=(Tagger &&other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Virtual destructor
|
||||||
|
*/
|
||||||
|
virtual ~Tagger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to check how many messages are still unacked.
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t unacknowledged() const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a message to an exchange. See amqpcpp/channel.h for more details on the flags.
|
||||||
|
* Delays actual publishing depending on the publisher confirms sent by RabbitMQ.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange to publish to
|
||||||
|
* @param routingkey the routing key
|
||||||
|
* @param envelope the full envelope to send
|
||||||
|
* @param message the message to send
|
||||||
|
* @param size size of the message
|
||||||
|
* @param flags optional flags
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t publish(const std::string_view &exchange, const std::string_view &routingKey, const Envelope &envelope, int flags = 0);
|
||||||
|
uint64_t publish(const std::string_view &exchange, const std::string_view &routingKey, const std::string_view &message, int flags = 0) { return publish(exchange, routingKey, Envelope(message.data(), message.size()), flags); }
|
||||||
|
uint64_t publish(const std::string_view &exchange, const std::string_view &routingKey, const char *message, size_t size, int flags = 0) { return publish(exchange, routingKey, Envelope(message, size), flags); }
|
||||||
|
uint64_t publish(const std::string_view &exchange, const std::string_view &routingKey, const char *message, int flags = 0) { return publish(exchange, routingKey, Envelope(message, strlen(message)), flags); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close underlying channel
|
||||||
|
* @return Deferred&
|
||||||
|
*/
|
||||||
|
Deferred &close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install an error callback
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
inline void onError(const ErrorCallback& callback) { return onError(ErrorCallback(callback)); }
|
||||||
|
void onError(ErrorCallback&& callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespaces
|
||||||
|
*/
|
||||||
|
}
|
||||||
149
builder/libs/AMQP-CPP/include/amqpcpp/throttle.h
Normal file
149
builder/libs/AMQP-CPP/include/amqpcpp/throttle.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* Throttle.h
|
||||||
|
*
|
||||||
|
* A channel wrapper that publishes more messages as soon as there is more capacity.
|
||||||
|
*
|
||||||
|
* @author Michael van der Werve <michael.vanderwerve@mailerq.com>
|
||||||
|
* @copyright 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes
|
||||||
|
*/
|
||||||
|
#include <cstdint>
|
||||||
|
#include <set>
|
||||||
|
#include <queue>
|
||||||
|
#include "copiedbuffer.h"
|
||||||
|
#include "channelimpl.h"
|
||||||
|
#include "tagger.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of namespaces
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Throttle : public Tagger
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Last sent ID
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _last = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throttle
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
size_t _throttle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messages that should still be sent out.
|
||||||
|
* @var queue
|
||||||
|
*/
|
||||||
|
std::queue<std::pair<uint64_t, CopiedBuffer>> _queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of open deliverytags. We want a normal set (not unordered_set) because
|
||||||
|
* removal will be cheaper for whole ranges.
|
||||||
|
* @var size_t
|
||||||
|
*/
|
||||||
|
std::set<size_t> _open;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Send method for a frame
|
||||||
|
* @param id
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
virtual bool send(uint64_t id, const Frame &frame) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called to report an error
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
virtual void reportError(const char *message) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called to report an ack/nack
|
||||||
|
* @param deliveryTag
|
||||||
|
* @param multiple
|
||||||
|
*/
|
||||||
|
virtual void onAck(uint64_t deliveryTag, bool multiple) override;
|
||||||
|
virtual void onNack(uint64_t deliveryTag, bool multiple) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor. Warning: this takes control of the channel, there should be no extra
|
||||||
|
* handlers set on the channel (onError) and no further publishes should be done on the
|
||||||
|
* raw channel either. Doing this will cause the throttle to work incorrectly, as the
|
||||||
|
* counters are not properly updated.
|
||||||
|
* @param channel
|
||||||
|
* @param throttle
|
||||||
|
*/
|
||||||
|
Throttle(Channel &channel, size_t throttle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted copy constructor, deleted move constructor
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Throttle(const Throttle &other) = delete;
|
||||||
|
Throttle(Throttle &&other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted copy assignment, deleted move assignment
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Throttle &operator=(const Throttle &other) = delete;
|
||||||
|
Throttle &operator=(Throttle &&other) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Virtual destructor
|
||||||
|
*/
|
||||||
|
virtual ~Throttle() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to check how many messages are still unacked.
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t unacknowledged() const override { return _open.size() + (_current - _last - 1); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the throttle
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t throttle() const { return _throttle; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a new throttle. Note that this will only gradually take effect when set down, and
|
||||||
|
* the update is picked up on the next acknowledgement.
|
||||||
|
* @param size_t
|
||||||
|
*/
|
||||||
|
void throttle(size_t throttle) { _throttle = throttle; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush the throttle. This flushes it _without_ taking the throttle into account, e.g. the messages
|
||||||
|
* are sent in a burst over the channel.
|
||||||
|
* @param max optional maximum, 0 is flush all
|
||||||
|
*/
|
||||||
|
size_t flush(size_t max = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespaces
|
||||||
|
*/
|
||||||
|
}
|
||||||
103
builder/libs/AMQP-CPP/include/amqpcpp/voidfield.h
Normal file
103
builder/libs/AMQP-CPP/include/amqpcpp/voidfield.h
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Void field type for AMQP
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
#include "outbuffer.h"
|
||||||
|
#include "field.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP
|
||||||
|
{
|
||||||
|
class VoidField : public Field
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
VoidField() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on incoming data
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
VoidField(InBuffer &frame) { (void)frame; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~VoidField() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of this object
|
||||||
|
* @return unique_ptr
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<Field> clone() const override
|
||||||
|
{
|
||||||
|
// create a new copy of ourselves and return it
|
||||||
|
return std::unique_ptr<Field>(new VoidField);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
virtual size_t size() const override
|
||||||
|
{
|
||||||
|
// numeric types have no extra storage requirements
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer OutBuffer to write to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer &buffer) const override { (void)buffer; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type ID that is used to identify this type of
|
||||||
|
* field in a field table
|
||||||
|
*/
|
||||||
|
virtual char typeID() const override
|
||||||
|
{
|
||||||
|
return 'V';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the object to a stream
|
||||||
|
* @param std::ostream
|
||||||
|
*/
|
||||||
|
virtual void output(std::ostream &stream) const override
|
||||||
|
{
|
||||||
|
// show
|
||||||
|
stream << "void()";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are an void field
|
||||||
|
*
|
||||||
|
* @return true, because we are an void
|
||||||
|
*/
|
||||||
|
bool isVoid() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
81
builder/libs/AMQP-CPP/include/amqpcpp/watchable.h
Normal file
81
builder/libs/AMQP-CPP/include/amqpcpp/watchable.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* Watchable.h
|
||||||
|
*
|
||||||
|
* Every class that overrides from the Watchable class can be monitored for
|
||||||
|
* destruction by a Monitor object
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
class Monitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class Watchable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The monitors
|
||||||
|
* @var std::vector
|
||||||
|
*/
|
||||||
|
std::vector<Monitor*> _monitors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a monitor
|
||||||
|
* @param monitor
|
||||||
|
*/
|
||||||
|
void add(Monitor *monitor)
|
||||||
|
{
|
||||||
|
// add to the vector
|
||||||
|
_monitors.push_back(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a monitor
|
||||||
|
* @param monitor
|
||||||
|
*/
|
||||||
|
void remove(Monitor *monitor)
|
||||||
|
{
|
||||||
|
// put the monitor at the end of the vector
|
||||||
|
auto iter = std::remove(_monitors.begin(), _monitors.end(), monitor);
|
||||||
|
|
||||||
|
// make the vector smaller
|
||||||
|
_monitors.erase(iter, _monitors.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Watchable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only a monitor has full access
|
||||||
|
*/
|
||||||
|
friend class Monitor;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
1
builder/libs/AMQP-CPP/src/.gitignore
vendored
Normal file
1
builder/libs/AMQP-CPP/src/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.d
|
||||||
96
builder/libs/AMQP-CPP/src/CMakeLists.txt
Normal file
96
builder/libs/AMQP-CPP/src/CMakeLists.txt
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
add_sources(
|
||||||
|
array.cpp
|
||||||
|
basicackframe.h
|
||||||
|
basiccancelframe.h
|
||||||
|
basiccancelokframe.h
|
||||||
|
basicconsumeframe.h
|
||||||
|
basicconsumeokframe.h
|
||||||
|
basicdeliverframe.h
|
||||||
|
basicframe.h
|
||||||
|
basicgetemptyframe.h
|
||||||
|
basicgetframe.h
|
||||||
|
basicgetokframe.h
|
||||||
|
basicheaderframe.h
|
||||||
|
basicnackframe.h
|
||||||
|
basicpublishframe.h
|
||||||
|
basicqosframe.h
|
||||||
|
basicqosokframe.h
|
||||||
|
basicrecoverasyncframe.h
|
||||||
|
basicrecoverframe.h
|
||||||
|
basicrecoverokframe.h
|
||||||
|
basicrejectframe.h
|
||||||
|
basicreturnframe.h
|
||||||
|
bodyframe.h
|
||||||
|
channelcloseframe.h
|
||||||
|
channelcloseokframe.h
|
||||||
|
channelflowframe.h
|
||||||
|
channelflowokframe.h
|
||||||
|
channelframe.h
|
||||||
|
channelimpl.cpp
|
||||||
|
channelopenframe.h
|
||||||
|
channelopenokframe.h
|
||||||
|
confirmselectframe.h
|
||||||
|
confirmselectokframe.h
|
||||||
|
connectioncloseframe.h
|
||||||
|
connectioncloseokframe.h
|
||||||
|
connectionframe.h
|
||||||
|
connectionimpl.cpp
|
||||||
|
connectionopenframe.h
|
||||||
|
connectionopenokframe.h
|
||||||
|
connectionsecureframe.h
|
||||||
|
connectionsecureokframe.h
|
||||||
|
connectionstartframe.h
|
||||||
|
connectionstartokframe.h
|
||||||
|
connectiontuneframe.h
|
||||||
|
connectiontuneokframe.h
|
||||||
|
consumedmessage.h
|
||||||
|
deferredcancel.cpp
|
||||||
|
deferredconfirm.cpp
|
||||||
|
deferredconsumer.cpp
|
||||||
|
deferredreceiver.cpp
|
||||||
|
deferredextreceiver.cpp
|
||||||
|
deferredrecall.cpp
|
||||||
|
deferredget.cpp
|
||||||
|
exchangebindframe.h
|
||||||
|
exchangebindokframe.h
|
||||||
|
exchangedeclareframe.h
|
||||||
|
exchangedeclareokframe.h
|
||||||
|
exchangedeleteframe.h
|
||||||
|
exchangedeleteokframe.h
|
||||||
|
exchangeframe.h
|
||||||
|
exchangeunbindframe.h
|
||||||
|
exchangeunbindokframe.h
|
||||||
|
extframe.h
|
||||||
|
field.cpp
|
||||||
|
flags.cpp
|
||||||
|
framecheck.h
|
||||||
|
headerframe.h
|
||||||
|
heartbeatframe.h
|
||||||
|
includes.h
|
||||||
|
methodframe.h
|
||||||
|
passthroughbuffer.h
|
||||||
|
protocolheaderframe.h
|
||||||
|
queuebindframe.h
|
||||||
|
queuebindokframe.h
|
||||||
|
queuedeclareframe.h
|
||||||
|
queuedeclareokframe.h
|
||||||
|
queuedeleteframe.h
|
||||||
|
queuedeleteokframe.h
|
||||||
|
queueframe.h
|
||||||
|
queuepurgeframe.h
|
||||||
|
queuepurgeokframe.h
|
||||||
|
queueunbindframe.h
|
||||||
|
queueunbindokframe.h
|
||||||
|
receivedframe.cpp
|
||||||
|
reducedbuffer.h
|
||||||
|
returnedmessage.h
|
||||||
|
table.cpp
|
||||||
|
transactioncommitframe.h
|
||||||
|
transactioncommitokframe.h
|
||||||
|
transactionframe.h
|
||||||
|
transactionrollbackframe.h
|
||||||
|
transactionrollbackokframe.h
|
||||||
|
transactionselectframe.h
|
||||||
|
transactionselectokframe.h
|
||||||
|
watchable.cpp
|
||||||
|
)
|
||||||
55
builder/libs/AMQP-CPP/src/Makefile
Normal file
55
builder/libs/AMQP-CPP/src/Makefile
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
CPP = g++
|
||||||
|
RM = rm -f
|
||||||
|
CPPFLAGS = -Wall -c -I../include -std=c++17 -MD -Wno-class-conversion -DVERSION=${VERSION}
|
||||||
|
LD = g++
|
||||||
|
LD_FLAGS = -Wall -shared
|
||||||
|
SHARED_LIB = lib$(LIBRARY_NAME).so.$(VERSION)
|
||||||
|
STATIC_LIB = lib$(LIBRARY_NAME).a.$(VERSION)
|
||||||
|
SOURCES = $(wildcard *.cpp) $(wildcard linux_tcp/*.cpp)
|
||||||
|
SHARED_OBJECTS = $(SOURCES:%.cpp=%.o)
|
||||||
|
STATIC_OBJECTS = $(SOURCES:%.cpp=%.s.o)
|
||||||
|
DEPENDENCIES = $(SOURCES:%.cpp=%.d)
|
||||||
|
PURE_SHARED_OBJECTS = $(filter-out tcpconnection.o, $(SOURCES:%.cpp=%.o))
|
||||||
|
PURE_STATIC_OBJECTS = $(filter-out tcpconnection.s.o, $(SOURCES:%.cpp=%.s.o))
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(shell uname -s),Darwin)
|
||||||
|
SONAMEPARAMETER = -install_name
|
||||||
|
else
|
||||||
|
SONAMEPARAMETER = -soname
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include ${DEPENDENCIES}
|
||||||
|
|
||||||
|
all: CPPFLAGS += -g
|
||||||
|
all: LD_FLAGS += -g
|
||||||
|
all: shared static
|
||||||
|
|
||||||
|
pure: CPPFLAGS += -g
|
||||||
|
pure: LD_FLAGS += -g
|
||||||
|
pure: shared_pure static_pure
|
||||||
|
|
||||||
|
release: CPPFLAGS += -O2
|
||||||
|
release: LD_FLAGS += -O2
|
||||||
|
release: shared static
|
||||||
|
|
||||||
|
shared: ${SHARED_OBJECTS} ${SHARED_LIB}
|
||||||
|
shared_pure: ${PURE_SHARED_OBJECTS} ${SHARED_LIB}
|
||||||
|
|
||||||
|
static: ${STATIC_OBJECTS} ${STATIC_LIB}
|
||||||
|
static_pure: ${PURE_STATIC_OBJECTS} ${STATIC_LIB}
|
||||||
|
|
||||||
|
${SHARED_LIB}: ${SHARED_OBJECTS}
|
||||||
|
${LD} ${LD_FLAGS} -Wl,${SONAMEPARAMETER},lib$(LIBRARY_NAME).so.$(SONAME) -o $@ ${SHARED_OBJECTS}
|
||||||
|
|
||||||
|
${STATIC_LIB}: ${STATIC_OBJECTS}
|
||||||
|
ar rcs ${STATIC_LIB} ${STATIC_OBJECTS}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
${RM} *.obj *~* ${SHARED_OBJECTS} ${STATIC_OBJECTS} ${SHARED_LIB} ${STATIC_LIB} ${DEPENDENCIES}
|
||||||
|
|
||||||
|
${SHARED_OBJECTS}:
|
||||||
|
${CPP} ${CPPFLAGS} -fpic -o $@ ${@:%.o=%.cpp}
|
||||||
|
|
||||||
|
${STATIC_OBJECTS}:
|
||||||
|
${CPP} ${CPPFLAGS} -o $@ ${@:%.s.o=%.cpp}
|
||||||
140
builder/libs/AMQP-CPP/src/array.cpp
Normal file
140
builder/libs/AMQP-CPP/src/array.cpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
* Array.cpp
|
||||||
|
*
|
||||||
|
* Implementation of an array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
// we live in the copernica namespace
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on incoming frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
Array::Array(InBuffer &frame)
|
||||||
|
{
|
||||||
|
// use this to see if we've read too many bytes.
|
||||||
|
uint32_t charsToRead = frame.nextUint32();
|
||||||
|
|
||||||
|
// keep going until all data is read
|
||||||
|
while (charsToRead > 0)
|
||||||
|
{
|
||||||
|
// one byte less for the field type
|
||||||
|
charsToRead -= 1;
|
||||||
|
|
||||||
|
// read the field type and construct the field
|
||||||
|
auto field = Field::decode(frame);
|
||||||
|
if (!field) continue;
|
||||||
|
|
||||||
|
// less bytes to read
|
||||||
|
charsToRead -= (uint32_t)field->size();
|
||||||
|
|
||||||
|
// add the additional field
|
||||||
|
_fields.push_back(std::move(field));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
* @param array
|
||||||
|
*/
|
||||||
|
Array::Array(const Array &array)
|
||||||
|
{
|
||||||
|
// loop through the other array
|
||||||
|
for (auto iter = array._fields.begin(); iter != array._fields.end(); iter++)
|
||||||
|
{
|
||||||
|
// add to this vector
|
||||||
|
_fields.push_back((*iter)->clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field
|
||||||
|
*
|
||||||
|
* If the field does not exist, an empty string is returned
|
||||||
|
*
|
||||||
|
* @param index field index
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
|
const Field &Array::get(uint8_t index) const
|
||||||
|
{
|
||||||
|
// used if index does not exist
|
||||||
|
static ShortString empty;
|
||||||
|
|
||||||
|
// check whether we have that many elements
|
||||||
|
if (index >= _fields.size()) return empty;
|
||||||
|
|
||||||
|
// get value
|
||||||
|
return *_fields[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of entries in the array
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t Array::count() const
|
||||||
|
{
|
||||||
|
return (uint32_t)_fields.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a field from the array
|
||||||
|
*/
|
||||||
|
void Array::pop_back()
|
||||||
|
{
|
||||||
|
_fields.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a field to the array
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
void Array::push_back(const Field& value)
|
||||||
|
{
|
||||||
|
_fields.push_back(value.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size this field will take when
|
||||||
|
* encoded in the AMQP wire-frame format
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t Array::size() const
|
||||||
|
{
|
||||||
|
// store the size (four bytes for the initial size)
|
||||||
|
size_t size = 4;
|
||||||
|
|
||||||
|
// iterate over all elements
|
||||||
|
for (const auto &item : _fields)
|
||||||
|
{
|
||||||
|
// add the size of the field type and size of element
|
||||||
|
size += sizeof(item->typeID());
|
||||||
|
size += item->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the result
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write encoded payload to the given buffer.
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
void Array::fill(OutBuffer& buffer) const
|
||||||
|
{
|
||||||
|
// store total size for all elements
|
||||||
|
buffer.add(static_cast<uint32_t>(size()-4));
|
||||||
|
|
||||||
|
// iterate over all elements
|
||||||
|
for (const auto &item : _fields)
|
||||||
|
{
|
||||||
|
// encode the element type and element
|
||||||
|
buffer.add((uint8_t)item->typeID());
|
||||||
|
item->fill(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// end namespace
|
||||||
|
}
|
||||||
145
builder/libs/AMQP-CPP/src/basicackframe.h
Normal file
145
builder/libs/AMQP-CPP/src/basicackframe.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic acknowledgement frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class defintion
|
||||||
|
*/
|
||||||
|
class BasicAckFrame : public BasicFrame {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* server-assigned and channel specific delivery tag
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _deliveryTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if set, tag is treated as "up to and including", so client can acknowledge multiple messages with a single method
|
||||||
|
* if not set, refers to single message
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _multiple;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
* @return pointer to object to allow for chaining
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// add the delivery tag
|
||||||
|
buffer.add(_deliveryTag);
|
||||||
|
|
||||||
|
// add the booleans
|
||||||
|
_multiple.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic acknowledgement frame
|
||||||
|
*
|
||||||
|
* @param channel Channel identifier
|
||||||
|
* @param deliveryTag server-assigned and channel specific delivery tag
|
||||||
|
* @param multiple acknowledge mutiple messages
|
||||||
|
*/
|
||||||
|
BasicAckFrame(uint16_t channel, uint64_t deliveryTag, bool multiple = false) :
|
||||||
|
BasicFrame(channel, 9),
|
||||||
|
_deliveryTag(deliveryTag),
|
||||||
|
_multiple(multiple) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on received frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicAckFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deliveryTag(frame.nextUint64()),
|
||||||
|
_multiple(frame) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicAckFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
virtual bool synchronous() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the server-assigned and channel specific delivery tag
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t deliveryTag() const
|
||||||
|
{
|
||||||
|
return _deliveryTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether to acknowledge multiple messages
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool multiple() const
|
||||||
|
{
|
||||||
|
return _multiple.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if(!channel) return false;
|
||||||
|
|
||||||
|
// get the current confirm
|
||||||
|
auto confirm = channel->confirm();
|
||||||
|
|
||||||
|
// if there is no deferred confirm, we can just as well stop
|
||||||
|
if (confirm == nullptr) return false;
|
||||||
|
|
||||||
|
// process the frame
|
||||||
|
confirm->process(*this);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
135
builder/libs/AMQP-CPP/src/basiccancelframe.h
Normal file
135
builder/libs/AMQP-CPP/src/basiccancelframe.h
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic cancel frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicCancelFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Holds the consumer tag specified by the client or provided by the server.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _consumerTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether to wait for a response
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _noWait;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// add consumer tag + booleans
|
||||||
|
_consumerTag.fill(buffer);
|
||||||
|
_noWait.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic cancel frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame to parse
|
||||||
|
*/
|
||||||
|
BasicCancelFrame(ReceivedFrame &frame) : BasicFrame(frame), _consumerTag(frame), _noWait(frame) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic cancel frame
|
||||||
|
*
|
||||||
|
* @param channel Channel identifier
|
||||||
|
* @param consumerTag consumertag specified by client of provided by server
|
||||||
|
* @param noWait whether to wait for a response.
|
||||||
|
*/
|
||||||
|
BasicCancelFrame(uint16_t channel, const std::string_view &consumerTag, bool noWait = false) :
|
||||||
|
BasicFrame(channel, (uint32_t)(consumerTag.size() + 2)), // 1 for extra string size, 1 for bool
|
||||||
|
_consumerTag(consumerTag),
|
||||||
|
_noWait(noWait) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicCancelFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
bool synchronous() const override
|
||||||
|
{
|
||||||
|
// we are synchronous when the nowait option is not used
|
||||||
|
return !noWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the consumertag, which is specified by the client or provided by the server
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& consumerTag() const
|
||||||
|
{
|
||||||
|
return _consumerTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether to wait for a response
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
bool noWait() const
|
||||||
|
{
|
||||||
|
return _noWait.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report
|
||||||
|
channel->reportCancelled(consumerTag());
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
108
builder/libs/AMQP-CPP/src/basiccancelokframe.h
Normal file
108
builder/libs/AMQP-CPP/src/basiccancelokframe.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic cancel ok frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicCancelOKFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Holds the consumer tag specified by the client or provided by the server.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _consumerTag;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// add own information
|
||||||
|
_consumerTag.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic cancel ok frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicCancelOKFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_consumerTag(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic cancel ok frame (client-side)
|
||||||
|
* @param channel channel identifier
|
||||||
|
* @param consumerTag holds the consumertag specified by client or server
|
||||||
|
*/
|
||||||
|
BasicCancelOKFrame(uint16_t channel, std::string& consumerTag) :
|
||||||
|
BasicFrame(channel, (uint32_t)(consumerTag.length() + 1)), // add 1 byte for encoding the size of consumer tag
|
||||||
|
_consumerTag(consumerTag)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicCancelOKFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the consumertag, which is specified by the client or provided by the server
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& consumerTag() const
|
||||||
|
{
|
||||||
|
return _consumerTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report
|
||||||
|
channel->reportSuccess<const std::string&>(consumerTag());
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
203
builder/libs/AMQP-CPP/src/basicconsumeframe.h
Normal file
203
builder/libs/AMQP-CPP/src/basicconsumeframe.h
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic consume frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicConsumeFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Field that is no longer used
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _deprecated = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* specifies the name of the queue to consume from
|
||||||
|
* @var Table
|
||||||
|
*/
|
||||||
|
ShortString _queueName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* specifies the identifier for the consumer tag.
|
||||||
|
* This tag is local to a channel so two clients can use the same consumer tags.
|
||||||
|
* If empty, the server generates a tag.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _consumerTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Booleans sent in frame
|
||||||
|
* 0: noLocal
|
||||||
|
* 1: noAck
|
||||||
|
* 2: exclusive
|
||||||
|
* 3: noWait
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _bools;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* additional arguments, implementation dependent
|
||||||
|
* @var Table
|
||||||
|
*/
|
||||||
|
Table _filter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// fill the buffer
|
||||||
|
buffer.add((uint16_t) _deprecated);
|
||||||
|
_queueName.fill(buffer);
|
||||||
|
_consumerTag.fill(buffer);
|
||||||
|
_bools.fill(buffer);
|
||||||
|
_filter.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic consume frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param queueName name of the queue to consume from
|
||||||
|
* @param consumerTag identifier for the consumer tag.
|
||||||
|
* @param noLocal no-local
|
||||||
|
* @param noAck no acknowledgements
|
||||||
|
* @param exclusive exclusive channel
|
||||||
|
* @param noWait don't wait for a response
|
||||||
|
* @param filter additional arguments
|
||||||
|
*/
|
||||||
|
BasicConsumeFrame(uint16_t channel, const std::string_view &queueName, const std::string_view &consumerTag, bool noLocal = false, bool noAck = false, bool exclusive = false, bool noWait = false, const Table& filter = {}) :
|
||||||
|
BasicFrame(channel, (uint32_t)(queueName.length() + consumerTag.length() + 5 + filter.size())), // size of vars, +1 for each shortstring size, +1 for bools, +2 for deprecated value
|
||||||
|
_queueName(queueName),
|
||||||
|
_consumerTag(consumerTag),
|
||||||
|
_bools(noLocal, noAck, exclusive, noWait),
|
||||||
|
_filter(filter)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on incoming data
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicConsumeFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deprecated(frame.nextUint16()), // read deprecated info
|
||||||
|
_queueName(frame),
|
||||||
|
_consumerTag(frame),
|
||||||
|
_bools(frame),
|
||||||
|
_filter(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicConsumeFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
bool synchronous() const override
|
||||||
|
{
|
||||||
|
// we are synchronous when the nowait option is not set
|
||||||
|
return !noWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the queue to consume from
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& queueName() const
|
||||||
|
{
|
||||||
|
return _queueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the identifier for the consumertag
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& consumerTag() const
|
||||||
|
{
|
||||||
|
return _consumerTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the value of the noLocal bool
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool noLocal() const
|
||||||
|
{
|
||||||
|
return _bools.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the value of the noAck bool
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool noAck() const
|
||||||
|
{
|
||||||
|
return _bools.get(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return whether the queue is exclusive
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool exclusive() const
|
||||||
|
{
|
||||||
|
return _bools.get(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return whether to wait for a response
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool noWait() const
|
||||||
|
{
|
||||||
|
return _bools.get(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the additional filter arguments
|
||||||
|
* @return Table
|
||||||
|
*/
|
||||||
|
const Table& filter() const
|
||||||
|
{
|
||||||
|
return _filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
108
builder/libs/AMQP-CPP/src/basicconsumeokframe.h
Normal file
108
builder/libs/AMQP-CPP/src/basicconsumeokframe.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic consume ok frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicConsumeOKFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Holds the consumer tag specified by the client or provided by the server.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _consumerTag;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// add payload
|
||||||
|
_consumerTag.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic consume frame
|
||||||
|
*
|
||||||
|
* @param consumerTag consumertag specified by client of provided by server
|
||||||
|
*/
|
||||||
|
BasicConsumeOKFrame(uint16_t channel, const std::string& consumerTag) :
|
||||||
|
BasicFrame(channel, (uint32_t)(consumerTag.length() + 1)), // length of string + 1 for encoding of stringsize
|
||||||
|
_consumerTag(consumerTag)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic consume ok frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicConsumeOKFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_consumerTag(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicConsumeOKFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 21;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the consumertag, which is specified by the client or provided by the server
|
||||||
|
* @return std::string
|
||||||
|
*/
|
||||||
|
const std::string& consumerTag() const
|
||||||
|
{
|
||||||
|
return _consumerTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report
|
||||||
|
channel->reportSuccess(consumerTag());
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
215
builder/libs/AMQP-CPP/src/basicdeliverframe.h
Normal file
215
builder/libs/AMQP-CPP/src/basicdeliverframe.h
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic deliver frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "basicframe.h"
|
||||||
|
#include "amqpcpp/stringfield.h"
|
||||||
|
#include "amqpcpp/booleanset.h"
|
||||||
|
#include "amqpcpp/connectionimpl.h"
|
||||||
|
#include "amqpcpp/deferredconsumer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicDeliverFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* identifier for the consumer, valid within current channel
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _consumerTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* server-assigned and channel specific delivery tag
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _deliveryTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* indicates whether the message has been previously delivered to this (or another) client
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _redelivered;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the name of the exchange to publish to. An empty exchange name means the default exchange.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _exchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message routing key
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _routingKey;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
_consumerTag.fill(buffer);
|
||||||
|
buffer.add(_deliveryTag);
|
||||||
|
_redelivered.fill(buffer);
|
||||||
|
_exchange.fill(buffer);
|
||||||
|
_routingKey.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic deliver frame (client side)
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param consumerTag identifier for the consumer, valid within current channel
|
||||||
|
* @param deliveryTag server-assigned and channel specific delivery tag
|
||||||
|
* @param redelivered indicates whether the message has been previously delivered to this (or another) client
|
||||||
|
* @param exchange name of exchange to publish to
|
||||||
|
* @param routingKey message routing key
|
||||||
|
*/
|
||||||
|
BasicDeliverFrame(uint16_t channel, const std::string& consumerTag, uint64_t deliveryTag, bool redelivered = false, const std::string& exchange = "", const std::string& routingKey = "") :
|
||||||
|
BasicFrame(channel, (uint32_t)(consumerTag.length() + exchange.length() + routingKey.length() + 12)),
|
||||||
|
// length of strings + 1 byte per string for stringsize, 8 bytes for uint64_t and 1 for bools
|
||||||
|
_consumerTag(consumerTag),
|
||||||
|
_deliveryTag(deliveryTag),
|
||||||
|
_redelivered(redelivered),
|
||||||
|
_exchange(exchange),
|
||||||
|
_routingKey(routingKey)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic deliver frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicDeliverFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_consumerTag(frame),
|
||||||
|
_deliveryTag(frame.nextUint64()),
|
||||||
|
_redelivered(frame),
|
||||||
|
_exchange(frame),
|
||||||
|
_routingKey(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicDeliverFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the exchange to publish to
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& exchange() const
|
||||||
|
{
|
||||||
|
return _exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the routing key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& routingKey() const
|
||||||
|
{
|
||||||
|
return _routingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
virtual bool synchronous() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the server-assigned and channel specific delivery tag
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t deliveryTag() const
|
||||||
|
{
|
||||||
|
return _deliveryTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the identifier for the consumer (channel specific)
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& consumerTag() const
|
||||||
|
{
|
||||||
|
return _consumerTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the message has been previously delivered to (another) client
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool redelivered() const
|
||||||
|
{
|
||||||
|
return _redelivered.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// get the appropriate consumer object
|
||||||
|
auto consumer = channel->consumer(_consumerTag);
|
||||||
|
|
||||||
|
// skip if there was no consumer for this tag
|
||||||
|
if (consumer == nullptr) return false;
|
||||||
|
|
||||||
|
// initialize the object, because we're about to receive a message
|
||||||
|
consumer->process(*this);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
62
builder/libs/AMQP-CPP/src/basicframe.h
Normal file
62
builder/libs/AMQP-CPP/src/basicframe.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Class describing an AMQP basic frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "methodframe.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicFrame : public MethodFrame
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param channel The channel ID
|
||||||
|
* @param size Payload size
|
||||||
|
*/
|
||||||
|
BasicFrame(uint16_t channel, uint32_t size) : MethodFrame(channel, size) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on a received frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicFrame(ReceivedFrame &frame) : MethodFrame(frame) {}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class id
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t classID() const override
|
||||||
|
{
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
99
builder/libs/AMQP-CPP/src/basicgetemptyframe.h
Normal file
99
builder/libs/AMQP-CPP/src/basicgetemptyframe.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic get empty frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicGetEmptyFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Field that is no longer used
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _deprecated;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// recreate deprecated field and encode
|
||||||
|
_deprecated.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic get empty frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
*/
|
||||||
|
BasicGetEmptyFrame(uint16_t channel) :
|
||||||
|
BasicFrame(channel, 1) // 1 for encoding the deprecated cluster id (shortstring)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for incoming data
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicGetEmptyFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deprecated(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicGetEmptyFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 72;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report
|
||||||
|
channel->reportSuccess();
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
116
builder/libs/AMQP-CPP/src/basicgetframe.h
Normal file
116
builder/libs/AMQP-CPP/src/basicgetframe.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic get frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicGetFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Deprecated field
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _deprecated = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* name of the queue to get a message from
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if set, server does not expect acknowledgement for messages. Server dequeues message after sending
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _noAck;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// encode other values
|
||||||
|
buffer.add(_deprecated);
|
||||||
|
_queue.fill(buffer);
|
||||||
|
_noAck.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic get frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param queue name of the queue
|
||||||
|
* @param noAck whether server expects acknowledgements for messages
|
||||||
|
*/
|
||||||
|
BasicGetFrame(uint16_t channel, const std::string_view &queue, bool noAck = false) :
|
||||||
|
BasicFrame(channel, (uint32_t)(queue.length() + 4)), // 1 for bool, 1 for string size, 2 for deprecated field
|
||||||
|
_queue(queue),
|
||||||
|
_noAck(noAck)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on incoming frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicGetFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deprecated(frame.nextUint16()),
|
||||||
|
_queue(frame),
|
||||||
|
_noAck(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicGetFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the queue
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& queue() const
|
||||||
|
{
|
||||||
|
return _queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the server expects acknowledgements for messages
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
bool noAck() const
|
||||||
|
{
|
||||||
|
return _noAck.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
194
builder/libs/AMQP-CPP/src/basicgetokframe.h
Normal file
194
builder/libs/AMQP-CPP/src/basicgetokframe.h
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic get ok frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2018 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicGetOKFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* server-assigned and channel specific delivery tag
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _deliveryTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* indicates whether the message has been previously delivered to this (or another) client
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _redelivered;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the name of the exchange to publish to. An empty exchange name means the default exchange.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _exchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message routing key
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _routingKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number of messages in the queue
|
||||||
|
* @var uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t _messageCount;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// encode rest of the fields
|
||||||
|
buffer.add(_deliveryTag);
|
||||||
|
_redelivered.fill(buffer);
|
||||||
|
_exchange.fill(buffer);
|
||||||
|
_routingKey.fill(buffer);
|
||||||
|
buffer.add(_messageCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic get ok frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param deliveryTag server-assigned and channel specific delivery tag
|
||||||
|
* @param redelivered indicates whether the message has been previously delivered to this (or another) client
|
||||||
|
* @param exchange name of exchange to publish to
|
||||||
|
* @param routingKey message routing key
|
||||||
|
* @param messageCount number of messages in the queue
|
||||||
|
*/
|
||||||
|
BasicGetOKFrame(uint16_t channel, uint64_t deliveryTag, bool redelivered, const std::string& exchange, const std::string& routingKey, uint32_t messageCount) :
|
||||||
|
BasicFrame(channel, (uint32_t)(exchange.length() + routingKey.length() + 15)), // string length, +1 for each shortsrting length + 8 (uint64_t) + 4 (uint32_t) + 1 (bool)
|
||||||
|
_deliveryTag(deliveryTag),
|
||||||
|
_redelivered(redelivered),
|
||||||
|
_exchange(exchange),
|
||||||
|
_routingKey(routingKey),
|
||||||
|
_messageCount(messageCount)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic get ok frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicGetOKFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deliveryTag(frame.nextUint64()),
|
||||||
|
_redelivered(frame),
|
||||||
|
_exchange(frame),
|
||||||
|
_routingKey(frame),
|
||||||
|
_messageCount(frame.nextUint32())
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicGetOKFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the exchange to publish to
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& exchange() const
|
||||||
|
{
|
||||||
|
return _exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the routing key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& routingKey() const
|
||||||
|
{
|
||||||
|
return _routingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 71;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the server-assigned and channel specific delivery tag
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t deliveryTag() const
|
||||||
|
{
|
||||||
|
return _deliveryTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of messages in the queue
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t messageCount() const
|
||||||
|
{
|
||||||
|
return _messageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the message has been previously delivered to (another) client
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool redelivered() const
|
||||||
|
{
|
||||||
|
return _redelivered.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report success for the get operation (this will also update the current receiver!)
|
||||||
|
channel->reportSuccess(messageCount(), _deliveryTag, redelivered());
|
||||||
|
|
||||||
|
// get the current receiver object
|
||||||
|
auto *receiver = channel->receiver();
|
||||||
|
|
||||||
|
// check if we have a valid receiver
|
||||||
|
if (receiver == nullptr) return false;
|
||||||
|
|
||||||
|
// initialize the receiver for the upcoming message
|
||||||
|
receiver->initialize(_exchange, _routingKey);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
168
builder/libs/AMQP-CPP/src/basicheaderframe.h
Normal file
168
builder/libs/AMQP-CPP/src/basicheaderframe.h
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/**
|
||||||
|
* Class describing an AMQP basic header frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2020 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include guard
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include "headerframe.h"
|
||||||
|
#include "amqpcpp/metadata.h"
|
||||||
|
#include "amqpcpp/envelope.h"
|
||||||
|
#include "amqpcpp/connectionimpl.h"
|
||||||
|
#include "amqpcpp/deferredreceiver.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicHeaderFrame : public HeaderFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Weight field, unused but must be sent, always value 0;
|
||||||
|
* @var uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t _weight = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Body size, sum of the sizes of all body frames following the content header
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _bodySize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The meta data
|
||||||
|
* @var MetaData
|
||||||
|
*/
|
||||||
|
MetaData _metadata;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a header frame to a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer &buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
HeaderFrame::fill(buffer);
|
||||||
|
|
||||||
|
// fill own fields.
|
||||||
|
buffer.add(_weight);
|
||||||
|
buffer.add(_bodySize);
|
||||||
|
|
||||||
|
// the meta data
|
||||||
|
_metadata.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an empty basic header frame
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param metadata the meta-data
|
||||||
|
* @param bodysize size of the body
|
||||||
|
*/
|
||||||
|
BasicHeaderFrame(uint16_t channel, const MetaData &metadata, size_t bodysize) :
|
||||||
|
HeaderFrame(channel, 10 + metadata.size()), // there are at least 10 bytes sent, weight (2), bodySize (8), plus the size of the meta data
|
||||||
|
_bodySize(bodysize),
|
||||||
|
_metadata(metadata)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct an empty basic header frame
|
||||||
|
*
|
||||||
|
* All options are set using setter functions.
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param envelope the envelope
|
||||||
|
*/
|
||||||
|
BasicHeaderFrame(uint16_t channel, const Envelope &envelope) :
|
||||||
|
BasicHeaderFrame(channel, envelope, envelope.bodySize()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor to parse incoming frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicHeaderFrame(ReceivedFrame &frame) :
|
||||||
|
HeaderFrame(frame),
|
||||||
|
_weight(frame.nextUint16()),
|
||||||
|
_bodySize(frame.nextUint64()),
|
||||||
|
_metadata(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicHeaderFrame() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the body
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t bodySize() const
|
||||||
|
{
|
||||||
|
return _bodySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The metadata sent in this frame
|
||||||
|
*
|
||||||
|
* @return All the metadata for this message
|
||||||
|
*/
|
||||||
|
const MetaData &metaData() const
|
||||||
|
{
|
||||||
|
return _metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t classID() const override
|
||||||
|
{
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// we need a channel
|
||||||
|
if (channel == nullptr) return false;
|
||||||
|
|
||||||
|
// do we have an object that is receiving this data?
|
||||||
|
auto *receiver = channel->receiver();
|
||||||
|
|
||||||
|
// check if we have a valid channel and consumer
|
||||||
|
if (receiver == nullptr) return false;
|
||||||
|
|
||||||
|
// the channel can process the frame
|
||||||
|
receiver->process(*this);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
143
builder/libs/AMQP-CPP/src/basicnackframe.h
Normal file
143
builder/libs/AMQP-CPP/src/basicnackframe.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic negative-acknowledgement frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class defintion
|
||||||
|
*/
|
||||||
|
class BasicNackFrame : public BasicFrame {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* server-assigned and channel specific delivery tag
|
||||||
|
* @var uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t _deliveryTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The additional bits
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _bits;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
* @return pointer to object to allow for chaining
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// add the delivery tag
|
||||||
|
buffer.add(_deliveryTag);
|
||||||
|
|
||||||
|
// add the booleans
|
||||||
|
_bits.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic negative-acknowledgement frame
|
||||||
|
*
|
||||||
|
* @param channel Channel identifier
|
||||||
|
* @param deliveryTag server-assigned and channel specific delivery tag
|
||||||
|
* @param multiple nack mutiple messages
|
||||||
|
* @param requeue requeue the message
|
||||||
|
*/
|
||||||
|
BasicNackFrame(uint16_t channel, uint64_t deliveryTag, bool multiple = false, bool requeue = false) :
|
||||||
|
BasicFrame(channel, 9),
|
||||||
|
_deliveryTag(deliveryTag),
|
||||||
|
_bits(multiple, requeue) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct based on received frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicNackFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deliveryTag(frame.nextUint64()),
|
||||||
|
_bits(frame) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicNackFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 120;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the server-assigned and channel specific delivery tag
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t deliveryTag() const
|
||||||
|
{
|
||||||
|
return _deliveryTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether to acknowledgement multiple messages
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool multiple() const
|
||||||
|
{
|
||||||
|
return _bits.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should the message be put back in the queue?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool requeue() const
|
||||||
|
{
|
||||||
|
return _bits.get(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if(!channel) return false;
|
||||||
|
|
||||||
|
// get the current confirm
|
||||||
|
auto confirm = channel->confirm();
|
||||||
|
|
||||||
|
// if there is no deferred confirm, we can just as well stop
|
||||||
|
if (confirm == nullptr) return false;
|
||||||
|
|
||||||
|
// process the frame
|
||||||
|
confirm->process(*this);
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
158
builder/libs/AMQP-CPP/src/basicpublishframe.h
Normal file
158
builder/libs/AMQP-CPP/src/basicpublishframe.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic publish frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 - 2023 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicPublishFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Variable that no longer is in use
|
||||||
|
* @var int16_t
|
||||||
|
*/
|
||||||
|
int16_t _deprecated = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the name of the exchange to publish to. An empty exchange name means the default exchange.
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _exchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message routing key
|
||||||
|
* @var ShortString
|
||||||
|
*/
|
||||||
|
ShortString _routingKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BooleanSet, contains:
|
||||||
|
* 0: mandatory, indicate mandatory routing. If set, server will return unroutable message, otherwise server silently drops message
|
||||||
|
* 1: immediate, Request immediate delivery, if set and cannot be routed, return unroutable message.
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _bools;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// encode fields
|
||||||
|
buffer.add(_deprecated);
|
||||||
|
_exchange.fill(buffer);
|
||||||
|
_routingKey.fill(buffer);
|
||||||
|
_bools.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic publish frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param exchange name of exchange to publish to @default = ""
|
||||||
|
* @param routingKey message routing key @default = ""
|
||||||
|
* @param mandatory indicate mandatory routing @default = false
|
||||||
|
* @param immediate request immediate delivery @default = false
|
||||||
|
*/
|
||||||
|
BasicPublishFrame(uint16_t channel, const std::string_view &exchange = "", const std::string_view &routingKey = "", bool mandatory = false, bool immediate = false) :
|
||||||
|
BasicFrame(channel, (uint32_t)(exchange.length() + routingKey.length() + 5)), // 1 extra per string (for the size), 1 for bools, 2 for deprecated field
|
||||||
|
_exchange(exchange),
|
||||||
|
_routingKey(routingKey),
|
||||||
|
_bools(mandatory, immediate)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic publish frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame to parse
|
||||||
|
*/
|
||||||
|
BasicPublishFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_deprecated(frame.nextInt16()),
|
||||||
|
_exchange(frame),
|
||||||
|
_routingKey(frame),
|
||||||
|
_bools(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicPublishFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
bool synchronous() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the exchange to publish to
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& exchange() const
|
||||||
|
{
|
||||||
|
return _exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the routing key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
const std::string& routingKey() const
|
||||||
|
{
|
||||||
|
return _routingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the mandatory routing indication
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
bool mandatory() const
|
||||||
|
{
|
||||||
|
return _bools.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the request immediate delivery indication
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
bool immediate() const
|
||||||
|
{
|
||||||
|
return _bools.get(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
125
builder/libs/AMQP-CPP/src/basicqosframe.h
Normal file
125
builder/libs/AMQP-CPP/src/basicqosframe.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic QOS frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicQosFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* specifies the size of the prefetch window in octets
|
||||||
|
* @var int32_t
|
||||||
|
*/
|
||||||
|
int32_t _prefetchSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* specifies a prefetch window in terms of whole messages
|
||||||
|
* @var int16_t
|
||||||
|
*/
|
||||||
|
int16_t _prefetchCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply QoS settings to entire connection
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _global;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// add fields
|
||||||
|
buffer.add(_prefetchSize);
|
||||||
|
buffer.add(_prefetchCount);
|
||||||
|
_global.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic qos frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param prefetchCount specifies a prefetch window in terms of whole messages
|
||||||
|
* @param global share prefetch count with all consumers on the same channel
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
BasicQosFrame(uint16_t channel, int16_t prefetchCount = 0, bool global = false) :
|
||||||
|
BasicFrame(channel, 7), // 4 (int32) + 2 (int16) + 1 (bool)
|
||||||
|
_prefetchSize(0),
|
||||||
|
_prefetchCount(prefetchCount),
|
||||||
|
_global(global)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on incoming frame
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicQosFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_prefetchSize(frame.nextInt32()),
|
||||||
|
_prefetchCount(frame.nextInt16()),
|
||||||
|
_global(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicQosFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the prefetch count
|
||||||
|
* @return int16_t
|
||||||
|
*/
|
||||||
|
int16_t prefetchCount() const
|
||||||
|
{
|
||||||
|
return _prefetchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the value of global
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
bool global() const
|
||||||
|
{
|
||||||
|
return _global.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the prefetch size
|
||||||
|
* @return int32_t
|
||||||
|
*/
|
||||||
|
int32_t prefetchSize() const
|
||||||
|
{
|
||||||
|
return _prefetchSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
81
builder/libs/AMQP-CPP/src/basicqosokframe.h
Normal file
81
builder/libs/AMQP-CPP/src/basicqosokframe.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic QOS frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementation
|
||||||
|
*/
|
||||||
|
class BasicQosOKFrame : public BasicFrame
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base, then done (no other params)
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic qos ok frame
|
||||||
|
* @param channel channel we're working on
|
||||||
|
*/
|
||||||
|
BasicQosOKFrame(uint16_t channel) : BasicFrame(channel, 0) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor based on incoming data
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
BasicQosOKFrame(ReceivedFrame &frame) : BasicFrame(frame) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicQosOKFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method id
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report
|
||||||
|
channel->reportSuccess();
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
99
builder/libs/AMQP-CPP/src/basicrecoverasyncframe.h
Normal file
99
builder/libs/AMQP-CPP/src/basicrecoverasyncframe.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic recover-async frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class BasicRecoverAsyncFrame : public BasicFrame {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Server will try to requeue messages. If requeue is false or requeue attempt fails, messages are discarded or dead-lettered
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _requeue;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// encode fields
|
||||||
|
_requeue.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic recover async frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicRecoverAsyncFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_requeue(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic recover-async frame
|
||||||
|
*
|
||||||
|
* @param channel channel we're working on
|
||||||
|
* @param requeue whether to attempt to requeue messages
|
||||||
|
*/
|
||||||
|
BasicRecoverAsyncFrame(uint16_t channel, bool requeue = false) :
|
||||||
|
BasicFrame(channel, 1), //sizeof bool
|
||||||
|
_requeue(requeue)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicRecoverAsyncFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
virtual bool synchronous() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the server will try to requeue
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool requeue() const
|
||||||
|
{
|
||||||
|
return _requeue.get(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
100
builder/libs/AMQP-CPP/src/basicrecoverframe.h
Normal file
100
builder/libs/AMQP-CPP/src/basicrecoverframe.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic recover frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class BasicRecoverFrame : public BasicFrame {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Server will try to requeue messages. If requeue is false or requeue attempt fails, messages are discarded or dead-lettered
|
||||||
|
* @var BooleanSet
|
||||||
|
*/
|
||||||
|
BooleanSet _requeue;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
|
||||||
|
// encode fields
|
||||||
|
_requeue.fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic recover frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicRecoverFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame),
|
||||||
|
_requeue(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic recover frame
|
||||||
|
*
|
||||||
|
* @param channel channel ID
|
||||||
|
* @param requeue whether to attempt to requeue messages
|
||||||
|
*/
|
||||||
|
BasicRecoverFrame(uint16_t channel, bool requeue = false) :
|
||||||
|
BasicFrame(channel, 1), //sizeof bool
|
||||||
|
_requeue(requeue)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicRecoverFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a synchronous frame?
|
||||||
|
*
|
||||||
|
* After a synchronous frame no more frames may be
|
||||||
|
* sent until the accompanying -ok frame arrives
|
||||||
|
*/
|
||||||
|
bool synchronous() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 110;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the server will try to requeue
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool requeue() const
|
||||||
|
{
|
||||||
|
return _requeue.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
87
builder/libs/AMQP-CPP/src/basicrecoverokframe.h
Normal file
87
builder/libs/AMQP-CPP/src/basicrecoverokframe.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* Class describing a basic recover-async frame
|
||||||
|
*
|
||||||
|
* @copyright 2014 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up namespace
|
||||||
|
*/
|
||||||
|
namespace AMQP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
class BasicRecoverOKFrame : public BasicFrame {
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Encode a frame on a string buffer
|
||||||
|
*
|
||||||
|
* @param buffer buffer to write frame to
|
||||||
|
*/
|
||||||
|
virtual void fill(OutBuffer& buffer) const override
|
||||||
|
{
|
||||||
|
// call base then done, no other fields to encode
|
||||||
|
BasicFrame::fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a basic recover ok frame from a received frame
|
||||||
|
*
|
||||||
|
* @param frame received frame
|
||||||
|
*/
|
||||||
|
BasicRecoverOKFrame(ReceivedFrame &frame) :
|
||||||
|
BasicFrame(frame)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a basic recover ok frame
|
||||||
|
*
|
||||||
|
* @param channel channel id
|
||||||
|
*/
|
||||||
|
BasicRecoverOKFrame(uint16_t channel) :
|
||||||
|
BasicFrame(channel, 0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~BasicRecoverOKFrame() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method ID
|
||||||
|
* @return uint16_t
|
||||||
|
*/
|
||||||
|
virtual uint16_t methodID() const override
|
||||||
|
{
|
||||||
|
return 111;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the frame
|
||||||
|
* @param connection The connection over which it was received
|
||||||
|
* @return bool Was it succesfully processed?
|
||||||
|
*/
|
||||||
|
virtual bool process(ConnectionImpl *connection) override
|
||||||
|
{
|
||||||
|
// we need the appropriate channel
|
||||||
|
auto channel = connection->channel(this->channel());
|
||||||
|
|
||||||
|
// channel does not exist
|
||||||
|
if (!channel) return false;
|
||||||
|
|
||||||
|
// report
|
||||||
|
channel->reportSuccess();
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of namespace
|
||||||
|
*/
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user