blob: 8d8c9b730ba97b9a80b4b2ac9c6cfe06bc412682 [file] [log] [blame]
[email protected]9400ff82012-02-07 23:48:351// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]a9e91492011-07-30 19:13:312// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "dbus/message.h"
6
[email protected]c033c5082012-02-09 18:14:087#include <string>
8
[email protected]a9e91492011-07-30 19:13:319#include "base/format_macros.h"
10#include "base/logging.h"
ricea19b947df2015-09-18 22:26:1011#include "base/numerics/safe_conversions.h"
riceaa01edead2015-07-01 15:56:5012#include "base/strings/string_number_conversions.h"
[email protected]0d8db082013-06-11 07:27:0113#include "base/strings/string_util.h"
14#include "base/strings/stringprintf.h"
[email protected]216ed0b2012-02-14 21:29:0615#include "dbus/object_path.h"
[email protected]c033c5082012-02-09 18:14:0816#include "third_party/protobuf/src/google/protobuf/message_lite.h"
[email protected]a9e91492011-07-30 19:13:3117
[email protected]9cce2d32011-08-10 22:34:0218namespace {
19
20// Appends the header name and the value to |output|, if the value is
21// not empty.
[email protected]73c71512012-07-25 19:29:5722void AppendStringHeader(const std::string& header_name,
23 const std::string& header_value,
24 std::string* output) {
[email protected]9cce2d32011-08-10 22:34:0225 if (!header_value.empty()) {
26 *output += header_name + ": " + header_value + "\n";
27 }
28}
29
30// Appends the header name and the value to |output|, if the value is
31// nonzero.
[email protected]73c71512012-07-25 19:29:5732void AppendUint32Header(const std::string& header_name,
avi22437c692015-12-22 18:12:4533 uint32_t header_value,
[email protected]73c71512012-07-25 19:29:5734 std::string* output) {
[email protected]9cce2d32011-08-10 22:34:0235 if (header_value != 0) {
ricea19b947df2015-09-18 22:26:1036 *output += (header_name + ": " + base::UintToString(header_value) + "\n");
[email protected]9cce2d32011-08-10 22:34:0237 }
38}
39
40} // namespace
41
[email protected]a9e91492011-07-30 19:13:3142namespace dbus {
43
[email protected]73c71512012-07-25 19:29:5744bool IsDBusTypeUnixFdSupported() {
45 int major = 0, minor = 0, micro = 0;
46 dbus_get_version(&major, &minor, &micro);
47 return major >= 1 && minor >= 4;
48}
49
Hidehiko Abe1156b452017-09-12 03:55:0650Message::Message() : raw_message_(nullptr) {}
[email protected]a9e91492011-07-30 19:13:3151
52Message::~Message() {
53 if (raw_message_)
54 dbus_message_unref(raw_message_);
55}
56
[email protected]06ead872011-08-24 03:32:0657void Message::Init(DBusMessage* raw_message) {
58 DCHECK(!raw_message_);
59 raw_message_ = raw_message;
60}
61
[email protected]a9e91492011-07-30 19:13:3162Message::MessageType Message::GetMessageType() {
63 if (!raw_message_)
64 return MESSAGE_INVALID;
65 const int type = dbus_message_get_type(raw_message_);
66 return static_cast<Message::MessageType>(type);
67}
68
[email protected]06ead872011-08-24 03:32:0669std::string Message::GetMessageTypeAsString() {
70 switch (GetMessageType()) {
71 case MESSAGE_INVALID:
72 return "MESSAGE_INVALID";
73 case MESSAGE_METHOD_CALL:
74 return "MESSAGE_METHOD_CALL";
75 case MESSAGE_METHOD_RETURN:
76 return "MESSAGE_METHOD_RETURN";
77 case MESSAGE_SIGNAL:
78 return "MESSAGE_SIGNAL";
79 case MESSAGE_ERROR:
80 return "MESSAGE_ERROR";
81 }
82 NOTREACHED();
[email protected]007b3f82013-04-09 08:46:4583 return std::string();
[email protected]a9e91492011-07-30 19:13:3184}
85
86std::string Message::ToStringInternal(const std::string& indent,
87 MessageReader* reader) {
88 const char* kBrokenMessage = "[broken message]";
89 std::string output;
90 while (reader->HasMoreData()) {
91 const DataType type = reader->GetDataType();
92 switch (type) {
93 case BYTE: {
avi22437c692015-12-22 18:12:4594 uint8_t value = 0;
[email protected]a9e91492011-07-30 19:13:3195 if (!reader->PopByte(&value))
96 return kBrokenMessage;
ricea19b947df2015-09-18 22:26:1097 output += indent + "byte " + base::UintToString(value) + "\n";
[email protected]a9e91492011-07-30 19:13:3198 break;
99 }
100 case BOOL: {
101 bool value = false;
102 if (!reader->PopBool(&value))
103 return kBrokenMessage;
104 output += indent + "bool " + (value ? "true" : "false") + "\n";
105 break;
106 }
107 case INT16: {
avi22437c692015-12-22 18:12:45108 int16_t value = 0;
[email protected]a9e91492011-07-30 19:13:31109 if (!reader->PopInt16(&value))
110 return kBrokenMessage;
avi22437c692015-12-22 18:12:45111 output += indent + "int16_t " + base::IntToString(value) + "\n";
[email protected]a9e91492011-07-30 19:13:31112 break;
113 }
114 case UINT16: {
avi22437c692015-12-22 18:12:45115 uint16_t value = 0;
[email protected]a9e91492011-07-30 19:13:31116 if (!reader->PopUint16(&value))
117 return kBrokenMessage;
avi22437c692015-12-22 18:12:45118 output += indent + "uint16_t " + base::UintToString(value) + "\n";
[email protected]a9e91492011-07-30 19:13:31119 break;
120 }
121 case INT32: {
avi22437c692015-12-22 18:12:45122 int32_t value = 0;
[email protected]a9e91492011-07-30 19:13:31123 if (!reader->PopInt32(&value))
124 return kBrokenMessage;
avi22437c692015-12-22 18:12:45125 output += indent + "int32_t " + base::IntToString(value) + "\n";
[email protected]a9e91492011-07-30 19:13:31126 break;
127 }
128 case UINT32: {
avi22437c692015-12-22 18:12:45129 uint32_t value = 0;
[email protected]a9e91492011-07-30 19:13:31130 if (!reader->PopUint32(&value))
131 return kBrokenMessage;
avi22437c692015-12-22 18:12:45132 output += indent + "uint32_t " + base::UintToString(value) + "\n";
[email protected]a9e91492011-07-30 19:13:31133 break;
134 }
135 case INT64: {
avi22437c692015-12-22 18:12:45136 int64_t value = 0;
[email protected]a9e91492011-07-30 19:13:31137 if (!reader->PopInt64(&value))
138 return kBrokenMessage;
avi22437c692015-12-22 18:12:45139 output += (indent + "int64_t " + base::Int64ToString(value) + "\n");
[email protected]a9e91492011-07-30 19:13:31140 break;
141 }
142 case UINT64: {
avi22437c692015-12-22 18:12:45143 uint64_t value = 0;
[email protected]a9e91492011-07-30 19:13:31144 if (!reader->PopUint64(&value))
145 return kBrokenMessage;
Daniel Cheng3d199b12017-12-12 03:51:09146 output += (indent + "uint64_t " + base::NumberToString(value) + "\n");
[email protected]a9e91492011-07-30 19:13:31147 break;
148 }
149 case DOUBLE: {
150 double value = 0;
151 if (!reader->PopDouble(&value))
152 return kBrokenMessage;
Brett Wilson5ed06e72017-12-01 01:25:11153 output += indent + "double " + base::NumberToString(value) + "\n";
[email protected]a9e91492011-07-30 19:13:31154 break;
155 }
156 case STRING: {
157 std::string value;
158 if (!reader->PopString(&value))
159 return kBrokenMessage;
[email protected]6df1b9592012-06-07 16:41:26160 // Truncate if the string is longer than the limit.
161 const size_t kTruncateLength = 100;
162 if (value.size() < kTruncateLength) {
163 output += indent + "string \"" + value + "\"\n";
164 } else {
165 std::string truncated;
[email protected]466c9862013-12-03 22:05:28166 base::TruncateUTF8ToByteSize(value, kTruncateLength, &truncated);
[email protected]69226d72013-07-31 02:29:01167 base::StringAppendF(&truncated, "... (%" PRIuS " bytes in total)",
[email protected]6df1b9592012-06-07 16:41:26168 value.size());
169 output += indent + "string \"" + truncated + "\"\n";
170 }
[email protected]a9e91492011-07-30 19:13:31171 break;
172 }
173 case OBJECT_PATH: {
[email protected]216ed0b2012-02-14 21:29:06174 ObjectPath value;
[email protected]a9e91492011-07-30 19:13:31175 if (!reader->PopObjectPath(&value))
176 return kBrokenMessage;
[email protected]216ed0b2012-02-14 21:29:06177 output += indent + "object_path \"" + value.value() + "\"\n";
[email protected]a9e91492011-07-30 19:13:31178 break;
179 }
180 case ARRAY: {
181 MessageReader sub_reader(this);
182 if (!reader->PopArray(&sub_reader))
183 return kBrokenMessage;
184 output += indent + "array [\n";
185 output += ToStringInternal(indent + " ", &sub_reader);
186 output += indent + "]\n";
187 break;
188 }
189 case STRUCT: {
190 MessageReader sub_reader(this);
191 if (!reader->PopStruct(&sub_reader))
192 return kBrokenMessage;
193 output += indent + "struct {\n";
194 output += ToStringInternal(indent + " ", &sub_reader);
195 output += indent + "}\n";
196 break;
197 }
198 case DICT_ENTRY: {
199 MessageReader sub_reader(this);
200 if (!reader->PopDictEntry(&sub_reader))
201 return kBrokenMessage;
202 output += indent + "dict entry {\n";
203 output += ToStringInternal(indent + " ", &sub_reader);
204 output += indent + "}\n";
205 break;
206 }
207 case VARIANT: {
208 MessageReader sub_reader(this);
209 if (!reader->PopVariant(&sub_reader))
210 return kBrokenMessage;
211 output += indent + "variant ";
212 output += ToStringInternal(indent + " ", &sub_reader);
213 break;
214 }
[email protected]e146bfc2012-03-30 06:46:20215 case UNIX_FD: {
[email protected]73c71512012-07-25 19:29:57216 CHECK(IsDBusTypeUnixFdSupported());
[email protected]e146bfc2012-03-30 06:46:20217
hashimotodc693af2016-09-14 04:05:02218 base::ScopedFD file_descriptor;
[email protected]e146bfc2012-03-30 06:46:20219 if (!reader->PopFileDescriptor(&file_descriptor))
220 return kBrokenMessage;
221 output += indent + "fd#" +
hashimotodc693af2016-09-14 04:05:02222 base::IntToString(file_descriptor.get()) + "\n";
[email protected]e146bfc2012-03-30 06:46:20223 break;
224 }
[email protected]a9e91492011-07-30 19:13:31225 default:
226 LOG(FATAL) << "Unknown type: " << type;
227 }
228 }
229 return output;
230}
231
232// The returned string consists of message headers such as
233// destination if any, followed by a blank line, and the message
234// payload. For example, a MethodCall's ToString() will look like:
235//
236// destination: com.example.Service
237// path: /com/example/Object
238// interface: com.example.Interface
239// member: SomeMethod
240//
241// string \"payload\"
242// ...
243std::string Message::ToString() {
244 if (!raw_message_)
[email protected]007b3f82013-04-09 08:46:45245 return std::string();
[email protected]a9e91492011-07-30 19:13:31246
247 // Generate headers first.
248 std::string headers;
[email protected]06ead872011-08-24 03:32:06249 AppendStringHeader("message_type", GetMessageTypeAsString(), &headers);
[email protected]9cce2d32011-08-10 22:34:02250 AppendStringHeader("destination", GetDestination(), &headers);
[email protected]216ed0b2012-02-14 21:29:06251 AppendStringHeader("path", GetPath().value(), &headers);
[email protected]9cce2d32011-08-10 22:34:02252 AppendStringHeader("interface", GetInterface(), &headers);
253 AppendStringHeader("member", GetMember(), &headers);
254 AppendStringHeader("error_name", GetErrorName(), &headers);
255 AppendStringHeader("sender", GetSender(), &headers);
benchan5d15ab582014-08-25 11:16:56256 AppendStringHeader("signature", GetSignature(), &headers);
[email protected]9cce2d32011-08-10 22:34:02257 AppendUint32Header("serial", GetSerial(), &headers);
258 AppendUint32Header("reply_serial", GetReplySerial(), &headers);
[email protected]a9e91492011-07-30 19:13:31259
260 // Generate the payload.
261 MessageReader reader(this);
[email protected]007b3f82013-04-09 08:46:45262 return headers + "\n" + ToStringInternal(std::string(), &reader);
[email protected]a9e91492011-07-30 19:13:31263}
264
[email protected]ca72ff22012-05-23 06:55:22265bool Message::SetDestination(const std::string& destination) {
266 return dbus_message_set_destination(raw_message_, destination.c_str());
[email protected]9cce2d32011-08-10 22:34:02267}
268
[email protected]ca72ff22012-05-23 06:55:22269bool Message::SetPath(const ObjectPath& path) {
270 return dbus_message_set_path(raw_message_, path.value().c_str());
[email protected]9cce2d32011-08-10 22:34:02271}
272
[email protected]ca72ff22012-05-23 06:55:22273bool Message::SetInterface(const std::string& interface) {
274 return dbus_message_set_interface(raw_message_, interface.c_str());
[email protected]9cce2d32011-08-10 22:34:02275}
276
[email protected]ca72ff22012-05-23 06:55:22277bool Message::SetMember(const std::string& member) {
278 return dbus_message_set_member(raw_message_, member.c_str());
[email protected]9cce2d32011-08-10 22:34:02279}
280
[email protected]ca72ff22012-05-23 06:55:22281bool Message::SetErrorName(const std::string& error_name) {
282 return dbus_message_set_error_name(raw_message_, error_name.c_str());
[email protected]9cce2d32011-08-10 22:34:02283}
284
[email protected]ca72ff22012-05-23 06:55:22285bool Message::SetSender(const std::string& sender) {
286 return dbus_message_set_sender(raw_message_, sender.c_str());
[email protected]9cce2d32011-08-10 22:34:02287}
288
avi22437c692015-12-22 18:12:45289void Message::SetSerial(uint32_t serial) {
[email protected]9cce2d32011-08-10 22:34:02290 dbus_message_set_serial(raw_message_, serial);
291}
292
avi22437c692015-12-22 18:12:45293void Message::SetReplySerial(uint32_t reply_serial) {
[email protected]9cce2d32011-08-10 22:34:02294 dbus_message_set_reply_serial(raw_message_, reply_serial);
295}
296
297std::string Message::GetDestination() {
298 const char* destination = dbus_message_get_destination(raw_message_);
299 return destination ? destination : "";
300}
301
[email protected]216ed0b2012-02-14 21:29:06302ObjectPath Message::GetPath() {
[email protected]9cce2d32011-08-10 22:34:02303 const char* path = dbus_message_get_path(raw_message_);
[email protected]216ed0b2012-02-14 21:29:06304 return ObjectPath(path ? path : "");
[email protected]9cce2d32011-08-10 22:34:02305}
306
307std::string Message::GetInterface() {
308 const char* interface = dbus_message_get_interface(raw_message_);
309 return interface ? interface : "";
310}
311
312std::string Message::GetMember() {
313 const char* member = dbus_message_get_member(raw_message_);
314 return member ? member : "";
315}
316
317std::string Message::GetErrorName() {
318 const char* error_name = dbus_message_get_error_name(raw_message_);
319 return error_name ? error_name : "";
320}
321
322std::string Message::GetSender() {
323 const char* sender = dbus_message_get_sender(raw_message_);
324 return sender ? sender : "";
325}
326
benchan5d15ab582014-08-25 11:16:56327std::string Message::GetSignature() {
[email protected]9cce2d32011-08-10 22:34:02328 const char* signature = dbus_message_get_signature(raw_message_);
329 return signature ? signature : "";
330}
331
avi22437c692015-12-22 18:12:45332uint32_t Message::GetSerial() {
[email protected]9cce2d32011-08-10 22:34:02333 return dbus_message_get_serial(raw_message_);
334}
335
avi22437c692015-12-22 18:12:45336uint32_t Message::GetReplySerial() {
[email protected]9cce2d32011-08-10 22:34:02337 return dbus_message_get_reply_serial(raw_message_);
338}
339
[email protected]a9e91492011-07-30 19:13:31340//
341// MethodCall implementation.
342//
343
344MethodCall::MethodCall(const std::string& interface_name,
Hidehiko Abe1156b452017-09-12 03:55:06345 const std::string& method_name) {
[email protected]06ead872011-08-24 03:32:06346 Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL));
[email protected]a9e91492011-07-30 19:13:31347
[email protected]ca72ff22012-05-23 06:55:22348 CHECK(SetInterface(interface_name));
349 CHECK(SetMember(method_name));
[email protected]a9e91492011-07-30 19:13:31350}
351
Hidehiko Abe1156b452017-09-12 03:55:06352MethodCall::MethodCall() = default;
[email protected]06ead872011-08-24 03:32:06353
Hidehiko Abe1156b452017-09-12 03:55:06354std::unique_ptr<MethodCall> MethodCall::FromRawMessage(
355 DBusMessage* raw_message) {
[email protected]9cce2d32011-08-10 22:34:02356 DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message));
[email protected]a9e91492011-07-30 19:13:31357
Hidehiko Abe1156b452017-09-12 03:55:06358 std::unique_ptr<MethodCall> method_call(new MethodCall());
[email protected]06ead872011-08-24 03:32:06359 method_call->Init(raw_message);
[email protected]9cce2d32011-08-10 22:34:02360 return method_call;
[email protected]a9e91492011-07-30 19:13:31361}
362
363//
[email protected]3beaaa4e2011-08-23 07:29:21364// Signal implementation.
365//
366Signal::Signal(const std::string& interface_name,
Hidehiko Abe1156b452017-09-12 03:55:06367 const std::string& method_name) {
[email protected]06ead872011-08-24 03:32:06368 Init(dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL));
[email protected]3beaaa4e2011-08-23 07:29:21369
[email protected]ca72ff22012-05-23 06:55:22370 CHECK(SetInterface(interface_name));
371 CHECK(SetMember(method_name));
[email protected]3beaaa4e2011-08-23 07:29:21372}
373
Hidehiko Abe1156b452017-09-12 03:55:06374Signal::Signal() = default;
[email protected]06ead872011-08-24 03:32:06375
Hidehiko Abe1156b452017-09-12 03:55:06376std::unique_ptr<Signal> Signal::FromRawMessage(DBusMessage* raw_message) {
[email protected]3beaaa4e2011-08-23 07:29:21377 DCHECK_EQ(DBUS_MESSAGE_TYPE_SIGNAL, dbus_message_get_type(raw_message));
378
Hidehiko Abe1156b452017-09-12 03:55:06379 std::unique_ptr<Signal> signal(new Signal());
[email protected]06ead872011-08-24 03:32:06380 signal->Init(raw_message);
[email protected]3beaaa4e2011-08-23 07:29:21381 return signal;
382}
383
384//
[email protected]a9e91492011-07-30 19:13:31385// Response implementation.
386//
387
Hidehiko Abe1156b452017-09-12 03:55:06388Response::Response() = default;
[email protected]a9e91492011-07-30 19:13:31389
dcheng2a193282016-04-08 22:55:04390std::unique_ptr<Response> Response::FromRawMessage(DBusMessage* raw_message) {
[email protected]06ead872011-08-24 03:32:06391 DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_RETURN,
392 dbus_message_get_type(raw_message));
393
Hidehiko Abe1156b452017-09-12 03:55:06394 std::unique_ptr<Response> response(new Response());
[email protected]06ead872011-08-24 03:32:06395 response->Init(raw_message);
dchenge48600452015-12-28 02:24:50396 return response;
[email protected]9cce2d32011-08-10 22:34:02397}
398
dcheng2a193282016-04-08 22:55:04399std::unique_ptr<Response> Response::FromMethodCall(MethodCall* method_call) {
Hidehiko Abe1156b452017-09-12 03:55:06400 std::unique_ptr<Response> response(new Response());
[email protected]06ead872011-08-24 03:32:06401 response->Init(dbus_message_new_method_return(method_call->raw_message()));
dchenge48600452015-12-28 02:24:50402 return response;
[email protected]06ead872011-08-24 03:32:06403}
404
dcheng2a193282016-04-08 22:55:04405std::unique_ptr<Response> Response::CreateEmpty() {
Hidehiko Abe1156b452017-09-12 03:55:06406 std::unique_ptr<Response> response(new Response());
[email protected]06ead872011-08-24 03:32:06407 response->Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN));
dchenge48600452015-12-28 02:24:50408 return response;
[email protected]06ead872011-08-24 03:32:06409}
[email protected]9b25d452013-02-07 09:46:24410
[email protected]9cce2d32011-08-10 22:34:02411//
412// ErrorResponse implementation.
413//
414
Hidehiko Abe1156b452017-09-12 03:55:06415ErrorResponse::ErrorResponse() = default;
[email protected]9cce2d32011-08-10 22:34:02416
dcheng2a193282016-04-08 22:55:04417std::unique_ptr<ErrorResponse> ErrorResponse::FromRawMessage(
[email protected]9b25d452013-02-07 09:46:24418 DBusMessage* raw_message) {
[email protected]06ead872011-08-24 03:32:06419 DCHECK_EQ(DBUS_MESSAGE_TYPE_ERROR, dbus_message_get_type(raw_message));
420
Hidehiko Abe1156b452017-09-12 03:55:06421 std::unique_ptr<ErrorResponse> response(new ErrorResponse());
[email protected]06ead872011-08-24 03:32:06422 response->Init(raw_message);
dchenge48600452015-12-28 02:24:50423 return response;
[email protected]06ead872011-08-24 03:32:06424}
425
dcheng2a193282016-04-08 22:55:04426std::unique_ptr<ErrorResponse> ErrorResponse::FromMethodCall(
[email protected]9cce2d32011-08-10 22:34:02427 MethodCall* method_call,
428 const std::string& error_name,
429 const std::string& error_message) {
Hidehiko Abe1156b452017-09-12 03:55:06430 std::unique_ptr<ErrorResponse> response(new ErrorResponse());
[email protected]06ead872011-08-24 03:32:06431 response->Init(dbus_message_new_error(method_call->raw_message(),
432 error_name.c_str(),
433 error_message.c_str()));
dchenge48600452015-12-28 02:24:50434 return response;
[email protected]9cce2d32011-08-10 22:34:02435}
436
[email protected]a9e91492011-07-30 19:13:31437//
438// MessageWriter implementation.
439//
440
[email protected]2a57ca642013-06-13 06:37:19441MessageWriter::MessageWriter(Message* message)
442 : message_(message),
443 container_is_open_(false) {
[email protected]269508f2012-02-13 04:12:40444 memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
[email protected]9400ff82012-02-07 23:48:35445 if (message)
446 dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_);
[email protected]a9e91492011-07-30 19:13:31447}
448
Chris Watkins3740aae2017-11-29 07:44:11449MessageWriter::~MessageWriter() = default;
[email protected]a9e91492011-07-30 19:13:31450
avi22437c692015-12-22 18:12:45451void MessageWriter::AppendByte(uint8_t value) {
[email protected]a9e91492011-07-30 19:13:31452 AppendBasic(DBUS_TYPE_BYTE, &value);
453}
454
455void MessageWriter::AppendBool(bool value) {
[email protected]52e3f6a2011-08-04 21:57:21456 // The size of dbus_bool_t and the size of bool are different. The
457 // former is always 4 per dbus-types.h, whereas the latter is usually 1.
458 // dbus_message_iter_append_basic() used in AppendBasic() expects four
459 // bytes for DBUS_TYPE_BOOLEAN, so we must pass a dbus_bool_t, instead
460 // of a bool, to AppendBasic().
Ryo Hashimoto9dbc169b2017-09-25 07:06:14461 dbus_bool_t dbus_value = value ? 1 : 0;
[email protected]52e3f6a2011-08-04 21:57:21462 AppendBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
[email protected]a9e91492011-07-30 19:13:31463}
464
avi22437c692015-12-22 18:12:45465void MessageWriter::AppendInt16(int16_t value) {
[email protected]a9e91492011-07-30 19:13:31466 AppendBasic(DBUS_TYPE_INT16, &value);
467}
468
avi22437c692015-12-22 18:12:45469void MessageWriter::AppendUint16(uint16_t value) {
[email protected]a9e91492011-07-30 19:13:31470 AppendBasic(DBUS_TYPE_UINT16, &value);
471}
472
avi22437c692015-12-22 18:12:45473void MessageWriter::AppendInt32(int32_t value) {
[email protected]a9e91492011-07-30 19:13:31474 AppendBasic(DBUS_TYPE_INT32, &value);
475}
476
avi22437c692015-12-22 18:12:45477void MessageWriter::AppendUint32(uint32_t value) {
[email protected]a9e91492011-07-30 19:13:31478 AppendBasic(DBUS_TYPE_UINT32, &value);
479}
480
avi22437c692015-12-22 18:12:45481void MessageWriter::AppendInt64(int64_t value) {
[email protected]a9e91492011-07-30 19:13:31482 AppendBasic(DBUS_TYPE_INT64, &value);
483}
484
avi22437c692015-12-22 18:12:45485void MessageWriter::AppendUint64(uint64_t value) {
[email protected]a9e91492011-07-30 19:13:31486 AppendBasic(DBUS_TYPE_UINT64, &value);
487}
488
489void MessageWriter::AppendDouble(double value) {
490 AppendBasic(DBUS_TYPE_DOUBLE, &value);
491}
492
493void MessageWriter::AppendString(const std::string& value) {
[email protected]43fa5b82012-06-05 04:15:50494 // D-Bus Specification (0.19) says a string "must be valid UTF-8".
[email protected]527965412014-05-07 14:38:26495 CHECK(base::IsStringUTF8(value));
[email protected]a9e91492011-07-30 19:13:31496 const char* pointer = value.c_str();
497 AppendBasic(DBUS_TYPE_STRING, &pointer);
498 // TODO(satorux): It may make sense to return an error here, as the
499 // input string can be large. If needed, we could add something like
500 // bool AppendStringWithErrorChecking().
501}
502
[email protected]216ed0b2012-02-14 21:29:06503void MessageWriter::AppendObjectPath(const ObjectPath& value) {
[email protected]43fa5b82012-06-05 04:15:50504 CHECK(value.IsValid());
[email protected]216ed0b2012-02-14 21:29:06505 const char* pointer = value.value().c_str();
[email protected]a9e91492011-07-30 19:13:31506 AppendBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
507}
508
509// Ideally, client shouldn't need to supply the signature string, but
510// the underlying D-Bus library requires us to supply this before
511// appending contents to array and variant. It's technically possible
512// for us to design API that doesn't require the signature but it will
513// complicate the implementation so we decided to have the signature
514// parameter. Hopefully, variants are less used in request messages from
515// client side than response message from server side, so this should
516// not be a big issue.
517void MessageWriter::OpenArray(const std::string& signature,
518 MessageWriter* writer) {
519 DCHECK(!container_is_open_);
520
521 const bool success = dbus_message_iter_open_container(
522 &raw_message_iter_,
523 DBUS_TYPE_ARRAY,
524 signature.c_str(),
525 &writer->raw_message_iter_);
526 CHECK(success) << "Unable to allocate memory";
527 container_is_open_ = true;
528}
529
530void MessageWriter::OpenVariant(const std::string& signature,
531 MessageWriter* writer) {
532 DCHECK(!container_is_open_);
533
534 const bool success = dbus_message_iter_open_container(
535 &raw_message_iter_,
536 DBUS_TYPE_VARIANT,
537 signature.c_str(),
538 &writer->raw_message_iter_);
539 CHECK(success) << "Unable to allocate memory";
540 container_is_open_ = true;
541}
542
543void MessageWriter::OpenStruct(MessageWriter* writer) {
544 DCHECK(!container_is_open_);
545
Hidehiko Abe1156b452017-09-12 03:55:06546 const bool success =
547 dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_STRUCT,
548 nullptr, // Signature should be nullptr.
549 &writer->raw_message_iter_);
[email protected]a9e91492011-07-30 19:13:31550 CHECK(success) << "Unable to allocate memory";
551 container_is_open_ = true;
552}
553
554void MessageWriter::OpenDictEntry(MessageWriter* writer) {
555 DCHECK(!container_is_open_);
556
Hidehiko Abe1156b452017-09-12 03:55:06557 const bool success =
558 dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_DICT_ENTRY,
559 nullptr, // Signature should be nullptr.
560 &writer->raw_message_iter_);
[email protected]a9e91492011-07-30 19:13:31561 CHECK(success) << "Unable to allocate memory";
562 container_is_open_ = true;
563}
564
565void MessageWriter::CloseContainer(MessageWriter* writer) {
566 DCHECK(container_is_open_);
567
568 const bool success = dbus_message_iter_close_container(
569 &raw_message_iter_, &writer->raw_message_iter_);
570 CHECK(success) << "Unable to allocate memory";
571 container_is_open_ = false;
572}
573
avi22437c692015-12-22 18:12:45574void MessageWriter::AppendArrayOfBytes(const uint8_t* values, size_t length) {
[email protected]a9e91492011-07-30 19:13:31575 DCHECK(!container_is_open_);
576 MessageWriter array_writer(message_);
577 OpenArray("y", &array_writer);
578 const bool success = dbus_message_iter_append_fixed_array(
579 &(array_writer.raw_message_iter_),
580 DBUS_TYPE_BYTE,
581 &values,
582 static_cast<int>(length));
583 CHECK(success) << "Unable to allocate memory";
584 CloseContainer(&array_writer);
585}
586
warxa377c042016-03-30 21:27:41587void MessageWriter::AppendArrayOfDoubles(const double* values, size_t length) {
588 DCHECK(!container_is_open_);
589 MessageWriter array_writer(message_);
590 OpenArray("d", &array_writer);
591 const bool success = dbus_message_iter_append_fixed_array(
592 &(array_writer.raw_message_iter_),
593 DBUS_TYPE_DOUBLE,
594 &values,
595 static_cast<int>(length));
596 CHECK(success) << "Unable to allocate memory";
597 CloseContainer(&array_writer);
598}
599
[email protected]8bc83fd2011-09-19 18:22:14600void MessageWriter::AppendArrayOfStrings(
601 const std::vector<std::string>& strings) {
602 DCHECK(!container_is_open_);
603 MessageWriter array_writer(message_);
604 OpenArray("s", &array_writer);
605 for (size_t i = 0; i < strings.size(); ++i) {
606 array_writer.AppendString(strings[i]);
607 }
608 CloseContainer(&array_writer);
609}
610
[email protected]090d8e512011-08-22 18:28:42611void MessageWriter::AppendArrayOfObjectPaths(
[email protected]216ed0b2012-02-14 21:29:06612 const std::vector<ObjectPath>& object_paths) {
[email protected]090d8e512011-08-22 18:28:42613 DCHECK(!container_is_open_);
614 MessageWriter array_writer(message_);
615 OpenArray("o", &array_writer);
616 for (size_t i = 0; i < object_paths.size(); ++i) {
617 array_writer.AppendObjectPath(object_paths[i]);
618 }
619 CloseContainer(&array_writer);
620}
621
[email protected]c033c5082012-02-09 18:14:08622bool MessageWriter::AppendProtoAsArrayOfBytes(
623 const google::protobuf::MessageLite& protobuf) {
624 std::string serialized_proto;
625 if (!protobuf.SerializeToString(&serialized_proto)) {
626 LOG(ERROR) << "Unable to serialize supplied protocol buffer";
627 return false;
628 }
avi22437c692015-12-22 18:12:45629 AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(serialized_proto.data()),
[email protected]c033c5082012-02-09 18:14:08630 serialized_proto.size());
631 return true;
632}
633
avi22437c692015-12-22 18:12:45634void MessageWriter::AppendVariantOfByte(uint8_t value) {
[email protected]a9e91492011-07-30 19:13:31635 AppendVariantOfBasic(DBUS_TYPE_BYTE, &value);
636}
637
638void MessageWriter::AppendVariantOfBool(bool value) {
[email protected]52e3f6a2011-08-04 21:57:21639 // See the comment at MessageWriter::AppendBool().
640 dbus_bool_t dbus_value = value;
641 AppendVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
[email protected]a9e91492011-07-30 19:13:31642}
643
avi22437c692015-12-22 18:12:45644void MessageWriter::AppendVariantOfInt16(int16_t value) {
[email protected]a9e91492011-07-30 19:13:31645 AppendVariantOfBasic(DBUS_TYPE_INT16, &value);
646}
647
avi22437c692015-12-22 18:12:45648void MessageWriter::AppendVariantOfUint16(uint16_t value) {
[email protected]a9e91492011-07-30 19:13:31649 AppendVariantOfBasic(DBUS_TYPE_UINT16, &value);
650}
651
avi22437c692015-12-22 18:12:45652void MessageWriter::AppendVariantOfInt32(int32_t value) {
[email protected]a9e91492011-07-30 19:13:31653 AppendVariantOfBasic(DBUS_TYPE_INT32, &value);
654}
655
avi22437c692015-12-22 18:12:45656void MessageWriter::AppendVariantOfUint32(uint32_t value) {
[email protected]a9e91492011-07-30 19:13:31657 AppendVariantOfBasic(DBUS_TYPE_UINT32, &value);
658}
659
avi22437c692015-12-22 18:12:45660void MessageWriter::AppendVariantOfInt64(int64_t value) {
[email protected]a9e91492011-07-30 19:13:31661 AppendVariantOfBasic(DBUS_TYPE_INT64, &value);
662}
663
avi22437c692015-12-22 18:12:45664void MessageWriter::AppendVariantOfUint64(uint64_t value) {
[email protected]a9e91492011-07-30 19:13:31665 AppendVariantOfBasic(DBUS_TYPE_UINT64, &value);
666}
667
668void MessageWriter::AppendVariantOfDouble(double value) {
669 AppendVariantOfBasic(DBUS_TYPE_DOUBLE, &value);
670}
671
672void MessageWriter::AppendVariantOfString(const std::string& value) {
673 const char* pointer = value.c_str();
674 AppendVariantOfBasic(DBUS_TYPE_STRING, &pointer);
675}
676
[email protected]216ed0b2012-02-14 21:29:06677void MessageWriter::AppendVariantOfObjectPath(const ObjectPath& value) {
678 const char* pointer = value.value().c_str();
[email protected]a9e91492011-07-30 19:13:31679 AppendVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
680}
681
682void MessageWriter::AppendBasic(int dbus_type, const void* value) {
683 DCHECK(!container_is_open_);
684
685 const bool success = dbus_message_iter_append_basic(
686 &raw_message_iter_, dbus_type, value);
687 // dbus_message_iter_append_basic() fails only when there is not enough
688 // memory. We don't return this error as there is nothing we can do when
689 // it fails to allocate memory for a byte etc.
690 CHECK(success) << "Unable to allocate memory";
691}
692
693void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) {
ricea19b947df2015-09-18 22:26:10694 const std::string signature(1u, // length
695 base::checked_cast<char>(dbus_type));
[email protected]a9e91492011-07-30 19:13:31696 MessageWriter variant_writer(message_);
697 OpenVariant(signature, &variant_writer);
698 variant_writer.AppendBasic(dbus_type, value);
699 CloseContainer(&variant_writer);
700}
701
hashimoto89822572016-08-24 16:51:38702void MessageWriter::AppendFileDescriptor(int value) {
703 CHECK(IsDBusTypeUnixFdSupported());
704 AppendBasic(DBUS_TYPE_UNIX_FD, &value); // This duplicates the FD.
705}
706
[email protected]a9e91492011-07-30 19:13:31707//
708// MessageReader implementation.
709//
710
711MessageReader::MessageReader(Message* message)
712 : message_(message) {
[email protected]269508f2012-02-13 04:12:40713 memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
[email protected]9400ff82012-02-07 23:48:35714 if (message)
715 dbus_message_iter_init(message_->raw_message(), &raw_message_iter_);
[email protected]a9e91492011-07-30 19:13:31716}
717
Chris Watkins3740aae2017-11-29 07:44:11718MessageReader::~MessageReader() = default;
[email protected]a9e91492011-07-30 19:13:31719
720bool MessageReader::HasMoreData() {
721 const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
722 return dbus_type != DBUS_TYPE_INVALID;
723}
724
avi22437c692015-12-22 18:12:45725bool MessageReader::PopByte(uint8_t* value) {
[email protected]a9e91492011-07-30 19:13:31726 return PopBasic(DBUS_TYPE_BYTE, value);
727}
728
729bool MessageReader::PopBool(bool* value) {
[email protected]52e3f6a2011-08-04 21:57:21730 // Like MessageWriter::AppendBool(), we should copy |value| to
731 // dbus_bool_t, as dbus_message_iter_get_basic() used in PopBasic()
732 // expects four bytes for DBUS_TYPE_BOOLEAN.
733 dbus_bool_t dbus_value = FALSE;
734 const bool success = PopBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
735 *value = static_cast<bool>(dbus_value);
736 return success;
[email protected]a9e91492011-07-30 19:13:31737}
738
avi22437c692015-12-22 18:12:45739bool MessageReader::PopInt16(int16_t* value) {
[email protected]a9e91492011-07-30 19:13:31740 return PopBasic(DBUS_TYPE_INT16, value);
741}
742
avi22437c692015-12-22 18:12:45743bool MessageReader::PopUint16(uint16_t* value) {
[email protected]a9e91492011-07-30 19:13:31744 return PopBasic(DBUS_TYPE_UINT16, value);
745}
746
avi22437c692015-12-22 18:12:45747bool MessageReader::PopInt32(int32_t* value) {
[email protected]a9e91492011-07-30 19:13:31748 return PopBasic(DBUS_TYPE_INT32, value);
749}
750
avi22437c692015-12-22 18:12:45751bool MessageReader::PopUint32(uint32_t* value) {
[email protected]a9e91492011-07-30 19:13:31752 return PopBasic(DBUS_TYPE_UINT32, value);
753}
754
avi22437c692015-12-22 18:12:45755bool MessageReader::PopInt64(int64_t* value) {
[email protected]a9e91492011-07-30 19:13:31756 return PopBasic(DBUS_TYPE_INT64, value);
757}
758
avi22437c692015-12-22 18:12:45759bool MessageReader::PopUint64(uint64_t* value) {
[email protected]a9e91492011-07-30 19:13:31760 return PopBasic(DBUS_TYPE_UINT64, value);
761}
762
763bool MessageReader::PopDouble(double* value) {
764 return PopBasic(DBUS_TYPE_DOUBLE, value);
765}
766
767bool MessageReader::PopString(std::string* value) {
Hidehiko Abe1156b452017-09-12 03:55:06768 char* tmp_value = nullptr;
[email protected]a9e91492011-07-30 19:13:31769 const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value);
770 if (success)
771 value->assign(tmp_value);
772 return success;
773}
774
[email protected]216ed0b2012-02-14 21:29:06775bool MessageReader::PopObjectPath(ObjectPath* value) {
Hidehiko Abe1156b452017-09-12 03:55:06776 char* tmp_value = nullptr;
[email protected]a9e91492011-07-30 19:13:31777 const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
778 if (success)
[email protected]216ed0b2012-02-14 21:29:06779 *value = ObjectPath(tmp_value);
[email protected]a9e91492011-07-30 19:13:31780 return success;
781}
782
783bool MessageReader::PopArray(MessageReader* sub_reader) {
784 return PopContainer(DBUS_TYPE_ARRAY, sub_reader);
785}
786
787bool MessageReader::PopStruct(MessageReader* sub_reader) {
788 return PopContainer(DBUS_TYPE_STRUCT, sub_reader);
789}
790
791bool MessageReader::PopDictEntry(MessageReader* sub_reader) {
792 return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader);
793}
794
795bool MessageReader::PopVariant(MessageReader* sub_reader) {
796 return PopContainer(DBUS_TYPE_VARIANT, sub_reader);
797}
798
avi22437c692015-12-22 18:12:45799bool MessageReader::PopArrayOfBytes(const uint8_t** bytes, size_t* length) {
[email protected]a9e91492011-07-30 19:13:31800 MessageReader array_reader(message_);
801 if (!PopArray(&array_reader))
802 return false;
[email protected]3ed06262011-11-11 02:13:56803 // An empty array is allowed.
804 if (!array_reader.HasMoreData()) {
805 *length = 0;
Hidehiko Abe1156b452017-09-12 03:55:06806 *bytes = nullptr;
[email protected]3ed06262011-11-11 02:13:56807 return true;
808 }
[email protected]a9e91492011-07-30 19:13:31809 if (!array_reader.CheckDataType(DBUS_TYPE_BYTE))
810 return false;
811 int int_length = 0;
812 dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
813 bytes,
814 &int_length);
warxa377c042016-03-30 21:27:41815 *length = static_cast<size_t>(int_length);
816 return true;
817}
818
819bool MessageReader::PopArrayOfDoubles(const double** doubles, size_t* length) {
820 MessageReader array_reader(message_);
821 if (!PopArray(&array_reader))
822 return false;
823 if (!array_reader.HasMoreData()) {
824 *length = 0;
825 *doubles = nullptr;
826 return true;
827 }
828 if (!array_reader.CheckDataType(DBUS_TYPE_DOUBLE))
829 return false;
830 int int_length = 0;
831 dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
832 doubles,
833 &int_length);
834 *length = static_cast<size_t>(int_length);
[email protected]3ed06262011-11-11 02:13:56835 return true;
[email protected]a9e91492011-07-30 19:13:31836}
837
[email protected]8bc83fd2011-09-19 18:22:14838bool MessageReader::PopArrayOfStrings(
839 std::vector<std::string> *strings) {
[email protected]38715910e2014-02-24 15:59:40840 strings->clear();
[email protected]8bc83fd2011-09-19 18:22:14841 MessageReader array_reader(message_);
842 if (!PopArray(&array_reader))
[email protected]38715910e2014-02-24 15:59:40843 return false;
[email protected]8bc83fd2011-09-19 18:22:14844 while (array_reader.HasMoreData()) {
845 std::string string;
846 if (!array_reader.PopString(&string))
847 return false;
848 strings->push_back(string);
849 }
850 return true;
851}
852
[email protected]a9e91492011-07-30 19:13:31853bool MessageReader::PopArrayOfObjectPaths(
[email protected]216ed0b2012-02-14 21:29:06854 std::vector<ObjectPath> *object_paths) {
[email protected]38715910e2014-02-24 15:59:40855 object_paths->clear();
[email protected]a9e91492011-07-30 19:13:31856 MessageReader array_reader(message_);
857 if (!PopArray(&array_reader))
[email protected]38715910e2014-02-24 15:59:40858 return false;
[email protected]a9e91492011-07-30 19:13:31859 while (array_reader.HasMoreData()) {
[email protected]216ed0b2012-02-14 21:29:06860 ObjectPath object_path;
[email protected]a9e91492011-07-30 19:13:31861 if (!array_reader.PopObjectPath(&object_path))
862 return false;
863 object_paths->push_back(object_path);
864 }
865 return true;
866}
867
[email protected]c033c5082012-02-09 18:14:08868bool MessageReader::PopArrayOfBytesAsProto(
869 google::protobuf::MessageLite* protobuf) {
Hidehiko Abe1156b452017-09-12 03:55:06870 DCHECK(protobuf);
871 const char* serialized_buf = nullptr;
[email protected]c033c5082012-02-09 18:14:08872 size_t buf_size = 0;
avi22437c692015-12-22 18:12:45873 if (!PopArrayOfBytes(reinterpret_cast<const uint8_t**>(&serialized_buf),
874 &buf_size)) {
[email protected]c033c5082012-02-09 18:14:08875 LOG(ERROR) << "Error reading array of bytes";
876 return false;
877 }
878 if (!protobuf->ParseFromArray(serialized_buf, buf_size)) {
879 LOG(ERROR) << "Failed to parse protocol buffer from array";
880 return false;
881 }
882 return true;
883}
884
avi22437c692015-12-22 18:12:45885bool MessageReader::PopVariantOfByte(uint8_t* value) {
[email protected]a9e91492011-07-30 19:13:31886 return PopVariantOfBasic(DBUS_TYPE_BYTE, value);
887}
888
889bool MessageReader::PopVariantOfBool(bool* value) {
[email protected]52e3f6a2011-08-04 21:57:21890 // See the comment at MessageReader::PopBool().
891 dbus_bool_t dbus_value = FALSE;
892 const bool success = PopVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
893 *value = static_cast<bool>(dbus_value);
894 return success;
[email protected]a9e91492011-07-30 19:13:31895}
896
avi22437c692015-12-22 18:12:45897bool MessageReader::PopVariantOfInt16(int16_t* value) {
[email protected]a9e91492011-07-30 19:13:31898 return PopVariantOfBasic(DBUS_TYPE_INT16, value);
899}
900
avi22437c692015-12-22 18:12:45901bool MessageReader::PopVariantOfUint16(uint16_t* value) {
[email protected]a9e91492011-07-30 19:13:31902 return PopVariantOfBasic(DBUS_TYPE_UINT16, value);
903}
904
avi22437c692015-12-22 18:12:45905bool MessageReader::PopVariantOfInt32(int32_t* value) {
[email protected]a9e91492011-07-30 19:13:31906 return PopVariantOfBasic(DBUS_TYPE_INT32, value);
907}
908
avi22437c692015-12-22 18:12:45909bool MessageReader::PopVariantOfUint32(uint32_t* value) {
[email protected]a9e91492011-07-30 19:13:31910 return PopVariantOfBasic(DBUS_TYPE_UINT32, value);
911}
912
avi22437c692015-12-22 18:12:45913bool MessageReader::PopVariantOfInt64(int64_t* value) {
[email protected]a9e91492011-07-30 19:13:31914 return PopVariantOfBasic(DBUS_TYPE_INT64, value);
915}
916
avi22437c692015-12-22 18:12:45917bool MessageReader::PopVariantOfUint64(uint64_t* value) {
[email protected]a9e91492011-07-30 19:13:31918 return PopVariantOfBasic(DBUS_TYPE_UINT64, value);
919}
920
921bool MessageReader::PopVariantOfDouble(double* value) {
922 return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value);
923}
924
925bool MessageReader::PopVariantOfString(std::string* value) {
Hidehiko Abe1156b452017-09-12 03:55:06926 char* tmp_value = nullptr;
[email protected]a9e91492011-07-30 19:13:31927 const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value);
928 if (success)
929 value->assign(tmp_value);
930 return success;
931}
932
[email protected]216ed0b2012-02-14 21:29:06933bool MessageReader::PopVariantOfObjectPath(ObjectPath* value) {
Hidehiko Abe1156b452017-09-12 03:55:06934 char* tmp_value = nullptr;
[email protected]a9e91492011-07-30 19:13:31935 const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
936 if (success)
[email protected]216ed0b2012-02-14 21:29:06937 *value = ObjectPath(tmp_value);
[email protected]a9e91492011-07-30 19:13:31938 return success;
939}
940
941Message::DataType MessageReader::GetDataType() {
942 const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
943 return static_cast<Message::DataType>(dbus_type);
944}
945
benchand2c6ebe2014-08-25 06:50:29946std::string MessageReader::GetDataSignature() {
947 std::string signature;
948 char* raw_signature = dbus_message_iter_get_signature(&raw_message_iter_);
949 if (raw_signature) {
950 signature = raw_signature;
951 dbus_free(raw_signature);
952 }
953 return signature;
954}
955
[email protected]a9e91492011-07-30 19:13:31956bool MessageReader::CheckDataType(int dbus_type) {
957 const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
958 if (actual_type != dbus_type) {
959 VLOG(1) << "Type " << dbus_type << " is expected but got "
960 << actual_type;
961 return false;
962 }
963 return true;
964}
965
966bool MessageReader::PopBasic(int dbus_type, void* value) {
967 if (!CheckDataType(dbus_type))
968 return false;
969 // dbus_message_iter_get_basic() here should always work, as we have
970 // already checked the next item's data type in CheckDataType(). Note
971 // that dbus_message_iter_get_basic() is a void function.
972 dbus_message_iter_get_basic(&raw_message_iter_, value);
973 DCHECK(value);
974 dbus_message_iter_next(&raw_message_iter_);
975 return true;
976}
977
978bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) {
979 DCHECK_NE(this, sub_reader);
980
981 if (!CheckDataType(dbus_type))
982 return false;
983 dbus_message_iter_recurse(&raw_message_iter_,
984 &sub_reader->raw_message_iter_);
985 dbus_message_iter_next(&raw_message_iter_);
986 return true;
987}
988
989bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) {
[email protected]2a57ca642013-06-13 06:37:19990 MessageReader variant_reader(message_);
[email protected]a9e91492011-07-30 19:13:31991 if (!PopVariant(&variant_reader))
992 return false;
993 return variant_reader.PopBasic(dbus_type, value);
994}
995
hashimoto89822572016-08-24 16:51:38996bool MessageReader::PopFileDescriptor(base::ScopedFD* value) {
997 CHECK(IsDBusTypeUnixFdSupported());
998
999 int fd = -1;
1000 const bool success = PopBasic(DBUS_TYPE_UNIX_FD, &fd);
1001 if (!success)
1002 return false;
1003
1004 *value = base::ScopedFD(fd);
1005 return true;
1006}
1007
[email protected]a9e91492011-07-30 19:13:311008} // namespace dbus