1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "dbus/message.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <string>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include "base/format_macros.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
15*635a8641SAndroid Build Coastguard Worker #include "dbus/object_path.h"
16*635a8641SAndroid Build Coastguard Worker #include "third_party/protobuf/src/google/protobuf/message_lite.h"
17*635a8641SAndroid Build Coastguard Worker
18*635a8641SAndroid Build Coastguard Worker namespace {
19*635a8641SAndroid Build Coastguard Worker
20*635a8641SAndroid Build Coastguard Worker // Appends the header name and the value to |output|, if the value is
21*635a8641SAndroid Build Coastguard Worker // not empty.
AppendStringHeader(const std::string & header_name,const std::string & header_value,std::string * output)22*635a8641SAndroid Build Coastguard Worker void AppendStringHeader(const std::string& header_name,
23*635a8641SAndroid Build Coastguard Worker const std::string& header_value,
24*635a8641SAndroid Build Coastguard Worker std::string* output) {
25*635a8641SAndroid Build Coastguard Worker if (!header_value.empty()) {
26*635a8641SAndroid Build Coastguard Worker *output += header_name + ": " + header_value + "\n";
27*635a8641SAndroid Build Coastguard Worker }
28*635a8641SAndroid Build Coastguard Worker }
29*635a8641SAndroid Build Coastguard Worker
30*635a8641SAndroid Build Coastguard Worker // Appends the header name and the value to |output|, if the value is
31*635a8641SAndroid Build Coastguard Worker // nonzero.
AppendUint32Header(const std::string & header_name,uint32_t header_value,std::string * output)32*635a8641SAndroid Build Coastguard Worker void AppendUint32Header(const std::string& header_name,
33*635a8641SAndroid Build Coastguard Worker uint32_t header_value,
34*635a8641SAndroid Build Coastguard Worker std::string* output) {
35*635a8641SAndroid Build Coastguard Worker if (header_value != 0) {
36*635a8641SAndroid Build Coastguard Worker *output += (header_name + ": " + base::UintToString(header_value) + "\n");
37*635a8641SAndroid Build Coastguard Worker }
38*635a8641SAndroid Build Coastguard Worker }
39*635a8641SAndroid Build Coastguard Worker
40*635a8641SAndroid Build Coastguard Worker } // namespace
41*635a8641SAndroid Build Coastguard Worker
42*635a8641SAndroid Build Coastguard Worker namespace dbus {
43*635a8641SAndroid Build Coastguard Worker
IsDBusTypeUnixFdSupported()44*635a8641SAndroid Build Coastguard Worker bool IsDBusTypeUnixFdSupported() {
45*635a8641SAndroid Build Coastguard Worker int major = 0, minor = 0, micro = 0;
46*635a8641SAndroid Build Coastguard Worker dbus_get_version(&major, &minor, µ);
47*635a8641SAndroid Build Coastguard Worker return major >= 1 && minor >= 4;
48*635a8641SAndroid Build Coastguard Worker }
49*635a8641SAndroid Build Coastguard Worker
Message()50*635a8641SAndroid Build Coastguard Worker Message::Message() : raw_message_(nullptr) {}
51*635a8641SAndroid Build Coastguard Worker
~Message()52*635a8641SAndroid Build Coastguard Worker Message::~Message() {
53*635a8641SAndroid Build Coastguard Worker if (raw_message_)
54*635a8641SAndroid Build Coastguard Worker dbus_message_unref(raw_message_);
55*635a8641SAndroid Build Coastguard Worker }
56*635a8641SAndroid Build Coastguard Worker
Init(DBusMessage * raw_message)57*635a8641SAndroid Build Coastguard Worker void Message::Init(DBusMessage* raw_message) {
58*635a8641SAndroid Build Coastguard Worker DCHECK(!raw_message_);
59*635a8641SAndroid Build Coastguard Worker raw_message_ = raw_message;
60*635a8641SAndroid Build Coastguard Worker }
61*635a8641SAndroid Build Coastguard Worker
GetMessageType()62*635a8641SAndroid Build Coastguard Worker Message::MessageType Message::GetMessageType() {
63*635a8641SAndroid Build Coastguard Worker if (!raw_message_)
64*635a8641SAndroid Build Coastguard Worker return MESSAGE_INVALID;
65*635a8641SAndroid Build Coastguard Worker const int type = dbus_message_get_type(raw_message_);
66*635a8641SAndroid Build Coastguard Worker return static_cast<Message::MessageType>(type);
67*635a8641SAndroid Build Coastguard Worker }
68*635a8641SAndroid Build Coastguard Worker
GetMessageTypeAsString()69*635a8641SAndroid Build Coastguard Worker std::string Message::GetMessageTypeAsString() {
70*635a8641SAndroid Build Coastguard Worker switch (GetMessageType()) {
71*635a8641SAndroid Build Coastguard Worker case MESSAGE_INVALID:
72*635a8641SAndroid Build Coastguard Worker return "MESSAGE_INVALID";
73*635a8641SAndroid Build Coastguard Worker case MESSAGE_METHOD_CALL:
74*635a8641SAndroid Build Coastguard Worker return "MESSAGE_METHOD_CALL";
75*635a8641SAndroid Build Coastguard Worker case MESSAGE_METHOD_RETURN:
76*635a8641SAndroid Build Coastguard Worker return "MESSAGE_METHOD_RETURN";
77*635a8641SAndroid Build Coastguard Worker case MESSAGE_SIGNAL:
78*635a8641SAndroid Build Coastguard Worker return "MESSAGE_SIGNAL";
79*635a8641SAndroid Build Coastguard Worker case MESSAGE_ERROR:
80*635a8641SAndroid Build Coastguard Worker return "MESSAGE_ERROR";
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker NOTREACHED();
83*635a8641SAndroid Build Coastguard Worker return std::string();
84*635a8641SAndroid Build Coastguard Worker }
85*635a8641SAndroid Build Coastguard Worker
ToStringInternal(const std::string & indent,MessageReader * reader)86*635a8641SAndroid Build Coastguard Worker std::string Message::ToStringInternal(const std::string& indent,
87*635a8641SAndroid Build Coastguard Worker MessageReader* reader) {
88*635a8641SAndroid Build Coastguard Worker const char* kBrokenMessage = "[broken message]";
89*635a8641SAndroid Build Coastguard Worker std::string output;
90*635a8641SAndroid Build Coastguard Worker while (reader->HasMoreData()) {
91*635a8641SAndroid Build Coastguard Worker const DataType type = reader->GetDataType();
92*635a8641SAndroid Build Coastguard Worker switch (type) {
93*635a8641SAndroid Build Coastguard Worker case BYTE: {
94*635a8641SAndroid Build Coastguard Worker uint8_t value = 0;
95*635a8641SAndroid Build Coastguard Worker if (!reader->PopByte(&value))
96*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
97*635a8641SAndroid Build Coastguard Worker output += indent + "byte " + base::UintToString(value) + "\n";
98*635a8641SAndroid Build Coastguard Worker break;
99*635a8641SAndroid Build Coastguard Worker }
100*635a8641SAndroid Build Coastguard Worker case BOOL: {
101*635a8641SAndroid Build Coastguard Worker bool value = false;
102*635a8641SAndroid Build Coastguard Worker if (!reader->PopBool(&value))
103*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
104*635a8641SAndroid Build Coastguard Worker output += indent + "bool " + (value ? "true" : "false") + "\n";
105*635a8641SAndroid Build Coastguard Worker break;
106*635a8641SAndroid Build Coastguard Worker }
107*635a8641SAndroid Build Coastguard Worker case INT16: {
108*635a8641SAndroid Build Coastguard Worker int16_t value = 0;
109*635a8641SAndroid Build Coastguard Worker if (!reader->PopInt16(&value))
110*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
111*635a8641SAndroid Build Coastguard Worker output += indent + "int16_t " + base::IntToString(value) + "\n";
112*635a8641SAndroid Build Coastguard Worker break;
113*635a8641SAndroid Build Coastguard Worker }
114*635a8641SAndroid Build Coastguard Worker case UINT16: {
115*635a8641SAndroid Build Coastguard Worker uint16_t value = 0;
116*635a8641SAndroid Build Coastguard Worker if (!reader->PopUint16(&value))
117*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
118*635a8641SAndroid Build Coastguard Worker output += indent + "uint16_t " + base::UintToString(value) + "\n";
119*635a8641SAndroid Build Coastguard Worker break;
120*635a8641SAndroid Build Coastguard Worker }
121*635a8641SAndroid Build Coastguard Worker case INT32: {
122*635a8641SAndroid Build Coastguard Worker int32_t value = 0;
123*635a8641SAndroid Build Coastguard Worker if (!reader->PopInt32(&value))
124*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
125*635a8641SAndroid Build Coastguard Worker output += indent + "int32_t " + base::IntToString(value) + "\n";
126*635a8641SAndroid Build Coastguard Worker break;
127*635a8641SAndroid Build Coastguard Worker }
128*635a8641SAndroid Build Coastguard Worker case UINT32: {
129*635a8641SAndroid Build Coastguard Worker uint32_t value = 0;
130*635a8641SAndroid Build Coastguard Worker if (!reader->PopUint32(&value))
131*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
132*635a8641SAndroid Build Coastguard Worker output += indent + "uint32_t " + base::UintToString(value) + "\n";
133*635a8641SAndroid Build Coastguard Worker break;
134*635a8641SAndroid Build Coastguard Worker }
135*635a8641SAndroid Build Coastguard Worker case INT64: {
136*635a8641SAndroid Build Coastguard Worker int64_t value = 0;
137*635a8641SAndroid Build Coastguard Worker if (!reader->PopInt64(&value))
138*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
139*635a8641SAndroid Build Coastguard Worker output += (indent + "int64_t " + base::Int64ToString(value) + "\n");
140*635a8641SAndroid Build Coastguard Worker break;
141*635a8641SAndroid Build Coastguard Worker }
142*635a8641SAndroid Build Coastguard Worker case UINT64: {
143*635a8641SAndroid Build Coastguard Worker uint64_t value = 0;
144*635a8641SAndroid Build Coastguard Worker if (!reader->PopUint64(&value))
145*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
146*635a8641SAndroid Build Coastguard Worker output += (indent + "uint64_t " + base::NumberToString(value) + "\n");
147*635a8641SAndroid Build Coastguard Worker break;
148*635a8641SAndroid Build Coastguard Worker }
149*635a8641SAndroid Build Coastguard Worker case DOUBLE: {
150*635a8641SAndroid Build Coastguard Worker double value = 0;
151*635a8641SAndroid Build Coastguard Worker if (!reader->PopDouble(&value))
152*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
153*635a8641SAndroid Build Coastguard Worker output += indent + "double " + base::NumberToString(value) + "\n";
154*635a8641SAndroid Build Coastguard Worker break;
155*635a8641SAndroid Build Coastguard Worker }
156*635a8641SAndroid Build Coastguard Worker case STRING: {
157*635a8641SAndroid Build Coastguard Worker std::string value;
158*635a8641SAndroid Build Coastguard Worker if (!reader->PopString(&value))
159*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
160*635a8641SAndroid Build Coastguard Worker // Truncate if the string is longer than the limit.
161*635a8641SAndroid Build Coastguard Worker const size_t kTruncateLength = 100;
162*635a8641SAndroid Build Coastguard Worker if (value.size() < kTruncateLength) {
163*635a8641SAndroid Build Coastguard Worker output += indent + "string \"" + value + "\"\n";
164*635a8641SAndroid Build Coastguard Worker } else {
165*635a8641SAndroid Build Coastguard Worker std::string truncated;
166*635a8641SAndroid Build Coastguard Worker base::TruncateUTF8ToByteSize(value, kTruncateLength, &truncated);
167*635a8641SAndroid Build Coastguard Worker base::StringAppendF(&truncated, "... (%" PRIuS " bytes in total)",
168*635a8641SAndroid Build Coastguard Worker value.size());
169*635a8641SAndroid Build Coastguard Worker output += indent + "string \"" + truncated + "\"\n";
170*635a8641SAndroid Build Coastguard Worker }
171*635a8641SAndroid Build Coastguard Worker break;
172*635a8641SAndroid Build Coastguard Worker }
173*635a8641SAndroid Build Coastguard Worker case OBJECT_PATH: {
174*635a8641SAndroid Build Coastguard Worker ObjectPath value;
175*635a8641SAndroid Build Coastguard Worker if (!reader->PopObjectPath(&value))
176*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
177*635a8641SAndroid Build Coastguard Worker output += indent + "object_path \"" + value.value() + "\"\n";
178*635a8641SAndroid Build Coastguard Worker break;
179*635a8641SAndroid Build Coastguard Worker }
180*635a8641SAndroid Build Coastguard Worker case ARRAY: {
181*635a8641SAndroid Build Coastguard Worker MessageReader sub_reader(this);
182*635a8641SAndroid Build Coastguard Worker if (!reader->PopArray(&sub_reader))
183*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
184*635a8641SAndroid Build Coastguard Worker output += indent + "array [\n";
185*635a8641SAndroid Build Coastguard Worker output += ToStringInternal(indent + " ", &sub_reader);
186*635a8641SAndroid Build Coastguard Worker output += indent + "]\n";
187*635a8641SAndroid Build Coastguard Worker break;
188*635a8641SAndroid Build Coastguard Worker }
189*635a8641SAndroid Build Coastguard Worker case STRUCT: {
190*635a8641SAndroid Build Coastguard Worker MessageReader sub_reader(this);
191*635a8641SAndroid Build Coastguard Worker if (!reader->PopStruct(&sub_reader))
192*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
193*635a8641SAndroid Build Coastguard Worker output += indent + "struct {\n";
194*635a8641SAndroid Build Coastguard Worker output += ToStringInternal(indent + " ", &sub_reader);
195*635a8641SAndroid Build Coastguard Worker output += indent + "}\n";
196*635a8641SAndroid Build Coastguard Worker break;
197*635a8641SAndroid Build Coastguard Worker }
198*635a8641SAndroid Build Coastguard Worker case DICT_ENTRY: {
199*635a8641SAndroid Build Coastguard Worker MessageReader sub_reader(this);
200*635a8641SAndroid Build Coastguard Worker if (!reader->PopDictEntry(&sub_reader))
201*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
202*635a8641SAndroid Build Coastguard Worker output += indent + "dict entry {\n";
203*635a8641SAndroid Build Coastguard Worker output += ToStringInternal(indent + " ", &sub_reader);
204*635a8641SAndroid Build Coastguard Worker output += indent + "}\n";
205*635a8641SAndroid Build Coastguard Worker break;
206*635a8641SAndroid Build Coastguard Worker }
207*635a8641SAndroid Build Coastguard Worker case VARIANT: {
208*635a8641SAndroid Build Coastguard Worker MessageReader sub_reader(this);
209*635a8641SAndroid Build Coastguard Worker if (!reader->PopVariant(&sub_reader))
210*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
211*635a8641SAndroid Build Coastguard Worker output += indent + "variant ";
212*635a8641SAndroid Build Coastguard Worker output += ToStringInternal(indent + " ", &sub_reader);
213*635a8641SAndroid Build Coastguard Worker break;
214*635a8641SAndroid Build Coastguard Worker }
215*635a8641SAndroid Build Coastguard Worker case UNIX_FD: {
216*635a8641SAndroid Build Coastguard Worker CHECK(IsDBusTypeUnixFdSupported());
217*635a8641SAndroid Build Coastguard Worker
218*635a8641SAndroid Build Coastguard Worker base::ScopedFD file_descriptor;
219*635a8641SAndroid Build Coastguard Worker if (!reader->PopFileDescriptor(&file_descriptor))
220*635a8641SAndroid Build Coastguard Worker return kBrokenMessage;
221*635a8641SAndroid Build Coastguard Worker output +=
222*635a8641SAndroid Build Coastguard Worker indent + "fd#" + base::IntToString(file_descriptor.get()) + "\n";
223*635a8641SAndroid Build Coastguard Worker break;
224*635a8641SAndroid Build Coastguard Worker }
225*635a8641SAndroid Build Coastguard Worker default:
226*635a8641SAndroid Build Coastguard Worker LOG(FATAL) << "Unknown type: " << type;
227*635a8641SAndroid Build Coastguard Worker }
228*635a8641SAndroid Build Coastguard Worker }
229*635a8641SAndroid Build Coastguard Worker return output;
230*635a8641SAndroid Build Coastguard Worker }
231*635a8641SAndroid Build Coastguard Worker
232*635a8641SAndroid Build Coastguard Worker // The returned string consists of message headers such as
233*635a8641SAndroid Build Coastguard Worker // destination if any, followed by a blank line, and the message
234*635a8641SAndroid Build Coastguard Worker // payload. For example, a MethodCall's ToString() will look like:
235*635a8641SAndroid Build Coastguard Worker //
236*635a8641SAndroid Build Coastguard Worker // destination: com.example.Service
237*635a8641SAndroid Build Coastguard Worker // path: /com/example/Object
238*635a8641SAndroid Build Coastguard Worker // interface: com.example.Interface
239*635a8641SAndroid Build Coastguard Worker // member: SomeMethod
240*635a8641SAndroid Build Coastguard Worker //
241*635a8641SAndroid Build Coastguard Worker // string \"payload\"
242*635a8641SAndroid Build Coastguard Worker // ...
ToString()243*635a8641SAndroid Build Coastguard Worker std::string Message::ToString() {
244*635a8641SAndroid Build Coastguard Worker if (!raw_message_)
245*635a8641SAndroid Build Coastguard Worker return std::string();
246*635a8641SAndroid Build Coastguard Worker
247*635a8641SAndroid Build Coastguard Worker // Generate headers first.
248*635a8641SAndroid Build Coastguard Worker std::string headers;
249*635a8641SAndroid Build Coastguard Worker AppendStringHeader("message_type", GetMessageTypeAsString(), &headers);
250*635a8641SAndroid Build Coastguard Worker AppendStringHeader("destination", GetDestination(), &headers);
251*635a8641SAndroid Build Coastguard Worker AppendStringHeader("path", GetPath().value(), &headers);
252*635a8641SAndroid Build Coastguard Worker AppendStringHeader("interface", GetInterface(), &headers);
253*635a8641SAndroid Build Coastguard Worker AppendStringHeader("member", GetMember(), &headers);
254*635a8641SAndroid Build Coastguard Worker AppendStringHeader("error_name", GetErrorName(), &headers);
255*635a8641SAndroid Build Coastguard Worker AppendStringHeader("sender", GetSender(), &headers);
256*635a8641SAndroid Build Coastguard Worker AppendStringHeader("signature", GetSignature(), &headers);
257*635a8641SAndroid Build Coastguard Worker AppendUint32Header("serial", GetSerial(), &headers);
258*635a8641SAndroid Build Coastguard Worker AppendUint32Header("reply_serial", GetReplySerial(), &headers);
259*635a8641SAndroid Build Coastguard Worker
260*635a8641SAndroid Build Coastguard Worker // Generate the payload.
261*635a8641SAndroid Build Coastguard Worker MessageReader reader(this);
262*635a8641SAndroid Build Coastguard Worker return headers + "\n" + ToStringInternal(std::string(), &reader);
263*635a8641SAndroid Build Coastguard Worker }
264*635a8641SAndroid Build Coastguard Worker
SetDestination(const std::string & destination)265*635a8641SAndroid Build Coastguard Worker bool Message::SetDestination(const std::string& destination) {
266*635a8641SAndroid Build Coastguard Worker return dbus_message_set_destination(raw_message_, destination.c_str());
267*635a8641SAndroid Build Coastguard Worker }
268*635a8641SAndroid Build Coastguard Worker
SetPath(const ObjectPath & path)269*635a8641SAndroid Build Coastguard Worker bool Message::SetPath(const ObjectPath& path) {
270*635a8641SAndroid Build Coastguard Worker return dbus_message_set_path(raw_message_, path.value().c_str());
271*635a8641SAndroid Build Coastguard Worker }
272*635a8641SAndroid Build Coastguard Worker
SetInterface(const std::string & interface)273*635a8641SAndroid Build Coastguard Worker bool Message::SetInterface(const std::string& interface) {
274*635a8641SAndroid Build Coastguard Worker return dbus_message_set_interface(raw_message_, interface.c_str());
275*635a8641SAndroid Build Coastguard Worker }
276*635a8641SAndroid Build Coastguard Worker
SetMember(const std::string & member)277*635a8641SAndroid Build Coastguard Worker bool Message::SetMember(const std::string& member) {
278*635a8641SAndroid Build Coastguard Worker return dbus_message_set_member(raw_message_, member.c_str());
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker
SetErrorName(const std::string & error_name)281*635a8641SAndroid Build Coastguard Worker bool Message::SetErrorName(const std::string& error_name) {
282*635a8641SAndroid Build Coastguard Worker return dbus_message_set_error_name(raw_message_, error_name.c_str());
283*635a8641SAndroid Build Coastguard Worker }
284*635a8641SAndroid Build Coastguard Worker
SetSender(const std::string & sender)285*635a8641SAndroid Build Coastguard Worker bool Message::SetSender(const std::string& sender) {
286*635a8641SAndroid Build Coastguard Worker return dbus_message_set_sender(raw_message_, sender.c_str());
287*635a8641SAndroid Build Coastguard Worker }
288*635a8641SAndroid Build Coastguard Worker
SetSerial(uint32_t serial)289*635a8641SAndroid Build Coastguard Worker void Message::SetSerial(uint32_t serial) {
290*635a8641SAndroid Build Coastguard Worker dbus_message_set_serial(raw_message_, serial);
291*635a8641SAndroid Build Coastguard Worker }
292*635a8641SAndroid Build Coastguard Worker
SetReplySerial(uint32_t reply_serial)293*635a8641SAndroid Build Coastguard Worker void Message::SetReplySerial(uint32_t reply_serial) {
294*635a8641SAndroid Build Coastguard Worker dbus_message_set_reply_serial(raw_message_, reply_serial);
295*635a8641SAndroid Build Coastguard Worker }
296*635a8641SAndroid Build Coastguard Worker
GetDestination()297*635a8641SAndroid Build Coastguard Worker std::string Message::GetDestination() {
298*635a8641SAndroid Build Coastguard Worker const char* destination = dbus_message_get_destination(raw_message_);
299*635a8641SAndroid Build Coastguard Worker return destination ? destination : "";
300*635a8641SAndroid Build Coastguard Worker }
301*635a8641SAndroid Build Coastguard Worker
GetPath()302*635a8641SAndroid Build Coastguard Worker ObjectPath Message::GetPath() {
303*635a8641SAndroid Build Coastguard Worker const char* path = dbus_message_get_path(raw_message_);
304*635a8641SAndroid Build Coastguard Worker return ObjectPath(path ? path : "");
305*635a8641SAndroid Build Coastguard Worker }
306*635a8641SAndroid Build Coastguard Worker
GetInterface()307*635a8641SAndroid Build Coastguard Worker std::string Message::GetInterface() {
308*635a8641SAndroid Build Coastguard Worker const char* interface = dbus_message_get_interface(raw_message_);
309*635a8641SAndroid Build Coastguard Worker return interface ? interface : "";
310*635a8641SAndroid Build Coastguard Worker }
311*635a8641SAndroid Build Coastguard Worker
GetMember()312*635a8641SAndroid Build Coastguard Worker std::string Message::GetMember() {
313*635a8641SAndroid Build Coastguard Worker const char* member = dbus_message_get_member(raw_message_);
314*635a8641SAndroid Build Coastguard Worker return member ? member : "";
315*635a8641SAndroid Build Coastguard Worker }
316*635a8641SAndroid Build Coastguard Worker
GetErrorName()317*635a8641SAndroid Build Coastguard Worker std::string Message::GetErrorName() {
318*635a8641SAndroid Build Coastguard Worker const char* error_name = dbus_message_get_error_name(raw_message_);
319*635a8641SAndroid Build Coastguard Worker return error_name ? error_name : "";
320*635a8641SAndroid Build Coastguard Worker }
321*635a8641SAndroid Build Coastguard Worker
GetSender()322*635a8641SAndroid Build Coastguard Worker std::string Message::GetSender() {
323*635a8641SAndroid Build Coastguard Worker const char* sender = dbus_message_get_sender(raw_message_);
324*635a8641SAndroid Build Coastguard Worker return sender ? sender : "";
325*635a8641SAndroid Build Coastguard Worker }
326*635a8641SAndroid Build Coastguard Worker
GetSignature()327*635a8641SAndroid Build Coastguard Worker std::string Message::GetSignature() {
328*635a8641SAndroid Build Coastguard Worker const char* signature = dbus_message_get_signature(raw_message_);
329*635a8641SAndroid Build Coastguard Worker return signature ? signature : "";
330*635a8641SAndroid Build Coastguard Worker }
331*635a8641SAndroid Build Coastguard Worker
GetSerial()332*635a8641SAndroid Build Coastguard Worker uint32_t Message::GetSerial() {
333*635a8641SAndroid Build Coastguard Worker return dbus_message_get_serial(raw_message_);
334*635a8641SAndroid Build Coastguard Worker }
335*635a8641SAndroid Build Coastguard Worker
GetReplySerial()336*635a8641SAndroid Build Coastguard Worker uint32_t Message::GetReplySerial() {
337*635a8641SAndroid Build Coastguard Worker return dbus_message_get_reply_serial(raw_message_);
338*635a8641SAndroid Build Coastguard Worker }
339*635a8641SAndroid Build Coastguard Worker
340*635a8641SAndroid Build Coastguard Worker //
341*635a8641SAndroid Build Coastguard Worker // MethodCall implementation.
342*635a8641SAndroid Build Coastguard Worker //
343*635a8641SAndroid Build Coastguard Worker
MethodCall(const std::string & interface_name,const std::string & method_name)344*635a8641SAndroid Build Coastguard Worker MethodCall::MethodCall(const std::string& interface_name,
345*635a8641SAndroid Build Coastguard Worker const std::string& method_name) {
346*635a8641SAndroid Build Coastguard Worker Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL));
347*635a8641SAndroid Build Coastguard Worker
348*635a8641SAndroid Build Coastguard Worker CHECK(SetInterface(interface_name));
349*635a8641SAndroid Build Coastguard Worker CHECK(SetMember(method_name));
350*635a8641SAndroid Build Coastguard Worker }
351*635a8641SAndroid Build Coastguard Worker
352*635a8641SAndroid Build Coastguard Worker MethodCall::MethodCall() = default;
353*635a8641SAndroid Build Coastguard Worker
FromRawMessage(DBusMessage * raw_message)354*635a8641SAndroid Build Coastguard Worker std::unique_ptr<MethodCall> MethodCall::FromRawMessage(
355*635a8641SAndroid Build Coastguard Worker DBusMessage* raw_message) {
356*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message));
357*635a8641SAndroid Build Coastguard Worker
358*635a8641SAndroid Build Coastguard Worker std::unique_ptr<MethodCall> method_call(new MethodCall());
359*635a8641SAndroid Build Coastguard Worker method_call->Init(raw_message);
360*635a8641SAndroid Build Coastguard Worker return method_call;
361*635a8641SAndroid Build Coastguard Worker }
362*635a8641SAndroid Build Coastguard Worker
363*635a8641SAndroid Build Coastguard Worker //
364*635a8641SAndroid Build Coastguard Worker // Signal implementation.
365*635a8641SAndroid Build Coastguard Worker //
Signal(const std::string & interface_name,const std::string & method_name)366*635a8641SAndroid Build Coastguard Worker Signal::Signal(const std::string& interface_name,
367*635a8641SAndroid Build Coastguard Worker const std::string& method_name) {
368*635a8641SAndroid Build Coastguard Worker Init(dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL));
369*635a8641SAndroid Build Coastguard Worker
370*635a8641SAndroid Build Coastguard Worker CHECK(SetInterface(interface_name));
371*635a8641SAndroid Build Coastguard Worker CHECK(SetMember(method_name));
372*635a8641SAndroid Build Coastguard Worker }
373*635a8641SAndroid Build Coastguard Worker
374*635a8641SAndroid Build Coastguard Worker Signal::Signal() = default;
375*635a8641SAndroid Build Coastguard Worker
FromRawMessage(DBusMessage * raw_message)376*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Signal> Signal::FromRawMessage(DBusMessage* raw_message) {
377*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(DBUS_MESSAGE_TYPE_SIGNAL, dbus_message_get_type(raw_message));
378*635a8641SAndroid Build Coastguard Worker
379*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Signal> signal(new Signal());
380*635a8641SAndroid Build Coastguard Worker signal->Init(raw_message);
381*635a8641SAndroid Build Coastguard Worker return signal;
382*635a8641SAndroid Build Coastguard Worker }
383*635a8641SAndroid Build Coastguard Worker
384*635a8641SAndroid Build Coastguard Worker //
385*635a8641SAndroid Build Coastguard Worker // Response implementation.
386*635a8641SAndroid Build Coastguard Worker //
387*635a8641SAndroid Build Coastguard Worker
388*635a8641SAndroid Build Coastguard Worker Response::Response() = default;
389*635a8641SAndroid Build Coastguard Worker
FromRawMessage(DBusMessage * raw_message)390*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> Response::FromRawMessage(DBusMessage* raw_message) {
391*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_RETURN,
392*635a8641SAndroid Build Coastguard Worker dbus_message_get_type(raw_message));
393*635a8641SAndroid Build Coastguard Worker
394*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> response(new Response());
395*635a8641SAndroid Build Coastguard Worker response->Init(raw_message);
396*635a8641SAndroid Build Coastguard Worker return response;
397*635a8641SAndroid Build Coastguard Worker }
398*635a8641SAndroid Build Coastguard Worker
FromMethodCall(MethodCall * method_call)399*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> Response::FromMethodCall(MethodCall* method_call) {
400*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> response(new Response());
401*635a8641SAndroid Build Coastguard Worker response->Init(dbus_message_new_method_return(method_call->raw_message()));
402*635a8641SAndroid Build Coastguard Worker return response;
403*635a8641SAndroid Build Coastguard Worker }
404*635a8641SAndroid Build Coastguard Worker
CreateEmpty()405*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> Response::CreateEmpty() {
406*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> response(new Response());
407*635a8641SAndroid Build Coastguard Worker response->Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN));
408*635a8641SAndroid Build Coastguard Worker return response;
409*635a8641SAndroid Build Coastguard Worker }
410*635a8641SAndroid Build Coastguard Worker
411*635a8641SAndroid Build Coastguard Worker //
412*635a8641SAndroid Build Coastguard Worker // ErrorResponse implementation.
413*635a8641SAndroid Build Coastguard Worker //
414*635a8641SAndroid Build Coastguard Worker
415*635a8641SAndroid Build Coastguard Worker ErrorResponse::ErrorResponse() = default;
416*635a8641SAndroid Build Coastguard Worker
FromRawMessage(DBusMessage * raw_message)417*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ErrorResponse> ErrorResponse::FromRawMessage(
418*635a8641SAndroid Build Coastguard Worker DBusMessage* raw_message) {
419*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(DBUS_MESSAGE_TYPE_ERROR, dbus_message_get_type(raw_message));
420*635a8641SAndroid Build Coastguard Worker
421*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ErrorResponse> response(new ErrorResponse());
422*635a8641SAndroid Build Coastguard Worker response->Init(raw_message);
423*635a8641SAndroid Build Coastguard Worker return response;
424*635a8641SAndroid Build Coastguard Worker }
425*635a8641SAndroid Build Coastguard Worker
FromMethodCall(MethodCall * method_call,const std::string & error_name,const std::string & error_message)426*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ErrorResponse> ErrorResponse::FromMethodCall(
427*635a8641SAndroid Build Coastguard Worker MethodCall* method_call,
428*635a8641SAndroid Build Coastguard Worker const std::string& error_name,
429*635a8641SAndroid Build Coastguard Worker const std::string& error_message) {
430*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ErrorResponse> response(new ErrorResponse());
431*635a8641SAndroid Build Coastguard Worker response->Init(dbus_message_new_error(
432*635a8641SAndroid Build Coastguard Worker method_call->raw_message(), error_name.c_str(), error_message.c_str()));
433*635a8641SAndroid Build Coastguard Worker return response;
434*635a8641SAndroid Build Coastguard Worker }
435*635a8641SAndroid Build Coastguard Worker
436*635a8641SAndroid Build Coastguard Worker //
437*635a8641SAndroid Build Coastguard Worker // MessageWriter implementation.
438*635a8641SAndroid Build Coastguard Worker //
439*635a8641SAndroid Build Coastguard Worker
MessageWriter(Message * message)440*635a8641SAndroid Build Coastguard Worker MessageWriter::MessageWriter(Message* message)
441*635a8641SAndroid Build Coastguard Worker : message_(message), container_is_open_(false) {
442*635a8641SAndroid Build Coastguard Worker memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
443*635a8641SAndroid Build Coastguard Worker if (message)
444*635a8641SAndroid Build Coastguard Worker dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_);
445*635a8641SAndroid Build Coastguard Worker }
446*635a8641SAndroid Build Coastguard Worker
447*635a8641SAndroid Build Coastguard Worker MessageWriter::~MessageWriter() = default;
448*635a8641SAndroid Build Coastguard Worker
AppendByte(uint8_t value)449*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendByte(uint8_t value) {
450*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_BYTE, &value);
451*635a8641SAndroid Build Coastguard Worker }
452*635a8641SAndroid Build Coastguard Worker
AppendBool(bool value)453*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendBool(bool value) {
454*635a8641SAndroid Build Coastguard Worker // The size of dbus_bool_t and the size of bool are different. The
455*635a8641SAndroid Build Coastguard Worker // former is always 4 per dbus-types.h, whereas the latter is usually 1.
456*635a8641SAndroid Build Coastguard Worker // dbus_message_iter_append_basic() used in AppendBasic() expects four
457*635a8641SAndroid Build Coastguard Worker // bytes for DBUS_TYPE_BOOLEAN, so we must pass a dbus_bool_t, instead
458*635a8641SAndroid Build Coastguard Worker // of a bool, to AppendBasic().
459*635a8641SAndroid Build Coastguard Worker dbus_bool_t dbus_value = value ? 1 : 0;
460*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
461*635a8641SAndroid Build Coastguard Worker }
462*635a8641SAndroid Build Coastguard Worker
AppendInt16(int16_t value)463*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendInt16(int16_t value) {
464*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_INT16, &value);
465*635a8641SAndroid Build Coastguard Worker }
466*635a8641SAndroid Build Coastguard Worker
AppendUint16(uint16_t value)467*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendUint16(uint16_t value) {
468*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_UINT16, &value);
469*635a8641SAndroid Build Coastguard Worker }
470*635a8641SAndroid Build Coastguard Worker
AppendInt32(int32_t value)471*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendInt32(int32_t value) {
472*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_INT32, &value);
473*635a8641SAndroid Build Coastguard Worker }
474*635a8641SAndroid Build Coastguard Worker
AppendUint32(uint32_t value)475*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendUint32(uint32_t value) {
476*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_UINT32, &value);
477*635a8641SAndroid Build Coastguard Worker }
478*635a8641SAndroid Build Coastguard Worker
AppendInt64(int64_t value)479*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendInt64(int64_t value) {
480*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_INT64, &value);
481*635a8641SAndroid Build Coastguard Worker }
482*635a8641SAndroid Build Coastguard Worker
AppendUint64(uint64_t value)483*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendUint64(uint64_t value) {
484*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_UINT64, &value);
485*635a8641SAndroid Build Coastguard Worker }
486*635a8641SAndroid Build Coastguard Worker
AppendDouble(double value)487*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendDouble(double value) {
488*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_DOUBLE, &value);
489*635a8641SAndroid Build Coastguard Worker }
490*635a8641SAndroid Build Coastguard Worker
AppendString(const std::string & value)491*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendString(const std::string& value) {
492*635a8641SAndroid Build Coastguard Worker // D-Bus Specification (0.19) says a string "must be valid UTF-8".
493*635a8641SAndroid Build Coastguard Worker CHECK(base::IsStringUTF8(value));
494*635a8641SAndroid Build Coastguard Worker const char* pointer = value.c_str();
495*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_STRING, &pointer);
496*635a8641SAndroid Build Coastguard Worker // TODO(satorux): It may make sense to return an error here, as the
497*635a8641SAndroid Build Coastguard Worker // input string can be large. If needed, we could add something like
498*635a8641SAndroid Build Coastguard Worker // bool AppendStringWithErrorChecking().
499*635a8641SAndroid Build Coastguard Worker }
500*635a8641SAndroid Build Coastguard Worker
AppendObjectPath(const ObjectPath & value)501*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendObjectPath(const ObjectPath& value) {
502*635a8641SAndroid Build Coastguard Worker CHECK(value.IsValid());
503*635a8641SAndroid Build Coastguard Worker const char* pointer = value.value().c_str();
504*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
505*635a8641SAndroid Build Coastguard Worker }
506*635a8641SAndroid Build Coastguard Worker
507*635a8641SAndroid Build Coastguard Worker // Ideally, client shouldn't need to supply the signature string, but
508*635a8641SAndroid Build Coastguard Worker // the underlying D-Bus library requires us to supply this before
509*635a8641SAndroid Build Coastguard Worker // appending contents to array and variant. It's technically possible
510*635a8641SAndroid Build Coastguard Worker // for us to design API that doesn't require the signature but it will
511*635a8641SAndroid Build Coastguard Worker // complicate the implementation so we decided to have the signature
512*635a8641SAndroid Build Coastguard Worker // parameter. Hopefully, variants are less used in request messages from
513*635a8641SAndroid Build Coastguard Worker // client side than response message from server side, so this should
514*635a8641SAndroid Build Coastguard Worker // not be a big issue.
OpenArray(const std::string & signature,MessageWriter * writer)515*635a8641SAndroid Build Coastguard Worker void MessageWriter::OpenArray(const std::string& signature,
516*635a8641SAndroid Build Coastguard Worker MessageWriter* writer) {
517*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
518*635a8641SAndroid Build Coastguard Worker
519*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_open_container(
520*635a8641SAndroid Build Coastguard Worker &raw_message_iter_, DBUS_TYPE_ARRAY, signature.c_str(),
521*635a8641SAndroid Build Coastguard Worker &writer->raw_message_iter_);
522*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
523*635a8641SAndroid Build Coastguard Worker container_is_open_ = true;
524*635a8641SAndroid Build Coastguard Worker }
525*635a8641SAndroid Build Coastguard Worker
OpenVariant(const std::string & signature,MessageWriter * writer)526*635a8641SAndroid Build Coastguard Worker void MessageWriter::OpenVariant(const std::string& signature,
527*635a8641SAndroid Build Coastguard Worker MessageWriter* writer) {
528*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
529*635a8641SAndroid Build Coastguard Worker
530*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_open_container(
531*635a8641SAndroid Build Coastguard Worker &raw_message_iter_, DBUS_TYPE_VARIANT, signature.c_str(),
532*635a8641SAndroid Build Coastguard Worker &writer->raw_message_iter_);
533*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
534*635a8641SAndroid Build Coastguard Worker container_is_open_ = true;
535*635a8641SAndroid Build Coastguard Worker }
536*635a8641SAndroid Build Coastguard Worker
OpenStruct(MessageWriter * writer)537*635a8641SAndroid Build Coastguard Worker void MessageWriter::OpenStruct(MessageWriter* writer) {
538*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
539*635a8641SAndroid Build Coastguard Worker
540*635a8641SAndroid Build Coastguard Worker const bool success =
541*635a8641SAndroid Build Coastguard Worker dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_STRUCT,
542*635a8641SAndroid Build Coastguard Worker nullptr, // Signature should be nullptr.
543*635a8641SAndroid Build Coastguard Worker &writer->raw_message_iter_);
544*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
545*635a8641SAndroid Build Coastguard Worker container_is_open_ = true;
546*635a8641SAndroid Build Coastguard Worker }
547*635a8641SAndroid Build Coastguard Worker
OpenDictEntry(MessageWriter * writer)548*635a8641SAndroid Build Coastguard Worker void MessageWriter::OpenDictEntry(MessageWriter* writer) {
549*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
550*635a8641SAndroid Build Coastguard Worker
551*635a8641SAndroid Build Coastguard Worker const bool success =
552*635a8641SAndroid Build Coastguard Worker dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_DICT_ENTRY,
553*635a8641SAndroid Build Coastguard Worker nullptr, // Signature should be nullptr.
554*635a8641SAndroid Build Coastguard Worker &writer->raw_message_iter_);
555*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
556*635a8641SAndroid Build Coastguard Worker container_is_open_ = true;
557*635a8641SAndroid Build Coastguard Worker }
558*635a8641SAndroid Build Coastguard Worker
CloseContainer(MessageWriter * writer)559*635a8641SAndroid Build Coastguard Worker void MessageWriter::CloseContainer(MessageWriter* writer) {
560*635a8641SAndroid Build Coastguard Worker DCHECK(container_is_open_);
561*635a8641SAndroid Build Coastguard Worker
562*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_close_container(
563*635a8641SAndroid Build Coastguard Worker &raw_message_iter_, &writer->raw_message_iter_);
564*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
565*635a8641SAndroid Build Coastguard Worker container_is_open_ = false;
566*635a8641SAndroid Build Coastguard Worker }
567*635a8641SAndroid Build Coastguard Worker
AppendArrayOfBytes(const uint8_t * values,size_t length)568*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendArrayOfBytes(const uint8_t* values, size_t length) {
569*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
570*635a8641SAndroid Build Coastguard Worker MessageWriter array_writer(message_);
571*635a8641SAndroid Build Coastguard Worker OpenArray("y", &array_writer);
572*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_append_fixed_array(
573*635a8641SAndroid Build Coastguard Worker &(array_writer.raw_message_iter_), DBUS_TYPE_BYTE, &values,
574*635a8641SAndroid Build Coastguard Worker static_cast<int>(length));
575*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
576*635a8641SAndroid Build Coastguard Worker CloseContainer(&array_writer);
577*635a8641SAndroid Build Coastguard Worker }
578*635a8641SAndroid Build Coastguard Worker
AppendArrayOfInt32s(const int32_t * values,size_t length)579*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendArrayOfInt32s(const int32_t* values, size_t length) {
580*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
581*635a8641SAndroid Build Coastguard Worker MessageWriter array_writer(message_);
582*635a8641SAndroid Build Coastguard Worker OpenArray("i", &array_writer);
583*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_append_fixed_array(
584*635a8641SAndroid Build Coastguard Worker &(array_writer.raw_message_iter_), DBUS_TYPE_INT32, &values,
585*635a8641SAndroid Build Coastguard Worker static_cast<int>(length));
586*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
587*635a8641SAndroid Build Coastguard Worker CloseContainer(&array_writer);
588*635a8641SAndroid Build Coastguard Worker }
589*635a8641SAndroid Build Coastguard Worker
AppendArrayOfUint32s(const uint32_t * values,size_t length)590*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendArrayOfUint32s(const uint32_t* values,
591*635a8641SAndroid Build Coastguard Worker size_t length) {
592*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
593*635a8641SAndroid Build Coastguard Worker MessageWriter array_writer(message_);
594*635a8641SAndroid Build Coastguard Worker OpenArray("u", &array_writer);
595*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_append_fixed_array(
596*635a8641SAndroid Build Coastguard Worker &(array_writer.raw_message_iter_), DBUS_TYPE_UINT32, &values,
597*635a8641SAndroid Build Coastguard Worker static_cast<int>(length));
598*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
599*635a8641SAndroid Build Coastguard Worker CloseContainer(&array_writer);
600*635a8641SAndroid Build Coastguard Worker }
601*635a8641SAndroid Build Coastguard Worker
AppendArrayOfDoubles(const double * values,size_t length)602*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendArrayOfDoubles(const double* values, size_t length) {
603*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
604*635a8641SAndroid Build Coastguard Worker MessageWriter array_writer(message_);
605*635a8641SAndroid Build Coastguard Worker OpenArray("d", &array_writer);
606*635a8641SAndroid Build Coastguard Worker const bool success = dbus_message_iter_append_fixed_array(
607*635a8641SAndroid Build Coastguard Worker &(array_writer.raw_message_iter_), DBUS_TYPE_DOUBLE, &values,
608*635a8641SAndroid Build Coastguard Worker static_cast<int>(length));
609*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
610*635a8641SAndroid Build Coastguard Worker CloseContainer(&array_writer);
611*635a8641SAndroid Build Coastguard Worker }
612*635a8641SAndroid Build Coastguard Worker
AppendArrayOfStrings(const std::vector<std::string> & strings)613*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendArrayOfStrings(
614*635a8641SAndroid Build Coastguard Worker const std::vector<std::string>& strings) {
615*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
616*635a8641SAndroid Build Coastguard Worker MessageWriter array_writer(message_);
617*635a8641SAndroid Build Coastguard Worker OpenArray("s", &array_writer);
618*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < strings.size(); ++i) {
619*635a8641SAndroid Build Coastguard Worker array_writer.AppendString(strings[i]);
620*635a8641SAndroid Build Coastguard Worker }
621*635a8641SAndroid Build Coastguard Worker CloseContainer(&array_writer);
622*635a8641SAndroid Build Coastguard Worker }
623*635a8641SAndroid Build Coastguard Worker
AppendArrayOfObjectPaths(const std::vector<ObjectPath> & object_paths)624*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendArrayOfObjectPaths(
625*635a8641SAndroid Build Coastguard Worker const std::vector<ObjectPath>& object_paths) {
626*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
627*635a8641SAndroid Build Coastguard Worker MessageWriter array_writer(message_);
628*635a8641SAndroid Build Coastguard Worker OpenArray("o", &array_writer);
629*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < object_paths.size(); ++i) {
630*635a8641SAndroid Build Coastguard Worker array_writer.AppendObjectPath(object_paths[i]);
631*635a8641SAndroid Build Coastguard Worker }
632*635a8641SAndroid Build Coastguard Worker CloseContainer(&array_writer);
633*635a8641SAndroid Build Coastguard Worker }
634*635a8641SAndroid Build Coastguard Worker
AppendProtoAsArrayOfBytes(const google::protobuf::MessageLite & protobuf)635*635a8641SAndroid Build Coastguard Worker bool MessageWriter::AppendProtoAsArrayOfBytes(
636*635a8641SAndroid Build Coastguard Worker const google::protobuf::MessageLite& protobuf) {
637*635a8641SAndroid Build Coastguard Worker std::string serialized_proto;
638*635a8641SAndroid Build Coastguard Worker if (!protobuf.SerializeToString(&serialized_proto)) {
639*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Unable to serialize supplied protocol buffer";
640*635a8641SAndroid Build Coastguard Worker return false;
641*635a8641SAndroid Build Coastguard Worker }
642*635a8641SAndroid Build Coastguard Worker AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(serialized_proto.data()),
643*635a8641SAndroid Build Coastguard Worker serialized_proto.size());
644*635a8641SAndroid Build Coastguard Worker return true;
645*635a8641SAndroid Build Coastguard Worker }
646*635a8641SAndroid Build Coastguard Worker
AppendVariantOfByte(uint8_t value)647*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfByte(uint8_t value) {
648*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_BYTE, &value);
649*635a8641SAndroid Build Coastguard Worker }
650*635a8641SAndroid Build Coastguard Worker
AppendVariantOfBool(bool value)651*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfBool(bool value) {
652*635a8641SAndroid Build Coastguard Worker // See the comment at MessageWriter::AppendBool().
653*635a8641SAndroid Build Coastguard Worker dbus_bool_t dbus_value = value;
654*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
655*635a8641SAndroid Build Coastguard Worker }
656*635a8641SAndroid Build Coastguard Worker
AppendVariantOfInt16(int16_t value)657*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfInt16(int16_t value) {
658*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_INT16, &value);
659*635a8641SAndroid Build Coastguard Worker }
660*635a8641SAndroid Build Coastguard Worker
AppendVariantOfUint16(uint16_t value)661*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfUint16(uint16_t value) {
662*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_UINT16, &value);
663*635a8641SAndroid Build Coastguard Worker }
664*635a8641SAndroid Build Coastguard Worker
AppendVariantOfInt32(int32_t value)665*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfInt32(int32_t value) {
666*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_INT32, &value);
667*635a8641SAndroid Build Coastguard Worker }
668*635a8641SAndroid Build Coastguard Worker
AppendVariantOfUint32(uint32_t value)669*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfUint32(uint32_t value) {
670*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_UINT32, &value);
671*635a8641SAndroid Build Coastguard Worker }
672*635a8641SAndroid Build Coastguard Worker
AppendVariantOfInt64(int64_t value)673*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfInt64(int64_t value) {
674*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_INT64, &value);
675*635a8641SAndroid Build Coastguard Worker }
676*635a8641SAndroid Build Coastguard Worker
AppendVariantOfUint64(uint64_t value)677*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfUint64(uint64_t value) {
678*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_UINT64, &value);
679*635a8641SAndroid Build Coastguard Worker }
680*635a8641SAndroid Build Coastguard Worker
AppendVariantOfDouble(double value)681*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfDouble(double value) {
682*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_DOUBLE, &value);
683*635a8641SAndroid Build Coastguard Worker }
684*635a8641SAndroid Build Coastguard Worker
AppendVariantOfString(const std::string & value)685*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfString(const std::string& value) {
686*635a8641SAndroid Build Coastguard Worker const char* pointer = value.c_str();
687*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_STRING, &pointer);
688*635a8641SAndroid Build Coastguard Worker }
689*635a8641SAndroid Build Coastguard Worker
AppendVariantOfObjectPath(const ObjectPath & value)690*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfObjectPath(const ObjectPath& value) {
691*635a8641SAndroid Build Coastguard Worker const char* pointer = value.value().c_str();
692*635a8641SAndroid Build Coastguard Worker AppendVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
693*635a8641SAndroid Build Coastguard Worker }
694*635a8641SAndroid Build Coastguard Worker
AppendBasic(int dbus_type,const void * value)695*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendBasic(int dbus_type, const void* value) {
696*635a8641SAndroid Build Coastguard Worker DCHECK(!container_is_open_);
697*635a8641SAndroid Build Coastguard Worker
698*635a8641SAndroid Build Coastguard Worker const bool success =
699*635a8641SAndroid Build Coastguard Worker dbus_message_iter_append_basic(&raw_message_iter_, dbus_type, value);
700*635a8641SAndroid Build Coastguard Worker // dbus_message_iter_append_basic() fails only when there is not enough
701*635a8641SAndroid Build Coastguard Worker // memory. We don't return this error as there is nothing we can do when
702*635a8641SAndroid Build Coastguard Worker // it fails to allocate memory for a byte etc.
703*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
704*635a8641SAndroid Build Coastguard Worker }
705*635a8641SAndroid Build Coastguard Worker
AppendVariantOfBasic(int dbus_type,const void * value)706*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) {
707*635a8641SAndroid Build Coastguard Worker const std::string signature(1u, // length
708*635a8641SAndroid Build Coastguard Worker base::checked_cast<char>(dbus_type));
709*635a8641SAndroid Build Coastguard Worker MessageWriter variant_writer(message_);
710*635a8641SAndroid Build Coastguard Worker OpenVariant(signature, &variant_writer);
711*635a8641SAndroid Build Coastguard Worker variant_writer.AppendBasic(dbus_type, value);
712*635a8641SAndroid Build Coastguard Worker CloseContainer(&variant_writer);
713*635a8641SAndroid Build Coastguard Worker }
714*635a8641SAndroid Build Coastguard Worker
AppendFileDescriptor(int value)715*635a8641SAndroid Build Coastguard Worker void MessageWriter::AppendFileDescriptor(int value) {
716*635a8641SAndroid Build Coastguard Worker CHECK(IsDBusTypeUnixFdSupported());
717*635a8641SAndroid Build Coastguard Worker AppendBasic(DBUS_TYPE_UNIX_FD, &value); // This duplicates the FD.
718*635a8641SAndroid Build Coastguard Worker }
719*635a8641SAndroid Build Coastguard Worker
720*635a8641SAndroid Build Coastguard Worker //
721*635a8641SAndroid Build Coastguard Worker // MessageReader implementation.
722*635a8641SAndroid Build Coastguard Worker //
723*635a8641SAndroid Build Coastguard Worker
MessageReader(Message * message)724*635a8641SAndroid Build Coastguard Worker MessageReader::MessageReader(Message* message) : message_(message) {
725*635a8641SAndroid Build Coastguard Worker memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
726*635a8641SAndroid Build Coastguard Worker if (message)
727*635a8641SAndroid Build Coastguard Worker dbus_message_iter_init(message_->raw_message(), &raw_message_iter_);
728*635a8641SAndroid Build Coastguard Worker }
729*635a8641SAndroid Build Coastguard Worker
730*635a8641SAndroid Build Coastguard Worker MessageReader::~MessageReader() = default;
731*635a8641SAndroid Build Coastguard Worker
HasMoreData()732*635a8641SAndroid Build Coastguard Worker bool MessageReader::HasMoreData() {
733*635a8641SAndroid Build Coastguard Worker const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
734*635a8641SAndroid Build Coastguard Worker return dbus_type != DBUS_TYPE_INVALID;
735*635a8641SAndroid Build Coastguard Worker }
736*635a8641SAndroid Build Coastguard Worker
PopByte(uint8_t * value)737*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopByte(uint8_t* value) {
738*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_BYTE, value);
739*635a8641SAndroid Build Coastguard Worker }
740*635a8641SAndroid Build Coastguard Worker
PopBool(bool * value)741*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopBool(bool* value) {
742*635a8641SAndroid Build Coastguard Worker // Like MessageWriter::AppendBool(), we should copy |value| to
743*635a8641SAndroid Build Coastguard Worker // dbus_bool_t, as dbus_message_iter_get_basic() used in PopBasic()
744*635a8641SAndroid Build Coastguard Worker // expects four bytes for DBUS_TYPE_BOOLEAN.
745*635a8641SAndroid Build Coastguard Worker dbus_bool_t dbus_value = FALSE;
746*635a8641SAndroid Build Coastguard Worker const bool success = PopBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
747*635a8641SAndroid Build Coastguard Worker *value = static_cast<bool>(dbus_value);
748*635a8641SAndroid Build Coastguard Worker return success;
749*635a8641SAndroid Build Coastguard Worker }
750*635a8641SAndroid Build Coastguard Worker
PopInt16(int16_t * value)751*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopInt16(int16_t* value) {
752*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_INT16, value);
753*635a8641SAndroid Build Coastguard Worker }
754*635a8641SAndroid Build Coastguard Worker
PopUint16(uint16_t * value)755*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopUint16(uint16_t* value) {
756*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_UINT16, value);
757*635a8641SAndroid Build Coastguard Worker }
758*635a8641SAndroid Build Coastguard Worker
PopInt32(int32_t * value)759*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopInt32(int32_t* value) {
760*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_INT32, value);
761*635a8641SAndroid Build Coastguard Worker }
762*635a8641SAndroid Build Coastguard Worker
PopUint32(uint32_t * value)763*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopUint32(uint32_t* value) {
764*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_UINT32, value);
765*635a8641SAndroid Build Coastguard Worker }
766*635a8641SAndroid Build Coastguard Worker
PopInt64(int64_t * value)767*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopInt64(int64_t* value) {
768*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_INT64, value);
769*635a8641SAndroid Build Coastguard Worker }
770*635a8641SAndroid Build Coastguard Worker
PopUint64(uint64_t * value)771*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopUint64(uint64_t* value) {
772*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_UINT64, value);
773*635a8641SAndroid Build Coastguard Worker }
774*635a8641SAndroid Build Coastguard Worker
PopDouble(double * value)775*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopDouble(double* value) {
776*635a8641SAndroid Build Coastguard Worker return PopBasic(DBUS_TYPE_DOUBLE, value);
777*635a8641SAndroid Build Coastguard Worker }
778*635a8641SAndroid Build Coastguard Worker
PopString(std::string * value)779*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopString(std::string* value) {
780*635a8641SAndroid Build Coastguard Worker char* tmp_value = nullptr;
781*635a8641SAndroid Build Coastguard Worker const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value);
782*635a8641SAndroid Build Coastguard Worker if (success)
783*635a8641SAndroid Build Coastguard Worker value->assign(tmp_value);
784*635a8641SAndroid Build Coastguard Worker return success;
785*635a8641SAndroid Build Coastguard Worker }
786*635a8641SAndroid Build Coastguard Worker
PopObjectPath(ObjectPath * value)787*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopObjectPath(ObjectPath* value) {
788*635a8641SAndroid Build Coastguard Worker char* tmp_value = nullptr;
789*635a8641SAndroid Build Coastguard Worker const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
790*635a8641SAndroid Build Coastguard Worker if (success)
791*635a8641SAndroid Build Coastguard Worker *value = ObjectPath(tmp_value);
792*635a8641SAndroid Build Coastguard Worker return success;
793*635a8641SAndroid Build Coastguard Worker }
794*635a8641SAndroid Build Coastguard Worker
PopArray(MessageReader * sub_reader)795*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArray(MessageReader* sub_reader) {
796*635a8641SAndroid Build Coastguard Worker return PopContainer(DBUS_TYPE_ARRAY, sub_reader);
797*635a8641SAndroid Build Coastguard Worker }
798*635a8641SAndroid Build Coastguard Worker
PopStruct(MessageReader * sub_reader)799*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopStruct(MessageReader* sub_reader) {
800*635a8641SAndroid Build Coastguard Worker return PopContainer(DBUS_TYPE_STRUCT, sub_reader);
801*635a8641SAndroid Build Coastguard Worker }
802*635a8641SAndroid Build Coastguard Worker
PopDictEntry(MessageReader * sub_reader)803*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopDictEntry(MessageReader* sub_reader) {
804*635a8641SAndroid Build Coastguard Worker return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader);
805*635a8641SAndroid Build Coastguard Worker }
806*635a8641SAndroid Build Coastguard Worker
PopVariant(MessageReader * sub_reader)807*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariant(MessageReader* sub_reader) {
808*635a8641SAndroid Build Coastguard Worker return PopContainer(DBUS_TYPE_VARIANT, sub_reader);
809*635a8641SAndroid Build Coastguard Worker }
810*635a8641SAndroid Build Coastguard Worker
PopArrayOfBytes(const uint8_t ** bytes,size_t * length)811*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfBytes(const uint8_t** bytes, size_t* length) {
812*635a8641SAndroid Build Coastguard Worker MessageReader array_reader(message_);
813*635a8641SAndroid Build Coastguard Worker if (!PopArray(&array_reader))
814*635a8641SAndroid Build Coastguard Worker return false;
815*635a8641SAndroid Build Coastguard Worker // An empty array is allowed.
816*635a8641SAndroid Build Coastguard Worker if (!array_reader.HasMoreData()) {
817*635a8641SAndroid Build Coastguard Worker *length = 0;
818*635a8641SAndroid Build Coastguard Worker *bytes = nullptr;
819*635a8641SAndroid Build Coastguard Worker return true;
820*635a8641SAndroid Build Coastguard Worker }
821*635a8641SAndroid Build Coastguard Worker if (!array_reader.CheckDataType(DBUS_TYPE_BYTE))
822*635a8641SAndroid Build Coastguard Worker return false;
823*635a8641SAndroid Build Coastguard Worker int int_length = 0;
824*635a8641SAndroid Build Coastguard Worker dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, bytes,
825*635a8641SAndroid Build Coastguard Worker &int_length);
826*635a8641SAndroid Build Coastguard Worker *length = static_cast<size_t>(int_length);
827*635a8641SAndroid Build Coastguard Worker return true;
828*635a8641SAndroid Build Coastguard Worker }
829*635a8641SAndroid Build Coastguard Worker
PopArrayOfInt32s(const int32_t ** signed_ints,size_t * length)830*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfInt32s(const int32_t** signed_ints,
831*635a8641SAndroid Build Coastguard Worker size_t* length) {
832*635a8641SAndroid Build Coastguard Worker MessageReader array_reader(message_);
833*635a8641SAndroid Build Coastguard Worker if (!PopArray(&array_reader))
834*635a8641SAndroid Build Coastguard Worker return false;
835*635a8641SAndroid Build Coastguard Worker // An empty array is allowed.
836*635a8641SAndroid Build Coastguard Worker if (!array_reader.HasMoreData()) {
837*635a8641SAndroid Build Coastguard Worker *length = 0;
838*635a8641SAndroid Build Coastguard Worker *signed_ints = nullptr;
839*635a8641SAndroid Build Coastguard Worker return true;
840*635a8641SAndroid Build Coastguard Worker }
841*635a8641SAndroid Build Coastguard Worker if (!array_reader.CheckDataType(DBUS_TYPE_INT32))
842*635a8641SAndroid Build Coastguard Worker return false;
843*635a8641SAndroid Build Coastguard Worker int int_length = 0;
844*635a8641SAndroid Build Coastguard Worker dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
845*635a8641SAndroid Build Coastguard Worker signed_ints, &int_length);
846*635a8641SAndroid Build Coastguard Worker *length = static_cast<size_t>(int_length);
847*635a8641SAndroid Build Coastguard Worker return true;
848*635a8641SAndroid Build Coastguard Worker }
849*635a8641SAndroid Build Coastguard Worker
PopArrayOfUint32s(const uint32_t ** unsigned_ints,size_t * length)850*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfUint32s(const uint32_t** unsigned_ints,
851*635a8641SAndroid Build Coastguard Worker size_t* length) {
852*635a8641SAndroid Build Coastguard Worker MessageReader array_reader(message_);
853*635a8641SAndroid Build Coastguard Worker if (!PopArray(&array_reader))
854*635a8641SAndroid Build Coastguard Worker return false;
855*635a8641SAndroid Build Coastguard Worker // An empty array is allowed.
856*635a8641SAndroid Build Coastguard Worker if (!array_reader.HasMoreData()) {
857*635a8641SAndroid Build Coastguard Worker *length = 0;
858*635a8641SAndroid Build Coastguard Worker *unsigned_ints = nullptr;
859*635a8641SAndroid Build Coastguard Worker return true;
860*635a8641SAndroid Build Coastguard Worker }
861*635a8641SAndroid Build Coastguard Worker if (!array_reader.CheckDataType(DBUS_TYPE_UINT32))
862*635a8641SAndroid Build Coastguard Worker return false;
863*635a8641SAndroid Build Coastguard Worker int int_length = 0;
864*635a8641SAndroid Build Coastguard Worker dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
865*635a8641SAndroid Build Coastguard Worker unsigned_ints, &int_length);
866*635a8641SAndroid Build Coastguard Worker *length = static_cast<size_t>(int_length);
867*635a8641SAndroid Build Coastguard Worker return true;
868*635a8641SAndroid Build Coastguard Worker }
869*635a8641SAndroid Build Coastguard Worker
PopArrayOfDoubles(const double ** doubles,size_t * length)870*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfDoubles(const double** doubles, size_t* length) {
871*635a8641SAndroid Build Coastguard Worker MessageReader array_reader(message_);
872*635a8641SAndroid Build Coastguard Worker if (!PopArray(&array_reader))
873*635a8641SAndroid Build Coastguard Worker return false;
874*635a8641SAndroid Build Coastguard Worker if (!array_reader.HasMoreData()) {
875*635a8641SAndroid Build Coastguard Worker *length = 0;
876*635a8641SAndroid Build Coastguard Worker *doubles = nullptr;
877*635a8641SAndroid Build Coastguard Worker return true;
878*635a8641SAndroid Build Coastguard Worker }
879*635a8641SAndroid Build Coastguard Worker if (!array_reader.CheckDataType(DBUS_TYPE_DOUBLE))
880*635a8641SAndroid Build Coastguard Worker return false;
881*635a8641SAndroid Build Coastguard Worker int int_length = 0;
882*635a8641SAndroid Build Coastguard Worker dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, doubles,
883*635a8641SAndroid Build Coastguard Worker &int_length);
884*635a8641SAndroid Build Coastguard Worker *length = static_cast<size_t>(int_length);
885*635a8641SAndroid Build Coastguard Worker return true;
886*635a8641SAndroid Build Coastguard Worker }
887*635a8641SAndroid Build Coastguard Worker
PopArrayOfStrings(std::vector<std::string> * strings)888*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfStrings(std::vector<std::string>* strings) {
889*635a8641SAndroid Build Coastguard Worker strings->clear();
890*635a8641SAndroid Build Coastguard Worker MessageReader array_reader(message_);
891*635a8641SAndroid Build Coastguard Worker if (!PopArray(&array_reader))
892*635a8641SAndroid Build Coastguard Worker return false;
893*635a8641SAndroid Build Coastguard Worker while (array_reader.HasMoreData()) {
894*635a8641SAndroid Build Coastguard Worker std::string string;
895*635a8641SAndroid Build Coastguard Worker if (!array_reader.PopString(&string))
896*635a8641SAndroid Build Coastguard Worker return false;
897*635a8641SAndroid Build Coastguard Worker strings->push_back(string);
898*635a8641SAndroid Build Coastguard Worker }
899*635a8641SAndroid Build Coastguard Worker return true;
900*635a8641SAndroid Build Coastguard Worker }
901*635a8641SAndroid Build Coastguard Worker
PopArrayOfObjectPaths(std::vector<ObjectPath> * object_paths)902*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfObjectPaths(
903*635a8641SAndroid Build Coastguard Worker std::vector<ObjectPath>* object_paths) {
904*635a8641SAndroid Build Coastguard Worker object_paths->clear();
905*635a8641SAndroid Build Coastguard Worker MessageReader array_reader(message_);
906*635a8641SAndroid Build Coastguard Worker if (!PopArray(&array_reader))
907*635a8641SAndroid Build Coastguard Worker return false;
908*635a8641SAndroid Build Coastguard Worker while (array_reader.HasMoreData()) {
909*635a8641SAndroid Build Coastguard Worker ObjectPath object_path;
910*635a8641SAndroid Build Coastguard Worker if (!array_reader.PopObjectPath(&object_path))
911*635a8641SAndroid Build Coastguard Worker return false;
912*635a8641SAndroid Build Coastguard Worker object_paths->push_back(object_path);
913*635a8641SAndroid Build Coastguard Worker }
914*635a8641SAndroid Build Coastguard Worker return true;
915*635a8641SAndroid Build Coastguard Worker }
916*635a8641SAndroid Build Coastguard Worker
PopArrayOfBytesAsProto(google::protobuf::MessageLite * protobuf)917*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopArrayOfBytesAsProto(
918*635a8641SAndroid Build Coastguard Worker google::protobuf::MessageLite* protobuf) {
919*635a8641SAndroid Build Coastguard Worker DCHECK(protobuf);
920*635a8641SAndroid Build Coastguard Worker const char* serialized_buf = nullptr;
921*635a8641SAndroid Build Coastguard Worker size_t buf_size = 0;
922*635a8641SAndroid Build Coastguard Worker if (!PopArrayOfBytes(reinterpret_cast<const uint8_t**>(&serialized_buf),
923*635a8641SAndroid Build Coastguard Worker &buf_size)) {
924*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Error reading array of bytes";
925*635a8641SAndroid Build Coastguard Worker return false;
926*635a8641SAndroid Build Coastguard Worker }
927*635a8641SAndroid Build Coastguard Worker if (!protobuf->ParseFromArray(serialized_buf, buf_size)) {
928*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to parse protocol buffer from array";
929*635a8641SAndroid Build Coastguard Worker return false;
930*635a8641SAndroid Build Coastguard Worker }
931*635a8641SAndroid Build Coastguard Worker return true;
932*635a8641SAndroid Build Coastguard Worker }
933*635a8641SAndroid Build Coastguard Worker
PopVariantOfByte(uint8_t * value)934*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfByte(uint8_t* value) {
935*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_BYTE, value);
936*635a8641SAndroid Build Coastguard Worker }
937*635a8641SAndroid Build Coastguard Worker
PopVariantOfBool(bool * value)938*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfBool(bool* value) {
939*635a8641SAndroid Build Coastguard Worker // See the comment at MessageReader::PopBool().
940*635a8641SAndroid Build Coastguard Worker dbus_bool_t dbus_value = FALSE;
941*635a8641SAndroid Build Coastguard Worker const bool success = PopVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
942*635a8641SAndroid Build Coastguard Worker *value = static_cast<bool>(dbus_value);
943*635a8641SAndroid Build Coastguard Worker return success;
944*635a8641SAndroid Build Coastguard Worker }
945*635a8641SAndroid Build Coastguard Worker
PopVariantOfInt16(int16_t * value)946*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfInt16(int16_t* value) {
947*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_INT16, value);
948*635a8641SAndroid Build Coastguard Worker }
949*635a8641SAndroid Build Coastguard Worker
PopVariantOfUint16(uint16_t * value)950*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfUint16(uint16_t* value) {
951*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_UINT16, value);
952*635a8641SAndroid Build Coastguard Worker }
953*635a8641SAndroid Build Coastguard Worker
PopVariantOfInt32(int32_t * value)954*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfInt32(int32_t* value) {
955*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_INT32, value);
956*635a8641SAndroid Build Coastguard Worker }
957*635a8641SAndroid Build Coastguard Worker
PopVariantOfUint32(uint32_t * value)958*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfUint32(uint32_t* value) {
959*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_UINT32, value);
960*635a8641SAndroid Build Coastguard Worker }
961*635a8641SAndroid Build Coastguard Worker
PopVariantOfInt64(int64_t * value)962*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfInt64(int64_t* value) {
963*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_INT64, value);
964*635a8641SAndroid Build Coastguard Worker }
965*635a8641SAndroid Build Coastguard Worker
PopVariantOfUint64(uint64_t * value)966*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfUint64(uint64_t* value) {
967*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_UINT64, value);
968*635a8641SAndroid Build Coastguard Worker }
969*635a8641SAndroid Build Coastguard Worker
PopVariantOfDouble(double * value)970*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfDouble(double* value) {
971*635a8641SAndroid Build Coastguard Worker return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value);
972*635a8641SAndroid Build Coastguard Worker }
973*635a8641SAndroid Build Coastguard Worker
PopVariantOfString(std::string * value)974*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfString(std::string* value) {
975*635a8641SAndroid Build Coastguard Worker char* tmp_value = nullptr;
976*635a8641SAndroid Build Coastguard Worker const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value);
977*635a8641SAndroid Build Coastguard Worker if (success)
978*635a8641SAndroid Build Coastguard Worker value->assign(tmp_value);
979*635a8641SAndroid Build Coastguard Worker return success;
980*635a8641SAndroid Build Coastguard Worker }
981*635a8641SAndroid Build Coastguard Worker
PopVariantOfObjectPath(ObjectPath * value)982*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfObjectPath(ObjectPath* value) {
983*635a8641SAndroid Build Coastguard Worker char* tmp_value = nullptr;
984*635a8641SAndroid Build Coastguard Worker const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
985*635a8641SAndroid Build Coastguard Worker if (success)
986*635a8641SAndroid Build Coastguard Worker *value = ObjectPath(tmp_value);
987*635a8641SAndroid Build Coastguard Worker return success;
988*635a8641SAndroid Build Coastguard Worker }
989*635a8641SAndroid Build Coastguard Worker
GetDataType()990*635a8641SAndroid Build Coastguard Worker Message::DataType MessageReader::GetDataType() {
991*635a8641SAndroid Build Coastguard Worker const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
992*635a8641SAndroid Build Coastguard Worker return static_cast<Message::DataType>(dbus_type);
993*635a8641SAndroid Build Coastguard Worker }
994*635a8641SAndroid Build Coastguard Worker
GetDataSignature()995*635a8641SAndroid Build Coastguard Worker std::string MessageReader::GetDataSignature() {
996*635a8641SAndroid Build Coastguard Worker std::string signature;
997*635a8641SAndroid Build Coastguard Worker char* raw_signature = dbus_message_iter_get_signature(&raw_message_iter_);
998*635a8641SAndroid Build Coastguard Worker if (raw_signature) {
999*635a8641SAndroid Build Coastguard Worker signature = raw_signature;
1000*635a8641SAndroid Build Coastguard Worker dbus_free(raw_signature);
1001*635a8641SAndroid Build Coastguard Worker }
1002*635a8641SAndroid Build Coastguard Worker return signature;
1003*635a8641SAndroid Build Coastguard Worker }
1004*635a8641SAndroid Build Coastguard Worker
CheckDataType(int dbus_type)1005*635a8641SAndroid Build Coastguard Worker bool MessageReader::CheckDataType(int dbus_type) {
1006*635a8641SAndroid Build Coastguard Worker const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
1007*635a8641SAndroid Build Coastguard Worker if (actual_type != dbus_type) {
1008*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Type " << dbus_type << " is expected but got " << actual_type;
1009*635a8641SAndroid Build Coastguard Worker return false;
1010*635a8641SAndroid Build Coastguard Worker }
1011*635a8641SAndroid Build Coastguard Worker return true;
1012*635a8641SAndroid Build Coastguard Worker }
1013*635a8641SAndroid Build Coastguard Worker
PopBasic(int dbus_type,void * value)1014*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopBasic(int dbus_type, void* value) {
1015*635a8641SAndroid Build Coastguard Worker if (!CheckDataType(dbus_type))
1016*635a8641SAndroid Build Coastguard Worker return false;
1017*635a8641SAndroid Build Coastguard Worker // dbus_message_iter_get_basic() here should always work, as we have
1018*635a8641SAndroid Build Coastguard Worker // already checked the next item's data type in CheckDataType(). Note
1019*635a8641SAndroid Build Coastguard Worker // that dbus_message_iter_get_basic() is a void function.
1020*635a8641SAndroid Build Coastguard Worker dbus_message_iter_get_basic(&raw_message_iter_, value);
1021*635a8641SAndroid Build Coastguard Worker DCHECK(value);
1022*635a8641SAndroid Build Coastguard Worker dbus_message_iter_next(&raw_message_iter_);
1023*635a8641SAndroid Build Coastguard Worker return true;
1024*635a8641SAndroid Build Coastguard Worker }
1025*635a8641SAndroid Build Coastguard Worker
PopContainer(int dbus_type,MessageReader * sub_reader)1026*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) {
1027*635a8641SAndroid Build Coastguard Worker DCHECK_NE(this, sub_reader);
1028*635a8641SAndroid Build Coastguard Worker
1029*635a8641SAndroid Build Coastguard Worker if (!CheckDataType(dbus_type))
1030*635a8641SAndroid Build Coastguard Worker return false;
1031*635a8641SAndroid Build Coastguard Worker dbus_message_iter_recurse(&raw_message_iter_, &sub_reader->raw_message_iter_);
1032*635a8641SAndroid Build Coastguard Worker dbus_message_iter_next(&raw_message_iter_);
1033*635a8641SAndroid Build Coastguard Worker return true;
1034*635a8641SAndroid Build Coastguard Worker }
1035*635a8641SAndroid Build Coastguard Worker
PopVariantOfBasic(int dbus_type,void * value)1036*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) {
1037*635a8641SAndroid Build Coastguard Worker MessageReader variant_reader(message_);
1038*635a8641SAndroid Build Coastguard Worker if (!PopVariant(&variant_reader))
1039*635a8641SAndroid Build Coastguard Worker return false;
1040*635a8641SAndroid Build Coastguard Worker return variant_reader.PopBasic(dbus_type, value);
1041*635a8641SAndroid Build Coastguard Worker }
1042*635a8641SAndroid Build Coastguard Worker
PopFileDescriptor(base::ScopedFD * value)1043*635a8641SAndroid Build Coastguard Worker bool MessageReader::PopFileDescriptor(base::ScopedFD* value) {
1044*635a8641SAndroid Build Coastguard Worker CHECK(IsDBusTypeUnixFdSupported());
1045*635a8641SAndroid Build Coastguard Worker
1046*635a8641SAndroid Build Coastguard Worker int fd = -1;
1047*635a8641SAndroid Build Coastguard Worker const bool success = PopBasic(DBUS_TYPE_UNIX_FD, &fd);
1048*635a8641SAndroid Build Coastguard Worker if (!success)
1049*635a8641SAndroid Build Coastguard Worker return false;
1050*635a8641SAndroid Build Coastguard Worker
1051*635a8641SAndroid Build Coastguard Worker *value = base::ScopedFD(fd);
1052*635a8641SAndroid Build Coastguard Worker return true;
1053*635a8641SAndroid Build Coastguard Worker }
1054*635a8641SAndroid Build Coastguard Worker
1055*635a8641SAndroid Build Coastguard Worker } // namespace dbus
1056