USRP Hardware Driver and USRP Manual Version: 4.2.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
17namespace uhd { namespace rfnoc {
18
19// Forward declaration, separates includes
20class prop_accessor_t;
21
26{
27public:
28 enum access_t {
30 RO = 0x1,
31 RW = 0x3,
32 RWLOCKED = 0x5
34 };
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
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
76 {
77 return static_cast<uint8_t>(_access_mode) & 0x1;
78 }
79
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
120private:
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
149template <typename data_t>
151{
152public:
154 using value_type = data_t;
155
156 property_t(const std::string& id, data_t&& value, const res_source_info& source_info);
157
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
282private:
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>
Definition: property.hpp:26
const std::string & get_id() const
Gets the ID (name) of this property.
Definition: property.hpp:51
virtual void force_dirty()=0
const res_source_info & get_src_info() const
Return the source info for this property.
Definition: property.hpp:57
virtual bool equal(property_base_t *rhs) const =0
Return true if rhs has the same type and value.
access_t
Definition: property.hpp:28
@ NONE
Neither reading nor writing to this property is permitted.
Definition: property.hpp:29
property_base_t(const std::string &id, const res_source_info &source_info)
Definition: property.hpp:36
virtual void set_from_str(const std::string &new_val_str)=0
virtual bool is_valid() const =0
Query this property's valid flag.
virtual std::unique_ptr< property_base_t > clone(res_source_info)
Create a copy of this property.
Definition: property.hpp:103
access_t get_access_mode() const
Return the current access mode.
Definition: property.hpp:87
virtual ~property_base_t()
Definition: property.hpp:45
bool write_access_granted() const
Returns true if this property can be written to.
Definition: property.hpp:81
bool read_access_granted() const
Returns true if this property can be read.
Definition: property.hpp:75
virtual bool is_dirty() const =0
Query this property's dirty flag.
Definition: property.hpp:151
const data_t & get() const
Get the value of this property.
Definition: property.hpp:252
void set(const data_t &value)
Returns the source info for the property.
Definition: property.hpp:215
bool is_dirty() const override
Returns the dirty state of this property.
Definition: property.hpp:169
property_t< data_t > & operator=(const data_t &value)
Definition: property.hpp:276
bool is_valid() const override
Query this property's valid flag.
Definition: property.hpp:178
void set_from_str(const std::string &new_val_str) override
Definition: property.hpp:197
data_t value_type
We want to be good C++ citizens.
Definition: property.hpp:154
bool operator==(const data_t &rhs)
Definition: property.hpp:271
bool equal(property_base_t *rhs) const override
Return true if rhs has the same type and value.
Definition: property.hpp:183
void force_dirty() override
Definition: property.hpp:232
std::unique_ptr< property_base_t > clone(res_source_info new_src_info) override
Create a copy of this property.
Definition: property.hpp:191
property_t(const property_t< data_t > &prop)=default
#define UHD_API_HEADER
Definition: config.h:88
#define UHD_API
Definition: config.h:87
Definition: build_info.hpp:12
Definition: exception.hpp:168
Definition: exception.hpp:157
Definition: exception.hpp:281
Definition: res_source_info.hpp:18
Definition: exception.hpp:132
Definition: exception.hpp:96
Definition: exception.hpp:108