blob: d1c082df23f9a938b5760dd88c2d63c8b0b293d4 [file] [log] [blame]
// Copyright (c) 2011 The Chromium OS 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 <map>
#include <string>
#include <vector>
#include <base/logging.h>
#include <dbus-c++/dbus.h>
#include "shill/accessor_interface.h"
#include "shill/dbus_adaptor.h"
#include "shill/error.h"
#include "shill/key_value_store.h"
#include "shill/property_store.h"
using std::map;
using std::string;
using std::vector;
namespace shill {
// static
const char DBusAdaptor::kPathArraySig[] = "ao";
// static
const char DBusAdaptor::kStringmapSig[] = "a{ss}";
// static
const char DBusAdaptor::kStringmapsSig[] = "aa{ss}";
// static
const char DBusAdaptor::kStringsSig[] = "as";
DBusAdaptor::DBusAdaptor(DBus::Connection* conn, const string &object_path)
: DBus::ObjectAdaptor(*conn, object_path) {
VLOG(2) << "DBusAdaptor: " << object_path;
}
DBusAdaptor::~DBusAdaptor() {}
// static
bool DBusAdaptor::DispatchOnType(PropertyStore *store,
const string &name,
const ::DBus::Variant &value,
::DBus::Error *error) {
bool set = false;
Error e(Error::kInvalidArguments, "Could not write " + name);
if (DBusAdaptor::IsBool(value.signature()))
set = store->SetBoolProperty(name, value.reader().get_bool(), &e);
else if (DBusAdaptor::IsByte(value.signature()))
set = store->SetUint8Property(name, value.reader().get_byte(), &e);
else if (DBusAdaptor::IsInt16(value.signature()))
set = store->SetInt16Property(name, value.reader().get_int16(), &e);
else if (DBusAdaptor::IsInt32(value.signature()))
set = store->SetInt32Property(name, value.reader().get_int32(), &e);
else if (DBusAdaptor::IsPath(value.signature()))
set = store->SetStringProperty(name, value.reader().get_path(), &e);
else if (DBusAdaptor::IsString(value.signature()))
set = store->SetStringProperty(name, value.reader().get_string(), &e);
else if (DBusAdaptor::IsStringmap(value.signature()))
set = store->SetStringmapProperty(name,
value.operator map<string, string>(),
&e);
else if (DBusAdaptor::IsStringmaps(value.signature()))
VLOG(1) << " can't yet handle setting type " << value.signature();
else if (DBusAdaptor::IsStrings(value.signature()))
set = store->SetStringsProperty(name, value.operator vector<string>(), &e);
else if (DBusAdaptor::IsUint16(value.signature()))
set = store->SetUint16Property(name, value.reader().get_uint16(), &e);
else if (DBusAdaptor::IsUint32(value.signature()))
set = store->SetUint32Property(name, value.reader().get_uint32(), &e);
else
NOTREACHED() << " unknown type: " << value.signature();
if (!set && error) {
if (!store->Contains(name))
Error(Error::kInvalidProperty, name + " is invalid.").ToDBusError(error);
else
e.ToDBusError(error);
}
return set;
}
// static
bool DBusAdaptor::GetProperties(const PropertyStore &store,
map<string, ::DBus::Variant> *out,
::DBus::Error */*error*/) {
{
PropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = BoolToVariant(it.Value());
}
{
PropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = Int16ToVariant(it.Value());
}
{
PropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = Int32ToVariant(it.Value());
}
{
PropertyConstIterator<string> it = store.GetStringPropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = StringToVariant(it.Value());
}
{
PropertyConstIterator<Stringmap> it = store.GetStringmapPropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = StringmapToVariant(it.Value());
}
{
PropertyConstIterator<Strings> it = store.GetStringsPropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = StringsToVariant(it.Value());
}
{
PropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = ByteToVariant(it.Value());
}
{
PropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = Uint16ToVariant(it.Value());
}
{
PropertyConstIterator<uint32> it = store.GetUint32PropertiesIter();
for ( ; !it.AtEnd(); it.Advance())
(*out)[it.Key()] = Uint32ToVariant(it.Value());
}
return true;
}
// static
void DBusAdaptor::ArgsToKeyValueStore(
const map<string, ::DBus::Variant> &args,
KeyValueStore *out,
Error *error) { // XXX should be ::DBus::Error?
for (map<string, ::DBus::Variant>::const_iterator it = args.begin();
it != args.end();
++it) {
DBus::type<string> string_type;
DBus::type<bool> bool_type;
if (it->second.signature() == string_type.sig()) {
out->SetString(it->first, it->second.reader().get_string());
} else if (it->second.signature() == bool_type.sig()) {
out->SetBool(it->first, it->second.reader().get_bool());
} else {
error->Populate(Error::kInternalError);
return; // skip remaining args after error
}
}
}
// static
::DBus::Variant DBusAdaptor::BoolToVariant(bool value) {
::DBus::Variant v;
v.writer().append_bool(value);
return v;
}
// static
::DBus::Variant DBusAdaptor::ByteToVariant(uint8 value) {
::DBus::Variant v;
v.writer().append_byte(value);
return v;
}
// static
::DBus::Variant DBusAdaptor::Int16ToVariant(int16 value) {
::DBus::Variant v;
v.writer().append_int16(value);
return v;
}
// static
::DBus::Variant DBusAdaptor::Int32ToVariant(int32 value) {
::DBus::Variant v;
v.writer().append_int32(value);
return v;
}
// static
::DBus::Variant DBusAdaptor::PathToVariant(const ::DBus::Path &value) {
::DBus::Variant v;
v.writer().append_path(value.c_str());
return v;
}
// static
::DBus::Variant DBusAdaptor::PathArrayToVariant(
const vector< ::DBus::Path> &value) {
::DBus::MessageIter writer;
::DBus::Variant v;
// TODO(quiche): figure out why we can't use operator<< without the
// temporary variable.
writer = v.writer();
writer << value;
return v;
}
// static
::DBus::Variant DBusAdaptor::StringToVariant(const string &value) {
::DBus::Variant v;
v.writer().append_string(value.c_str());
return v;
}
// static
::DBus::Variant DBusAdaptor::StringmapToVariant(const Stringmap &value) {
::DBus::Variant v;
::DBus::MessageIter writer = v.writer();
writer << value;
return v;
}
// static
::DBus::Variant DBusAdaptor::StringmapsToVariant(const Stringmaps &value) {
::DBus::Variant v;
::DBus::MessageIter writer = v.writer();
writer << value;
return v;
}
// static
::DBus::Variant DBusAdaptor::StringsToVariant(const Strings &value) {
::DBus::Variant v;
::DBus::MessageIter writer = v.writer();
writer << value;
return v;
}
// static
::DBus::Variant DBusAdaptor::StrIntPairToVariant(const StrIntPair &value) {
::DBus::Variant v;
::DBus::MessageIter writer = v.writer();
writer << value.string_property();
writer << value.uint_property();
return v;
}
// static
::DBus::Variant DBusAdaptor::Uint16ToVariant(uint16 value) {
::DBus::Variant v;
v.writer().append_uint16(value);
return v;
}
// static
::DBus::Variant DBusAdaptor::Uint32ToVariant(uint32 value) {
::DBus::Variant v;
v.writer().append_uint32(value);
return v;
}
// static
bool DBusAdaptor::IsBool(::DBus::Signature signature) {
return signature == ::DBus::type<bool>::sig();
}
// static
bool DBusAdaptor::IsByte(::DBus::Signature signature) {
return signature == ::DBus::type<uint8>::sig();
}
// static
bool DBusAdaptor::IsInt16(::DBus::Signature signature) {
return signature == ::DBus::type<int16>::sig();
}
// static
bool DBusAdaptor::IsInt32(::DBus::Signature signature) {
return signature == ::DBus::type<int32>::sig();
}
// static
bool DBusAdaptor::IsPath(::DBus::Signature signature) {
return signature == ::DBus::type< ::DBus::Path >::sig();
}
// static
bool DBusAdaptor::IsPathArray(::DBus::Signature signature) {
return signature == DBusAdaptor::kPathArraySig;
}
// static
bool DBusAdaptor::IsString(::DBus::Signature signature) {
return signature == ::DBus::type<string>::sig();
}
// static
bool DBusAdaptor::IsStringmap(::DBus::Signature signature) {
return signature == DBusAdaptor::kStringmapSig;
}
// static
bool DBusAdaptor::IsStringmaps(::DBus::Signature signature) {
return signature == DBusAdaptor::kStringmapsSig;
}
// static
bool DBusAdaptor::IsStrings(::DBus::Signature signature) {
return signature == DBusAdaptor::kStringsSig;
}
// static
bool DBusAdaptor::IsUint16(::DBus::Signature signature) {
return signature == ::DBus::type<uint16>::sig();
}
// static
bool DBusAdaptor::IsUint32(::DBus::Signature signature) {
return signature == ::DBus::type<uint32>::sig();
}
} // namespace shill