shill: CustomAccessor: Allow custom Clear methods

Allow creators of a CustomAccessor to provide a clear method
instead of using the default of calling Set() with the default
value.  This allows providing a clear method without providing
a set method (not so useful) as well as allowing a property
owner to perform ancillary actions specific to returning a
property to its default state.

BUG=chromium:307692
TEST=Unit test

Change-Id: I02413782e2cccfd6679c3d2945aa218236c82115
Reviewed-on: https://chromium-review.googlesource.com/173321
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: David James <davidjames@chromium.org>
diff --git a/property_accessor.h b/property_accessor.h
index fb0d6df..a12ef56 100644
--- a/property_accessor.h
+++ b/property_accessor.h
@@ -134,18 +134,22 @@
 template<class C, class T>
 class CustomAccessor : public AccessorInterface<T> {
  public:
-  // |target| is the object on which to call the methods |getter| and |setter|
-  // |setter| is allowed to be NULL, in which case we will simply reject
-  // attempts to set via the accessor. |setter| should return true if the
-  // value was changed, and false otherwise.
-  // It is an error to pass NULL for either of the other two arguments.
+  // |target| is the object on which to call the methods |getter|, |setter|
+  // and |clearer|.  |setter| is allowed to be NULL, in which case we will
+  // simply reject attempts to set via the accessor. |setter| should return
+  // true if the value was changed, and false otherwise.  |clearer| is allowed
+  // to be NULL (which is what happens if it is not passed to the constructor),
+  // in which case, |setter| is called is called with the default value.
+  // It is an error to pass NULL for either |target| or |getter|.
   CustomAccessor(C *target,
                  T(C::*getter)(Error *error),
-                 bool(C::*setter)(const T &value, Error *error))
+                 bool(C::*setter)(const T &value, Error *error),
+                 void(C::*clearer)(Error *error))
       : target_(target),
         default_value_(),
         getter_(getter),
-        setter_(setter) {
+        setter_(setter),
+        clearer_(clearer) {
     DCHECK(target);
     DCHECK(getter);  // otherwise, use CustomWriteOnlyAccessor
     if (setter_) {
@@ -153,9 +157,19 @@
       default_value_ = Get(&e);
     }
   }
+  CustomAccessor(C *target,
+                 T(C::*getter)(Error *error),
+                 bool(C::*setter)(const T &value, Error *error))
+      : CustomAccessor(target, getter, setter, NULL) {}
   virtual ~CustomAccessor() {}
 
-  void Clear(Error *error) { Set(default_value_, error); }
+  void Clear(Error *error) {
+    if (clearer_) {
+      (target_->*clearer_)(error);
+    } else {
+      Set(default_value_, error);
+    }
+  }
   T Get(Error *error) {
     return (target_->*getter_)(error);
   }
@@ -175,6 +189,7 @@
   T default_value_;
   T(C::*const getter_)(Error *error);
   bool(C::*const setter_)(const T &value, Error *error);
+  void(C::*const clearer_)(Error *error);
   DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
 };