shill: allow property accessors to return an error message if a
property's value cannot be changed.
also, reduce some code duplication in property_store.cc
BUG=chromium-os:21384
TEST=unittests
Change-Id: Iaac8d40bbb9e9a1341d6c6d01642885d88ac0e27
Reviewed-on: http://gerrit.chromium.org/gerrit/8925
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: mukesh agrawal <quiche@chromium.org>
diff --git a/accessor_interface.h b/accessor_interface.h
index 3a62696..7186a54 100644
--- a/accessor_interface.h
+++ b/accessor_interface.h
@@ -15,6 +15,8 @@
namespace shill {
+class Error;
+
// A templated abstract base class for objects that can be used to access
// properties stored in objects that are meant to be made available over RPC.
// The intended usage is that an object stores a maps of strings to
@@ -28,8 +30,8 @@
// Provides read-only access.
virtual const T &Get() = 0;
- // Attempts to set the wrapped value. Returns true upon success.
- virtual bool Set(const T &value) = 0;
+ // Attempts to set the wrapped value. Sets |error| on failure.
+ virtual void Set(const T &value, Error *error) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(AccessorInterface);
diff --git a/cellular.cc b/cellular.cc
index 81a3212..ff13300 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -1010,7 +1010,7 @@
void Cellular::HelpRegisterDerivedStrIntPair(
const string &name,
StrIntPair(Cellular::*get)(void),
- bool(Cellular::*set)(const StrIntPair&)) {
+ void(Cellular::*set)(const StrIntPair&, Error *)) {
mutable_store()->RegisterDerivedStrIntPair(
name,
StrIntPairAccessor(
diff --git a/cellular.h b/cellular.h
index 07bdfe9..d3359d9 100644
--- a/cellular.h
+++ b/cellular.h
@@ -239,12 +239,10 @@
StrIntPair SimLockStatusToProperty();
- void HelpRegisterDerivedStringmaps(const std::string &name,
- Stringmaps(Cellular::*get)(void),
- bool(Cellular::*set)(const Stringmaps&));
- void HelpRegisterDerivedStrIntPair(const std::string &name,
- StrIntPair(Cellular::*get)(void),
- bool(Cellular::*set)(const StrIntPair&));
+ void HelpRegisterDerivedStrIntPair(
+ const std::string &name,
+ StrIntPair(Cellular::*get)(void),
+ void(Cellular::*set)(const StrIntPair&, Error *));
void InitProxies();
diff --git a/dbus_adaptor.cc b/dbus_adaptor.cc
index d1c082d..dc69d9d 100644
--- a/dbus_adaptor.cc
+++ b/dbus_adaptor.cc
@@ -42,43 +42,43 @@
const string &name,
const ::DBus::Variant &value,
::DBus::Error *error) {
- bool set = false;
- Error e(Error::kInvalidArguments, "Could not write " + name);
+ Error e;
if (DBusAdaptor::IsBool(value.signature()))
- set = store->SetBoolProperty(name, value.reader().get_bool(), &e);
+ store->SetBoolProperty(name, value.reader().get_bool(), &e);
else if (DBusAdaptor::IsByte(value.signature()))
- set = store->SetUint8Property(name, value.reader().get_byte(), &e);
+ store->SetUint8Property(name, value.reader().get_byte(), &e);
else if (DBusAdaptor::IsInt16(value.signature()))
- set = store->SetInt16Property(name, value.reader().get_int16(), &e);
+ store->SetInt16Property(name, value.reader().get_int16(), &e);
else if (DBusAdaptor::IsInt32(value.signature()))
- set = store->SetInt32Property(name, value.reader().get_int32(), &e);
+ store->SetInt32Property(name, value.reader().get_int32(), &e);
else if (DBusAdaptor::IsPath(value.signature()))
- set = store->SetStringProperty(name, value.reader().get_path(), &e);
+ store->SetStringProperty(name, value.reader().get_path(), &e);
else if (DBusAdaptor::IsString(value.signature()))
- set = store->SetStringProperty(name, value.reader().get_string(), &e);
+ 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()))
+ 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);
+ e.Populate(Error::kInternalError);
+ } else if (DBusAdaptor::IsStrings(value.signature()))
+ store->SetStringsProperty(name, value.operator vector<string>(), &e);
else if (DBusAdaptor::IsUint16(value.signature()))
- set = store->SetUint16Property(name, value.reader().get_uint16(), &e);
+ store->SetUint16Property(name, value.reader().get_uint16(), &e);
else if (DBusAdaptor::IsUint32(value.signature()))
- set = store->SetUint32Property(name, value.reader().get_uint32(), &e);
- else
+ 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);
+ e.Populate(Error::kInternalError);
}
- return set;
+
+ if (error != NULL) {
+ e.ToDBusError(error);
+ }
+
+ return e.IsSuccess();
}
// static
diff --git a/device.cc b/device.cc
index 12300a9..583cf0f 100644
--- a/device.cc
+++ b/device.cc
@@ -257,9 +257,10 @@
return ipconfig_->RequestIP();
}
-void Device::HelpRegisterDerivedStrings(const string &name,
- Strings(Device::*get)(void),
- bool(Device::*set)(const Strings&)) {
+void Device::HelpRegisterDerivedStrings(
+ const string &name,
+ Strings(Device::*get)(void),
+ void(Device::*set)(const Strings&, Error *)) {
store_.RegisterDerivedStrings(
name,
StringsAccessor(new CustomAccessor<Device, Strings>(this, get, set)));
diff --git a/device.h b/device.h
index 17e7775..85ad698 100644
--- a/device.h
+++ b/device.h
@@ -132,7 +132,7 @@
void HelpRegisterDerivedStrings(const std::string &name,
Strings(Device::*get)(void),
- bool(Device::*set)(const Strings&));
+ void(Device::*set)(const Strings&, Error *));
// Property getters reserved for subclasses
ControlInterface *control_interface() const { return control_interface_; }
diff --git a/manager.cc b/manager.cc
index a99ac00..f8ebd53 100644
--- a/manager.cc
+++ b/manager.cc
@@ -259,17 +259,19 @@
return NULL;
}
-void Manager::HelpRegisterDerivedString(const string &name,
- string(Manager::*get)(void),
- bool(Manager::*set)(const string&)) {
+void Manager::HelpRegisterDerivedString(
+ const string &name,
+ string(Manager::*get)(void),
+ void(Manager::*set)(const string&, Error *)) {
store_.RegisterDerivedString(
name,
StringAccessor(new CustomAccessor<Manager, string>(this, get, set)));
}
-void Manager::HelpRegisterDerivedStrings(const string &name,
- Strings(Manager::*get)(void),
- bool(Manager::*set)(const Strings&)) {
+void Manager::HelpRegisterDerivedStrings(
+ const string &name,
+ Strings(Manager::*get)(void),
+ void(Manager::*set)(const Strings &, Error *)) {
store_.RegisterDerivedStrings(
name,
StringsAccessor(new CustomAccessor<Manager, Strings>(this, get, set)));
diff --git a/manager.h b/manager.h
index ede4f49..289ee09 100644
--- a/manager.h
+++ b/manager.h
@@ -102,12 +102,14 @@
std::vector<std::string> EnumerateWatchedServices();
std::string GetActiveProfileName();
- void HelpRegisterDerivedString(const std::string &name,
- std::string(Manager::*get)(void),
- bool(Manager::*set)(const std::string&));
- void HelpRegisterDerivedStrings(const std::string &name,
- Strings(Manager::*get)(void),
- bool(Manager::*set)(const Strings&));
+ void HelpRegisterDerivedString(
+ const std::string &name,
+ std::string(Manager::*get)(void),
+ void(Manager::*set)(const std::string&, Error *));
+ void HelpRegisterDerivedStrings(
+ const std::string &name,
+ Strings(Manager::*get)(void),
+ void(Manager::*set)(const Strings&, Error *));
bool OrderServices(ServiceRefPtr a, ServiceRefPtr b);
void SortServices();
diff --git a/profile.cc b/profile.cc
index b24b80e..4111588 100644
--- a/profile.cc
+++ b/profile.cc
@@ -183,9 +183,10 @@
return rpc_ids;
}
-void Profile::HelpRegisterDerivedStrings(const string &name,
- Strings(Profile::*get)(void),
- bool(Profile::*set)(const Strings&)) {
+void Profile::HelpRegisterDerivedStrings(
+ const string &name,
+ Strings(Profile::*get)(void),
+ void(Profile::*set)(const Strings&, Error *)) {
store_.RegisterDerivedStrings(
name,
StringsAccessor(new CustomAccessor<Profile, Strings>(this, get, set)));
diff --git a/profile.h b/profile.h
index 0b73950..e0d6a0a 100644
--- a/profile.h
+++ b/profile.h
@@ -116,9 +116,10 @@
return false;
}
- void HelpRegisterDerivedStrings(const std::string &name,
- Strings(Profile::*get)(void),
- bool(Profile::*set)(const Strings&));
+ void HelpRegisterDerivedStrings(
+ const std::string &name,
+ Strings(Profile::*get)(void),
+ void(Profile::*set)(const Strings&, Error *));
// Persists |services_| to disk.
bool SaveServices(StoreInterface *storage);
diff --git a/property_accessor.h b/property_accessor.h
index fda0623..542fd8d 100644
--- a/property_accessor.h
+++ b/property_accessor.h
@@ -9,6 +9,7 @@
#include <base/logging.h>
#include "shill/accessor_interface.h"
+#include "shill/error.h"
namespace shill {
@@ -34,9 +35,8 @@
virtual ~PropertyAccessor() {}
const T &Get() { return *property_; }
- bool Set(const T &value) {
+ void Set(const T &value, Error */*error*/) {
*property_ = value;
- return true;
}
private:
@@ -53,7 +53,11 @@
virtual ~ConstPropertyAccessor() {}
const T &Get() { return *property_; }
- bool Set(const T &/*value*/) { return false; }
+ void Set(const T &/*value*/, Error *error) {
+ // TODO(quiche): check if this is the right error.
+ // (maybe Error::kPermissionDenied instead?)
+ error->Populate(Error::kInvalidArguments, "Property is read-only");
+ }
private:
const T * const property_;
@@ -70,7 +74,9 @@
// |setter| is allowed to be NULL, in which case we will simply reject
// attempts to set via the accessor.
// It is an error to pass NULL for either of the other two arguments.
- CustomAccessor(C *target, T(C::*getter)(), bool(C::*setter)(const T&))
+ CustomAccessor(C *target,
+ T(C::*getter)(),
+ void(C::*setter)(const T&, Error *))
: target_(target),
getter_(getter),
setter_(setter) {
@@ -80,7 +86,13 @@
virtual ~CustomAccessor() {}
const T &Get() { return storage_ = (target_->*getter_)(); }
- bool Set(const T &value) { return setter_ && (target_->*setter_)(value); }
+ void Set(const T &value, Error *error) {
+ if (setter_) {
+ (target_->*setter_)(value, error);
+ } else {
+ error->Populate(Error::kInvalidArguments, "Property is read-only");
+ }
+ }
private:
C * const target_;
@@ -88,7 +100,7 @@
// return a reference.
T storage_;
T(C::*getter_)(void);
- bool(C::*setter_)(const T&);
+ void(C::*setter_)(const T&, Error *);
DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
};
diff --git a/property_accessor_unittest.cc b/property_accessor_unittest.cc
index 7e9a150..4303d13 100644
--- a/property_accessor_unittest.cc
+++ b/property_accessor_unittest.cc
@@ -13,6 +13,8 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
+#include "shill/error.h"
+
using std::map;
using std::string;
using std::vector;
@@ -24,22 +26,27 @@
TEST(PropertyAccessorTest, SignedIntCorrectness) {
int32 int_store = 0;
{
+ Error error;
Int32Accessor accessor(new PropertyAccessor<int32>(&int_store));
EXPECT_EQ(int_store, accessor->Get());
int32 expected_int32 = 127;
- ASSERT_TRUE(accessor->Set(expected_int32));
+ accessor->Set(expected_int32, &error);
+ ASSERT_TRUE(error.IsSuccess());
EXPECT_EQ(expected_int32, accessor->Get());
int_store = std::numeric_limits<int32>::max();
EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get());
}
{
+ Error error;
Int32Accessor accessor(new ConstPropertyAccessor<int32>(&int_store));
EXPECT_EQ(int_store, accessor->Get());
int32 expected_int32 = 127;
- ASSERT_FALSE(accessor->Set(expected_int32));
+ accessor->Set(expected_int32, &error);
+ ASSERT_FALSE(error.IsSuccess());
+ EXPECT_EQ(Error::kInvalidArguments, error.type());
EXPECT_EQ(int_store, accessor->Get());
int_store = std::numeric_limits<int32>::max();
@@ -50,22 +57,27 @@
TEST(PropertyAccessorTest, UnsignedIntCorrectness) {
uint32 int_store = 0;
{
+ Error error;
Uint32Accessor accessor(new PropertyAccessor<uint32>(&int_store));
EXPECT_EQ(int_store, accessor->Get());
uint32 expected_uint32 = 127;
- ASSERT_TRUE(accessor->Set(expected_uint32));
+ accessor->Set(expected_uint32, &error);
+ ASSERT_TRUE(error.IsSuccess());
EXPECT_EQ(expected_uint32, accessor->Get());
int_store = std::numeric_limits<uint32>::max();
EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get());
}
{
+ Error error;
Uint32Accessor accessor(new ConstPropertyAccessor<uint32>(&int_store));
EXPECT_EQ(int_store, accessor->Get());
uint32 expected_uint32 = 127;
- ASSERT_FALSE(accessor->Set(expected_uint32));
+ accessor->Set(expected_uint32, &error);
+ ASSERT_FALSE(error.IsSuccess());
+ EXPECT_EQ(Error::kInvalidArguments, error.type());
EXPECT_EQ(int_store, accessor->Get());
int_store = std::numeric_limits<uint32>::max();
@@ -76,22 +88,27 @@
TEST(PropertyAccessorTest, StringCorrectness) {
string storage;
{
+ Error error;
StringAccessor accessor(new PropertyAccessor<string>(&storage));
EXPECT_EQ(storage, accessor->Get());
string expected_string("what");
- ASSERT_TRUE(accessor->Set(expected_string));
+ accessor->Set(expected_string, &error);
+ ASSERT_TRUE(error.IsSuccess());
EXPECT_EQ(expected_string, accessor->Get());
storage = "nooooo";
EXPECT_EQ(storage, accessor->Get());
}
{
+ Error error;
StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
EXPECT_EQ(storage, accessor->Get());
string expected_string("what");
- ASSERT_FALSE(accessor->Set(expected_string));
+ accessor->Set(expected_string, &error);
+ ASSERT_FALSE(error.IsSuccess());
+ EXPECT_EQ(Error::kInvalidArguments, error.type());
EXPECT_EQ(storage, accessor->Get());
storage = "nooooo";
diff --git a/property_store.cc b/property_store.cc
index 9fb61ba..8cc67b1 100644
--- a/property_store.cc
+++ b/property_store.cc
@@ -42,101 +42,57 @@
bool PropertyStore::SetBoolProperty(const std::string& name,
bool value,
Error *error) {
- VLOG(2) << "Setting " << name << " as a bool.";
- bool set = (ContainsKey(bool_properties_, name) &&
- bool_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W bool.");
- return set;
+ return SetProperty(name, value, error, bool_properties_, "a bool");
}
bool PropertyStore::SetInt16Property(const std::string& name,
int16 value,
Error *error) {
- VLOG(2) << "Setting " << name << " as an int16.";
- bool set = (ContainsKey(int16_properties_, name) &&
- int16_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W int16.");
- return set;
+ return SetProperty(name, value, error, int16_properties_, "an int16");
}
bool PropertyStore::SetInt32Property(const std::string& name,
int32 value,
Error *error) {
- VLOG(2) << "Setting " << name << " as an int32.";
- bool set = (ContainsKey(int32_properties_, name) &&
- int32_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W int32.");
- return set;
+ return SetProperty(name, value, error, int32_properties_, "an int32.");
}
bool PropertyStore::SetStringProperty(const std::string& name,
const std::string& value,
Error *error) {
- VLOG(2) << "Setting " << name << " as a string.";
- bool set = (ContainsKey(string_properties_, name) &&
- string_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W string.");
- return set;
+ return SetProperty(name, value, error, string_properties_, "a string");
}
bool PropertyStore::SetStringmapProperty(
const std::string& name,
const std::map<std::string, std::string>& values,
Error *error) {
- VLOG(2) << "Setting " << name << " as a string map.";
- bool set = (ContainsKey(stringmap_properties_, name) &&
- stringmap_properties_[name]->Set(values));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W strmap.");
- return set;
+ return SetProperty(name, values, error, stringmap_properties_,
+ "a string map");
}
bool PropertyStore::SetStringsProperty(const std::string& name,
const std::vector<std::string>& values,
Error *error) {
- VLOG(2) << "Setting " << name << " as a string list.";
- bool set = (ContainsKey(strings_properties_, name) &&
- strings_properties_[name]->Set(values));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W str list.");
- return set;
+ return SetProperty(name, values, error, strings_properties_, "a string list");
}
bool PropertyStore::SetUint8Property(const std::string& name,
uint8 value,
Error *error) {
- VLOG(2) << "Setting " << name << " as a uint8.";
- bool set = (ContainsKey(uint8_properties_, name) &&
- uint8_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W uint8.");
- return set;
+ return SetProperty(name, value, error, uint8_properties_, "a uint8");
}
bool PropertyStore::SetUint16Property(const std::string& name,
uint16 value,
Error *error) {
- VLOG(2) << "Setting " << name << " as a uint16.";
- bool set = (ContainsKey(uint16_properties_, name) &&
- uint16_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W uint16.");
- return set;
+ return SetProperty(name, value, error, uint16_properties_, "a uint16");
}
bool PropertyStore::SetUint32Property(const std::string& name,
uint32 value,
Error *error) {
- VLOG(2) << "Setting " << name << " as a uint32.";
- bool set = (ContainsKey(uint32_properties_, name) &&
- uint32_properties_[name]->Set(value));
- if (!set && error)
- error->Populate(Error::kInvalidArguments, name + " is not a R/W uint32.");
- return set;
+ return SetProperty(name, value, error, uint32_properties_, "a uint32");
}
PropertyConstIterator<bool> PropertyStore::GetBoolPropertiesIter() const {
@@ -295,4 +251,28 @@
strintpair_properties_[name] = acc;
}
+// private
+template <class V>
+bool PropertyStore::SetProperty(
+ const string &name,
+ const V &value,
+ Error *error,
+ map< string, std::tr1::shared_ptr< AccessorInterface<V> > >&collection,
+ const string &value_type_english) {
+ VLOG(2) << "Setting " << name << " as " << value_type_english << ".";
+ if (ContainsKey(collection, name)) {
+ collection[name]->Set(value, error);
+ } else {
+ if (Contains(name)) {
+ error->Populate(
+ Error::kInvalidArguments,
+ "Property " + name + " is not " + value_type_english + ".");
+ } else {
+ error->Populate(
+ Error::kInvalidProperty, "Property " + name + " does not exist.");
+ }
+ }
+ return error->IsSuccess();
+};
+
} // namespace shill
diff --git a/property_store.h b/property_store.h
index 2edc333..696ea17 100644
--- a/property_store.h
+++ b/property_store.h
@@ -68,7 +68,13 @@
uint32 value,
Error *error);
- // Accessors for iterators over property maps.
+ // We do not provide methods for reading individual properties,
+ // because we don't need them to implement the flimflam API. (The flimflam
+ // API only allows fetching all properties at once -- not individual
+ // properties.)
+
+ // Accessors for iterators over property maps. Useful for dumping all
+ // properties.
PropertyConstIterator<bool> GetBoolPropertiesIter() const;
PropertyConstIterator<int16> GetInt16PropertiesIter() const;
PropertyConstIterator<int32> GetInt32PropertiesIter() const;
@@ -112,6 +118,14 @@
const StrIntPairAccessor &accessor);
private:
+ template <class V>
+ bool SetProperty(
+ const std::string &name,
+ const V &value,
+ Error *error,
+ std::map< std::string, std::tr1::shared_ptr< AccessorInterface<V> > > &,
+ const std::string &value_type_english);
+
// These are std::maps instead of something cooler because the common
// operation is iterating through them and returning all properties.
std::map<std::string, BoolAccessor> bool_properties_;
diff --git a/property_store_unittest.cc b/property_store_unittest.cc
index 3149146..26f8382 100644
--- a/property_store_unittest.cc
+++ b/property_store_unittest.cc
@@ -62,7 +62,8 @@
DBusAdaptor::Uint32ToVariant(0);
PropertyStoreTest::PropertyStoreTest()
- : invalid_args_(Error::GetName(Error::kInvalidArguments)),
+ : internal_error_(Error::GetName(Error::kInternalError)),
+ invalid_args_(Error::GetName(Error::kInvalidArguments)),
invalid_prop_(Error::GetName(Error::kInvalidProperty)),
path_(dir_.CreateUniqueTempDir() ? dir_.path().value() : ""),
manager_(control_interface(),
@@ -97,10 +98,17 @@
PropertyStoreTest::kInt16V,
PropertyStoreTest::kInt32V,
PropertyStoreTest::kStringmapV,
- PropertyStoreTest::kStringmapsV,
PropertyStoreTest::kStringsV,
PropertyStoreTest::kStrIntPairV,
PropertyStoreTest::kUint16V,
PropertyStoreTest::kUint32V));
+TEST_F(PropertyStoreTest, SetStringmapsProperty) {
+ PropertyStore store;
+ ::DBus::Error error;
+ EXPECT_FALSE(DBusAdaptor::DispatchOnType(
+ &store, "", PropertyStoreTest::kStringmapsV, &error));
+ EXPECT_EQ(internal_error(), error.name());
+}
+
} // namespace shill
diff --git a/property_store_unittest.h b/property_store_unittest.h
index 639649f..42a0e8d 100644
--- a/property_store_unittest.h
+++ b/property_store_unittest.h
@@ -58,10 +58,12 @@
const std::string &run_path() const { return path_; }
const std::string &storage_path() const { return path_; }
+ const std::string &internal_error() const { return internal_error_; }
const std::string &invalid_args() const { return invalid_args_; }
const std::string &invalid_prop() const { return invalid_prop_; }
private:
+ const std::string internal_error_;
const std::string invalid_args_;
const std::string invalid_prop_;
ScopedTempDir dir_;
diff --git a/service.cc b/service.cc
index 489fe5c..e38893e 100644
--- a/service.cc
+++ b/service.cc
@@ -335,17 +335,19 @@
}
}
-void Service::HelpRegisterDerivedBool(const string &name,
- bool(Service::*get)(void),
- bool(Service::*set)(const bool&)) {
+void Service::HelpRegisterDerivedBool(
+ const string &name,
+ bool(Service::*get)(void),
+ void(Service::*set)(const bool&, Error *)) {
store_.RegisterDerivedBool(
name,
BoolAccessor(new CustomAccessor<Service, bool>(this, get, set)));
}
-void Service::HelpRegisterDerivedString(const string &name,
- string(Service::*get)(void),
- bool(Service::*set)(const string&)) {
+void Service::HelpRegisterDerivedString(
+ const string &name,
+ string(Service::*get)(void),
+ void(Service::*set)(const string&, Error *)) {
store_.RegisterDerivedString(
name,
StringAccessor(new CustomAccessor<Service, string>(this, get, set)));
diff --git a/service.h b/service.h
index d6912e8..9c21aee 100644
--- a/service.h
+++ b/service.h
@@ -176,12 +176,14 @@
virtual std::string CalculateState();
- void HelpRegisterDerivedBool(const std::string &name,
- bool(Service::*get)(void),
- bool(Service::*set)(const bool&));
- void HelpRegisterDerivedString(const std::string &name,
- std::string(Service::*get)(void),
- bool(Service::*set)(const std::string&));
+ void HelpRegisterDerivedBool(
+ const std::string &name,
+ bool(Service::*get)(void),
+ void(Service::*set)(const bool&, Error *));
+ void HelpRegisterDerivedString(
+ const std::string &name,
+ std::string(Service::*get)(void),
+ void(Service::*set)(const std::string&, Error *));
// Assigns |value| to |key| in |storage| if |value| is non-empty and |save| is
// true. Otherwise, removes |key| from |storage|. If |crypted| is true, the