PROTON-865: C++ binding API documentation and cleanup. - API doc comments on most of API, some TODO notes left in headers. - Use proton::url consistently rather than std::string in API where appropriate. - Fix some const issues. - Clean up messaging_event enum names, add event_type constants to proton_event. - Consistent option parsing for examples, python compatible.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/035b6957 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/035b6957 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/035b6957 Branch: refs/heads/cjansen-cpp-client Commit: 035b6957ce92ed033876ca81b149014d7c5cc0d6 Parents: cdad4dd Author: Alan Conway <[email protected]> Authored: Tue Jul 14 18:53:11 2015 -0400 Committer: Alan Conway <[email protected]> Committed: Thu Jul 16 01:20:25 2015 -0400 ---------------------------------------------------------------------- examples/cpp/broker.cpp | 13 +- examples/cpp/direct_recv.cpp | 55 +---- examples/cpp/direct_send.cpp | 54 +---- examples/cpp/encode_decode.cpp | 3 +- examples/cpp/example_test.py | 2 +- examples/cpp/helloworld.cpp | 15 +- examples/cpp/helloworld_blocking.cpp | 23 +- examples/cpp/helloworld_direct.cpp | 20 +- examples/cpp/options.hpp | 173 +++++++++++++ examples/cpp/simple_recv.cpp | 55 ++--- examples/cpp/simple_send.cpp | 54 +---- proton-c/bindings/cpp/README.md | 8 +- proton-c/bindings/cpp/docs/tutorial.md | 38 +-- .../bindings/cpp/include/proton/acceptor.hpp | 3 + proton-c/bindings/cpp/include/proton/acking.hpp | 9 + .../cpp/include/proton/blocking_connection.hpp | 9 +- .../cpp/include/proton/blocking_link.hpp | 1 + .../cpp/include/proton/blocking_sender.hpp | 1 + proton-c/bindings/cpp/include/proton/config.hpp | 30 +++ .../bindings/cpp/include/proton/connection.hpp | 26 +- .../bindings/cpp/include/proton/container.hpp | 49 +++- proton-c/bindings/cpp/include/proton/data.hpp | 2 +- .../bindings/cpp/include/proton/decoder.hpp | 10 +- .../bindings/cpp/include/proton/delivery.hpp | 21 +- .../bindings/cpp/include/proton/duration.hpp | 12 +- .../bindings/cpp/include/proton/encoder.hpp | 5 +- .../bindings/cpp/include/proton/endpoint.hpp | 35 ++- proton-c/bindings/cpp/include/proton/error.hpp | 7 +- proton-c/bindings/cpp/include/proton/event.hpp | 20 +- proton-c/bindings/cpp/include/proton/export.hpp | 2 + proton-c/bindings/cpp/include/proton/handle.hpp | 4 +- .../bindings/cpp/include/proton/handler.hpp | 7 +- proton-c/bindings/cpp/include/proton/link.hpp | 27 ++- .../bindings/cpp/include/proton/message.hpp | 32 ++- .../cpp/include/proton/messaging_adapter.hpp | 4 +- .../cpp/include/proton/messaging_event.hpp | 95 ++++---- .../cpp/include/proton/messaging_handler.hpp | 19 +- .../cpp/include/proton/proton_event.hpp | 242 ++++++++++++++++++- .../cpp/include/proton/proton_handle.hpp | 2 + .../cpp/include/proton/proton_handler.hpp | 7 +- .../bindings/cpp/include/proton/receiver.hpp | 1 + proton-c/bindings/cpp/include/proton/sender.hpp | 4 +- .../bindings/cpp/include/proton/session.hpp | 29 ++- .../bindings/cpp/include/proton/terminus.hpp | 8 +- .../bindings/cpp/include/proton/transport.hpp | 3 + .../bindings/cpp/include/proton/type_traits.hpp | 19 +- proton-c/bindings/cpp/include/proton/types.hpp | 86 +++---- proton-c/bindings/cpp/include/proton/url.hpp | 28 ++- .../cpp/include/proton/wait_condition.hpp | 3 + .../bindings/cpp/src/blocking_connection.cpp | 5 +- .../cpp/src/blocking_connection_impl.cpp | 3 +- proton-c/bindings/cpp/src/connection.cpp | 2 +- proton-c/bindings/cpp/src/connection_impl.cpp | 2 +- proton-c/bindings/cpp/src/connection_impl.hpp | 2 +- proton-c/bindings/cpp/src/container.cpp | 6 +- proton-c/bindings/cpp/src/container_impl.cpp | 12 +- proton-c/bindings/cpp/src/container_impl.hpp | 4 +- proton-c/bindings/cpp/src/decoder.cpp | 1 - proton-c/bindings/cpp/src/endpoint.cpp | 10 + proton-c/bindings/cpp/src/error.cpp | 2 + proton-c/bindings/cpp/src/link.cpp | 2 +- proton-c/bindings/cpp/src/message.cpp | 11 +- proton-c/bindings/cpp/src/messaging_adapter.cpp | 54 ++--- proton-c/bindings/cpp/src/messaging_event.cpp | 83 ++++--- proton-c/bindings/cpp/src/proton_event.cpp | 144 +++++++---- proton-c/bindings/cpp/src/session.cpp | 4 +- proton-c/bindings/cpp/src/url.cpp | 21 ++ proton-c/include/proton/message.h | 2 +- 68 files changed, 1200 insertions(+), 545 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/broker.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp index 86f5b89..a57fff9 100644 --- a/examples/cpp/broker.cpp +++ b/examples/cpp/broker.cpp @@ -19,6 +19,8 @@ * */ +#include "options.hpp" + #include "proton/container.hpp" #include "proton/messaging_handler.hpp" #include "proton/url.hpp" @@ -196,12 +198,19 @@ class broker : public proton::messaging_handler { }; int main(int argc, char **argv) { + // Command line options + proton::url url("0.0.0.0"); + options opts(argc, argv); + opts.add_value(url, 'a', "address", "listen on URL", "URL"); try { - std::string url(argc > 1 ? argv[1] : "0.0.0.0"); + opts.parse(); broker broker(url); proton::container(broker).run(); + return 0; + } catch (const bad_option& e) { + std::cout << opts << std::endl << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/direct_recv.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp index 5c8c808..9eead92 100644 --- a/examples/cpp/direct_recv.cpp +++ b/examples/cpp/direct_recv.cpp @@ -19,6 +19,8 @@ * */ +#include "options.hpp" + #include "proton/container.hpp" #include "proton/messaging_handler.hpp" #include "proton/link.hpp" @@ -30,8 +32,6 @@ #include <stdio.h> #include <string.h> - - class direct_recv : public proton::messaging_handler { private: proton::url url; @@ -66,52 +66,23 @@ class direct_recv : public proton::messaging_handler { } }; -static void parse_options(int argc, char **argv, int &count, std::string &addr); - int main(int argc, char **argv) { + // Command line options + std::string address("127.0.0.1:5672/examples"); + int message_count = 100; + options opts(argc, argv); + opts.add_value(address, 'a', "address", "listen and receive on URL", "URL"); + opts.add_value(message_count, 'm', "messages", "receive COUNT messages", "COUNT"); try { - int message_count = 100; - std::string address("127.0.0.1:5672/examples"); - parse_options(argc, argv, message_count, address); + opts.parse(); direct_recv recv(address, message_count); proton::container(recv).run(); + return 0; + } catch (const bad_option& e) { + std::cout << opts << std::endl << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; } + return 1; } - -static void usage() { - std::cout << "Usage: direct_recv -m message_count -a address:" << std::endl; - exit (1); -} - - -static void parse_options(int argc, char **argv, int &count, std::string &addr) { - int c, i; - for (i = 1; i < argc; i++) { - if (strlen(argv[i]) == 2 && argv[i][0] == '-') { - c = argv[i][1]; - const char *nextarg = i < argc ? argv[i+1] : NULL; - - switch (c) { - case 'a': - if (!nextarg) usage(); - addr = nextarg; - i++; - break; - case 'm': - if (!nextarg) usage(); - unsigned newc; - if (sscanf( nextarg, "%d", &newc) != 1) usage(); - count = newc; - i++; - break; - default: - usage(); - } - } - else usage(); - } -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/direct_send.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp index 9ffa28a..a4e572c 100644 --- a/examples/cpp/direct_send.cpp +++ b/examples/cpp/direct_send.cpp @@ -19,6 +19,8 @@ * */ +#include "options.hpp" + #include "proton/container.hpp" #include "proton/messaging_handler.hpp" #include "proton/connection.hpp" @@ -74,52 +76,22 @@ class simple_send : public proton::messaging_handler { } }; -static void parse_options(int argc, char **argv, int &count, std::string &addr); - int main(int argc, char **argv) { + // Command line options + std::string address("127.0.0.1:5672/examples"); + int message_count = 100; + options opts(argc, argv); + opts.add_value(address, 'a', "address", "listen and send on URL", "URL"); + opts.add_value(message_count, 'm', "messages", "send COUNT messages", "COUNT"); try { - int message_count = 100; - std::string address("127.0.0.1:5672/examples"); - parse_options(argc, argv, message_count, address); + opts.parse(); simple_send send(address, message_count); proton::container(send).run(); + return 0; + } catch (const bad_option& e) { + std::cout << opts << std::endl << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; - } -} - - -static void usage() { - std::cout << "Usage: simple_send -m message_count -a address:" << std::endl; - exit (1); -} - - -static void parse_options(int argc, char **argv, int &count, std::string &addr) { - int c, i; - for (i = 1; i < argc; i++) { - if (strlen(argv[i]) == 2 && argv[i][0] == '-') { - c = argv[i][1]; - const char *nextarg = i < argc ? argv[i+1] : NULL; - - switch (c) { - case 'a': - if (!nextarg) usage(); - addr = nextarg; - i++; - break; - case 'm': - if (!nextarg) usage(); - unsigned newc; - if (sscanf( nextarg, "%d", &newc) != 1) usage(); - count = newc; - i++; - break; - default: - usage(); - } - } - else usage(); } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/encode_decode.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp index df9ad15..ea0f471 100644 --- a/examples/cpp/encode_decode.cpp +++ b/examples/cpp/encode_decode.cpp @@ -175,10 +175,11 @@ int main(int, char**) { insert_extract_containers(); mixed_containers(); insert_extract_stream_operators(); + return 0; } catch (const exception& e) { cerr << endl << "error: " << e.what() << endl; - return 1; } + return 1; } // print_next prints the next value from values by recursively descending into complex values. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/example_test.py ---------------------------------------------------------------------- diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py index b2110f6..8dd4341 100644 --- a/examples/cpp/example_test.py +++ b/examples/cpp/example_test.py @@ -94,7 +94,7 @@ class Broker(object): def __init__(self): self.addr = pick_addr() - cmd = [exe_name("broker"), self.addr] + cmd = [exe_name("broker"), "-a", self.addr] try: self.process = Popen(cmd, stdout=NULL, stderr=NULL) wait_addr(self.addr) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/helloworld.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp index 13bdbc7..34e5076 100644 --- a/examples/cpp/helloworld.cpp +++ b/examples/cpp/helloworld.cpp @@ -27,16 +27,16 @@ class hello_world : public proton::messaging_handler { private: - proton::url server; - std::string address; + proton::url url; + public: - hello_world(const proton::url &url) : server(url), address(url.path()) {} + hello_world(const proton::url& u) : url(u) {} void on_start(proton::event &e) { - proton::connection conn = e.container().connect(server); - e.container().create_receiver(conn, address); - e.container().create_sender(conn, address); + proton::connection conn = e.container().connect(url); + e.container().create_receiver(conn, url.path()); + e.container().create_sender(conn, url.path()); } void on_sendable(proton::event &e) { @@ -58,8 +58,9 @@ int main(int argc, char **argv) { std::string url = argc > 1 ? argv[1] : "127.0.0.1:5672/examples"; hello_world hw(url); proton::container(hw).run(); + return 0; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/helloworld_blocking.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/helloworld_blocking.cpp b/examples/cpp/helloworld_blocking.cpp index ff14320..2b6b4db 100644 --- a/examples/cpp/helloworld_blocking.cpp +++ b/examples/cpp/helloworld_blocking.cpp @@ -27,15 +27,15 @@ class hello_world_blocking : public proton::messaging_handler { private: - std::string server; - std::string address; + proton::url url; + public: - hello_world_blocking(const std::string &s, const std::string &addr) : server(s), address(addr) {} + hello_world_blocking(const proton::url& u) : url(u) {} void on_start(proton::event &e) { - proton::connection conn = e.container().connect(server); - e.container().create_receiver(conn, address); + proton::connection conn = e.container().connect(url); + e.container().create_receiver(conn, url.path()); } void on_message(proton::event &e) { @@ -47,20 +47,21 @@ class hello_world_blocking : public proton::messaging_handler { int main(int argc, char **argv) { try { - std::string server = argc > 1 ? argv[1] : ":5672"; - std::string addr = argc > 2 ? argv[2] : "examples"; - proton::blocking_connection conn(server); - proton::blocking_sender sender = conn.create_sender(addr); + proton::url url(argc > 1 ? argv[1] : "127.0.0.1:5672/examples"); + + proton::blocking_connection conn(url); + proton::blocking_sender sender = conn.create_sender(url.path()); proton::message m; m.body("Hello World!"); sender.send(m); conn.close(); // TODO Temporary hack until blocking receiver available - hello_world_blocking hw(server, addr); + hello_world_blocking hw(url); proton::container(hw).run(); + return 0; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/helloworld_direct.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp index d81d2b7..2c7792e 100644 --- a/examples/cpp/helloworld_direct.cpp +++ b/examples/cpp/helloworld_direct.cpp @@ -27,15 +27,15 @@ class hello_world_direct : public proton::messaging_handler { private: - proton::url url_; - proton::acceptor acceptor_; + proton::url url; + proton::acceptor acceptor; public: - hello_world_direct(const std::string &u) : url_(u) {} + hello_world_direct(const proton::url& u) : url(u) {} void on_start(proton::event &e) { - acceptor_ = e.container().listen(url_); - e.container().create_sender(url_); + acceptor = e.container().listen(url); + e.container().create_sender(url); } void on_sendable(proton::event &e) { @@ -54,18 +54,20 @@ class hello_world_direct : public proton::messaging_handler { } void on_connection_closed(proton::event &e) { - acceptor_.close(); + acceptor.close(); } - }; int main(int argc, char **argv) { try { - std::string url = argc > 1 ? argv[1] : ":8888/examples"; + // Pick an "unusual" port since we are going to be talking to ourselves, not a broker. + std::string url = argc > 1 ? argv[1] : "127.0.0.1:8888/examples"; + hello_world_direct hwd(url); proton::container(hwd).run(); + return 0; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/options.hpp ---------------------------------------------------------------------- diff --git a/examples/cpp/options.hpp b/examples/cpp/options.hpp new file mode 100644 index 0000000..5378507 --- /dev/null +++ b/examples/cpp/options.hpp @@ -0,0 +1,173 @@ +#ifndef OPTIONS_HPP +#define OPTIONS_HPP +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string> +#include <sstream> +#include <ostream> +#include <vector> +#include <stdexcept> + +/** bad_option is thrown for option parsing errors */ +struct bad_option : public std::runtime_error { + bad_option(const std::string& s) : std::runtime_error(s) {} +}; + +/** Simple command-line option parser for example programs */ +class options { + public: + + options(int argc, char const * const * argv) : argc_(argc), argv_(argv), prog_(argv[0]), help_() { + size_t slash = prog_.find_last_of("/\\"); + if (slash != std::string::npos) + prog_ = prog_.substr(slash+1); // Extract prog name from path + add_flag(help_, 'h', "help", "Print the help message"); + } + + ~options() { + for (opts::iterator i = opts_.begin(); i != opts_.end(); ++i) + delete *i; + } + + /** Updates value when parse() is called if option is present with a value. */ + template<class T> + void add_value(T& value, char short_name, const std::string& long_name, const std::string& description, const std::string var) { + opts_.push_back(new option_value<T>(value, short_name, long_name, description, var)); + } + + /** Sets flag when parse() is called if option is present. */ + void add_flag(bool& flag, char short_name, const std::string& long_name, const std::string& description) { + opts_.push_back(new option_flag(flag, short_name, long_name, description)); + } + + /** Parse the command line, return the index of the first non-option argument. + *@throws bad_option if there is a parsing error or unknown option. + */ + int parse() { + int arg = 1; + for (; arg < argc_ && argv_[arg][0] == '-'; ++arg) { + opts::iterator i = opts_.begin(); + while (i != opts_.end() && !(*i)->parse(argc_, argv_, arg)) + ++i; + if (i == opts_.end()) + throw bad_option(std::string("unknown option ") + argv_[arg]); + } + if (help_) throw bad_option(""); + return arg; + } + + /** Print a usage message */ + friend std::ostream& operator<<(std::ostream& os, const options& op) { + os << std::endl << "usage: " << op.prog_ << " [options]" << std::endl; + os << std::endl << "options:" << std::endl; + for (opts::const_iterator i = op.opts_.begin(); i < op.opts_.end(); ++i) + os << **i << std::endl; + return os; + } + + private: + class option { + public: + option(char s, const std::string& l, const std::string& d, const std::string v) : + short_(std::string("-") + s), long_("--" + l), desc_(d), var_(v) {} + virtual ~option() {} + + virtual bool parse(int argc, char const * const * argv, int &i) = 0; + virtual void print_default(std::ostream&) const {}; + + friend std::ostream& operator<<(std::ostream& os, const option& op) { + os << " " << op.short_; + if (!op.var_.empty()) os << " " << op.var_; + os << ", " << op.long_; + if (!op.var_.empty()) os << "=" << op.var_; + os << std::endl << " " << op.desc_; + op.print_default(os); + return os; + } + + protected: + std::string short_, long_, desc_, var_; + }; + + template <class T> + class option_value : public option { + public: + option_value(T& value, char s, const std::string& l, const std::string& d, const std::string& v) : + option(s, l, d, v), value_(value) {} + + bool parse(int argc, char const * const * argv, int &i) { + std::string arg(argv[i]); + if (arg == short_ || arg == long_) { + if (i < argc-1) { + set_value(arg, argv[++i]); + return true; + } else { + throw bad_option("missing value for " + arg); + } + } + if (arg.compare(0, long_.size(), long_) == 0 && arg[long_.size()] == '=' ) { + set_value(long_, arg.substr(long_.size()+1)); + return true; + } + return false; + } + + virtual void print_default(std::ostream& os) const { os << " (default " << value_ << ")"; } + + void set_value(const std::string& opt, const std::string& s) { + std::istringstream is(s); + is >> value_; + if (is.fail() || is.bad()) + throw bad_option("bad value for " + opt + ": " + s); + } + + private: + T& value_; + }; + + class option_flag: public option { + public: + option_flag(bool& flag, const char s, const std::string& l, const std::string& d) : + option(s, l, d, ""), flag_(flag) + { flag_ = false; } + + bool parse(int /*argc*/, char const * const * argv, int &i) { + if (argv[i] == short_ || argv[i] == long_) { + flag_ = true; + return true; + } else { + return false; + } + } + + private: + bool &flag_; + }; + + typedef std::vector<option*> opts; + + int argc_; + char const * const * argv_; + std::string prog_; + opts opts_; + bool help_; +}; + +#endif // OPTIONS_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/simple_recv.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp index 8cc8bc4..b2cec63 100644 --- a/examples/cpp/simple_recv.cpp +++ b/examples/cpp/simple_recv.cpp @@ -19,6 +19,8 @@ * */ +#include "options.hpp" + #include "proton/container.hpp" #include "proton/messaging_handler.hpp" #include "proton/link.hpp" @@ -63,52 +65,23 @@ class simple_recv : public proton::messaging_handler { } }; -static void parse_options(int argc, char **argv, int &count, std::string &addr); - int main(int argc, char **argv) { + // Command line options + std::string address("127.0.0.1:5672/examples"); + int message_count = 100; + options opts(argc, argv); + opts.add_value(address, 'a', "address", "connect to and receive from URL", "URL"); + opts.add_value(message_count, 'm', "messages", "receive COUNT messages", "COUNT"); + try { - int message_count = 100; - std::string address("127.0.0.1:5672/examples"); - parse_options(argc, argv, message_count, address); + opts.parse(); simple_recv recv(address, message_count); proton::container(recv).run(); + return 0; + } catch (const bad_option& e) { + std::cout << opts << std::endl << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; - } -} - - -static void usage() { - std::cout << "Usage: simple_recv -m message_count -a address:" << std::endl; - exit (1); -} - - -static void parse_options(int argc, char **argv, int &count, std::string &addr) { - int c, i; - for (i = 1; i < argc; i++) { - if (strlen(argv[i]) == 2 && argv[i][0] == '-') { - c = argv[i][1]; - const char *nextarg = i < argc ? argv[i+1] : NULL; - - switch (c) { - case 'a': - if (!nextarg) usage(); - addr = nextarg; - i++; - break; - case 'm': - if (!nextarg) usage(); - unsigned newc; - if (sscanf( nextarg, "%d", &newc) != 1) usage(); - count = newc; - i++; - break; - default: - usage(); - } - } - else usage(); } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/examples/cpp/simple_send.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp index 0cf4cd3..0bac49b 100644 --- a/examples/cpp/simple_send.cpp +++ b/examples/cpp/simple_send.cpp @@ -19,6 +19,8 @@ * */ +#include "options.hpp" + #include "proton/container.hpp" #include "proton/messaging_handler.hpp" #include "proton/connection.hpp" @@ -71,52 +73,22 @@ class simple_send : public proton::messaging_handler { } }; -static void parse_options(int argc, char **argv, int &count, std::string &addr); - int main(int argc, char **argv) { + // Command line options + std::string address("127.0.0.1:5672/examples"); + int message_count = 100; + options opts(argc, argv); + opts.add_value(address, 'a', "address", "connect and send to URL", "URL"); + opts.add_value(message_count, 'm', "messages", "receive COUNT messages", "COUNT"); try { - int message_count = 100; - std::string address("127.0.0.1:5672/examples"); - parse_options(argc, argv, message_count, address); + opts.parse(); simple_send send(address, message_count); proton::container(send).run(); + return 0; + } catch (const bad_option& e) { + std::cout << opts << std::endl << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return 1; - } -} - - -static void usage() { - std::cout << "Usage: simple_send -m message_count -a address:" << std::endl; - exit (1); -} - - -static void parse_options(int argc, char **argv, int &count, std::string &addr) { - int c, i; - for (i = 1; i < argc; i++) { - if (strlen(argv[i]) == 2 && argv[i][0] == '-') { - c = argv[i][1]; - const char *nextarg = i < argc ? argv[i+1] : NULL; - - switch (c) { - case 'a': - if (!nextarg) usage(); - addr = nextarg; - i++; - break; - case 'm': - if (!nextarg) usage(); - unsigned newc; - if (sscanf( nextarg, "%d", &newc) != 1) usage(); - count = newc; - i++; - break; - default: - usage(); - } - } - else usage(); } + return 1; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/README.md ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/README.md b/proton-c/bindings/cpp/README.md index b6640e5..28eabbe 100644 --- a/proton-c/bindings/cpp/README.md +++ b/proton-c/bindings/cpp/README.md @@ -8,10 +8,8 @@ API documentation in doxygen format. # TO DO Doc & examples -- Example set with tutorial documentation. Follow pyton examples + C++ encode/decode example. - - Consistent option parsing for examples, like other languages. - - Auto tests for all examples validating all statements & code in tutorial. -- API documentation, fill out & organize for readable doxygen HTML. +- Finish example set and tutorial documentation, following pyton examples. +- Auto tests for all examples validating all statements & code in tutorial. - C++ section on website. Bugs @@ -19,7 +17,7 @@ Bugs - Drop PIMPL pattern in API: pn_foo pointer is already hiding the impl. - Proper ownership of pn_objects created by user, e.g. Message. Let user choose pointer style? - Error handling, examples crash on error e.g. queue not found. -- FIXME and TODO notes in code. +- TODO notes in code. Tests - Interop/type testing for full AMQP type coverage. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/docs/tutorial.md ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/docs/tutorial.md b/proton-c/bindings/cpp/docs/tutorial.md index 91c3c91..e695aaf 100644 --- a/proton-c/bindings/cpp/docs/tutorial.md +++ b/proton-c/bindings/cpp/docs/tutorial.md @@ -5,23 +5,18 @@ This is a brief tutorial that will walk you through the fundamentals of building messaging applications in incremental steps. There are further examples, in addition the ones mentioned in the tutorial. -Note on Brokers and URLs ------------------------- +Some of the examples require an AMQP *broker* that can receive, store and send +messages. \ref broker.cpp is a simple example broker which you can use. When run +without arguments it listens on `0.0.0.0:5672`, the standard AMQP port on all +network interfaces. To use a different port or network interface: -Some of the examples require an AMQP *broker* that can receive, store and send messages. - -There is a very simple broker included as an example (\ref broker.cpp) which you can use. -Run it like this: - - broker [URL] - -The default URL is "0.0.0.0:5672" which listens on the standard AMQP port on all -network interfaces. + broker -a <host>:<port> Instead of the example broker, you can use any AMQP 1.0 compliant broker. You must configure your broker to have a queue (or topic) named "examples". -Most of the examples take an optional URL argument, the simplest form is: +Most of the examples take an optional URL argument or `-a URL` option the +URL looks like: HOST:PORT/ADDRESS @@ -140,6 +135,11 @@ event loop exits, and the run() method will return. So now we have our example working without a broker involved! +Note that for this example we paick an "unusual" port 8888 since we are talking +to ourselves rather than a broker. + +\skipline url = + Asynchronous Send and Receive ----------------------------- @@ -212,7 +212,7 @@ got to. \dontinclude simple_recv.cpp -Now let's look at the corresponding receiver \ref simple_recv.cpp: +Now let's look at the corresponding receiver \ref simple_recv.cpp This time we'll use an `expected` member variable for for the number of messages we expecct and a `received` variable to count how many we have received so far.send. @@ -295,7 +295,7 @@ as a simple broker for testing purposes is an example of this). Request/Response ---------------- -\todo FIXME missing example in C++ +\todo TODO missing example in C++ A common pattern is to send a request message and expect a response message in return. AMQP has special support for this pattern. Let's have a look at a simple @@ -303,7 +303,7 @@ example. We'll start with \ref server.cpp, the program that will process the request and send the response. Note that we are still using a broker in this example. -\todo FIXME insert server snips +\todo TODO insert server snips Our server will provide a very simple service: it will respond with the body of the request converted to uppercase. @@ -316,7 +316,7 @@ reply\_to. Now let's create a simple \ref client.cpp to test this service out. -\todo FIXME insert client snips +\todo TODO insert client snips As well as sending requests, we need to be able to get back the responses. We create a receiver for that (see line 14), but we don't @@ -335,7 +335,7 @@ Again, we could avoid having any intermediary process here if we wished. The following code implementas a server to which the client above could connect directly without any need for a broker or similar. -\todo FIXME missing server_direct.cpp +\todo TODO missing server_direct.cpp Though this requires some more extensive changes than the simple sending and receiving examples, the essence of the program is still the same. @@ -349,7 +349,7 @@ Many brokers offer the ability to consume messages based on a 'selector' that defines which messages are of interest based on particular values of the headers. The following example shows how that can be achieved: -\todo FIXME selected_recv.cpp +\todo TODO selected_recv.cpp When creating the receiver, we specify a Selector object as an option. The options argument can take a single object or a list. Another option @@ -359,4 +359,4 @@ done in AMQP by specifying a distribution mode of 'copy' (instead of 'move' which is the expected default for queues). An example of that is shown next: -\todo FIXME queue_browser.cpp +\todo TODO queue_browser.cpp http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/acceptor.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/acceptor.hpp b/proton-c/bindings/cpp/include/proton/acceptor.hpp index 0df9589..bc9edbc 100644 --- a/proton-c/bindings/cpp/include/proton/acceptor.hpp +++ b/proton-c/bindings/cpp/include/proton/acceptor.hpp @@ -30,6 +30,7 @@ struct pn_connection_t; namespace proton { +/** acceptor accepts connections. @see container::listen */ class acceptor : public proton_handle<pn_acceptor_t> { public: @@ -39,7 +40,9 @@ class acceptor : public proton_handle<pn_acceptor_t> PN_CPP_EXTERN acceptor& operator=(const acceptor&); PN_CPP_EXTERN ~acceptor(); + /** close the acceptor */ PN_CPP_EXTERN void close(); + private: friend class proton_impl_ref<acceptor>; }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/acking.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/acking.hpp b/proton-c/bindings/cpp/include/proton/acking.hpp index edc2d81..0001a4d 100644 --- a/proton-c/bindings/cpp/include/proton/acking.hpp +++ b/proton-c/bindings/cpp/include/proton/acking.hpp @@ -28,12 +28,19 @@ namespace proton { +/** acking provides simple functions to acknowledge, or settle, a delivery */ class acking { public: + /** accept a delivery */ PN_CPP_EXTERN virtual void accept(delivery &d); + /** reject a delivery */ PN_CPP_EXTERN virtual void reject(delivery &d); + /** release a delivery. Mark it delivery::MODIFIED if it has already been delivered, + * delivery::RELEASED otherwise. + */ PN_CPP_EXTERN virtual void release(delivery &d, bool delivered=true); + /** settle a delivery with the given delivery::state */ PN_CPP_EXTERN virtual void settle(delivery &d, delivery::state s = delivery::REJECTED); }; @@ -41,3 +48,5 @@ class acking } #endif /*!PROTON_CPP_ACKING_H*/ + + http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/blocking_connection.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp index 27d7cdd..9aa456f 100644 --- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp +++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp @@ -33,13 +33,14 @@ struct pn_connection_t; namespace proton { - +class url; class container; class blocking_connection_impl; class ssl_domain; class blocking_sender; class wait_condition; +// TODO documentation class blocking_connection : public handle<blocking_connection_impl> { public: @@ -48,11 +49,11 @@ class blocking_connection : public handle<blocking_connection_impl> PN_CPP_EXTERN blocking_connection& operator=(const blocking_connection& c); PN_CPP_EXTERN ~blocking_connection(); - PN_CPP_EXTERN blocking_connection(std::string &url, duration = duration::FOREVER, - ssl_domain *ssld=0, container *c=0); + PN_CPP_EXTERN blocking_connection(const proton::url &url, duration = duration::FOREVER, + ssl_domain *ssld=0, container *c=0); PN_CPP_EXTERN void close(); - PN_CPP_EXTERN blocking_sender create_sender(std::string &address, handler *h=0); + PN_CPP_EXTERN blocking_sender create_sender(const std::string &address, handler *h=0); PN_CPP_EXTERN void wait(wait_condition &condition); PN_CPP_EXTERN void wait(wait_condition &condition, std::string &msg, duration timeout=duration::FOREVER); PN_CPP_EXTERN duration timeout(); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/blocking_link.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/blocking_link.hpp b/proton-c/bindings/cpp/include/proton/blocking_link.hpp index c1872a4..0fe5e9a 100644 --- a/proton-c/bindings/cpp/include/proton/blocking_link.hpp +++ b/proton-c/bindings/cpp/include/proton/blocking_link.hpp @@ -35,6 +35,7 @@ namespace proton { class blocking_connection; +// TODO documentation class blocking_link { public: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/blocking_sender.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp index 0df5a9c..0fa89d9 100644 --- a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp +++ b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp @@ -37,6 +37,7 @@ namespace proton { class blocking_connection; class blocking_link; +// TODO documentation class blocking_sender : public blocking_link { public: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/config.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/config.hpp b/proton-c/bindings/cpp/include/proton/config.hpp new file mode 100644 index 0000000..70260b7 --- /dev/null +++ b/proton-c/bindings/cpp/include/proton/config.hpp @@ -0,0 +1,30 @@ +#ifndef CONFIG_HPP +#define CONFIG_HPP +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/**@file + * @internal + */ + +#if (defined(__cplusplus) && __cplusplus >= 201100) || (defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729) +#define USE_CPP11 +#endif + +#endif // CONFIG_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/connection.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp index 9998a0a..af3c585 100644 --- a/proton-c/bindings/cpp/include/proton/connection.hpp +++ b/proton-c/bindings/cpp/include/proton/connection.hpp @@ -36,6 +36,7 @@ class handler; class transport; class connection_impl; +/** connection is the local end of a connectoin to a remote AMQP peer. */ class connection : public endpoint, public handle<connection_impl> { public: @@ -47,15 +48,32 @@ class connection : public endpoint, public handle<connection_impl> PN_CPP_EXTERN connection& operator=(const connection& c); + ///@name getters @{ PN_CPP_EXTERN class transport& transport(); PN_CPP_EXTERN handler *override(); - PN_CPP_EXTERN void override(handler *h); - PN_CPP_EXTERN void open(); - PN_CPP_EXTERN void close(); PN_CPP_EXTERN pn_connection_t *pn_connection(); PN_CPP_EXTERN class container &container(); PN_CPP_EXTERN std::string hostname(); - PN_CPP_EXTERN link link_head(endpoint::State mask); + ///@} + + /** override the handler for this connection */ + PN_CPP_EXTERN void override(handler *h); + + /** Initiate local open, not complete till messaging_handler::on_connection_opened() + * or proton_handler::on_connection_remote_open() + */ + PN_CPP_EXTERN void open(); + + /** Initiate local close, not complete till messaging_handler::on_connection_closed() + * or proton_handler::on_connection_remote_close() + */ + PN_CPP_EXTERN void close(); + + /** Get the first link on this connection matching the state mask. + * @see link::next, endpoint::state + */ + PN_CPP_EXTERN link link_head(endpoint::state mask); + private: friend class private_impl_ref<connection>; friend class connector; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/container.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp index 2aaa289..ec55167 100644 --- a/proton-c/bindings/cpp/include/proton/container.hpp +++ b/proton-c/bindings/cpp/include/proton/container.hpp @@ -40,35 +40,70 @@ class messaging_handler; class sender; class receiver; class link; - class handler; +class handler; +/** Top level container for connections and other objects, runs the event loop */ class container : public handle<container_impl> { public: + ///@name internal @internal @{ PN_CPP_EXTERN container(container_impl *); PN_CPP_EXTERN container(const container& c); PN_CPP_EXTERN container& operator=(const container& c); PN_CPP_EXTERN ~container(); + ///@} + /** Create a container */ PN_CPP_EXTERN container(); + + /** Create a container and set the top-level messaging_handler */ PN_CPP_EXTERN container(messaging_handler &mhandler); + + /** Locally open a connection @see connection::open */ PN_CPP_EXTERN connection connect(const proton::url&, handler *h=0); + + /** Run the event loop, return when all connections and acceptors are closed. */ PN_CPP_EXTERN void run(); + + /** Start the reactor, you must call process() to process events */ PN_CPP_EXTERN void start(); + + /** Process events, return true if there are more events to process. */ PN_CPP_EXTERN bool process(); + + /** Stop the reactor, causes run() to return and process() to return false. */ PN_CPP_EXTERN void stop(); - PN_CPP_EXTERN void wakeup(); - PN_CPP_EXTERN bool is_quiesced(); - PN_CPP_EXTERN pn_reactor_t *reactor(); - PN_CPP_EXTERN sender create_sender(connection &connection, std::string &addr, handler *h=0); + + /** Create a sender on connection with target=addr and optional handler h */ + PN_CPP_EXTERN sender create_sender(connection &connection, const std::string &addr, handler *h=0); + + /** Open a connection to url and create a sender with target=url.path() */ PN_CPP_EXTERN sender create_sender(const proton::url &); - PN_CPP_EXTERN receiver create_receiver(connection &connection, std::string &addr); + + /** Create a receiver on connection with target=addr and optional handler h */ + PN_CPP_EXTERN receiver create_receiver(connection &connection, const std::string &addr, handler *h=0); + + /** Create a receiver on connection with source=addr and optional handler h */ PN_CPP_EXTERN receiver create_receiver(const url &); + + /** Open a connection to url and create a receiver with source=url.path() */ PN_CPP_EXTERN acceptor listen(const proton::url &); + + /// Identifier for the container PN_CPP_EXTERN std::string container_id(); + + /// Get timeout, process() will return if there is no activity within the timeout. PN_CPP_EXTERN duration timeout(); + + /// Set timeout, process() will return if there is no activity within the timeout. PN_CPP_EXTERN void timeout(duration timeout); - private: + + /// Get the reactor + PN_CPP_EXTERN pn_reactor_t *reactor(); + + PN_CPP_EXTERN void wakeup(); + PN_CPP_EXTERN bool is_quiesced(); +private: friend class private_impl_ref<container>; }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/data.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/data.hpp b/proton-c/bindings/cpp/include/proton/data.hpp index c0d3e8c..638315a 100644 --- a/proton-c/bindings/cpp/include/proton/data.hpp +++ b/proton-c/bindings/cpp/include/proton/data.hpp @@ -26,7 +26,7 @@ struct pn_data_t; namespace proton { -/** Base for classes that hold AMQP data. */ +/** Base for classes that hold AMQP data, not for direct use. @see value, encoder, decoder. */ class data { public: PN_CPP_EXTERN explicit data(); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/decoder.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/decoder.hpp b/proton-c/bindings/cpp/include/proton/decoder.hpp index 22effe3..6761653 100644 --- a/proton-c/bindings/cpp/include/proton/decoder.hpp +++ b/proton-c/bindings/cpp/include/proton/decoder.hpp @@ -29,13 +29,13 @@ namespace proton { class value; -/** Raised by decoder operations on error. @ingroup cpp*/ +/** Raised by decoder operations on error.*/ struct decode_error : public error { PN_CPP_EXTERN explicit decode_error(const std::string&) throw(); }; -/** Skips a value with `decoder >> skip()`. @ingroup cpp */ +/** Skips a value with `decoder >> skip()`. */ struct skip{}; -/** Rewind the decoder with `decoder >> rewind()`. @ingroup cpp */ +/** Rewind the decoder with `decoder >> rewind()`. */ struct rewind{}; /** @@ -64,7 +64,7 @@ struct rewind{}; * extracting AMQP maps. * * You can also extract container values element-by-element, see decoder::operator>>(decoder&, start&) - * @ingroup cpp + * */ class decoder : public virtual data { public: @@ -126,7 +126,7 @@ class decoder : public virtual data { template <class T, type_id A> T get_as() { T value; *this >> as<A>(value); return value; } /** Call decoder::start() in constructor, decoder::finish in destructor(). - * @ingroup cpp + * */ struct scope : public start { decoder& decoder_; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/delivery.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/delivery.hpp b/proton-c/bindings/cpp/include/proton/delivery.hpp index 0dc80da..3f4dafc 100644 --- a/proton-c/bindings/cpp/include/proton/delivery.hpp +++ b/proton-c/bindings/cpp/include/proton/delivery.hpp @@ -29,17 +29,19 @@ namespace proton { +/** delivery status of a message */ class delivery : public proton_handle<pn_delivery_t> { public: + /** Delivery state of a message */ enum state { - NONE = 0, - RECEIVED = PN_RECEIVED, - ACCEPTED = PN_ACCEPTED, - REJECTED = PN_REJECTED, - RELEASED = PN_RELEASED, - MODIFIED = PN_MODIFIED + NONE = 0, ///< Unknown state + RECEIVED = PN_RECEIVED, ///< Received but not yet settled + ACCEPTED = PN_ACCEPTED, ///< Settled as accepted + REJECTED = PN_REJECTED, ///< Settled as rejected + RELEASED = PN_RELEASED, ///< Settled as released + MODIFIED = PN_MODIFIED ///< Settled as modified }; // AMQP spec 3.4 delivery State PN_CPP_EXTERN delivery(pn_delivery_t *d); @@ -47,8 +49,15 @@ class delivery : public proton_handle<pn_delivery_t> PN_CPP_EXTERN ~delivery(); PN_CPP_EXTERN delivery(const delivery&); PN_CPP_EXTERN delivery& operator=(const delivery&); + + /** Return true if the delivery has been settled. */ PN_CPP_EXTERN bool settled(); + + /** Settle the delivery, informs the remote end. */ PN_CPP_EXTERN void settle(); + + // TODO aconway 2015-07-15: add update() here? + PN_CPP_EXTERN pn_delivery_t *pn_delivery(); private: friend class proton_impl_ref<delivery>; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/duration.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/duration.hpp b/proton-c/bindings/cpp/include/proton/duration.hpp index b5bd59b..8b7d1ad 100644 --- a/proton-c/bindings/cpp/include/proton/duration.hpp +++ b/proton-c/bindings/cpp/include/proton/duration.hpp @@ -27,9 +27,7 @@ namespace proton { -/** @ingroup cpp - * A duration is a time in milliseconds. - */ +/** Duration in milliseconds. */ class duration : public comparable<duration> { public: @@ -39,10 +37,10 @@ class duration : public comparable<duration> bool operator<(duration d) { return milliseconds < d.milliseconds; } bool operator==(duration d) { return milliseconds == d.milliseconds; } - PN_CPP_EXTERN static const duration FOREVER; - PN_CPP_EXTERN static const duration IMMEDIATE; - PN_CPP_EXTERN static const duration SECOND; - PN_CPP_EXTERN static const duration MINUTE; + PN_CPP_EXTERN static const duration FOREVER; ///< Wait for ever + PN_CPP_EXTERN static const duration IMMEDIATE; ///< Don't wait at all + PN_CPP_EXTERN static const duration SECOND; ///< One second + PN_CPP_EXTERN static const duration MINUTE; ///< One minute }; inline duration operator*(duration d, std::uint64_t n) { return duration(d.milliseconds*n); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/encoder.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/encoder.hpp b/proton-c/bindings/cpp/include/proton/encoder.hpp index 57f3c45..b3e2ab4 100644 --- a/proton-c/bindings/cpp/include/proton/encoder.hpp +++ b/proton-c/bindings/cpp/include/proton/encoder.hpp @@ -25,8 +25,6 @@ #include "proton/type_traits.hpp" #include <iosfwd> -#include <iostream> // FIXME aconway 2015-06-18: - struct pn_data_t; namespace proton { @@ -60,7 +58,6 @@ struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const s * You can also insert containers element-by-element, see operator<<(encoder&, const start&) * *@throw decoder::error if the curent value is not a container type. - *@ingroup cpp */ class encoder : public virtual data { public: @@ -137,7 +134,7 @@ class encoder : public virtual data { template <class T> friend encoder& operator<<(encoder&, cref<T, ARRAY>); template <class T> friend encoder& operator<<(encoder&, cref<T, LIST>); template <class T> friend encoder& operator<<(encoder&, cref<T, MAP>); - // TODO aconway 2015-06-16: DESCRIBED. + // TODO aconway 2015-06-16: described values. ///@} /** Copy data from a raw pn_data_t */ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/endpoint.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp index 89904ba..11970c7 100644 --- a/proton-c/bindings/cpp/include/proton/endpoint.hpp +++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp @@ -30,21 +30,36 @@ class handler; class connection; class transport; +/** endpoint is a base class for session, connection and link */ class endpoint { public: - enum { - LOCAL_UNINIT = PN_LOCAL_UNINIT, - REMOTE_UNINIT = PN_REMOTE_UNINIT, - LOCAL_ACTIVE = PN_LOCAL_ACTIVE, - REMOTE_ACTIVE = PN_REMOTE_ACTIVE, - LOCAL_CLOSED = PN_LOCAL_CLOSED, - REMOTE_CLOSED = PN_REMOTE_CLOSED - }; - typedef int State; + /** state is a bit mask of state_bit values. + * + * A state mask is matched against an endpoint as follows: If the state mask + * contains both local and remote flags, then an exact match against those + * flags is performed. If state contains only local or only remote flags, + * then a match occurs if any of the local or remote flags are set + * respectively. + * + * @see connection::link_head, connection::session_head, link::next, session::next + */ + typedef int state; + + /// endpoint state bit values @{ + static const int LOCAL_UNINIT; ///< Local endpoint is un-initialized + static const int REMOTE_UNINIT; ///< Remote endpoint is un-initialized + static const int LOCAL_ACTIVE; ///< Local endpoint is active + static const int REMOTE_ACTIVE; ///< Remote endpoint is active + static const int LOCAL_CLOSED; ///< Local endpoint has been closed + static const int REMOTE_CLOSED; ///< Remote endpoint has been closed + static const int LOCAL_MASK; ///< Mask including all LOCAL_ bits (UNINIT, ACTIVE, CLOSED) + static const int REMOTE_MASK; ///< Mask including all REMOTE_ bits (UNINIT, ACTIVE, CLOSED) + ///@} // TODO: condition, remote_condition, update_condition, get/handler -protected: + + protected: PN_CPP_EXTERN endpoint(); PN_CPP_EXTERN ~endpoint(); }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/error.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/error.hpp b/proton-c/bindings/cpp/include/proton/error.hpp index 2e2ac17..6432b71 100644 --- a/proton-c/bindings/cpp/include/proton/error.hpp +++ b/proton-c/bindings/cpp/include/proton/error.hpp @@ -27,11 +27,12 @@ namespace proton { -/** @ingroup cpp - * Functions in the proton namespace throw a subclass of proton::error on error. - */ +/** Functions in the proton namespace throw a subclass of proton::error on error. */ struct error : public std::runtime_error { PN_CPP_EXTERN explicit error(const std::string&) throw(); }; +/** Raised if timeout expires */ +struct timeout_error : public error { PN_CPP_EXTERN explicit timeout_error(const std::string&) throw(); }; + /** Raised if a message is rejected */ struct message_reject : public error { PN_CPP_EXTERN explicit message_reject(const std::string&) throw(); }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/event.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/event.hpp b/proton-c/bindings/cpp/include/proton/event.hpp index 2feff2b..c4c5d7c 100644 --- a/proton-c/bindings/cpp/include/proton/event.hpp +++ b/proton-c/bindings/cpp/include/proton/event.hpp @@ -34,20 +34,32 @@ class handler; class container; class connection; -class event -{ +/** Context information about a proton event */ +class event { public: + virtual PN_CPP_EXTERN ~event(); + + /// Dispatch this event to a handler. virtual PN_CPP_EXTERN void dispatch(handler &h) = 0; + + /// Get container. virtual PN_CPP_EXTERN class container &container(); + /// Get connection. virtual PN_CPP_EXTERN class connection &connection(); + /// Get sender @throws error if no sender. virtual PN_CPP_EXTERN class sender sender(); + /// Get receiver @throws error if no receiver. virtual PN_CPP_EXTERN class receiver receiver(); + /// Get link @throws error if no link. virtual PN_CPP_EXTERN class link link(); + /// Get message @throws error if no message. virtual PN_CPP_EXTERN class message message(); - virtual PN_CPP_EXTERN void message(class message &); - virtual PN_CPP_EXTERN ~event(); + /// Get message @throws error if no message. + virtual PN_CPP_EXTERN void message(class message&); + protected: PN_CPP_EXTERN event(); + private: event(const event&); event& operator=(const event&); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/export.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/export.hpp b/proton-c/bindings/cpp/include/proton/export.hpp index 0be5187..bb211ae 100644 --- a/proton-c/bindings/cpp/include/proton/export.hpp +++ b/proton-c/bindings/cpp/include/proton/export.hpp @@ -22,6 +22,7 @@ * */ +/// Internal: import/export macros @cond INTERNAL #if defined(WIN32) && !defined(PN_CPP_DECLARE_STATIC) // // Import and Export definitions for Windows: @@ -42,5 +43,6 @@ #else # define PN_CPP_EXTERN PN_CPP_IMPORT #endif +///@endcond #endif /*!PN_CPP_IMPORTEXPORT_H*/ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/handle.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/handle.hpp b/proton-c/bindings/cpp/include/proton/handle.hpp index 0a23b01..e0542ef 100644 --- a/proton-c/bindings/cpp/include/proton/handle.hpp +++ b/proton-c/bindings/cpp/include/proton/handle.hpp @@ -26,10 +26,10 @@ namespace proton { +///@cond INTERNAL template <class> class private_impl_ref; template <class> class proton_impl_ref; - -// FIXME aconway 2015-06-09: don't need handle, get rid of it. +///@endcond INTERNAL /** * A handle is like a pointer: refers to an underlying implementation object. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/handler.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/handler.hpp b/proton-c/bindings/cpp/include/proton/handler.hpp index eb019e3..cb4ff81 100644 --- a/proton-c/bindings/cpp/include/proton/handler.hpp +++ b/proton-c/bindings/cpp/include/proton/handler.hpp @@ -28,14 +28,19 @@ namespace proton { +/// Base class for event handlers. +/// Handlers form a tree, a handler is a vector of pointers to child handlers. class handler : public std::vector<handler*> { public: PN_CPP_EXTERN handler(); PN_CPP_EXTERN virtual ~handler(); + /// Called if a handler function is not over-ridden to handle an event. PN_CPP_EXTERN virtual void on_unhandled(event &e); - PN_CPP_EXTERN virtual void add_child_handler(handler &e); + /// Add a child handler, equivalent to this->push_back(&h) + /// h must not be deleted before this handler. + PN_CPP_EXTERN virtual void add_child_handler(handler &h); }; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/link.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/link.hpp b/proton-c/bindings/cpp/include/proton/link.hpp index ba17584..feabfec 100644 --- a/proton-c/bindings/cpp/include/proton/link.hpp +++ b/proton-c/bindings/cpp/include/proton/link.hpp @@ -32,6 +32,7 @@ struct pn_connection_t; namespace proton { +/** Messages are transferred across a link. Base class for sender, receiver. */ class link : public endpoint, public proton_handle<pn_link_t> { public: @@ -40,20 +41,42 @@ class link : public endpoint, public proton_handle<pn_link_t> PN_CPP_EXTERN ~link(); PN_CPP_EXTERN link(const link&); PN_CPP_EXTERN link& operator=(const link&); + + /** Locally open the link, not complete till messaging_handler::on_link_opened or + * proton_handler::link_remote_open + */ PN_CPP_EXTERN void open(); + + /** Locally close the link, not complete till messaging_handler::on_link_closeed or + * proton_handler::link_remote_close + */ PN_CPP_EXTERN void close(); + + /** True if link is a sender */ PN_CPP_EXTERN bool is_sender(); + /** True if link is a receiver */ PN_CPP_EXTERN bool is_receiver(); + /** Credit available on the link */ PN_CPP_EXTERN int credit(); + /** Local source of the link */ PN_CPP_EXTERN terminus source(); + /** Local target of the link */ PN_CPP_EXTERN terminus target(); + /** Remote source of the link */ PN_CPP_EXTERN terminus remote_source(); + /** Remote source of the link */ PN_CPP_EXTERN terminus remote_target(); + /** Link name */ PN_CPP_EXTERN std::string name(); - PN_CPP_EXTERN pn_link_t *pn_link() const; - PN_CPP_EXTERN link next(endpoint::State mask); + + /** Next link that matches state mask. @see endpoint::state */ + PN_CPP_EXTERN link next(endpoint::state mask); + + /** Connection of the link */ PN_CPP_EXTERN class connection &connection(); + PN_CPP_EXTERN pn_link_t *pn_link() const; + protected: PN_CPP_EXTERN virtual void verify_type(pn_link_t *l); private: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/message.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/message.hpp b/proton-c/bindings/cpp/include/proton/message.hpp index 0667337..528088b 100644 --- a/proton-c/bindings/cpp/include/proton/message.hpp +++ b/proton-c/bindings/cpp/include/proton/message.hpp @@ -32,7 +32,7 @@ struct pn_data_t; namespace proton { -// FIXME aconway 2015-06-17: documentation of properties. +/// An AMQP message. class message : public proton_handle<pn_message_t> { public: @@ -44,7 +44,15 @@ class message : public proton_handle<pn_message_t> PN_CPP_EXTERN pn_message_t *pn_message() const; + /** Clear the message content */ + PN_CPP_EXTERN void clear(); + + ///@name Message properties + ///@{ + + /// Globally unique identifier, can be an a string, an unsigned long, a uuid or a binary value. PN_CPP_EXTERN void id(const value& id); + /// Globally unique identifier, can be an a string, an unsigned long, a uuid or a binary value. PN_CPP_EXTERN value id() const; PN_CPP_EXTERN void user(const std::string &user); @@ -59,7 +67,9 @@ class message : public proton_handle<pn_message_t> PN_CPP_EXTERN void reply_to(const std::string &s); PN_CPP_EXTERN std::string reply_to() const; + /// Correlation identifier, can be an a string, an unsigned long, a uuid or a binary value. PN_CPP_EXTERN void correlation_id(const value&); + /// Correlation identifier, can be an a string, an unsigned long, a uuid or a binary value. PN_CPP_EXTERN value correlation_id() const; PN_CPP_EXTERN void content_type(const std::string &s); @@ -77,29 +87,35 @@ class message : public proton_handle<pn_message_t> PN_CPP_EXTERN void group_id(const std::string &s); PN_CPP_EXTERN std::string group_id() const; - PN_CPP_EXTERN void reply_togroup_id(const std::string &s); - PN_CPP_EXTERN std::string reply_togroup_id() const; + PN_CPP_EXTERN void reply_to_group_id(const std::string &s); + PN_CPP_EXTERN std::string reply_to_group_id() const; + ///@} - /** Set the body to an AMQP value. */ + /** Set the body to a proton::value. */ PN_CPP_EXTERN void body(const value&); - /** Template to convert any type to a value and set as the body */ + /** Set the body to any type T that can be converted to a proton::value */ template <class T> void body(const T& v) { body(value(v)); } - /** Set the body to a sequence of sections containing AMQP values. */ + /** Set the body to a sequence of values, each value is encoded as an AMQP section. */ PN_CPP_EXTERN void body(const values&); + /** Get the body values, there may be more than one. */ PN_CPP_EXTERN const values& body() const; - PN_CPP_EXTERN values& body(); ///< Allows in-place modification of body sections. + /** Get a reference to the body, can be modified in-place. */ + PN_CPP_EXTERN values& body(); - // FIXME aconway 2015-06-17: consistent and flexible treatment of buffers. + // TODO aconway 2015-06-17: consistent and flexible treatment of buffers. // Allow convenient std::string encoding/decoding (with re-use of existing // string capacity) but also need to allow encoding/decoding of non-string // buffers. Introduce a buffer type with begin/end pointers? + /** Encode the message into string data */ PN_CPP_EXTERN void encode(std::string &data); + /** Retrun encoded message as a string */ PN_CPP_EXTERN std::string encode(); + /** Decode from string data into the message. */ PN_CPP_EXTERN void decode(const std::string &data); private: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp index 3486b97..8744c95 100644 --- a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp +++ b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp @@ -29,6 +29,8 @@ #include "proton/event.h" #include "proton/reactor.h" +///@cond INTERNAL + namespace proton { // Combine's Python's: endpoint_state_handler, incoming_message_handler, outgoing_message_handler @@ -72,5 +74,5 @@ class messaging_adapter : public messaging_handler }; } - +///@endcond INTERNAL #endif /*!PROTON_CPP_MESSAGING_ADAPTER_H*/ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/messaging_event.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/messaging_event.hpp b/proton-c/bindings/cpp/include/proton/messaging_event.hpp index 62f0160..950c389 100644 --- a/proton-c/bindings/cpp/include/proton/messaging_event.hpp +++ b/proton-c/bindings/cpp/include/proton/messaging_event.hpp @@ -30,54 +30,59 @@ class handler; class container; class connection; -typedef enum { - PN_MESSAGING_PROTON = 0, // Wrapped pn_event_t - // Covenience events for C++ messaging_handlers - PN_MESSAGING_ABORT, - PN_MESSAGING_ACCEPTED, - PN_MESSAGING_COMMIT, - PN_MESSAGING_CONNECTION_CLOSED, - PN_MESSAGING_CONNECTION_CLOSING, - PN_MESSAGING_CONNECTION_ERROR, - PN_MESSAGING_CONNECTION_OPENED, - PN_MESSAGING_CONNECTION_OPENING, - PN_MESSAGING_DISCONNECTED, - PN_MESSAGING_FETCH, - PN_MESSAGING_Id_LOADED, - PN_MESSAGING_LINK_CLOSED, - PN_MESSAGING_LINK_CLOSING, - PN_MESSAGING_LINK_OPENED, - PN_MESSAGING_LINK_OPENING, - PN_MESSAGING_LINK_ERROR, - PN_MESSAGING_MESSAGE, - PN_MESSAGING_QUIT, - PN_MESSAGING_RECORD_INSERTED, - PN_MESSAGING_RECORDS_LOADED, - PN_MESSAGING_REJECTED, - PN_MESSAGING_RELEASED, - PN_MESSAGING_REQUEST, - PN_MESSAGING_RESPONSE, - PN_MESSAGING_SENDABLE, - PN_MESSAGING_SESSION_CLOSED, - PN_MESSAGING_SESSION_CLOSING, - PN_MESSAGING_SESSION_OPENED, - PN_MESSAGING_SESSION_OPENING, - PN_MESSAGING_SESSION_ERROR, - PN_MESSAGING_SETTLED, - PN_MESSAGING_START, - PN_MESSAGING_TIMER, - PN_MESSAGING_TRANSACTION_ABORTED, - PN_MESSAGING_TRANSACTION_COMMITTED, - PN_MESSAGING_TRANSACTION_DECLARED, - PN_MESSAGING_TRANSPORT_CLOSED -} messaging_event_type_t; - +/** An event for the proton::messaging_handler */ class messaging_event : public proton_event { public: + + // TODO aconway 2015-07-16: document meaning of each event type. + + /** Event types for a messaging_handler */ + enum event_type { + PROTON = 0, // Wrapped pn_event_t + ABORT, + ACCEPTED, + COMMIT, + CONNECTION_CLOSED, + CONNECTION_CLOSING, + CONNECTION_ERROR, + CONNECTION_OPENED, + CONNECTION_OPENING, + DISCONNECTED, + FETCH, + ID_LOADED, + LINK_CLOSED, + LINK_CLOSING, + LINK_OPENED, + LINK_OPENING, + LINK_ERROR, + MESSAGE, + QUIT, + RECORD_INSERTED, + RECORDS_LOADED, + REJECTED, + RELEASED, + REQUEST, + RESPONSE, + SENDABLE, + SESSION_CLOSED, + SESSION_CLOSING, + SESSION_OPENED, + SESSION_OPENING, + SESSION_ERROR, + SETTLED, + START, + TIMER, + TRANSACTION_ABORTED, + TRANSACTION_COMMITTED, + TRANSACTION_DECLARED, + TRANSPORT_CLOSED + }; + messaging_event(pn_event_t *ce, pn_event_type_t t, class container &c); - messaging_event(messaging_event_type_t t, proton_event &parent); + messaging_event(event_type t, proton_event &parent); ~messaging_event(); + virtual PN_CPP_EXTERN void dispatch(handler &h); virtual PN_CPP_EXTERN class connection &connection(); virtual PN_CPP_EXTERN class sender sender(); @@ -85,8 +90,10 @@ class messaging_event : public proton_event virtual PN_CPP_EXTERN class link link(); virtual PN_CPP_EXTERN class message message(); virtual PN_CPP_EXTERN void message(class message &); + PN_CPP_EXTERN event_type type() const; + private: - messaging_event_type_t messaging_type_; + event_type type_; proton_event *parent_event_; class message *message_; messaging_event operator=(const messaging_event&); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/messaging_handler.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp index 946b9b5..7de6ebd 100644 --- a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp +++ b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp @@ -31,13 +31,27 @@ namespace proton { class event; class messaging_adapter; +/** messaging_handler base class. Provides a simpler set of events than + * proton::proton_handler and automates some common tasks. Subclass and + * over-ride event handling member functions. + * @see proton::messaging_event for meaning of events. + */ class messaging_handler : public proton_handler , public acking { public: + /** Create a messaging_handler + *@param prefetch set flow control to automatically pre-fetch this many messages + *@param auto_accept automatically accept received messages after on_message() + *@param auto_settle automatically settle on receipt of delivery for sent messages. + *@param peer_close_is_error treat orderly remote connection close as error. + */ PN_CPP_EXTERN messaging_handler(int prefetch=10, bool auto_accept=true, bool auto_settle=true, - bool peer_close_is_error=false); + bool peer_close_is_error=false); + PN_CPP_EXTERN virtual ~messaging_handler(); + ///@name Over-ride these member functions to handle events + ///@{ PN_CPP_EXTERN virtual void on_abort(event &e); PN_CPP_EXTERN virtual void on_accepted(event &e); PN_CPP_EXTERN virtual void on_commit(event &e); @@ -75,8 +89,9 @@ class messaging_handler : public proton_handler , public acking PN_CPP_EXTERN virtual void on_transaction_committed(event &e); PN_CPP_EXTERN virtual void on_transaction_declared(event &e); PN_CPP_EXTERN virtual void on_transport_closed(event &e); + ///@} - private: + private: int prefetch_; bool auto_accept_; bool auto_settle_; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/proton_event.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/proton_event.hpp b/proton-c/bindings/cpp/include/proton/proton_event.hpp index c4bd5e8..4a0a012 100644 --- a/proton-c/bindings/cpp/include/proton/proton_event.hpp +++ b/proton-c/bindings/cpp/include/proton/proton_event.hpp @@ -31,22 +31,260 @@ class container; class connection; class container; +/** Event information for a proton::proton_handler */ class proton_event : public event { public: + + ///@name Event types + ///@{ + + /// The type of an event + typedef int event_type; + + /** + * Defined as a programming convenience. No event of this type will + * ever be generated. + */ + static const event_type EVENT_NONE; + + /** + * A reactor has been started. Events of this type point to the reactor. + */ + static const event_type REACTOR_INIT; + + /** + * A reactor has no more events to process. Events of this type + * point to the reactor. + */ + static const event_type REACTOR_QUIESCED; + + /** + * A reactor has been stopped. Events of this type point to the reactor. + */ + static const event_type REACTOR_FINAL; + + /** + * A timer event has occurred. + */ + static const event_type TIMER_TASK; + + /** + * The connection has been created. This is the first event that + * will ever be issued for a connection. Events of this type point + * to the relevant connection. + */ + static const event_type CONNECTION_INIT; + + /** + * The connection has been bound to a transport. This event is + * issued when the transport::bind() is called. + */ + static const event_type CONNECTION_BOUND; + + /** + * The connection has been unbound from its transport. This event is + * issued when transport::unbind() is called. + */ + static const event_type CONNECTION_UNBOUND; + + /** + * The local connection endpoint has been closed. Events of this + * type point to the relevant connection. + */ + static const event_type CONNECTION_LOCAL_OPEN; + + /** + * The remote endpoint has opened the connection. Events of this + * type point to the relevant connection. + */ + static const event_type CONNECTION_REMOTE_OPEN; + + /** + * The local connection endpoint has been closed. Events of this + * type point to the relevant connection. + */ + static const event_type CONNECTION_LOCAL_CLOSE; + + /** + * The remote endpoint has closed the connection. Events of this + * type point to the relevant connection. + */ + static const event_type CONNECTION_REMOTE_CLOSE; + + /** + * The connection has been freed and any outstanding processing has + * been completed. This is the final event that will ever be issued + * for a connection. + */ + static const event_type CONNECTION_FINAL; + + /** + * The session has been created. This is the first event that will + * ever be issued for a session. + */ + static const event_type SESSION_INIT; + + /** + * The local session endpoint has been opened. Events of this type + * point ot the relevant session. + */ + static const event_type SESSION_LOCAL_OPEN; + + /** + * The remote endpoint has opened the session. Events of this type + * point to the relevant session. + */ + static const event_type SESSION_REMOTE_OPEN; + + /** + * The local session endpoint has been closed. Events of this type + * point ot the relevant session. + */ + static const event_type SESSION_LOCAL_CLOSE; + + /** + * The remote endpoint has closed the session. Events of this type + * point to the relevant session. + */ + static const event_type SESSION_REMOTE_CLOSE; + + /** + * The session has been freed and any outstanding processing has + * been completed. This is the final event that will ever be issued + * for a session. + */ + static const event_type SESSION_FINAL; + + /** + * The link has been created. This is the first event that will ever + * be issued for a link. + */ + static const event_type LINK_INIT; + + /** + * The local link endpoint has been opened. Events of this type + * point ot the relevant link. + */ + static const event_type LINK_LOCAL_OPEN; + + /** + * The remote endpoint has opened the link. Events of this type + * point to the relevant link. + */ + static const event_type LINK_REMOTE_OPEN; + + /** + * The local link endpoint has been closed. Events of this type + * point ot the relevant link. + */ + static const event_type LINK_LOCAL_CLOSE; + + /** + * The remote endpoint has closed the link. Events of this type + * point to the relevant link. + */ + static const event_type LINK_REMOTE_CLOSE; + + /** + * The local link endpoint has been detached. Events of this type + * point to the relevant link. + */ + static const event_type LINK_LOCAL_DETACH; + + /** + * The remote endpoint has detached the link. Events of this type + * point to the relevant link. + */ + static const event_type LINK_REMOTE_DETACH; + + /** + * The flow control state for a link has changed. Events of this + * type point to the relevant link. + */ + static const event_type LINK_FLOW; + + /** + * The link has been freed and any outstanding processing has been + * completed. This is the final event that will ever be issued for a + * link. Events of this type point to the relevant link. + */ + static const event_type LINK_FINAL; + + /** + * A delivery has been created or updated. Events of this type point + * to the relevant delivery. + */ + static const event_type DELIVERY; + + /** + * The transport has new data to read and/or write. Events of this + * type point to the relevant transport. + */ + static const event_type TRANSPORT; + + /** + * The transport has authenticated, if this is received by a server + * the associated transport has authenticated an incoming connection + * and transport::user() can be used to obtain the authenticated + * user. + */ + static const event_type TRANSPORT_AUTHENTICATED; + + /** + * Indicates that a transport error has occurred. Use + * transport::condition() to access the details of the error + * from the associated transport. + */ + static const event_type TRANSPORT_ERROR; + + /** + * Indicates that the head of the transport has been closed. This + * means the transport will never produce more bytes for output to + * the network. Events of this type point to the relevant transport. + */ + static const event_type TRANSPORT_HEAD_CLOSED; + + /** + * Indicates that the tail of the transport has been closed. This + * means the transport will never be able to process more bytes from + * the network. Events of this type point to the relevant transport. + */ + static const event_type TRANSPORT_TAIL_CLOSED; + + /** + * Indicates that the both the head and tail of the transport are + * closed. Events of this type point to the relevant transport. + */ + static const event_type TRANSPORT_CLOSED; + + static const event_type SELECTABLE_INIT; + static const event_type SELECTABLE_UPDATED; + static const event_type SELECTABLE_READABLE; + static const event_type SELECTABLE_WRITABLE; + static const event_type SELECTABLE_ERROR; + static const event_type SELECTABLE_EXPIRED; + static const event_type SELECTABLE_FINAL; + + ///@} + virtual PN_CPP_EXTERN void dispatch(handler &h); virtual PN_CPP_EXTERN class container &container(); virtual PN_CPP_EXTERN class connection &connection(); virtual PN_CPP_EXTERN class sender sender(); virtual PN_CPP_EXTERN class receiver receiver(); virtual PN_CPP_EXTERN class link link(); - PN_CPP_EXTERN int type(); + + /** Get type of event */ + PN_CPP_EXTERN event_type type(); + PN_CPP_EXTERN pn_event_t* pn_event(); + protected: PN_CPP_EXTERN proton_event(pn_event_t *ce, pn_event_type_t t, class container &c); private: pn_event_t *pn_event_; - int type_; + event_type type_; class container &container_; }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/proton_handle.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/proton_handle.hpp b/proton-c/bindings/cpp/include/proton/proton_handle.hpp index 5799bf6..6fc9211 100644 --- a/proton-c/bindings/cpp/include/proton/proton_handle.hpp +++ b/proton-c/bindings/cpp/include/proton/proton_handle.hpp @@ -26,7 +26,9 @@ namespace proton { +///@cond INTERNAL template <class> class proton_impl_ref; +///@endcond INTERNAL /** * See handle.h. Similar but for lightly wrapped Proton pn_object_t targets. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/proton_handler.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/proton_handler.hpp b/proton-c/bindings/cpp/include/proton/proton_handler.hpp index 24384a8..2738f71 100644 --- a/proton-c/bindings/cpp/include/proton/proton_handler.hpp +++ b/proton-c/bindings/cpp/include/proton/proton_handler.hpp @@ -28,10 +28,15 @@ namespace proton { class event; class proton_event; +/// Handler base class, subclass and over-ride event handling member functions. +/// @see proton::proton_event for meaning of events. class proton_handler : public handler { public: PN_CPP_EXTERN proton_handler(); + + ///@name Over-ride these member functions to handle events + ///@{ PN_CPP_EXTERN virtual void on_reactor_init(event &e); PN_CPP_EXTERN virtual void on_reactor_quiesced(event &e); PN_CPP_EXTERN virtual void on_reactor_final(event &e); @@ -72,8 +77,8 @@ class proton_handler : public handler PN_CPP_EXTERN virtual void on_selectable_expired(event &e); PN_CPP_EXTERN virtual void on_selectable_error(event &e); PN_CPP_EXTERN virtual void on_selectable_final(event &e); - PN_CPP_EXTERN virtual void on_unhandled(event &e); + ///@} }; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/receiver.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp b/proton-c/bindings/cpp/include/proton/receiver.hpp index be19358..4f2df0f 100644 --- a/proton-c/bindings/cpp/include/proton/receiver.hpp +++ b/proton-c/bindings/cpp/include/proton/receiver.hpp @@ -31,6 +31,7 @@ struct pn_connection_t; namespace proton { +/// A receiving link class receiver : public link { public: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/sender.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp b/proton-c/bindings/cpp/include/proton/sender.hpp index 1d35c42..3573a90 100644 --- a/proton-c/bindings/cpp/include/proton/sender.hpp +++ b/proton-c/bindings/cpp/include/proton/sender.hpp @@ -33,12 +33,14 @@ struct pn_connection_t; namespace proton { - +/// A sending link class sender : public link { public: PN_CPP_EXTERN sender(pn_link_t *lnk=0); PN_CPP_EXTERN sender(const link& c); + + /// Send a message on the link. PN_CPP_EXTERN delivery send(message &m); protected: http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/035b6957/proton-c/bindings/cpp/include/proton/session.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/session.hpp b/proton-c/bindings/cpp/include/proton/session.hpp index b0117c0..7f670b8 100644 --- a/proton-c/bindings/cpp/include/proton/session.hpp +++ b/proton-c/bindings/cpp/include/proton/session.hpp @@ -37,22 +37,37 @@ class container; class handler; class transport; - class session : public endpoint, public proton_handle<pn_session_t> +/** A session is a collection of links */ +class session : public endpoint, public proton_handle<pn_session_t> { public: PN_CPP_EXTERN session(pn_session_t *s); PN_CPP_EXTERN session(); - PN_CPP_EXTERN ~session(); - PN_CPP_EXTERN void open(); PN_CPP_EXTERN session(const session&); + PN_CPP_EXTERN ~session(); PN_CPP_EXTERN session& operator=(const session&); + + /** Initiate local open, not complete till messaging_handler::on_session_opened() + * or proton_handler::on_session_remote_open() + */ + PN_CPP_EXTERN void open(); + + /** Initiate local close, not complete till messaging_handler::on_session_closed() + * or proton_handler::on_session_remote_close() + */ PN_CPP_EXTERN void close(); - PN_CPP_EXTERN pn_session_t *pn_session(); + + /// Get connection PN_CPP_EXTERN virtual class connection &connection(); - PN_CPP_EXTERN receiver create_receiver(std::string name); - PN_CPP_EXTERN sender create_sender(std::string name); + /// Create a receiver link + PN_CPP_EXTERN receiver create_receiver(const std::string& name); + /// Create a sender link + PN_CPP_EXTERN sender create_sender(const std::string& name); + + PN_CPP_EXTERN pn_session_t *pn_session(); + private: - friend class proton_impl_ref<session>; + friend class proton_impl_ref<session>; }; } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
