blob: 542fd8d053eb005538cfb19dfcab4cd7a6339e96 [file] [log] [blame]
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_PROPERTY_ACCESSOR_
6#define SHILL_PROPERTY_ACCESSOR_
7
8#include <base/basictypes.h>
Chris Masone27bf1032011-06-28 17:02:01 -07009#include <base/logging.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070010
11#include "shill/accessor_interface.h"
mukesh agrawalffa3d042011-10-06 15:26:10 -070012#include "shill/error.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013
14namespace shill {
15
16// Templated implementations of AccessorInterface<>.
17// PropertyAccessor<> and ConstPropertyAccessor<> respectively provide
18// R/W and R/O access to the value pointed to by |property|.
19// this allows a class to easily map strings to member variables, so that
20// pieces of state stored in the class can be queried or updated by name.
21//
22// bool foo = true;
23// map<string, BoolAccessor> accessors;
24// accessors["foo"] = BoolAccessor(new PropertyAccessor<bool>(&foo));
25// bool new_foo = accessors["foo"]->Get(); // new_foo == true
26// accessors["foo"]->Set(false); // returns true, because setting is allowed.
27// // foo == false, new_foo == true
28// new_foo = accessors["foo"]->Get(); // new_foo == false
29template <class T>
30class PropertyAccessor : public AccessorInterface<T> {
31 public:
32 explicit PropertyAccessor(T *property) : property_(property) {
33 DCHECK(property);
34 }
35 virtual ~PropertyAccessor() {}
36
37 const T &Get() { return *property_; }
mukesh agrawalffa3d042011-10-06 15:26:10 -070038 void Set(const T &value, Error */*error*/) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039 *property_ = value;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070040 }
41
42 private:
43 T * const property_;
44 DISALLOW_COPY_AND_ASSIGN(PropertyAccessor);
45};
46
47template <class T>
48class ConstPropertyAccessor : public AccessorInterface<T> {
49 public:
50 explicit ConstPropertyAccessor(const T *property) : property_(property) {
51 DCHECK(property);
52 }
53 virtual ~ConstPropertyAccessor() {}
54
55 const T &Get() { return *property_; }
mukesh agrawalffa3d042011-10-06 15:26:10 -070056 void Set(const T &/*value*/, Error *error) {
57 // TODO(quiche): check if this is the right error.
58 // (maybe Error::kPermissionDenied instead?)
59 error->Populate(Error::kInvalidArguments, "Property is read-only");
60 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070061
62 private:
63 const T * const property_;
64 DISALLOW_COPY_AND_ASSIGN(ConstPropertyAccessor);
65};
66
67// CustomAccessor<> allows custom getter and setter methods to be provided.
68// Thus, if the state to be returned is to be derived on-demand, we can
69// still fit it into the AccessorInterface<> framework.
70template<class C, class T>
71class CustomAccessor : public AccessorInterface<T> {
72 public:
73 // |target| is the object on which to call the methods |getter| and |setter|
74 // |setter| is allowed to be NULL, in which case we will simply reject
75 // attempts to set via the accessor.
76 // It is an error to pass NULL for either of the other two arguments.
mukesh agrawalffa3d042011-10-06 15:26:10 -070077 CustomAccessor(C *target,
78 T(C::*getter)(),
79 void(C::*setter)(const T&, Error *))
Chris Masone3bd3c8c2011-06-13 08:20:26 -070080 : target_(target),
81 getter_(getter),
82 setter_(setter) {
83 DCHECK(target);
84 DCHECK(getter);
85 }
86 virtual ~CustomAccessor() {}
87
88 const T &Get() { return storage_ = (target_->*getter_)(); }
mukesh agrawalffa3d042011-10-06 15:26:10 -070089 void Set(const T &value, Error *error) {
90 if (setter_) {
91 (target_->*setter_)(value, error);
92 } else {
93 error->Populate(Error::kInvalidArguments, "Property is read-only");
94 }
95 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070096
97 private:
98 C * const target_;
99 // Get() returns a const&, so we need to have internal storage to which to
100 // return a reference.
101 T storage_;
102 T(C::*getter_)(void);
mukesh agrawalffa3d042011-10-06 15:26:10 -0700103 void(C::*setter_)(const T&, Error *);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700104 DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
105};
106
107} // namespace shill
108
109#endif // SHILL_PROPERTY_ACCESSOR_