1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
|
/*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Thomas Voß <thomas.voss@canonical.com>
*/
#ifndef CORE_DBUS_MESSAGE_H_
#define CORE_DBUS_MESSAGE_H_
#include <core/dbus/argument_type.h>
#include <core/dbus/visibility.h>
#include <core/dbus/types/object_path.h>
#include <core/dbus/types/signature.h>
#include <core/dbus/types/unix_fd.h>
#include <cstdint>
#include <exception>
#include <map>
#include <memory>
#include <ostream>
#include <stdexcept>
namespace core
{
namespace dbus
{
template<typename T> struct Codec;
class Error;
/**
* @brief The Message class wraps a raw DBus message
*/
class ORG_FREEDESKTOP_DBUS_DLL_PUBLIC Message : public std::enable_shared_from_this<Message>
{
public:
typedef std::shared_ptr<Message> Ptr;
/**
* @brief The Type enum models the type of the message.
*/
enum class Type : int
{
invalid = DBUS_MESSAGE_TYPE_INVALID, ///< Invalid message type
signal = DBUS_MESSAGE_TYPE_SIGNAL, ///< A signal message
method_call = DBUS_MESSAGE_TYPE_METHOD_CALL, ///< A method-call message
method_return = DBUS_MESSAGE_TYPE_METHOD_RETURN, ///< A method-return message
error = DBUS_MESSAGE_TYPE_ERROR ///< An error message.
};
/**
* @brief The Reader class allows type-safe reading of arguments from a message.
*/
class Reader
{
public:
Reader();
~Reader();
Reader(const Reader&) = default;
Reader& operator=(const Reader&) = default;
Reader(Reader&&);
Reader& operator=(Reader&&);
/**
* @brief Returns the current type.
*
*/
ArgumentType type() const;
/**
* @brief Advances this view into the message.
*/
void pop();
/**
* @brief Reads a byte from the underlying message.
*/
std::int8_t pop_byte();
/**
* @brief Reads a boolean from the underlying message.
*/
bool pop_boolean();
/**
* @brief Reads an int16 from the underlying message.
*/
std::int16_t pop_int16();
/**
* @brief Reads a uint16 from the underlying message.
*/
std::uint16_t pop_uint16();
/**
* @brief Reads an int32 from the underlying message.
*/
std::int32_t pop_int32();
/**
* @brief Reads a uint32 from the underlying message.
*/
std::uint32_t pop_uint32();
/**
* @brief Reads an int64 from the underlying message.
*/
std::int64_t pop_int64();
/**
* @brief Reads a uint64 from the underlying message.
*/
std::uint64_t pop_uint64();
/**
* @brief Reads a floating point value from the underlying message.
*/
double pop_floating_point();
/**
* @brief Reads a string from the underlying message.
*/
const char* pop_string();
/**
* @brief Reads an object_path from the underlying message.
*/
types::ObjectPath pop_object_path();
/**
* @brief Reads a signature from the underlying message.
*/
types::Signature pop_signature();
/**
* @brief Reads a unix fd from the underlying message.
*/
types::UnixFd pop_unix_fd();
/**
* @brief Prepares reading of an array from the underlying message.
* @return A reader pointing to the array.
*/
Reader pop_array();
/**
* @brief Prepares reading of a structure from the underlying message.
* @return A reader pointing into the structure.
*/
Reader pop_structure();
/**
* @brief Prepares reading of a variant from the underlying message.
* @return A reader pointing into the variant.
*/
Reader pop_variant();
/**
* @brief Prepares reading of a dict entry from the underlying message.
* @return A reader pointing to the array.
*/
Reader pop_dict_entry();
private:
friend class Message;
explicit Reader(const std::shared_ptr<Message>& msg);
const std::shared_ptr<Message>& access_message();
struct Private;
std::shared_ptr<Private> d;
};
/**
* @brief The Writer class allows type-safe serialization of input arguments to a message.
*/
class Writer
{
public:
~Writer();
Writer(const Writer&) = delete;
Writer& operator=(const Writer&) = delete;
Writer(Writer&&);
Writer& operator=(Writer&&);
/**
* @brief Writes a byte to the underlying message.
*/
void push_byte(std::int8_t value);
/**
* @brief Writes a boolean to the underlying message.
*/
void push_boolean(bool value);
/**
* @brief Writes an int16 to the underlying message.
*/
void push_int16(std::int16_t value);
/**
* @brief Writes a uint16 to the underlying message.
*/
void push_uint16(std::uint16_t value);
/**
* @brief Writes an int32 to the underlying message.
*/
void push_int32(std::int32_t value);
/**
* @brief Writes a uint32 to the underlying message.
*/
void push_uint32(std::uint32_t value);
/**
* @brief Writes an int64 to the underlying message.
*/
void push_int64(std::int64_t value);
/**
* @brief Writes a uint64 to the underlying message.
*/
void push_uint64(std::uint64_t value);
/**
* @brief Writes a floating point value to the underlying message.
*/
void push_floating_point(double value);
/**
* @brief Writes a string to the underlying message.
*/
void push_stringn(const char* value, std::size_t size);
/**
* @brief Writes an object_path to the underlying message.
*/
void push_object_path(const types::ObjectPath& value);
/**
* @brief Writes a signature to the underlying message.
*/
void push_signature(const types::Signature& value);
/**
* @brief Writes a unix fd to the underlying message.
*/
void push_unix_fd(const types::UnixFd& value);
/**
* @brief Prepares writing of an array to the underlying message.
* @param [in] signature The signature of the contained data type.
*/
Writer open_array(const types::Signature& signature);
/**
* @brief Finalizes writing of an array to the underlying message.
*/
void close_array(Writer writer);
/**
* @brief Prepares writing of a structure to the underlying message.
*/
Writer open_structure();
/**
* @brief Finalizes writing of a structure to the underlying message.
*/
void close_structure(Writer writer);
/**
* @brief Prepares writing of a variant to the underlying message.
* @param [in] signature The signature of the contained data type.
*/
Writer open_variant(const types::Signature& signature);
/**
* @brief Finalizes writing of a variant to the underlying message.
*/
void close_variant(Writer writer);
/**
* @brief Prepares writing of a dict entry to the underlying message.
*/
Writer open_dict_entry();
/**
* @brief Finalizes writing of a dict entry to the underlying message.
*/
void close_dict_entry(Writer writer);
private:
friend class Message;
explicit Writer(const std::shared_ptr<Message>& msg);
struct Private;
std::unique_ptr<Private> d;
};
/**
* @brief make_method_call creates an instance of Message with type Type::method_call.
* @param destination The name of the remote service to send the message to.
* @param path The name of the remote object to send the message to.
* @param interface The interface to route the message to.
* @param method The actual method that should be invoked
* @return An instance of message of type Type::method_call.
* @throw std::runtime_error if any of the parameters violates the DBus specification.
*/
static std::shared_ptr<Message> make_method_call(
const std::string& destination,
const types::ObjectPath& path,
const std::string& interface,
const std::string& method);
/**
* @brief make_method_return creates a message instance in response to a raw DBus message of type method-call.
* @param msg The message to reply to, must not be null. Must be of type Type::method_call.
* @return An instance of message of type Type::method_return.
*/
static std::shared_ptr<Message> make_method_return(const Message::Ptr& msg);
/**
* @brief make_signal creates a message instance wrapping a signal emission.
* @param path The path of the object emitting the signal.
* @param interface The interface containing the signal.
* @param signal The actual signal name.
* @return An instance of message of type Type::signal.
*/
static std::shared_ptr<Message> make_signal(
const std::string& path,
const std::string& interface,
const std::string& signal);
/**
* @brief make_error creates an error message instance in response to a raw DBus message of type method-call.
* @param in_reply_to The message to reply to, must not be null. Must be of type Type::method_call.
* @param error_name The name of the error.
* @param error_desc Human-readable description of the error.
* @return An instance of message of type Type::error.
*/
static std::shared_ptr<Message> make_error(
const Message::Ptr& in_reply_to,
const std::string& error_name,
const std::string& error_desc);
/**
* @brief from_raw_message creates an instance of message from a raw message.
* @param msg The message to wrap.
* @return An instance of Message with a type corresponding to the type of the raw message.
*/
static std::shared_ptr<Message> from_raw_message(DBusMessage* msg);
~Message();
/**
* @brief Queries the type of the message.
*/
Type type() const;
/**
* @brief Checks if the message expects a reply, i.e., is of type Type::method_call.
*/
bool expects_reply() const;
/**
* @brief Queries the path of the object that this message belongs to.
*/
types::ObjectPath path() const;
/**
* @brief Queries the member name that this message corresponds to.
*/
std::string member() const;
/**
* @brief Queries the type signature of this message.
*/
std::string signature() const;
/**
* @brief Queries the interface name that this message corresponds to.
*/
std::string interface() const;
/**
* @brief Queries the name of the destination that this message should go to.
*/
std::string destination() const;
/**
* @brief Queries the name of the sender that this message originates from.
*/
std::string sender() const;
/**
* @brief Extracts error information from the message.
* @throw std::runtime_error if not an error message.
*/
Error error() const;
/**
* @brief Creates a Reader instance to read from this message.
*/
Reader reader();
/**
* @brief Creates a Writer instance to write to this message.
*/
Writer writer();
/**
* @brief Meant for testing purposes only.
*/
void ensure_serial_larger_than_zero_for_testing();
private:
friend class Bus;
std::shared_ptr<Message> clone();
struct Private;
std::unique_ptr<Private> d;
Message(std::unique_ptr<Private> d);
};
typedef std::shared_ptr<Message> MessagePtr;
typedef std::unique_ptr<Message> MessageUPtr;
ORG_FREEDESKTOP_DBUS_DLL_PUBLIC std::ostream& operator<<(std::ostream&, Message::Type);
}
}
namespace std
{
template<>
struct hash<core::dbus::Message::Type>
{
size_t operator()(const core::dbus::Message::Type& type) const
{
static const hash<int> h {};
return h(static_cast<int>(type));
}
};
}
#endif // CORE_DBUS_MESSAGE_H_
|