// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "dbus/message.h"

#include <string>

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "dbus/object_path.h"
#include "third_party/protobuf/src/google/protobuf/message_lite.h"

namespace {

// Appends the header name and the value to |output|, if the value is
// not empty.
void AppendStringHeader(const std::string& header_name,
                        const std::string& header_value,
                        std::string* output) {
  if (!header_value.empty()) {
    *output += header_name + ": " + header_value + "\n";
  }
}

// Appends the header name and the value to |output|, if the value is
// nonzero.
void AppendUint32Header(const std::string& header_name,
                        uint32_t header_value,
                        std::string* output) {
  if (header_value != 0) {
    *output += (header_name + ": " + base::UintToString(header_value) + "\n");
  }
}

}  // namespace

namespace dbus {

bool IsDBusTypeUnixFdSupported() {
  int major = 0, minor = 0, micro = 0;
  dbus_get_version(&major, &minor, &micro);
  return major >= 1 && minor >= 4;
}

Message::Message() : raw_message_(nullptr) {}

Message::~Message() {
  if (raw_message_)
    dbus_message_unref(raw_message_);
}

void Message::Init(DBusMessage* raw_message) {
  DCHECK(!raw_message_);
  raw_message_ = raw_message;
}

Message::MessageType Message::GetMessageType() {
  if (!raw_message_)
    return MESSAGE_INVALID;
  const int type = dbus_message_get_type(raw_message_);
  return static_cast<Message::MessageType>(type);
}

std::string Message::GetMessageTypeAsString() {
  switch (GetMessageType()) {
    case MESSAGE_INVALID:
      return "MESSAGE_INVALID";
    case MESSAGE_METHOD_CALL:
      return "MESSAGE_METHOD_CALL";
    case MESSAGE_METHOD_RETURN:
      return "MESSAGE_METHOD_RETURN";
    case MESSAGE_SIGNAL:
      return "MESSAGE_SIGNAL";
    case MESSAGE_ERROR:
      return "MESSAGE_ERROR";
  }
  NOTREACHED();
  return std::string();
}

std::string Message::ToStringInternal(const std::string& indent,
                                      MessageReader* reader) {
  const char* kBrokenMessage = "[broken message]";
  std::string output;
  while (reader->HasMoreData()) {
    const DataType type = reader->GetDataType();
    switch (type) {
      case BYTE: {
        uint8_t value = 0;
        if (!reader->PopByte(&value))
          return kBrokenMessage;
        output += indent + "byte " + base::UintToString(value) + "\n";
        break;
      }
      case BOOL: {
        bool value = false;
        if (!reader->PopBool(&value))
          return kBrokenMessage;
        output += indent + "bool " + (value ? "true" : "false") + "\n";
        break;
      }
      case INT16: {
        int16_t value = 0;
        if (!reader->PopInt16(&value))
          return kBrokenMessage;
        output += indent + "int16_t " + base::IntToString(value) + "\n";
        break;
      }
      case UINT16: {
        uint16_t value = 0;
        if (!reader->PopUint16(&value))
          return kBrokenMessage;
        output += indent + "uint16_t " + base::UintToString(value) + "\n";
        break;
      }
      case INT32: {
        int32_t value = 0;
        if (!reader->PopInt32(&value))
          return kBrokenMessage;
        output += indent + "int32_t " + base::IntToString(value) + "\n";
        break;
      }
      case UINT32: {
        uint32_t value = 0;
        if (!reader->PopUint32(&value))
          return kBrokenMessage;
        output += indent + "uint32_t " + base::UintToString(value) + "\n";
        break;
      }
      case INT64: {
        int64_t value = 0;
        if (!reader->PopInt64(&value))
          return kBrokenMessage;
        output += (indent + "int64_t " + base::Int64ToString(value) + "\n");
        break;
      }
      case UINT64: {
        uint64_t value = 0;
        if (!reader->PopUint64(&value))
          return kBrokenMessage;
        output += (indent + "uint64_t " + base::NumberToString(value) + "\n");
        break;
      }
      case DOUBLE: {
        double value = 0;
        if (!reader->PopDouble(&value))
          return kBrokenMessage;
        output += indent + "double " + base::NumberToString(value) + "\n";
        break;
      }
      case STRING: {
        std::string value;
        if (!reader->PopString(&value))
          return kBrokenMessage;
        // Truncate if the string is longer than the limit.
        const size_t kTruncateLength = 100;
        if (value.size() < kTruncateLength) {
          output += indent + "string \"" + value + "\"\n";
        } else {
          std::string truncated;
          base::TruncateUTF8ToByteSize(value, kTruncateLength, &truncated);
          base::StringAppendF(&truncated, "... (%" PRIuS " bytes in total)",
                              value.size());
          output += indent + "string \"" + truncated + "\"\n";
        }
        break;
      }
      case OBJECT_PATH: {
        ObjectPath value;
        if (!reader->PopObjectPath(&value))
          return kBrokenMessage;
        output += indent + "object_path \"" + value.value() + "\"\n";
        break;
      }
      case ARRAY: {
        MessageReader sub_reader(this);
        if (!reader->PopArray(&sub_reader))
          return kBrokenMessage;
        output += indent + "array [\n";
        output += ToStringInternal(indent + "  ", &sub_reader);
        output += indent + "]\n";
        break;
      }
      case STRUCT: {
        MessageReader sub_reader(this);
        if (!reader->PopStruct(&sub_reader))
          return kBrokenMessage;
        output += indent + "struct {\n";
        output += ToStringInternal(indent + "  ", &sub_reader);
        output += indent + "}\n";
        break;
      }
      case DICT_ENTRY: {
        MessageReader sub_reader(this);
        if (!reader->PopDictEntry(&sub_reader))
          return kBrokenMessage;
        output += indent + "dict entry {\n";
        output += ToStringInternal(indent + "  ", &sub_reader);
        output += indent + "}\n";
        break;
      }
      case VARIANT: {
        MessageReader sub_reader(this);
        if (!reader->PopVariant(&sub_reader))
          return kBrokenMessage;
        output += indent + "variant ";
        output += ToStringInternal(indent + "  ", &sub_reader);
        break;
      }
      case UNIX_FD: {
        CHECK(IsDBusTypeUnixFdSupported());

        base::ScopedFD file_descriptor;
        if (!reader->PopFileDescriptor(&file_descriptor))
          return kBrokenMessage;
        output +=
            indent + "fd#" + base::IntToString(file_descriptor.get()) + "\n";
        break;
      }
      default:
        LOG(FATAL) << "Unknown type: " << type;
    }
  }
  return output;
}

// The returned string consists of message headers such as
// destination if any, followed by a blank line, and the message
// payload. For example, a MethodCall's ToString() will look like:
//
// destination: com.example.Service
// path: /com/example/Object
// interface: com.example.Interface
// member: SomeMethod
//
// string \"payload\"
// ...
std::string Message::ToString() {
  if (!raw_message_)
    return std::string();

  // Generate headers first.
  std::string headers;
  AppendStringHeader("message_type", GetMessageTypeAsString(), &headers);
  AppendStringHeader("destination", GetDestination(), &headers);
  AppendStringHeader("path", GetPath().value(), &headers);
  AppendStringHeader("interface", GetInterface(), &headers);
  AppendStringHeader("member", GetMember(), &headers);
  AppendStringHeader("error_name", GetErrorName(), &headers);
  AppendStringHeader("sender", GetSender(), &headers);
  AppendStringHeader("signature", GetSignature(), &headers);
  AppendUint32Header("serial", GetSerial(), &headers);
  AppendUint32Header("reply_serial", GetReplySerial(), &headers);

  // Generate the payload.
  MessageReader reader(this);
  return headers + "\n" + ToStringInternal(std::string(), &reader);
}

bool Message::SetDestination(const std::string& destination) {
  return dbus_message_set_destination(raw_message_, destination.c_str());
}

bool Message::SetPath(const ObjectPath& path) {
  return dbus_message_set_path(raw_message_, path.value().c_str());
}

bool Message::SetInterface(const std::string& interface) {
  return dbus_message_set_interface(raw_message_, interface.c_str());
}

bool Message::SetMember(const std::string& member) {
  return dbus_message_set_member(raw_message_, member.c_str());
}

bool Message::SetErrorName(const std::string& error_name) {
  return dbus_message_set_error_name(raw_message_, error_name.c_str());
}

bool Message::SetSender(const std::string& sender) {
  return dbus_message_set_sender(raw_message_, sender.c_str());
}

void Message::SetSerial(uint32_t serial) {
  dbus_message_set_serial(raw_message_, serial);
}

void Message::SetReplySerial(uint32_t reply_serial) {
  dbus_message_set_reply_serial(raw_message_, reply_serial);
}

std::string Message::GetDestination() {
  const char* destination = dbus_message_get_destination(raw_message_);
  return destination ? destination : "";
}

ObjectPath Message::GetPath() {
  const char* path = dbus_message_get_path(raw_message_);
  return ObjectPath(path ? path : "");
}

std::string Message::GetInterface() {
  const char* interface = dbus_message_get_interface(raw_message_);
  return interface ? interface : "";
}

std::string Message::GetMember() {
  const char* member = dbus_message_get_member(raw_message_);
  return member ? member : "";
}

std::string Message::GetErrorName() {
  const char* error_name = dbus_message_get_error_name(raw_message_);
  return error_name ? error_name : "";
}

std::string Message::GetSender() {
  const char* sender = dbus_message_get_sender(raw_message_);
  return sender ? sender : "";
}

std::string Message::GetSignature() {
  const char* signature = dbus_message_get_signature(raw_message_);
  return signature ? signature : "";
}

uint32_t Message::GetSerial() {
  return dbus_message_get_serial(raw_message_);
}

uint32_t Message::GetReplySerial() {
  return dbus_message_get_reply_serial(raw_message_);
}

//
// MethodCall implementation.
//

MethodCall::MethodCall(const std::string& interface_name,
                       const std::string& method_name) {
  Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL));

  CHECK(SetInterface(interface_name));
  CHECK(SetMember(method_name));
}

MethodCall::MethodCall() = default;

std::unique_ptr<MethodCall> MethodCall::FromRawMessage(
    DBusMessage* raw_message) {
  DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message));

  std::unique_ptr<MethodCall> method_call(new MethodCall());
  method_call->Init(raw_message);
  return method_call;
}

//
// Signal implementation.
//
Signal::Signal(const std::string& interface_name,
               const std::string& method_name) {
  Init(dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL));

  CHECK(SetInterface(interface_name));
  CHECK(SetMember(method_name));
}

Signal::Signal() = default;

std::unique_ptr<Signal> Signal::FromRawMessage(DBusMessage* raw_message) {
  DCHECK_EQ(DBUS_MESSAGE_TYPE_SIGNAL, dbus_message_get_type(raw_message));

  std::unique_ptr<Signal> signal(new Signal());
  signal->Init(raw_message);
  return signal;
}

//
// Response implementation.
//

Response::Response() = default;

std::unique_ptr<Response> Response::FromRawMessage(DBusMessage* raw_message) {
  DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_RETURN,
            dbus_message_get_type(raw_message));

  std::unique_ptr<Response> response(new Response());
  response->Init(raw_message);
  return response;
}

std::unique_ptr<Response> Response::FromMethodCall(MethodCall* method_call) {
  std::unique_ptr<Response> response(new Response());
  response->Init(dbus_message_new_method_return(method_call->raw_message()));
  return response;
}

std::unique_ptr<Response> Response::CreateEmpty() {
  std::unique_ptr<Response> response(new Response());
  response->Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN));
  return response;
}

//
// ErrorResponse implementation.
//

ErrorResponse::ErrorResponse() = default;

std::unique_ptr<ErrorResponse> ErrorResponse::FromRawMessage(
    DBusMessage* raw_message) {
  DCHECK_EQ(DBUS_MESSAGE_TYPE_ERROR, dbus_message_get_type(raw_message));

  std::unique_ptr<ErrorResponse> response(new ErrorResponse());
  response->Init(raw_message);
  return response;
}

std::unique_ptr<ErrorResponse> ErrorResponse::FromMethodCall(
    MethodCall* method_call,
    const std::string& error_name,
    const std::string& error_message) {
  std::unique_ptr<ErrorResponse> response(new ErrorResponse());
  response->Init(dbus_message_new_error(
      method_call->raw_message(), error_name.c_str(), error_message.c_str()));
  return response;
}

//
// MessageWriter implementation.
//

MessageWriter::MessageWriter(Message* message)
    : message_(message), container_is_open_(false) {
  memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
  if (message)
    dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_);
}

MessageWriter::~MessageWriter() = default;

void MessageWriter::AppendByte(uint8_t value) {
  AppendBasic(DBUS_TYPE_BYTE, &value);
}

void MessageWriter::AppendBool(bool value) {
  // The size of dbus_bool_t and the size of bool are different. The
  // former is always 4 per dbus-types.h, whereas the latter is usually 1.
  // dbus_message_iter_append_basic() used in AppendBasic() expects four
  // bytes for DBUS_TYPE_BOOLEAN, so we must pass a dbus_bool_t, instead
  // of a bool, to AppendBasic().
  dbus_bool_t dbus_value = value ? 1 : 0;
  AppendBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
}

void MessageWriter::AppendInt16(int16_t value) {
  AppendBasic(DBUS_TYPE_INT16, &value);
}

void MessageWriter::AppendUint16(uint16_t value) {
  AppendBasic(DBUS_TYPE_UINT16, &value);
}

void MessageWriter::AppendInt32(int32_t value) {
  AppendBasic(DBUS_TYPE_INT32, &value);
}

void MessageWriter::AppendUint32(uint32_t value) {
  AppendBasic(DBUS_TYPE_UINT32, &value);
}

void MessageWriter::AppendInt64(int64_t value) {
  AppendBasic(DBUS_TYPE_INT64, &value);
}

void MessageWriter::AppendUint64(uint64_t value) {
  AppendBasic(DBUS_TYPE_UINT64, &value);
}

void MessageWriter::AppendDouble(double value) {
  AppendBasic(DBUS_TYPE_DOUBLE, &value);
}

void MessageWriter::AppendString(const std::string& value) {
  // D-Bus Specification (0.19) says a string "must be valid UTF-8".
  CHECK(base::IsStringUTF8(value));
  const char* pointer = value.c_str();
  AppendBasic(DBUS_TYPE_STRING, &pointer);
  // TODO(satorux): It may make sense to return an error here, as the
  // input string can be large. If needed, we could add something like
  // bool AppendStringWithErrorChecking().
}

void MessageWriter::AppendObjectPath(const ObjectPath& value) {
  CHECK(value.IsValid());
  const char* pointer = value.value().c_str();
  AppendBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
}

// Ideally, client shouldn't need to supply the signature string, but
// the underlying D-Bus library requires us to supply this before
// appending contents to array and variant. It's technically possible
// for us to design API that doesn't require the signature but it will
// complicate the implementation so we decided to have the signature
// parameter. Hopefully, variants are less used in request messages from
// client side than response message from server side, so this should
// not be a big issue.
void MessageWriter::OpenArray(const std::string& signature,
                              MessageWriter* writer) {
  DCHECK(!container_is_open_);

  const bool success = dbus_message_iter_open_container(
      &raw_message_iter_, DBUS_TYPE_ARRAY, signature.c_str(),
      &writer->raw_message_iter_);
  CHECK(success) << "Unable to allocate memory";
  container_is_open_ = true;
}

void MessageWriter::OpenVariant(const std::string& signature,
                                MessageWriter* writer) {
  DCHECK(!container_is_open_);

  const bool success = dbus_message_iter_open_container(
      &raw_message_iter_, DBUS_TYPE_VARIANT, signature.c_str(),
      &writer->raw_message_iter_);
  CHECK(success) << "Unable to allocate memory";
  container_is_open_ = true;
}

void MessageWriter::OpenStruct(MessageWriter* writer) {
  DCHECK(!container_is_open_);

  const bool success =
      dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_STRUCT,
                                       nullptr,  // Signature should be nullptr.
                                       &writer->raw_message_iter_);
  CHECK(success) << "Unable to allocate memory";
  container_is_open_ = true;
}

void MessageWriter::OpenDictEntry(MessageWriter* writer) {
  DCHECK(!container_is_open_);

  const bool success =
      dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_DICT_ENTRY,
                                       nullptr,  // Signature should be nullptr.
                                       &writer->raw_message_iter_);
  CHECK(success) << "Unable to allocate memory";
  container_is_open_ = true;
}

void MessageWriter::CloseContainer(MessageWriter* writer) {
  DCHECK(container_is_open_);

  const bool success = dbus_message_iter_close_container(
      &raw_message_iter_, &writer->raw_message_iter_);
  CHECK(success) << "Unable to allocate memory";
  container_is_open_ = false;
}

void MessageWriter::AppendArrayOfBytes(const uint8_t* values, size_t length) {
  DCHECK(!container_is_open_);
  MessageWriter array_writer(message_);
  OpenArray("y", &array_writer);
  const bool success = dbus_message_iter_append_fixed_array(
      &(array_writer.raw_message_iter_), DBUS_TYPE_BYTE, &values,
      static_cast<int>(length));
  CHECK(success) << "Unable to allocate memory";
  CloseContainer(&array_writer);
}

void MessageWriter::AppendArrayOfDoubles(const double* values, size_t length) {
  DCHECK(!container_is_open_);
  MessageWriter array_writer(message_);
  OpenArray("d", &array_writer);
  const bool success = dbus_message_iter_append_fixed_array(
      &(array_writer.raw_message_iter_), DBUS_TYPE_DOUBLE, &values,
      static_cast<int>(length));
  CHECK(success) << "Unable to allocate memory";
  CloseContainer(&array_writer);
}

void MessageWriter::AppendArrayOfStrings(
    const std::vector<std::string>& strings) {
  DCHECK(!container_is_open_);
  MessageWriter array_writer(message_);
  OpenArray("s", &array_writer);
  for (size_t i = 0; i < strings.size(); ++i) {
    array_writer.AppendString(strings[i]);
  }
  CloseContainer(&array_writer);
}

void MessageWriter::AppendArrayOfObjectPaths(
    const std::vector<ObjectPath>& object_paths) {
  DCHECK(!container_is_open_);
  MessageWriter array_writer(message_);
  OpenArray("o", &array_writer);
  for (size_t i = 0; i < object_paths.size(); ++i) {
    array_writer.AppendObjectPath(object_paths[i]);
  }
  CloseContainer(&array_writer);
}

bool MessageWriter::AppendProtoAsArrayOfBytes(
    const google::protobuf::MessageLite& protobuf) {
  std::string serialized_proto;
  if (!protobuf.SerializeToString(&serialized_proto)) {
    LOG(ERROR) << "Unable to serialize supplied protocol buffer";
    return false;
  }
  AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(serialized_proto.data()),
                     serialized_proto.size());
  return true;
}

void MessageWriter::AppendVariantOfByte(uint8_t value) {
  AppendVariantOfBasic(DBUS_TYPE_BYTE, &value);
}

void MessageWriter::AppendVariantOfBool(bool value) {
  // See the comment at MessageWriter::AppendBool().
  dbus_bool_t dbus_value = value;
  AppendVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
}

void MessageWriter::AppendVariantOfInt16(int16_t value) {
  AppendVariantOfBasic(DBUS_TYPE_INT16, &value);
}

void MessageWriter::AppendVariantOfUint16(uint16_t value) {
  AppendVariantOfBasic(DBUS_TYPE_UINT16, &value);
}

void MessageWriter::AppendVariantOfInt32(int32_t value) {
  AppendVariantOfBasic(DBUS_TYPE_INT32, &value);
}

void MessageWriter::AppendVariantOfUint32(uint32_t value) {
  AppendVariantOfBasic(DBUS_TYPE_UINT32, &value);
}

void MessageWriter::AppendVariantOfInt64(int64_t value) {
  AppendVariantOfBasic(DBUS_TYPE_INT64, &value);
}

void MessageWriter::AppendVariantOfUint64(uint64_t value) {
  AppendVariantOfBasic(DBUS_TYPE_UINT64, &value);
}

void MessageWriter::AppendVariantOfDouble(double value) {
  AppendVariantOfBasic(DBUS_TYPE_DOUBLE, &value);
}

void MessageWriter::AppendVariantOfString(const std::string& value) {
  const char* pointer = value.c_str();
  AppendVariantOfBasic(DBUS_TYPE_STRING, &pointer);
}

void MessageWriter::AppendVariantOfObjectPath(const ObjectPath& value) {
  const char* pointer = value.value().c_str();
  AppendVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
}

void MessageWriter::AppendBasic(int dbus_type, const void* value) {
  DCHECK(!container_is_open_);

  const bool success =
      dbus_message_iter_append_basic(&raw_message_iter_, dbus_type, value);
  // dbus_message_iter_append_basic() fails only when there is not enough
  // memory. We don't return this error as there is nothing we can do when
  // it fails to allocate memory for a byte etc.
  CHECK(success) << "Unable to allocate memory";
}

void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) {
  const std::string signature(1u,  // length
                              base::checked_cast<char>(dbus_type));
  MessageWriter variant_writer(message_);
  OpenVariant(signature, &variant_writer);
  variant_writer.AppendBasic(dbus_type, value);
  CloseContainer(&variant_writer);
}

void MessageWriter::AppendFileDescriptor(int value) {
  CHECK(IsDBusTypeUnixFdSupported());
  AppendBasic(DBUS_TYPE_UNIX_FD, &value);  // This duplicates the FD.
}

//
// MessageReader implementation.
//

MessageReader::MessageReader(Message* message) : message_(message) {
  memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
  if (message)
    dbus_message_iter_init(message_->raw_message(), &raw_message_iter_);
}

MessageReader::~MessageReader() = default;

bool MessageReader::HasMoreData() {
  const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
  return dbus_type != DBUS_TYPE_INVALID;
}

bool MessageReader::PopByte(uint8_t* value) {
  return PopBasic(DBUS_TYPE_BYTE, value);
}

bool MessageReader::PopBool(bool* value) {
  // Like MessageWriter::AppendBool(), we should copy |value| to
  // dbus_bool_t, as dbus_message_iter_get_basic() used in PopBasic()
  // expects four bytes for DBUS_TYPE_BOOLEAN.
  dbus_bool_t dbus_value = FALSE;
  const bool success = PopBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
  *value = static_cast<bool>(dbus_value);
  return success;
}

bool MessageReader::PopInt16(int16_t* value) {
  return PopBasic(DBUS_TYPE_INT16, value);
}

bool MessageReader::PopUint16(uint16_t* value) {
  return PopBasic(DBUS_TYPE_UINT16, value);
}

bool MessageReader::PopInt32(int32_t* value) {
  return PopBasic(DBUS_TYPE_INT32, value);
}

bool MessageReader::PopUint32(uint32_t* value) {
  return PopBasic(DBUS_TYPE_UINT32, value);
}

bool MessageReader::PopInt64(int64_t* value) {
  return PopBasic(DBUS_TYPE_INT64, value);
}

bool MessageReader::PopUint64(uint64_t* value) {
  return PopBasic(DBUS_TYPE_UINT64, value);
}

bool MessageReader::PopDouble(double* value) {
  return PopBasic(DBUS_TYPE_DOUBLE, value);
}

bool MessageReader::PopString(std::string* value) {
  char* tmp_value = nullptr;
  const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value);
  if (success)
    value->assign(tmp_value);
  return success;
}

bool MessageReader::PopObjectPath(ObjectPath* value) {
  char* tmp_value = nullptr;
  const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
  if (success)
    *value = ObjectPath(tmp_value);
  return success;
}

bool MessageReader::PopArray(MessageReader* sub_reader) {
  return PopContainer(DBUS_TYPE_ARRAY, sub_reader);
}

bool MessageReader::PopStruct(MessageReader* sub_reader) {
  return PopContainer(DBUS_TYPE_STRUCT, sub_reader);
}

bool MessageReader::PopDictEntry(MessageReader* sub_reader) {
  return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader);
}

bool MessageReader::PopVariant(MessageReader* sub_reader) {
  return PopContainer(DBUS_TYPE_VARIANT, sub_reader);
}

bool MessageReader::PopArrayOfBytes(const uint8_t** bytes, size_t* length) {
  MessageReader array_reader(message_);
  if (!PopArray(&array_reader))
    return false;
  // An empty array is allowed.
  if (!array_reader.HasMoreData()) {
    *length = 0;
    *bytes = nullptr;
    return true;
  }
  if (!array_reader.CheckDataType(DBUS_TYPE_BYTE))
    return false;
  int int_length = 0;
  dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, bytes,
                                    &int_length);
  *length = static_cast<size_t>(int_length);
  return true;
}

bool MessageReader::PopArrayOfDoubles(const double** doubles, size_t* length) {
  MessageReader array_reader(message_);
  if (!PopArray(&array_reader))
    return false;
  if (!array_reader.HasMoreData()) {
    *length = 0;
    *doubles = nullptr;
    return true;
  }
  if (!array_reader.CheckDataType(DBUS_TYPE_DOUBLE))
    return false;
  int int_length = 0;
  dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, doubles,
                                    &int_length);
  *length = static_cast<size_t>(int_length);
  return true;
}

bool MessageReader::PopArrayOfStrings(std::vector<std::string>* strings) {
  strings->clear();
  MessageReader array_reader(message_);
  if (!PopArray(&array_reader))
    return false;
  while (array_reader.HasMoreData()) {
    std::string string;
    if (!array_reader.PopString(&string))
      return false;
    strings->push_back(string);
  }
  return true;
}

bool MessageReader::PopArrayOfObjectPaths(
    std::vector<ObjectPath>* object_paths) {
  object_paths->clear();
  MessageReader array_reader(message_);
  if (!PopArray(&array_reader))
    return false;
  while (array_reader.HasMoreData()) {
    ObjectPath object_path;
    if (!array_reader.PopObjectPath(&object_path))
      return false;
    object_paths->push_back(object_path);
  }
  return true;
}

bool MessageReader::PopArrayOfBytesAsProto(
    google::protobuf::MessageLite* protobuf) {
  DCHECK(protobuf);
  const char* serialized_buf = nullptr;
  size_t buf_size = 0;
  if (!PopArrayOfBytes(reinterpret_cast<const uint8_t**>(&serialized_buf),
                       &buf_size)) {
    LOG(ERROR) << "Error reading array of bytes";
    return false;
  }
  if (!protobuf->ParseFromArray(serialized_buf, buf_size)) {
    LOG(ERROR) << "Failed to parse protocol buffer from array";
    return false;
  }
  return true;
}

bool MessageReader::PopVariantOfByte(uint8_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_BYTE, value);
}

bool MessageReader::PopVariantOfBool(bool* value) {
  // See the comment at MessageReader::PopBool().
  dbus_bool_t dbus_value = FALSE;
  const bool success = PopVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
  *value = static_cast<bool>(dbus_value);
  return success;
}

bool MessageReader::PopVariantOfInt16(int16_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_INT16, value);
}

bool MessageReader::PopVariantOfUint16(uint16_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_UINT16, value);
}

bool MessageReader::PopVariantOfInt32(int32_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_INT32, value);
}

bool MessageReader::PopVariantOfUint32(uint32_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_UINT32, value);
}

bool MessageReader::PopVariantOfInt64(int64_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_INT64, value);
}

bool MessageReader::PopVariantOfUint64(uint64_t* value) {
  return PopVariantOfBasic(DBUS_TYPE_UINT64, value);
}

bool MessageReader::PopVariantOfDouble(double* value) {
  return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value);
}

bool MessageReader::PopVariantOfString(std::string* value) {
  char* tmp_value = nullptr;
  const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value);
  if (success)
    value->assign(tmp_value);
  return success;
}

bool MessageReader::PopVariantOfObjectPath(ObjectPath* value) {
  char* tmp_value = nullptr;
  const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
  if (success)
    *value = ObjectPath(tmp_value);
  return success;
}

Message::DataType MessageReader::GetDataType() {
  const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
  return static_cast<Message::DataType>(dbus_type);
}

std::string MessageReader::GetDataSignature() {
  std::string signature;
  char* raw_signature = dbus_message_iter_get_signature(&raw_message_iter_);
  if (raw_signature) {
    signature = raw_signature;
    dbus_free(raw_signature);
  }
  return signature;
}

bool MessageReader::CheckDataType(int dbus_type) {
  const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
  if (actual_type != dbus_type) {
    VLOG(1) << "Type " << dbus_type << " is expected but got " << actual_type;
    return false;
  }
  return true;
}

bool MessageReader::PopBasic(int dbus_type, void* value) {
  if (!CheckDataType(dbus_type))
    return false;
  // dbus_message_iter_get_basic() here should always work, as we have
  // already checked the next item's data type in CheckDataType(). Note
  // that dbus_message_iter_get_basic() is a void function.
  dbus_message_iter_get_basic(&raw_message_iter_, value);
  DCHECK(value);
  dbus_message_iter_next(&raw_message_iter_);
  return true;
}

bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) {
  DCHECK_NE(this, sub_reader);

  if (!CheckDataType(dbus_type))
    return false;
  dbus_message_iter_recurse(&raw_message_iter_, &sub_reader->raw_message_iter_);
  dbus_message_iter_next(&raw_message_iter_);
  return true;
}

bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) {
  MessageReader variant_reader(message_);
  if (!PopVariant(&variant_reader))
    return false;
  return variant_reader.PopBasic(dbus_type, value);
}

bool MessageReader::PopFileDescriptor(base::ScopedFD* value) {
  CHECK(IsDBusTypeUnixFdSupported());

  int fd = -1;
  const bool success = PopBasic(DBUS_TYPE_UNIX_FD, &fd);
  if (!success)
    return false;

  *value = base::ScopedFD(fd);
  return true;
}

}  // namespace dbus
