message.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_SYSTEM_PROTOBUF) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <google/protobuf/message_lite.h> 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/protobuf/src/google/protobuf/message_lite.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends the header name and the value to |output|, if the value is 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not empty. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendStringHeader(const std::string& header_name, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& header_value, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* output) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_value.empty()) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output += header_name + ": " + header_value + "\n"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends the header name and the value to |output|, if the value is 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nonzero. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendUint32Header(const std::string& header_name, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 header_value, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* output) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_value != 0) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output += (header_name + ": " + base::StringPrintf("%u", header_value) + 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace dbus { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsDBusTypeUnixFdSupported() { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int major = 0, minor = 0, micro = 0; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_get_version(&major, &minor, µ); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return major >= 1 && minor >= 4; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::Message() 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : raw_message_(NULL) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::~Message() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (raw_message_) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_unref(raw_message_); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::Init(DBusMessage* raw_message) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!raw_message_); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_message_ = raw_message; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::MessageType Message::GetMessageType() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!raw_message_) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MESSAGE_INVALID; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int type = dbus_message_get_type(raw_message_); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<Message::MessageType>(type); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetMessageTypeAsString() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (GetMessageType()) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MESSAGE_INVALID: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "MESSAGE_INVALID"; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MESSAGE_METHOD_CALL: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "MESSAGE_METHOD_CALL"; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MESSAGE_METHOD_RETURN: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "MESSAGE_METHOD_RETURN"; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MESSAGE_SIGNAL: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "MESSAGE_SIGNAL"; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MESSAGE_ERROR: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "MESSAGE_ERROR"; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::ToStringInternal(const std::string& indent, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader* reader) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* kBrokenMessage = "[broken message]"; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (reader->HasMoreData()) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DataType type = reader->GetDataType(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BYTE: { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 value = 0; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopByte(&value)) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "byte " + base::StringPrintf("%d", value) + "\n"; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BOOL: { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool value = false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopBool(&value)) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "bool " + (value ? "true" : "false") + "\n"; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case INT16: { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int16 value = 0; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopInt16(&value)) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "int16 " + base::StringPrintf("%d", value) + "\n"; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UINT16: { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 value = 0; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopUint16(&value)) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "uint16 " + base::StringPrintf("%d", value) + "\n"; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case INT32: { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 value = 0; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopInt32(&value)) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "int32 " + base::StringPrintf("%d", value) + "\n"; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UINT32: { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 value = 0; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopUint32(&value)) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "uint32 " + base::StringPrintf("%u", value) + "\n"; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case INT64: { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 value = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopInt64(&value)) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += (indent + "int64 " + 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%" PRId64, value) + "\n"); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UINT64: { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 value = 0; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopUint64(&value)) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += (indent + "uint64 " + 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%" PRIu64, value) + "\n"); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DOUBLE: { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value = 0; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopDouble(&value)) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "double " + base::StringPrintf("%f", value) + "\n"; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STRING: { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopString(&value)) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Truncate if the string is longer than the limit. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kTruncateLength = 100; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value.size() < kTruncateLength) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "string \"" + value + "\"\n"; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string truncated; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TruncateUTF8ToByteSize(value, kTruncateLength, &truncated); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&truncated, "... (%"PRIuS" bytes in total)", 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.size()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "string \"" + truncated + "\"\n"; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OBJECT_PATH: { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectPath value; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopObjectPath(&value)) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "object_path \"" + value.value() + "\"\n"; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ARRAY: { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader sub_reader(this); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopArray(&sub_reader)) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "array [\n"; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += ToStringInternal(indent + " ", &sub_reader); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "]\n"; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STRUCT: { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader sub_reader(this); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopStruct(&sub_reader)) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "struct {\n"; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += ToStringInternal(indent + " ", &sub_reader); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "}\n"; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DICT_ENTRY: { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader sub_reader(this); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopDictEntry(&sub_reader)) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "dict entry {\n"; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += ToStringInternal(indent + " ", &sub_reader); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "}\n"; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VARIANT: { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader sub_reader(this); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopVariant(&sub_reader)) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "variant "; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += ToStringInternal(indent + " ", &sub_reader); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UNIX_FD: { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(IsDBusTypeUnixFdSupported()); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor file_descriptor; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader->PopFileDescriptor(&file_descriptor)) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kBrokenMessage; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output += indent + "fd#" + 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%d", file_descriptor.value()) + "\n"; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Unknown type: " << type; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The returned string consists of message headers such as 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destination if any, followed by a blank line, and the message 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// payload. For example, a MethodCall's ToString() will look like: 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destination: com.example.Service 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// path: /com/example/Object 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interface: com.example.Interface 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// member: SomeMethod 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string \"payload\" 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::ToString() { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!raw_message_) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate headers first. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string headers; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("message_type", GetMessageTypeAsString(), &headers); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("destination", GetDestination(), &headers); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("path", GetPath().value(), &headers); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("interface", GetInterface(), &headers); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("member", GetMember(), &headers); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("error_name", GetErrorName(), &headers); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("sender", GetSender(), &headers); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendStringHeader("signature", GetSignature(), &headers); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendUint32Header("serial", GetSerial(), &headers); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendUint32Header("reply_serial", GetReplySerial(), &headers); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the payload. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader reader(this); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return headers + "\n" + ToStringInternal(std::string(), &reader); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::SetDestination(const std::string& destination) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_set_destination(raw_message_, destination.c_str()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::SetPath(const ObjectPath& path) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_set_path(raw_message_, path.value().c_str()); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::SetInterface(const std::string& interface) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_set_interface(raw_message_, interface.c_str()); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::SetMember(const std::string& member) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_set_member(raw_message_, member.c_str()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::SetErrorName(const std::string& error_name) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_set_error_name(raw_message_, error_name.c_str()); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::SetSender(const std::string& sender) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_set_sender(raw_message_, sender.c_str()); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::SetSerial(uint32 serial) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_set_serial(raw_message_, serial); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::SetReplySerial(uint32 reply_serial) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_set_reply_serial(raw_message_, reply_serial); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetDestination() { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* destination = dbus_message_get_destination(raw_message_); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return destination ? destination : ""; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectPath Message::GetPath() { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* path = dbus_message_get_path(raw_message_); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ObjectPath(path ? path : ""); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetInterface() { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* interface = dbus_message_get_interface(raw_message_); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return interface ? interface : ""; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetMember() { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* member = dbus_message_get_member(raw_message_); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return member ? member : ""; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetErrorName() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* error_name = dbus_message_get_error_name(raw_message_); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error_name ? error_name : ""; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetSender() { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* sender = dbus_message_get_sender(raw_message_); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sender ? sender : ""; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Message::GetSignature() { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* signature = dbus_message_get_signature(raw_message_); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return signature ? signature : ""; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 Message::GetSerial() { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_get_serial(raw_message_); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 Message::GetReplySerial() { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_message_get_reply_serial(raw_message_); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MethodCall implementation. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MethodCall::MethodCall(const std::string& interface_name, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& method_name) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Message() { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL)); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(SetInterface(interface_name)); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(SetMember(method_name)); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MethodCall::MethodCall() : Message() { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MethodCall* MethodCall::FromRawMessage(DBusMessage* raw_message) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message)); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodCall* method_call = new MethodCall; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_call->Init(raw_message); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return method_call; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Signal implementation. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Signal::Signal(const std::string& interface_name, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& method_name) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Message() { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(SetInterface(interface_name)); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(SetMember(method_name)); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Signal::Signal() : Message() { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Signal* Signal::FromRawMessage(DBusMessage* raw_message) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(DBUS_MESSAGE_TYPE_SIGNAL, dbus_message_get_type(raw_message)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Signal* signal = new Signal; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal->Init(raw_message); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return signal; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response implementation. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Response::Response() : Message() { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<Response> Response::FromRawMessage(DBusMessage* raw_message) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_RETURN, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_get_type(raw_message)); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Response> response(new Response); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->Init(raw_message); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return response.Pass(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<Response> Response::FromMethodCall(MethodCall* method_call) { 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Response> response(new Response); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->Init(dbus_message_new_method_return(method_call->raw_message())); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return response.Pass(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<Response> Response::CreateEmpty() { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Response> response(new Response); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN)); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return response.Pass(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ErrorResponse implementation. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ErrorResponse::ErrorResponse() : Response() { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ErrorResponse> ErrorResponse::FromRawMessage( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DBusMessage* raw_message) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(DBUS_MESSAGE_TYPE_ERROR, dbus_message_get_type(raw_message)); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ErrorResponse> response(new ErrorResponse); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->Init(raw_message); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return response.Pass(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ErrorResponse> ErrorResponse::FromMethodCall( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodCall* method_call, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error_name, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error_message) { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ErrorResponse> response(new ErrorResponse); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->Init(dbus_message_new_error(method_call->raw_message(), 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_name.c_str(), 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_message.c_str())); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return response.Pass(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageWriter implementation. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageWriter::MessageWriter(Message* message) : 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_(message), 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container_is_open_(false) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&raw_message_iter_, 0, sizeof(raw_message_iter_)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageWriter::~MessageWriter() { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendByte(uint8 value) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_BYTE, &value); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendBool(bool value) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The size of dbus_bool_t and the size of bool are different. The 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // former is always 4 per dbus-types.h, whereas the latter is usually 1. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_message_iter_append_basic() used in AppendBasic() expects four 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes for DBUS_TYPE_BOOLEAN, so we must pass a dbus_bool_t, instead 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of a bool, to AppendBasic(). 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_bool_t dbus_value = value; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_BOOLEAN, &dbus_value); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendInt16(int16 value) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_INT16, &value); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendUint16(uint16 value) { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_UINT16, &value); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendInt32(int32 value) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_INT32, &value); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendUint32(uint32 value) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_UINT32, &value); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendInt64(int64 value) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_INT64, &value); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendUint64(uint64 value) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_UINT64, &value); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendDouble(double value) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_DOUBLE, &value); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendString(const std::string& value) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // D-Bus Specification (0.19) says a string "must be valid UTF-8". 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(IsStringUTF8(value)); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* pointer = value.c_str(); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_STRING, &pointer); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(satorux): It may make sense to return an error here, as the 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // input string can be large. If needed, we could add something like 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bool AppendStringWithErrorChecking(). 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendObjectPath(const ObjectPath& value) { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(value.IsValid()); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* pointer = value.value().c_str(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_OBJECT_PATH, &pointer); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ideally, client shouldn't need to supply the signature string, but 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the underlying D-Bus library requires us to supply this before 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// appending contents to array and variant. It's technically possible 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for us to design API that doesn't require the signature but it will 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// complicate the implementation so we decided to have the signature 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter. Hopefully, variants are less used in request messages from 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// client side than response message from server side, so this should 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not be a big issue. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::OpenArray(const std::string& signature, 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageWriter* writer) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_open_container( 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_message_iter_, 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_TYPE_ARRAY, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.c_str(), 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &writer->raw_message_iter_); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container_is_open_ = true; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::OpenVariant(const std::string& signature, 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageWriter* writer) { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_open_container( 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_message_iter_, 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_TYPE_VARIANT, 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.c_str(), 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &writer->raw_message_iter_); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container_is_open_ = true; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::OpenStruct(MessageWriter* writer) { 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_open_container( 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_message_iter_, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_TYPE_STRUCT, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Signature should be NULL. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &writer->raw_message_iter_); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container_is_open_ = true; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::OpenDictEntry(MessageWriter* writer) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_open_container( 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_message_iter_, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_TYPE_DICT_ENTRY, 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // Signature should be NULL. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &writer->raw_message_iter_); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container_is_open_ = true; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::CloseContainer(MessageWriter* writer) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(container_is_open_); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_close_container( 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_message_iter_, &writer->raw_message_iter_); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container_is_open_ = false; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendArrayOfBytes(const uint8* values, size_t length) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageWriter array_writer(message_); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenArray("y", &array_writer); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_append_fixed_array( 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(array_writer.raw_message_iter_), 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_TYPE_BYTE, 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &values, 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(length)); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseContainer(&array_writer); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendArrayOfStrings( 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& strings) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageWriter array_writer(message_); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenArray("s", &array_writer); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < strings.size(); ++i) { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array_writer.AppendString(strings[i]); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseContainer(&array_writer); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendArrayOfObjectPaths( 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ObjectPath>& object_paths) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageWriter array_writer(message_); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenArray("o", &array_writer); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < object_paths.size(); ++i) { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array_writer.AppendObjectPath(object_paths[i]); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseContainer(&array_writer); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageWriter::AppendProtoAsArrayOfBytes( 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const google::protobuf::MessageLite& protobuf) { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string serialized_proto; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!protobuf.SerializeToString(&serialized_proto)) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Unable to serialize supplied protocol buffer"; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendArrayOfBytes(reinterpret_cast<const uint8*>(serialized_proto.data()), 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serialized_proto.size()); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfByte(uint8 value) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_BYTE, &value); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfBool(bool value) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See the comment at MessageWriter::AppendBool(). 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_bool_t dbus_value = value; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfInt16(int16 value) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_INT16, &value); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfUint16(uint16 value) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_UINT16, &value); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfInt32(int32 value) { 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_INT32, &value); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfUint32(uint32 value) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_UINT32, &value); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfInt64(int64 value) { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_INT64, &value); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfUint64(uint64 value) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_UINT64, &value); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfDouble(double value) { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_DOUBLE, &value); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfString(const std::string& value) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* pointer = value.c_str(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_STRING, &pointer); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfObjectPath(const ObjectPath& value) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* pointer = value.value().c_str(); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &pointer); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendBasic(int dbus_type, const void* value) { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!container_is_open_); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_message_iter_append_basic( 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_message_iter_, dbus_type, value); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_message_iter_append_basic() fails only when there is not enough 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // memory. We don't return this error as there is nothing we can do when 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it fails to allocate memory for a byte etc. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string signature = base::StringPrintf("%c", dbus_type); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageWriter variant_writer(message_); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenVariant(signature, &variant_writer); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) variant_writer.AppendBasic(dbus_type, value); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseContainer(&variant_writer); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageWriter::AppendFileDescriptor(const FileDescriptor& value) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(IsDBusTypeUnixFdSupported()); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.is_valid()) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NB: sending a directory potentially enables sandbox escape 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Attempt to pass invalid file descriptor"; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd = value.value(); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendBasic(DBUS_TYPE_UNIX_FD, &fd); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageReader implementation. 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageReader::MessageReader(Message* message) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : message_(message) { 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&raw_message_iter_, 0, sizeof(raw_message_iter_)); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_init(message_->raw_message(), &raw_message_iter_); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageReader::~MessageReader() { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::HasMoreData() { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_type != DBUS_TYPE_INVALID; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopByte(uint8* value) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_BYTE, value); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopBool(bool* value) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like MessageWriter::AppendBool(), we should copy |value| to 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_bool_t, as dbus_message_iter_get_basic() used in PopBasic() 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expects four bytes for DBUS_TYPE_BOOLEAN. 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_bool_t dbus_value = FALSE; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopBasic(DBUS_TYPE_BOOLEAN, &dbus_value); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = static_cast<bool>(dbus_value); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopInt16(int16* value) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_INT16, value); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopUint16(uint16* value) { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_UINT16, value); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopInt32(int32* value) { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_INT32, value); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopUint32(uint32* value) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_UINT32, value); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopInt64(int64* value) { 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_INT64, value); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopUint64(uint64* value) { 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_UINT64, value); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopDouble(double* value) { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopBasic(DBUS_TYPE_DOUBLE, value); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopString(std::string* value) { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* tmp_value = NULL; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->assign(tmp_value); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopObjectPath(ObjectPath* value) { 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* tmp_value = NULL; 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = ObjectPath(tmp_value); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopArray(MessageReader* sub_reader) { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopContainer(DBUS_TYPE_ARRAY, sub_reader); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopStruct(MessageReader* sub_reader) { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopContainer(DBUS_TYPE_STRUCT, sub_reader); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopDictEntry(MessageReader* sub_reader) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariant(MessageReader* sub_reader) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopContainer(DBUS_TYPE_VARIANT, sub_reader); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopArrayOfBytes(uint8** bytes, size_t* length) { 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader array_reader(message_); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PopArray(&array_reader)) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An empty array is allowed. 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!array_reader.HasMoreData()) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = 0; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes = NULL; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!array_reader.CheckDataType(DBUS_TYPE_BYTE)) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int int_length = 0; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes, 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &int_length); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = static_cast<int>(int_length); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopArrayOfStrings( 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> *strings) { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader array_reader(message_); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PopArray(&array_reader)) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (array_reader.HasMoreData()) { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string string; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!array_reader.PopString(&string)) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings->push_back(string); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopArrayOfObjectPaths( 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ObjectPath> *object_paths) { 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageReader array_reader(message_); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PopArray(&array_reader)) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (array_reader.HasMoreData()) { 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectPath object_path; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!array_reader.PopObjectPath(&object_path)) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_paths->push_back(object_path); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopArrayOfBytesAsProto( 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::MessageLite* protobuf) { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(protobuf != NULL); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* serialized_buf = NULL; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t buf_size = 0; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PopArrayOfBytes(reinterpret_cast<uint8**>(&serialized_buf), &buf_size)) { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error reading array of bytes"; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!protobuf->ParseFromArray(serialized_buf, buf_size)) { 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to parse protocol buffer from array"; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfByte(uint8* value) { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_BYTE, value); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfBool(bool* value) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See the comment at MessageReader::PopBool(). 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_bool_t dbus_value = FALSE; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = static_cast<bool>(dbus_value); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfInt16(int16* value) { 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_INT16, value); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfUint16(uint16* value) { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_UINT16, value); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfInt32(int32* value) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_INT32, value); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfUint32(uint32* value) { 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_UINT32, value); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfInt64(int64* value) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_INT64, value); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfUint64(uint64* value) { 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_UINT64, value); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfDouble(double* value) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfString(std::string* value) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* tmp_value = NULL; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->assign(tmp_value); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfObjectPath(ObjectPath* value) { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* tmp_value = NULL; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = ObjectPath(tmp_value); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::DataType MessageReader::GetDataType() { 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<Message::DataType>(dbus_type); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::CheckDataType(int dbus_type) { 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (actual_type != dbus_type) { 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Type " << dbus_type << " is expected but got " 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << actual_type; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopBasic(int dbus_type, void* value) { 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CheckDataType(dbus_type)) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_message_iter_get_basic() here should always work, as we have 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already checked the next item's data type in CheckDataType(). Note 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that dbus_message_iter_get_basic() is a void function. 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_get_basic(&raw_message_iter_, value); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(value); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_next(&raw_message_iter_); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) { 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(this, sub_reader); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CheckDataType(dbus_type)) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_recurse(&raw_message_iter_, 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sub_reader->raw_message_iter_); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_iter_next(&raw_message_iter_); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) { 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageReader variant_reader(message_); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PopVariant(&variant_reader)) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return variant_reader.PopBasic(dbus_type, value); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageReader::PopFileDescriptor(FileDescriptor* value) { 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(IsDBusTypeUnixFdSupported()); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd = -1; 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = PopBasic(DBUS_TYPE_UNIX_FD, &fd); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->PutValue(fd); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NB: the caller must check validity before using the value 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace dbus 989