mirror of
https://github.com/eclipse/paho.mqtt.cpp.git
synced 2025-05-09 19:31:22 +08:00
- Added properties iterator.
- Added property typeid, type name, and cleaned up constructor. - Exception checks if return code is reason code. - Added 'server_property_v5' example app.
This commit is contained in:
parent
e3d6ad0710
commit
381caad141
@ -35,18 +35,19 @@ set(EXECUTABLES
|
|||||||
async_subscribe
|
async_subscribe
|
||||||
async_consume
|
async_consume
|
||||||
async_consume_v5
|
async_consume_v5
|
||||||
|
data_publish
|
||||||
|
mqttpp_chat
|
||||||
|
multithr_pub_sub
|
||||||
|
pub_speed_test
|
||||||
|
rpc_math_cli
|
||||||
|
rpc_math_srvr
|
||||||
|
server_props_v5
|
||||||
sync_publish
|
sync_publish
|
||||||
sync_consume
|
sync_consume
|
||||||
sync_consume_v5
|
sync_consume_v5
|
||||||
sync_reconnect
|
sync_reconnect
|
||||||
data_publish
|
|
||||||
rpc_math_cli
|
|
||||||
rpc_math_srvr
|
|
||||||
mqttpp_chat
|
|
||||||
topic_publish
|
topic_publish
|
||||||
multithr_pub_sub
|
|
||||||
ws_publish
|
ws_publish
|
||||||
pub_speed_test
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# These will only be built if SSL selected
|
# These will only be built if SSL selected
|
||||||
|
@ -130,7 +130,8 @@ int main(int argc, char* argv[])
|
|||||||
auto top = mqtt::topic(cli, "data/time", QOS);
|
auto top = mqtt::topic(cli, "data/time", QOS);
|
||||||
cout << "Publishing data..." << endl;
|
cout << "Publishing data..." << endl;
|
||||||
|
|
||||||
while (timestamp() % DELTA_MS != 0);
|
while (timestamp() % DELTA_MS != 0)
|
||||||
|
;
|
||||||
|
|
||||||
uint64_t t = timestamp(), tlast = t, tstart = t;
|
uint64_t t = timestamp(), tlast = t, tstart = t;
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// Just block till user tells us to quit.
|
// Just block till user tells us to quit.
|
||||||
|
|
||||||
while (std::tolower(std::cin.get()) != 'q');
|
while (std::tolower(std::cin.get()) != 'q')
|
||||||
|
;
|
||||||
|
|
||||||
// Disconnect
|
// Disconnect
|
||||||
|
|
||||||
|
117
examples/server_props_v5.cpp
Normal file
117
examples/server_props_v5.cpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// server_props_v5.cpp
|
||||||
|
//
|
||||||
|
// This is a Paho MQTT C++ client, sample application.
|
||||||
|
//
|
||||||
|
// This application is an MQTT client using the C++ asynchronous interface
|
||||||
|
// which shows how to check the server cofiguration for an MQTT v5
|
||||||
|
// connection.
|
||||||
|
//
|
||||||
|
// With an MQTT v5 connection, the server specify can some features that it
|
||||||
|
// doesn't supports, or limits in some way. It does this by adding v5
|
||||||
|
// properties to the CONNACK packet it sends back to the client in a connect
|
||||||
|
// transaction. The C++ application can retrieve these from the connect
|
||||||
|
// token via the `connect_response` object.
|
||||||
|
//
|
||||||
|
// It also shows short-lived persistent sessions. The client asks the server
|
||||||
|
// to just keep the session for 10sec. If you re-run the application in less
|
||||||
|
// than 10sec, it should report that the session exists. Any longer, and the
|
||||||
|
// session will be gone.
|
||||||
|
//
|
||||||
|
// Note that 10sec is probably *way too short* a time for real-world
|
||||||
|
// applications. This is just for demonstrating/testing the session expiry
|
||||||
|
// interval.
|
||||||
|
//
|
||||||
|
// The sample demonstrates:
|
||||||
|
// - Connecting to an MQTT v5 server/broker.
|
||||||
|
// - Specifying a short-lived (10sec) persistent session.
|
||||||
|
// - Retrieving the v5 properties from the connect response (i.e. CONNACK
|
||||||
|
// packet)
|
||||||
|
// - Iterating through v5 properties.
|
||||||
|
// - Displaying server properties to the user.
|
||||||
|
//
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013-2024 Frank Pagliughi <fpagliughi@mindspring.com>
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v2.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v20.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Frank Pagliughi - initial implementation and documentation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "mqtt/async_client.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
|
||||||
|
const string CLIENT_ID{"server_props_v5"};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
auto serverURI = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI;
|
||||||
|
|
||||||
|
mqtt::async_client cli(serverURI, CLIENT_ID);
|
||||||
|
auto connOpts = mqtt::connect_options_builder::v5()
|
||||||
|
.clean_start(false)
|
||||||
|
.properties({{mqtt::property::SESSION_EXPIRY_INTERVAL, 10}})
|
||||||
|
.finalize();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Connect to the server
|
||||||
|
|
||||||
|
cout << "Connecting to the MQTT server at '" << serverURI << "'..." << flush;
|
||||||
|
auto tok = cli.connect(connOpts);
|
||||||
|
|
||||||
|
// Getting the connect response will block waiting for the
|
||||||
|
// connection to complete.
|
||||||
|
auto rsp = tok->get_connect_response();
|
||||||
|
cout << "OK" << endl;
|
||||||
|
|
||||||
|
// Make sure we were granted a v5 connection.
|
||||||
|
if (rsp.get_mqtt_version() < MQTTVERSION_5) {
|
||||||
|
cout << "Did not get an MQTT v5 connection." << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the server have a session for us?
|
||||||
|
cout << "\nThe session is " << (rsp.is_session_present() ? "" : "not ")
|
||||||
|
<< "present on the server." << endl;
|
||||||
|
|
||||||
|
// Show the v5 properties from the CONNACK, if any
|
||||||
|
cout << "\nConnection Properties:" << endl;
|
||||||
|
if (rsp.get_properties().empty()) {
|
||||||
|
cout << " <none>" << endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (const auto& prop : rsp.get_properties()) {
|
||||||
|
cout << " " << prop << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK, we're done.
|
||||||
|
cli.disconnect()->wait();
|
||||||
|
}
|
||||||
|
catch (const mqtt::exception& exc) {
|
||||||
|
cerr << "\n " << exc << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2013-2019 Frank Pagliughi <fpagliughi@mindspring.com>
|
* Copyright (c) 2013-2024 Frank Pagliughi <fpagliughi@mindspring.com>
|
||||||
*
|
*
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v2.0
|
* are made available under the terms of the Eclipse Public License v2.0
|
||||||
@ -54,6 +54,13 @@ protected:
|
|||||||
/** The error message from the C library */
|
/** The error message from the C library */
|
||||||
string msg_;
|
string msg_;
|
||||||
|
|
||||||
|
/** See if the return code is actually a reason code error value */
|
||||||
|
static ReasonCode reason_code(int rc, ReasonCode reasonCode) {
|
||||||
|
if (reasonCode == ReasonCode::SUCCESS && rc >= ReasonCode::UNSPECIFIED_ERROR)
|
||||||
|
reasonCode = ReasonCode(rc);
|
||||||
|
return reasonCode;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates an MQTT exception.
|
* Creates an MQTT exception.
|
||||||
@ -72,11 +79,7 @@ public:
|
|||||||
* @param rc The error return code from the C library.
|
* @param rc The error return code from the C library.
|
||||||
* @param msg The text message for the error.
|
* @param msg The text message for the error.
|
||||||
*/
|
*/
|
||||||
exception(int rc, const string& msg)
|
exception(int rc, const string& msg) : exception(rc, ReasonCode::SUCCESS, msg) {}
|
||||||
: std::runtime_error(printable_error(rc, ReasonCode::SUCCESS, msg)),
|
|
||||||
rc_(rc),
|
|
||||||
reasonCode_(ReasonCode::SUCCESS),
|
|
||||||
msg_(msg) {}
|
|
||||||
/**
|
/**
|
||||||
* Creates an MQTT exception.
|
* Creates an MQTT exception.
|
||||||
* @param rc The error return code from the C library.
|
* @param rc The error return code from the C library.
|
||||||
@ -85,9 +88,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
exception(int rc, ReasonCode reasonCode, const string& msg)
|
exception(int rc, ReasonCode reasonCode, const string& msg)
|
||||||
: std::runtime_error(printable_error(rc, reasonCode, msg)),
|
: std::runtime_error(printable_error(rc, reasonCode, msg)),
|
||||||
rc_(rc),
|
rc_{rc},
|
||||||
reasonCode_(reasonCode),
|
reasonCode_{reason_code(rc, reasonCode)},
|
||||||
msg_(msg) {}
|
msg_{msg} {}
|
||||||
/**
|
/**
|
||||||
* Gets an error message from an error code.
|
* Gets an error message from an error code.
|
||||||
* @param rc The error code from the C lib
|
* @param rc The error code from the C lib
|
||||||
@ -116,13 +119,15 @@ public:
|
|||||||
* explanation message.
|
* explanation message.
|
||||||
*/
|
*/
|
||||||
static string printable_error(
|
static string printable_error(
|
||||||
int rc, int reasonCode = ReasonCode::SUCCESS, const string& msg = string()
|
int rc, ReasonCode reasonCode = ReasonCode::SUCCESS, const string& msg = string()
|
||||||
) {
|
) {
|
||||||
|
reasonCode = reason_code(rc, reasonCode);
|
||||||
|
|
||||||
string s = "MQTT error [" + std::to_string(rc) + "]";
|
string s = "MQTT error [" + std::to_string(rc) + "]";
|
||||||
if (!msg.empty())
|
if (!msg.empty())
|
||||||
s += string(": ") + msg;
|
s += string(": ") + msg;
|
||||||
if (reasonCode != ReasonCode::SUCCESS)
|
if (reasonCode != ReasonCode::SUCCESS)
|
||||||
s += string(". Reason: ") + reason_code_str(reasonCode);
|
s += string(". ") + reason_code_str(reasonCode);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,10 @@ extern "C" {
|
|||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
#include "mqtt/buffer_ref.h"
|
#include "mqtt/buffer_ref.h"
|
||||||
#include "mqtt/exception.h"
|
#include "mqtt/exception.h"
|
||||||
@ -56,6 +59,9 @@ class property
|
|||||||
// For string properties, this allocates memory and copied the string(s)
|
// For string properties, this allocates memory and copied the string(s)
|
||||||
void copy(const MQTTProperty& other);
|
void copy(const MQTTProperty& other);
|
||||||
|
|
||||||
|
friend class properties;
|
||||||
|
property() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The integer codes for the different v5 properties.
|
* The integer codes for the different v5 properties.
|
||||||
@ -90,6 +96,9 @@ public:
|
|||||||
SHARED_SUBSCRIPTION_AVAILABLE = 42
|
SHARED_SUBSCRIPTION_AVAILABLE = 42
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** The names of the different types of properties */
|
||||||
|
PAHO_MQTTPP_EXPORT static const std::map<code, std::string_view> TYPE_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a numeric property.
|
* Create a numeric property.
|
||||||
* This can be a byte, or 2-byte, 4-byte, or variable byte integer.
|
* This can be a byte, or 2-byte, 4-byte, or variable byte integer.
|
||||||
@ -121,18 +130,20 @@ public:
|
|||||||
* Creates a property from a C struct.
|
* Creates a property from a C struct.
|
||||||
* @param cprop A C struct for a property list.
|
* @param cprop A C struct for a property list.
|
||||||
*/
|
*/
|
||||||
explicit property(const MQTTProperty& cprop);
|
explicit property(const MQTTProperty& cprop) { copy(cprop); }
|
||||||
/**
|
/**
|
||||||
* Moves a C struct into this property list.
|
* Moves a C struct into this property list.
|
||||||
* This takes ownership of any memory that the C struct is holding.
|
* This takes ownership of any memory that the C struct is holding.
|
||||||
* @param cprop A C struct for a property list.
|
* @param cprop A C struct for a property list.
|
||||||
*/
|
*/
|
||||||
explicit property(MQTTProperty&& cprop);
|
explicit property(MQTTProperty&& cprop) : prop_(cprop) {
|
||||||
|
memset(&cprop, 0, sizeof(MQTTProperty));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Copy constructor
|
* Copy constructor
|
||||||
* @param other The other property to copy into this one.
|
* @param other The other property to copy into this one.
|
||||||
*/
|
*/
|
||||||
property(const property& other);
|
property(const property& other) { copy(other.prop_); }
|
||||||
/**
|
/**
|
||||||
* Move constructor.
|
* Move constructor.
|
||||||
* @param other The other property that is moved into this one.
|
* @param other The other property that is moved into this one.
|
||||||
@ -169,9 +180,16 @@ public:
|
|||||||
* Gets a printable name for the property type.
|
* Gets a printable name for the property type.
|
||||||
* @return A printable name for the property type.
|
* @return A printable name for the property type.
|
||||||
*/
|
*/
|
||||||
const char* type_name() const { return ::MQTTPropertyName(prop_.identifier); }
|
std::string_view type_name() const;
|
||||||
|
/**
|
||||||
|
* Gets the typeid for the value contained in the property.
|
||||||
|
* @return The typeid for the value contained in the property.
|
||||||
|
*/
|
||||||
|
const std::type_info& value_type_id();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const property& prop);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the value from the property as the specified type.
|
* Extracts the value from the property as the specified type.
|
||||||
* @return The value from the property as the specified type.
|
* @return The value from the property as the specified type.
|
||||||
@ -271,10 +289,10 @@ inline string_pair get<string_pair>(const property& prop) {
|
|||||||
class properties
|
class properties
|
||||||
{
|
{
|
||||||
/** The default C struct */
|
/** The default C struct */
|
||||||
PAHO_MQTTPP_EXPORT static const MQTTProperties DFLT_C_STRUCT;
|
static constexpr MQTTProperties DFLT_C_STRUCT MQTTProperties_initializer;
|
||||||
|
|
||||||
/** The underlying C properties struct */
|
/** The underlying C properties struct */
|
||||||
MQTTProperties props_;
|
MQTTProperties props_{DFLT_C_STRUCT};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
friend T get(const properties& props, property::code propid, size_t idx);
|
friend T get(const properties& props, property::code propid, size_t idx);
|
||||||
@ -283,11 +301,58 @@ class properties
|
|||||||
friend T get(const properties& props, property::code propid);
|
friend T get(const properties& props, property::code propid);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** A const iterator for the properties list */
|
||||||
|
class const_iterator
|
||||||
|
{
|
||||||
|
const MQTTProperty* curr_;
|
||||||
|
mutable property prop_;
|
||||||
|
|
||||||
|
friend properties;
|
||||||
|
const_iterator(const MQTTProperty* curr) : curr_{curr} {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Gets a reference to the current value.
|
||||||
|
* @return A reference to the current value.
|
||||||
|
*/
|
||||||
|
const property& operator*() const {
|
||||||
|
prop_ = property{*curr_};
|
||||||
|
return prop_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Postfix increment operator.
|
||||||
|
* @return An iterator pointing to the previous matching item.
|
||||||
|
*/
|
||||||
|
const_iterator operator++(int) noexcept {
|
||||||
|
auto tmp = *this;
|
||||||
|
curr_++;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prefix increment operator.
|
||||||
|
* @return An iterator pointing to the next matching item.
|
||||||
|
*/
|
||||||
|
const_iterator& operator++() noexcept {
|
||||||
|
++curr_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Compares two iterators to see if they don't refer to the same
|
||||||
|
* node.
|
||||||
|
*
|
||||||
|
* @param other The other iterator to compare against this one.
|
||||||
|
* @return @em true if they don't match, @em false if they do
|
||||||
|
*/
|
||||||
|
bool operator!=(const const_iterator& other) const noexcept {
|
||||||
|
return curr_ != other.curr_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
* Creates an empty properties list.
|
* Creates an empty properties list.
|
||||||
*/
|
*/
|
||||||
properties();
|
properties() {}
|
||||||
/**
|
/**
|
||||||
* Copy constructor.
|
* Copy constructor.
|
||||||
* @param other The property list to copy.
|
* @param other The property list to copy.
|
||||||
@ -342,6 +407,26 @@ public:
|
|||||||
* @return The number of property items in the list.
|
* @return The number of property items in the list.
|
||||||
*/
|
*/
|
||||||
size_t size() const { return size_t(props_.count); }
|
size_t size() const { return size_t(props_.count); }
|
||||||
|
/**
|
||||||
|
* Gets a const iterator to the full collection of properties.
|
||||||
|
* @return A const iterator to the full collection of properties.
|
||||||
|
*/
|
||||||
|
const_iterator begin() const { return const_iterator{props_.array}; }
|
||||||
|
/**
|
||||||
|
* Gets a const iterator to the full collection of properties.
|
||||||
|
* @return A const iterator to the full collection of properties.
|
||||||
|
*/
|
||||||
|
const_iterator cbegin() const { return begin(); }
|
||||||
|
/**
|
||||||
|
* Gets a const iterator to the end of the collection of properties.
|
||||||
|
* @return A const iterator to the end of collection of properties.
|
||||||
|
*/
|
||||||
|
const_iterator end() const { return const_iterator{props_.array + size()}; }
|
||||||
|
/**
|
||||||
|
* Gets a const iterator to the end of the collection of properties.
|
||||||
|
* @return A const iterator to the end of collection of properties.
|
||||||
|
*/
|
||||||
|
const_iterator cend() const { return end(); }
|
||||||
/**
|
/**
|
||||||
* Adds a property to the list.
|
* Adds a property to the list.
|
||||||
* @param prop The property to add to the list.
|
* @param prop The property to add to the list.
|
||||||
|
@ -20,6 +20,36 @@
|
|||||||
|
|
||||||
namespace mqtt {
|
namespace mqtt {
|
||||||
|
|
||||||
|
PAHO_MQTTPP_EXPORT const std::map<property::code, std::string_view> property::TYPE_NAME{
|
||||||
|
{PAYLOAD_FORMAT_INDICATOR, "PayloadFormatIndicator"},
|
||||||
|
{MESSAGE_EXPIRY_INTERVAL, "MessageExpiryInterval"},
|
||||||
|
{CONTENT_TYPE, "ContentType"},
|
||||||
|
{RESPONSE_TOPIC, "ResponseTopic"},
|
||||||
|
{CORRELATION_DATA, "CorrelationData"},
|
||||||
|
{SUBSCRIPTION_IDENTIFIER, "SubscriptionIdentifier"},
|
||||||
|
{SESSION_EXPIRY_INTERVAL, "SessionExpiryInterval"},
|
||||||
|
{ASSIGNED_CLIENT_IDENTIFIER, "AssignedClientIdentifer"},
|
||||||
|
{SERVER_KEEP_ALIVE, "ServerKeepAlive"},
|
||||||
|
{AUTHENTICATION_METHOD, "AuthenticationMethod"},
|
||||||
|
{AUTHENTICATION_DATA, "AuthenticationData"},
|
||||||
|
{REQUEST_PROBLEM_INFORMATION, "RequestProblemInformation"},
|
||||||
|
{WILL_DELAY_INTERVAL, "WillDelayInterval"},
|
||||||
|
{REQUEST_RESPONSE_INFORMATION, "RequestResponseInformation"},
|
||||||
|
{RESPONSE_INFORMATION, "ResponseInformation"},
|
||||||
|
{SERVER_REFERENCE, "ServerReference"},
|
||||||
|
{REASON_STRING, "ReasonString"},
|
||||||
|
{RECEIVE_MAXIMUM, "ReceiveMaximum"},
|
||||||
|
{TOPIC_ALIAS_MAXIMUM, "TopicAliasMaximum"},
|
||||||
|
{TOPIC_ALIAS, "TopicAlias"},
|
||||||
|
{MAXIMUM_QOS, "MaximumQos"},
|
||||||
|
{RETAIN_AVAILABLE, "RetainAvailable"},
|
||||||
|
{USER_PROPERTY, "UserProperty"},
|
||||||
|
{MAXIMUM_PACKET_SIZE, "MaximumPacketSize"},
|
||||||
|
{WILDCARD_SUBSCRIPTION_AVAILABLE, "WildcardSubscriptionAvailable"},
|
||||||
|
{SUBSCRIPTION_IDENTIFIERS_AVAILABLE, "SubscriptionIdentifiersAvailable"},
|
||||||
|
{SHARED_SUBSCRIPTION_AVAILABLE, "SharedSubscriptionAvailable"}
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
property::property(code c, int32_t val)
|
property::property(code c, int32_t val)
|
||||||
@ -68,15 +98,6 @@ property::property(code c, string_ref name, string_ref val)
|
|||||||
std::memcpy(prop_.value.value.data, val.data(), n);
|
std::memcpy(prop_.value.value.data, val.data(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
property::property(const MQTTProperty& cprop) { copy(cprop); }
|
|
||||||
|
|
||||||
property::property(MQTTProperty&& cprop) : prop_(cprop)
|
|
||||||
{
|
|
||||||
memset(&cprop, 0, sizeof(MQTTProperty));
|
|
||||||
}
|
|
||||||
|
|
||||||
property::property(const property& other) { copy(other.prop_); }
|
|
||||||
|
|
||||||
property::property(property&& other)
|
property::property(property&& other)
|
||||||
{
|
{
|
||||||
std::memcpy(&prop_, &other.prop_, sizeof(MQTTProperty));
|
std::memcpy(&prop_, &other.prop_, sizeof(MQTTProperty));
|
||||||
@ -144,16 +165,72 @@ property& property::operator=(property&& rhs)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view property::type_name() const
|
||||||
|
{
|
||||||
|
if (auto p = TYPE_NAME.find(code(prop_.identifier)); p != TYPE_NAME.end()) {
|
||||||
|
return p->second;
|
||||||
|
}
|
||||||
|
return std::string_view("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& property::value_type_id()
|
||||||
|
{
|
||||||
|
switch (::MQTTProperty_getType(prop_.identifier)) {
|
||||||
|
case MQTTPROPERTY_TYPE_BYTE:
|
||||||
|
return typeid(uint8_t);
|
||||||
|
case MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER:
|
||||||
|
return typeid(uint16_t);
|
||||||
|
case MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER:
|
||||||
|
case MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER:
|
||||||
|
return typeid(uint32_t);
|
||||||
|
case MQTTPROPERTY_TYPE_BINARY_DATA:
|
||||||
|
return typeid(binary);
|
||||||
|
case MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING:
|
||||||
|
return typeid(string);
|
||||||
|
case MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR:
|
||||||
|
return typeid(string_pair);
|
||||||
|
}
|
||||||
|
return typeid(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const property& prop)
|
||||||
|
{
|
||||||
|
os << prop.type_name() << ": ";
|
||||||
|
|
||||||
|
switch (::MQTTProperty_getType(MQTTPropertyCodes(prop.type()))) {
|
||||||
|
case MQTTPROPERTY_TYPE_BYTE:
|
||||||
|
case MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER:
|
||||||
|
case MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER:
|
||||||
|
case MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER:
|
||||||
|
os << get<int>(prop);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MQTTPROPERTY_TYPE_BINARY_DATA: {
|
||||||
|
auto bin = get<binary>(prop);
|
||||||
|
for (const char& by : bin) os << std::hex << unsigned(by);
|
||||||
|
os << std::dec;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING:
|
||||||
|
os << get<string>(prop);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR:
|
||||||
|
auto sp = get<string_pair>(prop);
|
||||||
|
os << '(' << std::get<0>(sp) << ',' << std::get<1>(sp) << ')';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PAHO_MQTTPP_EXPORT const MQTTProperties properties::DFLT_C_STRUCT =
|
properties::properties(std::initializer_list<property> props)
|
||||||
MQTTProperties_initializer;
|
|
||||||
|
|
||||||
properties::properties() : props_{DFLT_C_STRUCT} {}
|
|
||||||
|
|
||||||
properties::properties(std::initializer_list<property> props) : props_{DFLT_C_STRUCT}
|
|
||||||
{
|
{
|
||||||
for (const auto& prop : props) ::MQTTProperties_add(&props_, &prop.c_struct());
|
for (const auto& prop : props) {
|
||||||
|
::MQTTProperties_add(&props_, &prop.c_struct());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
properties& properties::operator=(const properties& rhs)
|
properties& properties::operator=(const properties& rhs)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user