USRP Hardware Driver and USRP Manual  Version: 4.6.0.0
UHD and USRP Manual
property.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2019 Ettus Research, a National Instruments Brand
3 //
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 //
6 
7 #pragma once
8 
9 #include <uhd/exception.hpp>
11 #include <uhd/utils/cast.hpp>
13 #include <memory>
14 #include <string>
15 
16 
17 namespace uhd { namespace rfnoc {
18 
19 // Forward declaration, separates includes
20 class prop_accessor_t;
21 
26 {
27 public:
28  enum access_t {
29  NONE,
30  RO = 0x1,
31  RW = 0x3,
32  RWLOCKED = 0x5
33  };
35 
36  property_base_t(const std::string& id, const res_source_info& source_info)
37  : _id(id), _source_info(source_info)
38  {
39  if (_id.find(':') != std::string::npos) {
40  throw uhd::value_error(
41  "Property ID `" + _id + "' contains invalid character!");
42  }
43  }
44 
45  virtual ~property_base_t()
46  {
47  // nop
48  }
49 
51  const std::string& get_id() const
52  {
53  return _id;
54  }
55 
58  {
59  return _source_info;
60  }
61 
63  //
64  // If it's true, that means this property was recently changed, but changes
65  // have not propagated yet and still need resolving.
66  virtual bool is_dirty() const = 0;
67 
69  //
70  // If it's false, that means this property has a default value that should
71  // NOT be forwarded.
72  virtual bool is_valid() const = 0;
73 
75  bool read_access_granted() const
76  {
77  return static_cast<uint8_t>(_access_mode) & 0x1;
78  }
79 
81  bool write_access_granted() const
82  {
83  return static_cast<uint8_t>(_access_mode) & 0x2;
84  }
85 
88  {
89  return _access_mode;
90  }
91 
93  virtual bool equal(property_base_t* rhs) const = 0;
94 
96  //
97  // The copy must have the same type, value, and ID. However, it is often
98  // desirable to have a new source information, so that can be overridden.
99  //
100  // The cleanliness state of \p original is not preserved. The new property
101  // will have the same cleanliness state as any other new property.
102  //
103  virtual std::unique_ptr<property_base_t> clone(res_source_info)
104  {
105  throw uhd::not_implemented_error("Cloning is not available for this property.");
106  }
107 
108  virtual void force_dirty() = 0;
109 
118  virtual void set_from_str(const std::string& new_val_str) = 0;
119 
120 private:
121  friend class prop_accessor_t;
122 
124  virtual void mark_clean() = 0;
125 
127  virtual void forward(property_base_t* next_prop) = 0;
128 
130  //
131  // Note: This uses RTTI to evaluate type equality
132  virtual bool is_type_equal(property_base_t* other_prop) const = 0;
133 
134  /*** Attributes **********************************************************/
136  const std::string _id;
137 
139  const res_source_info _source_info;
140 
142  // write this.
143  access_t _access_mode = RO;
144 };
145 
149 template <typename data_t>
151 {
152 public:
154  using value_type = data_t;
155 
156  property_t(const std::string& id, data_t&& value, const res_source_info& source_info);
157 
158  property_t(
159  const std::string& id, const data_t& value, const res_source_info& source_info);
160 
161  property_t(const std::string& id, const res_source_info& source_info);
162 
163  property_t(const property_t<data_t>& prop) = default;
164 
166  //
167  // If true, this means the value was recently changed, but it wasn't marked
168  // clean yet.
169  bool is_dirty() const override
170  {
171  return _data.is_dirty();
172  }
173 
175  //
176  // If it's false, that means this property has a default value that should
177  // NOT be used.
178  bool is_valid() const override
179  {
180  return _valid;
181  }
182 
183  bool equal(property_base_t* rhs) const override
184  {
185  if (!is_type_equal(rhs)) {
186  return false;
187  }
188  return get() == dynamic_cast<property_t<data_t>*>(rhs)->get();
189  }
190 
191  std::unique_ptr<property_base_t> clone(res_source_info new_src_info) override
192  {
193  return std::unique_ptr<property_base_t>(
194  new property_t<data_t>(get_id(), get(), new_src_info));
195  }
196 
197  void set_from_str(const std::string& new_val_str) override
198  {
199  try {
200  set(uhd::cast::from_str<data_t>(new_val_str));
201  } catch (uhd::runtime_error& ex) {
202  throw uhd::runtime_error(
203  std::string("Property ") + get_id() + ":" + ex.what());
204  }
205  }
206 
208  // const res_source_info& get_src_info() const = 0;
209 
211  //
212  // \throws uhd::access_error if the current access mode is not RW or RWLOCKED
213  // \throws uhd::resolve_error if the property is RWLOCKED but the new value
214  // doesn't match
215  void set(const data_t& value)
216  {
217  if (write_access_granted()) {
218  _data = value;
219  _valid = true;
220  } else if (get_access_mode() == RWLOCKED) {
221  if (_data.get() != value) {
222  throw uhd::resolve_error(std::string("Attempting to overwrite property `")
223  + get_id() + "@" + get_src_info().to_string()
224  + "' with a new value after it was locked!");
225  }
226  } else {
227  throw uhd::access_error(std::string("Attempting to write to property `")
228  + get_id() + "' without access privileges!");
229  }
230  }
231 
232  void force_dirty() override
233  {
234  if (write_access_granted()) {
235  _data.force_dirty();
236  } else if (get_access_mode() == RWLOCKED) {
237  if (!_data.is_dirty()) {
238  throw uhd::resolve_error(std::string("Attempting to overwrite property `")
239  + get_id()
240  + "' with dirty flag after it was locked!");
241  }
242  } else {
243  throw uhd::access_error(std::string("Attempting to flag dirty property `")
244  + get_id() + "' without access privileges!");
245  }
246  }
247 
249  //
250  // \throws uhd::access_error if either the property is flagged as invalid,
251  // or if no read access was granted.
252  const data_t& get() const
253  {
254  if (!is_valid()) {
255  throw uhd::access_error(std::string("Attempting to read property `")
256  + get_id() + "@" + get_src_info().to_string()
257  + "' before it was initialized!");
258  }
259  if (read_access_granted()) {
260  return _data;
261  }
262  throw uhd::access_error(std::string("Attempting to read property `") + get_id()
263  + "' without access privileges!");
264  }
265 
266  operator const data_t&() const
267  {
268  return get();
269  }
270 
271  bool operator==(const data_t& rhs)
272  {
273  return get() == rhs;
274  }
275 
276  property_t<data_t>& operator=(const data_t& value)
277  {
278  set(value);
279  return *this;
280  }
281 
282 private:
283  void mark_clean() override
284  {
285  _data.mark_clean();
286  }
287 
288  void forward(property_base_t* next_prop) override
289  {
290  if (not _valid) {
291  throw uhd::resolve_error(
292  std::string("Unable to forward invalid property ") + get_id());
293  }
294  property_t<data_t>* prop_ptr = dynamic_cast<property_t<data_t>*>(next_prop);
295  if (prop_ptr == nullptr) {
296  throw uhd::type_error(std::string("Unable to cast property ")
297  + next_prop->get_id() + " to the same type as property "
298  + get_id());
299  }
300 
301  prop_ptr->set(get());
302  }
303 
304  bool is_type_equal(property_base_t* other_prop) const override
305  {
306  return dynamic_cast<property_t<data_t>*>(other_prop) != nullptr;
307  }
308 
309  dirty_tracked<data_t> _data;
310  bool _valid;
311 }; // class property_t
312 
313 }} /* namespace uhd::rfnoc */
314 
315 #include <uhd/rfnoc/property.ipp>
property_t< data_t > & operator=(const data_t &value)
Definition: property.hpp:276
bool write_access_granted() const
Returns true if this property can be written to.
Definition: property.hpp:81
const data_t & get() const
Get the value of this property.
Definition: property.hpp:252
const std::string & get_id() const
Gets the ID (name) of this property.
Definition: property.hpp:51
Definition: exception.hpp:156
size_t value_type
We want to be good C++ citizens.
Definition: property.hpp:154
bool is_valid() const override
Query this property&#39;s valid flag.
Definition: property.hpp:178
const res_source_info & get_src_info() const
Return the source info for this property.
Definition: property.hpp:57
Definition: exception.hpp:131
#define UHD_API_HEADER
Definition: config.h:88
property_base_t(const std::string &id, const res_source_info &source_info)
Definition: property.hpp:36
Definition: exception.hpp:107
access_t get_access_mode() const
Return the current access mode.
Definition: property.hpp:87
bool operator==(const data_t &rhs)
Definition: property.hpp:271
Neither reading nor writing to this property is permitted.
Definition: property.hpp:29
bool equal(property_base_t *rhs) const override
Return true if rhs has the same type and value.
Definition: property.hpp:183
Definition: build_info.hpp:12
Definition: exception.hpp:167
void force_dirty() override
Definition: property.hpp:232
bool is_dirty() const override
Returns the dirty state of this property.
Definition: property.hpp:169
access_t
Definition: property.hpp:28
Definition: dirty_tracked.hpp:24
Definition: property.hpp:150
std::unique_ptr< property_base_t > clone(res_source_info new_src_info) override
Create a copy of this property.
Definition: property.hpp:191
virtual std::unique_ptr< property_base_t > clone(res_source_info)
Create a copy of this property.
Definition: property.hpp:103
bool read_access_granted() const
Returns true if this property can be read.
Definition: property.hpp:75
Definition: res_source_info.hpp:17
virtual ~property_base_t()
Definition: property.hpp:45
#define UHD_API
Definition: config.h:87
Definition: exception.hpp:280
Definition: property.hpp:25
Definition: exception.hpp:95
void set(const data_t &value)
Returns the source info for the property.
Definition: property.hpp:215
void set_from_str(const std::string &new_val_str) override
Definition: property.hpp:197