blob: 327fb7e914f9edf18b966070b4bcaf9585c68d8a [file] [log] [blame]
Patrick Williams5acb5492016-09-02 15:14:16 -05001#pragma once
2
3#include <memory>
4#include <systemd/sd-bus.h>
5#include <sdbusplus/message/append.hpp>
Patrick Williams4fe85a32016-09-08 15:03:56 -05006#include <sdbusplus/message/read.hpp>
Patrick Williams5acb5492016-09-02 15:14:16 -05007
8namespace sdbusplus
9{
10
11 // Forward declare sdbusplus::bus::bus for 'friend'ship.
12namespace bus { struct bus; };
13
14namespace message
15{
16
17using msgp_t = sd_bus_message*;
18class message;
19
20namespace details
21{
22
23/** @brief unique_ptr functor to release a msg reference. */
24struct MsgDeleter
25{
26 void operator()(msgp_t ptr) const
27 {
28 sd_bus_message_unref(ptr);
29 }
30};
31
32/* @brief Alias 'msg' to a unique_ptr type for auto-release. */
33using msg = std::unique_ptr<sd_bus_message, MsgDeleter>;
34
35} // namespace details
36
37/** @class message
38 * @brief Provides C++ bindings to the sd_bus_message_* class functions.
39 */
40struct message
41{
42 /* Define all of the basic class operations:
43 * Not allowed:
44 * - Default constructor to avoid nullptrs.
45 * - Copy operations due to internal unique_ptr.
46 * Allowed:
47 * - Move operations.
48 * - Destructor.
49 */
50 message() = delete;
51 message(const message&) = delete;
52 message& operator=(const message&) = delete;
53 message(message&&) = default;
54 message& operator=(message&&) = default;
55 ~message() = default;
56
57 /** @brief Conversion constructor for 'msgp_t'.
58 *
59 * Takes ownership of the msg-pointer and releases it when done.
60 */
61 explicit message(msgp_t m) : _msg(m) {}
62
63 /** @brief Release ownership of the stored msg-pointer. */
64 msgp_t release() { return _msg.release(); }
65
Patrick Williams4fe85a32016-09-08 15:03:56 -050066 /** @brief Check if message contains a real pointer. (non-nullptr). */
67 explicit operator bool() const { return bool(_msg); }
68
69
Patrick Williams5acb5492016-09-02 15:14:16 -050070 /** @brief Perform sd_bus_message_append, with automatic type deduction.
71 *
72 * @tparam ...Args - Type of items to append to message.
73 * @param[in] args - Items to append to message.
74 */
75 template <typename ...Args> void append(Args&&... args)
76 {
77 sdbusplus::message::append(_msg.get(), std::forward<Args>(args)...);
78 }
79
Patrick Williams4fe85a32016-09-08 15:03:56 -050080 /** @brief Perform sd_bus_message_read, with automatic type deduction.
81 *
82 * @tparam ...Args - Type of items to read from message.
83 * @param[out] args - Items to read from message.
84 */
85 template <typename ...Args> void read(Args&&... args)
86 {
87 sdbusplus::message::read(_msg.get(), std::forward<Args>(args)...);
88 }
89
90 /** @brief Get the signature of a message.
91 *
92 * @return A [weak] pointer to the signature of the message.
93 */
94 const char* get_signature()
95 {
96 return sd_bus_message_get_signature(_msg.get(), true);
97 }
98
99 /** @brief Check if message is a method call for an interface/method.
100 *
101 * @param[in] interface - The interface to match.
102 * @param[in] method - The method to match.
103 *
104 * @return True - if message is a method call for interface/method.
105 */
106 bool is_method_call(const char* interface, const char* method)
107 {
108 return sd_bus_message_is_method_call(_msg.get(), interface, method);
109 }
110
Patrick Williams2a47ecd2016-10-16 17:16:58 -0500111 /** @brief Create a 'method_return' type message from an existing message.
112 *
113 * @return method-return message.
114 */
115 message new_method_return()
116 {
117 msgp_t reply = nullptr;
118 sd_bus_message_new_method_return(this->get(), &reply);
119
120 return message(reply);
121 }
122
Patrick Williams425dc9b2016-10-17 16:50:53 -0500123 /** @brief Perform a 'method-return' response call. */
124 void method_return()
125 {
126 auto b = sd_bus_message_get_bus(this->get());
127 sd_bus_send(b, this->get(), nullptr);
128 }
129
Patrick Williams5acb5492016-09-02 15:14:16 -0500130 friend struct sdbusplus::bus::bus;
131
132 private:
133 /** @brief Get a pointer to the owned 'msgp_t'. */
134 msgp_t get() { return _msg.get(); }
135 details::msg _msg;
136};
137
138} // namespace message
139
140} // namespace sdbusplus