Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: net/dbus/dbus.cc

Issue 7413004: Uploading for backup... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: backup Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/dbus/dbus.h ('k') | net/dbus/dbus_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dbus/dbus.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "base/stringprintf.h"
11 #include "base/threading/thread.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "base/threading/platform_thread.h"
14
15 namespace net {
16 namespace dbus {
17
18 //
19 // Bus implementation.
20 //
21
22 Bus::Bus(const Options& options)
23 : bus_type_(options.bus_type),
24 connection_type_(options.connection_type),
25 connection_(NULL) {
26 }
27
28 Bus::~Bus() {
29 // Private connection should be closed.
30 if (connection_ && connection_type_ == PRIVATE) {
31 dbus_connection_close(connection_);
32 }
33 }
34
35 bool Bus::Init() {
36 // Check if it's already initialized.
37 if (connection_)
38 return true;
39
40 DBusError error = {};
41 dbus_error_init(&error);
42 const DBusBusType dbus_bus_type = static_cast<DBusBusType>(bus_type_);
43 if (connection_type_ == PRIVATE) {
44 connection_ = dbus_bus_get_private(dbus_bus_type, &error);
45 } else {
46 connection_ = dbus_bus_get(dbus_bus_type, &error);
47 }
48 if (!connection_) {
49 if (dbus_error_is_set(&error)) {
50 LOG(ERROR) << error.message;
51 }
52 return false;
53 }
54
55 return true;
56 }
57
58 void OnDispatchStatus(DBusConnection* connection,
59 DBusDispatchStatus status,
60 void *data) {
61 LOG(ERROR) << "is connected: "
62 << dbus_connection_get_is_connected(connection);
63 LOG(ERROR) << "new status: " << status;
64 }
65
66 bool Bus::InitForAsync() {
67 if (!Init()) {
68 return false;
69 }
70 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
71 dbus_connection_set_watch_functions(connection_,
72 &Bus::OnAddWatch,
73 &Bus::OnRemoveWatch,
74 &Bus::OnToggleWatch,
75 this,
76 NULL);
77 dbus_connection_set_timeout_functions(connection_,
78 NULL,
79 NULL,
80 NULL,
81 NULL,
82 NULL);
83 dbus_connection_set_dispatch_status_function(connection_,
84 OnDispatchStatus,
85 connection_,
86 NULL);
87 return true;
88 }
89
90 ObjectProxy* Bus::GetObjectProxy(const std::string& service_name,
91 const std::string& object_path) {
92 return new ObjectProxy(this, service_name, object_path);
93 }
94
95 class Bus::IOThread : public base::Thread {
96 public:
97 IOThread() : base::Thread("Bus::IOThread") {
98 }
99
100 ~IOThread() {
101 }
102 };
103
104
105 void Bus::StartIOThreadIfNeeded() {
106 if (io_thread_.get())
107 return;
108 base::Thread::Options thread_options;
109 thread_options.message_loop_type = MessageLoop::TYPE_IO;
110 io_thread_.reset(new IOThread);
111 io_thread_->StartWithOptions(thread_options);
112 }
113
114 void Bus::PostTask(const tracked_objects::Location& from_here,
115 const base::Closure& task) {
116 io_thread_->message_loop()->PostTask(from_here, task);
117 }
118
119 class Watch : public base::MessagePumpLibevent::Watcher {
120 public:
121 Watch(DBusWatch* watch, DBusConnection* connection)
122 : watch_(watch),
123 connection_(connection) {
124 dbus_watch_set_data(watch_, this, NULL);
125 }
126
127 ~Watch() {
128 file_descriptor_watcher_.StopWatchingFileDescriptor();
129 dbus_watch_set_data(watch_, NULL, NULL);
130 }
131
132 // Returns true if ready to watch.
133 bool IsEnabled() {
134 return dbus_watch_get_enabled(watch_);
135 }
136
137 void StartWatching() {
138 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
139
140 const int fd = dbus_watch_get_unix_fd(watch_);
141 LOG(ERROR) << "fd: " << fd;
142 const int flags = dbus_watch_get_flags(watch_);
143 LOG(ERROR) << "flags: " << flags;
144
145 MessageLoopForIO::Mode mode;
146 if ((flags & DBUS_WATCH_READABLE) && (flags & DBUS_WATCH_WRITABLE))
147 mode = MessageLoopForIO::WATCH_READ_WRITE;
148 if (flags & DBUS_WATCH_READABLE)
149 mode = MessageLoopForIO::WATCH_READ;
150 if (flags & DBUS_WATCH_WRITABLE)
151 mode = MessageLoopForIO::WATCH_WRITE;
152
153 const bool persistent = true; // Watch persistently.
154 const bool success = MessageLoopForIO::current()->WatchFileDescriptor(
155 fd,
156 persistent,
157 mode,
158 &file_descriptor_watcher_,
159 this);
160 DCHECK(success) << "Unable to allocate memory";
161 }
162
163 // Implements MessagePumpLibevent::Watcher::OnFileCanReadWithoutBlocking.
164 virtual void OnFileCanReadWithoutBlocking(int fd) {
165 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
166
167 int flags = 0;
168 flags |= DBUS_WATCH_READABLE;
169 flags |= DBUS_WATCH_WRITABLE;
170 LOG(ERROR) << "status: " <<
171 dbus_connection_get_dispatch_status(connection_);
172 const bool success = dbus_watch_handle(watch_, flags);
173 LOG(ERROR) << "status: " <<
174 dbus_connection_get_dispatch_status(connection_);
175 while (dbus_connection_dispatch(connection_) == DBUS_DISPATCH_DATA_REMAINS);
176
177 DCHECK(success) << "Unable to allocate memory";
178 }
179
180 // Implements MessagePumpLibevent::Watcher::OnFileCanWriteWithoutBlocking.
181 virtual void OnFileCanWriteWithoutBlocking(int fd) {
182 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
183
184 const bool success = dbus_watch_handle(watch_, DBUS_WATCH_WRITABLE);
185 DCHECK(success) << "Unable to allocate memory";
186 }
187
188 private:
189 DBusWatch* watch_;
190 DBusConnection* connection_;
191 base::MessagePumpLibevent::FileDescriptorWatcher file_descriptor_watcher_;
192 };
193
194 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch, void* data) {
195 LOG(ERROR) << "@@ " << "watch: " << raw_watch;
196
197 Bus* self = reinterpret_cast<Bus*>(data);
198 Watch* watch = new Watch(raw_watch, self->connection_);
199 LOG(ERROR) << "flags: " << dbus_watch_get_flags(raw_watch);
200 if (watch->IsEnabled()) {
201 watch->StartWatching();
202 }
203 return true;
204 }
205
206 void Bus::OnRemoveWatch(DBusWatch* raw_watch, void* data) {
207 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
208
209 Watch* watch = reinterpret_cast<Watch*>(dbus_watch_get_data(raw_watch));
210 delete watch;
211 }
212
213 void Bus::OnToggleWatch(DBusWatch* raw_watch, void* data) {
214 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
215
216 Watch* watch = reinterpret_cast<Watch*>(dbus_watch_get_data(raw_watch));
217 if (watch->IsEnabled()) {
218 OnAddWatch(raw_watch, data);
219 } else {
220 OnRemoveWatch(raw_watch, data);
221 }
222 }
223
224 //
225 // ObjectProxy implementation.
226 //
227
228 ObjectProxy::ObjectProxy(Bus* bus,
229 const std::string& service_name,
230 const std::string& object_path)
231 : bus_(bus),
232 service_name_(service_name),
233 object_path_(object_path) {
234 }
235
236 ObjectProxy::~ObjectProxy() {
237 }
238
239 // Originally we tried to make |method_call| a const reference, but we
240 // gave up as dbus_connection_send_with_reply_and_block() takes a
241 // non-const pointer of DBusMessage as the second parameter.
242 bool ObjectProxy::CallMethodSync(MethodCall* method_call,
243 Response* response) {
244 base::ThreadRestrictions::AssertIOAllowed();
245 if (!bus_->Init())
246 return false;
247 method_call->SetServiceName(service_name_);
248 method_call->SetObjectPath(object_path_);
249 DBusMessage* request_message = method_call->raw_message();
250
251 const int timeout_ms = -1; // Default timeout.
252 DBusError error = {};
253 dbus_error_init(&error);
254
255 // Send the message synchronously.
256 DBusMessage* response_message = dbus_connection_send_with_reply_and_block(
257 bus_->connection(), request_message, timeout_ms, &error);
258
259 if (!response_message) {
260 if (dbus_error_is_set(&error)) {
261 LOG(ERROR) << error.message;
262 }
263 return false;
264 }
265 response->reset_raw_message(response_message);
266
267 return true;
268 }
269
270 void ObjectProxy::CallMethodAsync(MethodCall* method_call,
271 ResponseCallback callback) {
272 bus_->StartIOThreadIfNeeded();
273
274 method_call->SetServiceName(service_name_);
275 method_call->SetObjectPath(object_path_);
276 // This is a bit tricky but increment the reference count of the request
277 // message here so that we can keep using the message even if the
278 // MethodCall object at the caller is gone before the method call is
279 // complete.
280 DBusMessage* request_message = method_call->raw_message();
281 dbus_message_ref(request_message);
282
283 // Bind() won't compile if we pass request_message as-is since
284 // DBusMessage is an opaque struct which Bind() does not like.
285 //
286 // /base/bind_helpers.h:145:
287 // error: invalid use of incomplete type 'struct DBusMessage'
288 //
289 // Hence we cast it to void* to workaround the issue.
290 base::Closure task = base::Bind(&ObjectProxy::StartAsyncMethodCall,
291 // Make this a ref-counted class?
292 base::Unretained(this),
293 reinterpret_cast<void*>(request_message),
294 MessageLoop::current(),
295 callback);
296 LOG(ERROR) << "CallMethodAsync: thread id: " << base::PlatformThread::CurrentI d();
297 bus_->PostTask(FROM_HERE, task);
298 }
299
300 void ObjectProxy::StartAsyncMethodCall(void* in_request_message,
301 MessageLoop* origin_loop,
302 ResponseCallback response_callback) {
303 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
304
305 DBusMessage* request_message =
306 reinterpret_cast<DBusMessage*>(in_request_message);
307 if (bus_->InitForAsync()) {
308 const int timeout_ms = -1; // Default timeout.
309 DBusPendingCall* pending_call = NULL;
310 // This returns false only when unable to allocate memory.
311 bool success = false;
312 success = dbus_connection_send_with_reply(
313 bus_->connection(), request_message, &pending_call, timeout_ms);
314 dbus_pending_call_ref(pending_call);
315 DCHECK(success) << "Unable to allocate memory";
316
317 OnPendingCallIsCompleteData* data =
318 new OnPendingCallIsCompleteData(origin_loop, response_callback);
319
320 // This returns false only when unable to allocate memory.
321 success = dbus_pending_call_set_notify(
322 pending_call,
323 &ObjectProxy::OnPendingCallIsComplete,
324 data,
325 NULL);
326 DCHECK(success) << "Unable to allocate memory";
327 } else {
328 Response* response = NULL;
329 base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback,
330 response_callback,
331 response);
332 origin_loop->PostTask(FROM_HERE, task);
333 }
334 // It's now safe to unref the request message.
335 dbus_message_unref(request_message);
336 }
337
338 void ObjectProxy::RunResponseCallback(ResponseCallback response_callback,
339 Response* response) {
340 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
341
342 response_callback.Run(response);
343 }
344
345 ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData(
346 MessageLoop* in_origin_loop,
347 ResponseCallback in_response_callback)
348 : origin_loop(in_origin_loop),
349 response_callback(in_response_callback) {
350 }
351
352 void ObjectProxy::OnPendingCallIsComplete(DBusPendingCall* pending_call,
353 void* user_data) {
354 LOG(ERROR) << "@@ " << __PRETTY_FUNCTION__;
355
356 OnPendingCallIsCompleteData* data =
357 reinterpret_cast<OnPendingCallIsCompleteData*>(user_data);
358
359 DBusMessage* response_message = dbus_pending_call_steal_reply(pending_call);
360 CHECK(response_message) << "hoge";
361 // This will be deleted in the callback.
362 Response* response = new Response;
363 response->reset_raw_message(response_message);
364 base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback,
365 data->response_callback,
366 response);
367 data->origin_loop->PostTask(FROM_HERE, task);
368
369 delete data;
370 }
371
372 //
373 // Message implementation.
374 //
375
376 Message::Message()
377 : raw_message_(NULL) {
378 }
379
380 Message::~Message() {
381 if (raw_message_)
382 dbus_message_unref(raw_message_);
383 }
384
385 void Message::reset_raw_message(DBusMessage* raw_message) {
386 if (raw_message_)
387 dbus_message_unref(raw_message_);
388 raw_message_ = raw_message;
389 }
390
391 std::string Message::ToStringInternal(const std::string& indent,
392 MessageReader* reader) {
393 std::string output;
394 while (reader->HasMore()) {
395 const Type type = reader->GetType();
396 switch (type) {
397 case BYTE: {
398 uint8 value;
399 reader->PopByte(&value);
400 output += indent + "byte " + base::StringPrintf("%d", value) + "\n";
401 break;
402 }
403 case BOOL: {
404 bool value;
405 reader->PopBool(&value);
406 output += indent + "bool " + (value ? "true" : "false") + "\n";
407 break;
408 }
409 case INT16: {
410 int16 value;
411 reader->PopInt16(&value);
412 output += indent + "int16 " + base::StringPrintf("%d", value) + "\n";
413 break;
414 }
415 case UINT16: {
416 uint16 value;
417 reader->PopUint16(&value);
418 output += indent + "uint16 " + base::StringPrintf("%d", value) + "\n";
419 break;
420 }
421 case INT32: {
422 int32 value;
423 reader->PopInt32(&value);
424 output += indent + "int32 " + base::StringPrintf("%d", value) + "\n";
425 break;
426 }
427 case UINT32: {
428 uint32 value;
429 reader->PopUint32(&value);
430 output += indent + "uint32 " + base::StringPrintf("%u", value) + "\n";
431 break;
432 }
433 case INT64: {
434 int64 value;
435 reader->PopInt64(&value);
436 output += indent + "int64 " + base::StringPrintf("%ld", value) + "\n";
437 break;
438 }
439 case UINT64: {
440 uint64 value;
441 reader->PopUint64(&value);
442 output += indent + "uint64 " + base::StringPrintf("%lu", value) + "\n";
443 break;
444 }
445 case DOUBLE: {
446 double value;
447 reader->PopDouble(&value);
448 output += indent + "double " + base::StringPrintf("%f", value) + "\n";
449 break;
450 }
451 case STRING: {
452 std::string value;
453 reader->PopString(&value);
454 output += indent + "string \"" + value + "\"\n";
455 break;
456 }
457 case OBJECT_PATH: {
458 std::string value;
459 reader->PopObjectPath(&value);
460 output += indent + "object_path \"" + value + "\"\n";
461 break;
462 }
463 case ARRAY: {
464 MessageReader sub_reader(this);
465 reader->PopArray(&sub_reader);
466 output += indent + "array [\n";
467 output += ToStringInternal(indent + " ", &sub_reader);
468 output += indent + "]\n";
469 break;
470 }
471 case STRUCT: {
472 MessageReader sub_reader(this);
473 reader->PopStruct(&sub_reader);
474 output += indent + "struct {\n";
475 output += ToStringInternal(indent + " ", &sub_reader);
476 output += indent + "}\n";
477 break;
478 }
479 case DICT_ENTRY: {
480 MessageReader sub_reader(this);
481 reader->PopDictEntry(&sub_reader);
482 output += indent + "dict entry {\n";
483 output += ToStringInternal(indent + " ", &sub_reader);
484 output += indent + "}\n";
485 break;
486 }
487 case VARIANT: {
488 MessageReader sub_reader(this);
489 reader->PopVariant(&sub_reader);
490 output += indent + "variant ";
491 output += ToStringInternal(indent + " ", &sub_reader);
492 break;
493 }
494 default:
495 LOG(FATAL) << "Unknown type: " << type;
496 }
497 }
498 return output;
499 }
500
501 std::string Message::ToString() {
502 std::string output;
503 MessageReader reader(this);
504 return ToStringInternal("", &reader);
505 }
506
507 //
508 // MethodCall implementation.
509 //
510
511 MethodCall::MethodCall(const std::string& interface_name,
512 const std::string& method_name)
513 : Message() {
514 reset_raw_message(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL));
515
516 bool success = false;
517 success = dbus_message_set_interface(raw_message(), interface_name.c_str());
518 DCHECK(success) << "Unable to allocate memory";
519
520 success = dbus_message_set_member(raw_message(), method_name.c_str());
521 DCHECK(success) << "Unable to allocate memory";
522 }
523
524 void MethodCall::SetServiceName(const std::string& service_name) {
525 const bool success = dbus_message_set_destination(raw_message(),
526 service_name.c_str());
527 DCHECK(success) << "Unable to allocate memory";
528 }
529
530 void MethodCall::SetObjectPath(const std::string& object_path) {
531 const bool success = dbus_message_set_path(raw_message(),
532 object_path.c_str());
533 DCHECK(success) << "Unable to allocate memory";
534 }
535
536 //
537 // Response implementation.
538 //
539
540 Response::Response() : Message() {
541 }
542
543 //
544 // MessageWriter implementation.
545 //
546
547 MessageWriter::MessageWriter(Message* message) :
548 message_(message) {
549 dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_);
550 }
551
552
553 MessageWriter::~MessageWriter() {
554 }
555
556 void MessageWriter::AppendByte(uint8 value) {
557 const bool success = dbus_message_iter_append_basic(
558 &raw_message_iter_, DBUS_TYPE_BYTE, &value);
559 // dbus_message_iter_append_basic() fails only when there is not enough
560 // memory. We don't return this error as there is nothing we can do when
561 // it fails to allocate memory for a byte.
562 DCHECK(success) << "Unable to allocate memory";
563 }
564
565 void MessageWriter::AppendBool(bool value) {
566 const bool success = dbus_message_iter_append_basic(
567 &raw_message_iter_, DBUS_TYPE_BOOLEAN, &value);
568 DCHECK(success) << "Unable to allocate memory";
569 }
570
571 void MessageWriter::AppendInt16(int16 value) {
572 const bool success = dbus_message_iter_append_basic(
573 &raw_message_iter_, DBUS_TYPE_INT16, &value);
574 DCHECK(success) << "Unable to allocate memory";
575 }
576
577 void MessageWriter::AppendUint16(uint16 value) {
578 const bool success = dbus_message_iter_append_basic(
579 &raw_message_iter_, DBUS_TYPE_UINT16, &value);
580 DCHECK(success) << "Unable to allocate memory";
581 }
582
583 void MessageWriter::AppendInt32(int32 value) {
584 const bool success = dbus_message_iter_append_basic(
585 &raw_message_iter_, DBUS_TYPE_INT32, &value);
586 DCHECK(success) << "Unable to allocate memory";
587 }
588
589 void MessageWriter::AppendUint32(uint32 value) {
590 const bool success = dbus_message_iter_append_basic(
591 &raw_message_iter_, DBUS_TYPE_UINT32, &value);
592 DCHECK(success) << "Unable to allocate memory";
593 }
594
595 void MessageWriter::AppendInt64(int64 value) {
596 const bool success = dbus_message_iter_append_basic(
597 &raw_message_iter_, DBUS_TYPE_INT64, &value);
598 DCHECK(success) << "Unable to allocate memory";
599 }
600
601 void MessageWriter::AppendUint64(uint64 value) {
602 const bool success = dbus_message_iter_append_basic(
603 &raw_message_iter_, DBUS_TYPE_UINT64, &value);
604 DCHECK(success) << "Unable to allocate memory";
605 }
606
607 void MessageWriter::AppendDouble(double value) {
608 const bool success = dbus_message_iter_append_basic(
609 &raw_message_iter_, DBUS_TYPE_DOUBLE, &value);
610 DCHECK(success) << "Unable to allocate memory";
611 }
612
613 void MessageWriter::AppendString(const std::string& value) {
614 const char* pointer = value.c_str();
615 const bool success = dbus_message_iter_append_basic(
616 &raw_message_iter_, DBUS_TYPE_STRING, &pointer);
617 // It may make sense to return an error here, as the input string can be
618 // large. If needed, we could add something like
619 // bool AppendStringWithErrorChecking().
620 DCHECK(success) << "Unable to allocate memory";
621 }
622
623 void MessageWriter::AppendObjectPath(const std::string& value) {
624 const char* pointer = value.c_str();
625 const bool success = dbus_message_iter_append_basic(
626 &raw_message_iter_, DBUS_TYPE_OBJECT_PATH, &pointer);
627 DCHECK(success) << "Unable to allocate memory";
628 }
629
630 void MessageWriter::OpenArray(const std::string& signature,
631 MessageWriter* writer) {
632 const bool success = dbus_message_iter_open_container(
633 &raw_message_iter_,
634 DBUS_TYPE_ARRAY,
635 signature.c_str(),
636 &writer->raw_message_iter_);
637 DCHECK(success) << "Unable to allocate memory";
638 }
639
640 void MessageWriter::OpenVariant(const std::string& signature,
641 MessageWriter* writer) {
642 const bool success = dbus_message_iter_open_container(
643 &raw_message_iter_,
644 DBUS_TYPE_VARIANT,
645 signature.c_str(),
646 &writer->raw_message_iter_);
647 DCHECK(success) << "Unable to allocate memory";
648 }
649
650 void MessageWriter::OpenStruct(MessageWriter* writer) {
651 const bool success = dbus_message_iter_open_container(
652 &raw_message_iter_,
653 DBUS_TYPE_STRUCT,
654 NULL, // Signature should be NULL.
655 &writer->raw_message_iter_);
656 DCHECK(success) << "Unable to allocate memory";
657 }
658
659 void MessageWriter::OpenDictEntry(MessageWriter* writer) {
660 const bool success = dbus_message_iter_open_container(
661 &raw_message_iter_,
662 DBUS_TYPE_DICT_ENTRY,
663 NULL, // Signature should be NULL.
664 &writer->raw_message_iter_);
665 DCHECK(success) << "Unable to allocate memory";
666 }
667
668 void MessageWriter::CloseContainer(MessageWriter* writer) {
669 const bool success = dbus_message_iter_close_container(
670 &raw_message_iter_, &writer->raw_message_iter_);
671 DCHECK(success) << "Unable to allocate memory";
672 }
673
674 //
675 // MessageReader implementation.
676 //
677
678 MessageReader::MessageReader(Message* message)
679 : message_(message) {
680 dbus_message_iter_init(message_->raw_message(), &raw_message_iter_);
681 }
682
683
684 MessageReader::~MessageReader() {
685 }
686
687 bool MessageReader::HasMore() {
688 const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
689 return dbus_type != DBUS_TYPE_INVALID;
690 }
691
692 bool MessageReader::PopByte(uint8* value) {
693 return PopBasic(DBUS_TYPE_BYTE, value);
694 }
695
696 bool MessageReader::PopBool(bool* value) {
697 return PopBasic(DBUS_TYPE_BOOLEAN, value);
698 }
699
700 bool MessageReader::PopInt16(int16* value) {
701 return PopBasic(DBUS_TYPE_INT16, value);
702 }
703
704 bool MessageReader::PopUint16(uint16* value) {
705 return PopBasic(DBUS_TYPE_UINT16, value);
706 }
707
708 bool MessageReader::PopInt32(int32* value) {
709 return PopBasic(DBUS_TYPE_INT32, value);
710 }
711
712 bool MessageReader::PopUint32(uint32* value) {
713 return PopBasic(DBUS_TYPE_UINT32, value);
714 }
715
716 bool MessageReader::PopInt64(int64* value) {
717 return PopBasic(DBUS_TYPE_INT64, value);
718 }
719
720 bool MessageReader::PopUint64(uint64* value) {
721 return PopBasic(DBUS_TYPE_UINT64, value);
722 }
723
724 bool MessageReader::PopDouble(double* value) {
725 return PopBasic(DBUS_TYPE_DOUBLE, value);
726 }
727
728 bool MessageReader::PopString(std::string* value) {
729 char* tmp_value = NULL;
730 const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value);
731 if (success)
732 *value = tmp_value; // Copy the string.
733 return success;
734 }
735
736 bool MessageReader::PopObjectPath(std::string* value) {
737 char* tmp_value = NULL;
738 const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
739 if (success)
740 *value = tmp_value; // Copy the string.
741 return success;
742 }
743
744 bool MessageReader::PopArray(MessageReader* sub_reader) {
745 return PopContainer(DBUS_TYPE_ARRAY, sub_reader);
746 }
747
748 bool MessageReader::PopStruct(MessageReader* sub_reader) {
749 return PopContainer(DBUS_TYPE_STRUCT, sub_reader);
750 }
751
752 bool MessageReader::PopDictEntry(MessageReader* sub_reader) {
753 return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader);
754 }
755
756 bool MessageReader::PopVariant(MessageReader* sub_reader) {
757 return PopContainer(DBUS_TYPE_VARIANT, sub_reader);
758 }
759
760 bool MessageReader::PopArrayOfBytes(
761 std::vector<uint8>* bytes) {
762 MessageReader array_reader(message_);
763 if (!PopArray(&array_reader))
764 return false;
765 if (!array_reader.CheckType(DBUS_TYPE_BYTE))
766 return false;
767 char* values = NULL;
768 int num_values = 0;
769 dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
770 &values, &num_values);
771 if (!values)
772 return false;
773
774 bytes->assign(values, values + num_values); // Copy the data.
775 return true;
776 }
777
778 bool MessageReader::PopArrayOfObjectPaths(
779 std::vector<std::string> *object_paths) {
780 MessageReader array_reader(message_);
781 if (!PopArray(&array_reader))
782 return false;
783 while (array_reader.HasMore()) {
784 std::string object_path;
785 if (!array_reader.PopObjectPath(&object_path))
786 return false;
787 object_paths->push_back(object_path);
788 }
789 return true;
790 }
791
792 bool MessageReader::PopVariantOfByte(uint8* value) {
793 return PopVariantOfBasic(DBUS_TYPE_BYTE, value);
794 }
795
796 bool MessageReader::PopVariantOfBool(bool* value) {
797 return PopVariantOfBasic(DBUS_TYPE_BOOLEAN, value);
798 }
799
800 bool MessageReader::PopVariantOfInt16(int16* value) {
801 return PopVariantOfBasic(DBUS_TYPE_INT16, value);
802 }
803
804 bool MessageReader::PopVariantOfUint16(uint16* value) {
805 return PopVariantOfBasic(DBUS_TYPE_UINT16, value);
806 }
807
808 bool MessageReader::PopVariantOfInt32(int32* value) {
809 return PopVariantOfBasic(DBUS_TYPE_INT32, value);
810 }
811
812 bool MessageReader::PopVariantOfUint32(uint32* value) {
813 return PopVariantOfBasic(DBUS_TYPE_UINT32, value);
814 }
815
816 bool MessageReader::PopVariantOfInt64(int64* value) {
817 return PopVariantOfBasic(DBUS_TYPE_INT64, value);
818 }
819
820 bool MessageReader::PopVariantOfUint64(uint64* value) {
821 return PopVariantOfBasic(DBUS_TYPE_UINT64, value);
822 }
823
824 bool MessageReader::PopVariantOfDouble(double* value) {
825 return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value);
826 }
827
828 bool MessageReader::PopVariantOfString(std::string* value) {
829 char* tmp_value = NULL;
830 const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value);
831 if (success)
832 *value = tmp_value; // Copy the string.
833 return success;
834 }
835
836 bool MessageReader::PopVariantOfObjectPath(std::string* value) {
837 char* tmp_value = NULL;
838 const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
839 if (success)
840 *value = tmp_value; // Copy the string.
841 return success;
842 }
843
844 Message::Type MessageReader::GetType() {
845 const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
846 return static_cast<Message::Type>(dbus_type);
847 }
848
849 bool MessageReader::CheckType(int dbus_type) {
850 const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
851 if (actual_type != dbus_type) {
852 VLOG(1) << "Type " << dbus_type << " is expected but got "
853 << actual_type;
854 return false;
855 }
856 return true;
857 }
858
859 bool MessageReader::PopBasic(int dbus_type, void* value) {
860 if (!CheckType(dbus_type))
861 return false;
862 dbus_message_iter_get_basic(&raw_message_iter_, value);
863 dbus_message_iter_next(&raw_message_iter_);
864 return true;
865 }
866
867 bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) {
868 DCHECK_NE(this, sub_reader);
869
870 if (!CheckType(dbus_type))
871 return false;
872 dbus_message_iter_recurse(&raw_message_iter_,
873 &sub_reader->raw_message_iter_);
874 dbus_message_iter_next(&raw_message_iter_);
875 return true;
876 }
877
878 bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) {
879 net::dbus::MessageReader variant_reader(message_);
880 if (!PopVariant(&variant_reader))
881 return false;
882 return variant_reader.PopBasic(dbus_type, value);
883 }
884
885 } // namespace dbus
886 } // namespace net
OLDNEW
« no previous file with comments | « net/dbus/dbus.h ('k') | net/dbus/dbus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698