Friendly LWM2M client
Resource.h
Go to the documentation of this file.
1 #ifndef WPP_RESOURCE_H
2 #define WPP_RESOURCE_H
3 
4 #include <unordered_map>
5 #include <type_traits>
6 #include <variant>
7 
8 #include "ObjectInfo.h"
9 #include "ItemOp.h"
10 #include "WppTypes.h"
11 #include "WppLogs.h"
12 
13 namespace wpp {
14 
49 class Resource {
50 public: /* ---------- Public subtypes ----------*/
54  using DATA_T = std::variant<BOOL_T, INT_T, UINT_T, FLOAT_T, OPAQUE_T, OBJ_LINK_T, STRING_T, EXECUTE_T>;
55 
59  struct ResInst {
62  };
63 
68  VERIFY_OBJ_LINK_T, VERIFY_STRING_T, VERIFY_EXECUTE_T/*, VERIFY_CORE_LINK_T*/>; // VERIFY_CORE_LINK_T the same as VERIFY_STRING_T therefore we use only VERIFY_STRING_T
69 
70 public: /* ---------- Public methods for common usage ----------*/
71  Resource();
72  Resource(ID_T id, const ItemOp &operation, IS_SINGLE isSingle, IS_MANDATORY isMandatory, TYPE_ID dataType);
73  Resource(const Resource& resource);
74  Resource(Resource&& resource);
75  Resource& operator=(const Resource& other);
76  Resource& operator=(Resource&& other);
77 
78  /* ---------- Methods for get resource metadata ----------*/
79  ID_T getId() const;
80  TYPE_ID getTypeId() const;
81  const ItemOp& getOperation() const;
82  bool isMandatory() const;
83  bool isOptional() const;
84  bool isSingle() const;
85  bool isMultiple() const;
86 
87  /* ---------- Helpful methods for check resource parameters ----------*/
96  template<typename T>
97  bool isDataValueValid(const T &data) const;
98 
105  bool isExist(ID_T resInstId) const;
106 
112  size_t instCount() const;
113 
119  std::vector<ID_T> instIds() const;
120 
126  ID_T newInstId() const;
127 
128  /* ---------- Methods for manage verifier ----------*/
135  bool setDataVerifier(const DATA_VERIFIER_T &verifier);
136 
137  /* ---------- Methods for manage resource data ----------*/
147  template<typename T>
148  bool set(const T &value, ID_T resInstId = SINGLE_INSTANCE_ID);
149 
159  template<typename T>
160  bool set(T &&value, ID_T resInstId = SINGLE_INSTANCE_ID);
161 
176  template<typename T>
177  const T& get(ID_T resInstId = SINGLE_INSTANCE_ID);
178 
192  template<typename T>
193  bool add(const T &value);
194 
208  template<typename T>
209  bool add(T &&value);
210 
217  bool remove(ID_T resInstId);
218 
224  bool clear();
225 
226 private:
227  template<typename T>
228  bool isDataTypeValid() const;
229  bool isDataVerifierValid(const DATA_VERIFIER_T &verifier) const;
230  bool isInstanceIdPossible(ID_T resInstId) const;
231  bool isTypeIdCompatible(TYPE_ID type) const;
232  std::vector<ResInst>::iterator getInstIter(ID_T resInstId) const;
233 
234 private: /* ---------- Private properties ----------*/
235  ID_T _id;
236  ItemOp _operation;
237  IS_SINGLE _isSingle;
238  IS_MANDATORY _isMandatory;
239  TYPE_ID _typeID;
240  mutable std::vector<ResInst> _instances;
241  DATA_VERIFIER_T _dataVerifier;
242 };
243 
244 
245 /* ---------- Implementation of template methods ----------*/
246 template<typename T>
247 bool Resource::isDataTypeValid() const {
248  TYPE_ID typeID = dataTypeToID<T>();
249  return typeID != TYPE_ID::UNDEFINED && isTypeIdCompatible(typeID);
250 }
251 
252 template<typename T>
253 bool Resource::set(const T &value, ID_T resInstId) {
254  if(isSingle()) resInstId = SINGLE_INSTANCE_ID;
255  if (!isInstanceIdPossible(resInstId) || !isDataValueValid(value)) {
256  WPP_LOGW(TAG_WPP_RES, "Resource[%d], invalid data value or instance id is not possible", _id);
257  return false;
258  }
259 
260  if (isExist(resInstId)) {
261  auto instIter = getInstIter(resInstId);
262  instIter->data = value;
263  } else {
264  _instances.push_back({resInstId, value});
265  }
266 
267  return true;
268 }
269 
270 template<typename T>
271 bool Resource::set(T &&value, ID_T resInstId) {
272  if(isSingle()) resInstId = SINGLE_INSTANCE_ID;
273  if (!isInstanceIdPossible(resInstId) || !isDataValueValid(value)) {
274  WPP_LOGW(TAG_WPP_RES, "Resource[%d], invalid data value or instance id is not possible", _id);
275  return false;
276  }
277 
278  if (isExist(resInstId)) {
279  auto instIter = getInstIter(resInstId);
280  instIter->data = std::move(value);
281  } else {
282  ResInst newInst = {resInstId, std::move(value)};
283  _instances.push_back(std::move(newInst));
284  }
285 
286  return true;
287 }
288 
289 template<typename T>
290 const T& Resource::get(ID_T resInstId) {
291  if(isSingle()) resInstId = SINGLE_INSTANCE_ID;
292  if (!isDataTypeValid<T>() || !isExist(resInstId)) {
293  WPP_LOGE(TAG_WPP_RES, "Resource[%d], invalid data type or instance does not exist", _id);
294  // TODO: It is workaround for the case when resource is not found
295  // This behavior is better than returning NULL, but it is not the best solution
296  // Return empty value if the data type is not valid or the instance does not exist
297  static T empty;
298  return empty;
299  }
300 
301  auto instIter = getInstIter(resInstId);
302  return std::get<T>(instIter->data);
303 }
304 
305 template<typename T>
306 bool Resource::add(const T &value) {
307  if (isSingle()) {
308  WPP_LOGW(TAG_WPP_RES, "Resource[%d] is SINGLE", _id);
309  return false;
310  }
311  if (!isDataValueValid(value)) {
312  WPP_LOGW(TAG_WPP_RES, "Resource[%d] invalid data value", _id);
313  return false;
314  }
315 
316  ID_T resInstId = newInstId();
317  if (resInstId == ID_T_MAX_VAL) {
318  WPP_LOGE(TAG_WPP_RES, "Resource[%d], no available instance ID", _id);
319  return false;
320  }
321  _instances.push_back({resInstId, value});
322 
323  return true;
324 }
325 
326 template<typename T>
327 bool Resource::add(T &&value) {
328  if (isSingle()) {
329  WPP_LOGW(TAG_WPP_RES, "Resource[%d] is SINGLE", _id);
330  return false;
331  }
332  if (!isDataValueValid(value)) {
333  WPP_LOGW(TAG_WPP_RES, "Resource[%d] invalid data value", _id);
334  return false;
335  }
336 
337  ID_T resInstId = newInstId();
338  if (resInstId == ID_T_MAX_VAL) {
339  WPP_LOGE(TAG_WPP_RES, "Resource[%d], no available instance ID", _id);
340  return false;
341  }
342  ResInst newInst = {resInstId, std::move(value)};
343  _instances.push_back(std::move(newInst));
344 
345  return true;
346 }
347 
348 template<typename T>
349 bool Resource::isDataValueValid(const T &data) const {
350  if (!isDataTypeValid<T>()) return false;
351  if (!isDataVerifierValid(_dataVerifier)) return true;
352 
353  if constexpr (std::is_same<T, BOOL_T>::value) {
354  return std::get<VERIFY_BOOL_T>(_dataVerifier)(data);
355  } else if constexpr (std::is_same<T, INT_T>::value) {
356  return std::get<VERIFY_INT_T>(_dataVerifier)(data);
357  } else if constexpr (std::is_same<T, UINT_T>::value) {
358  return std::get<VERIFY_UINT_T>(_dataVerifier)(data);
359  } else if constexpr (std::is_same<T, FLOAT_T>::value) {
360  return std::get<VERIFY_FLOAT_T>(_dataVerifier)(data);
361  } else if constexpr (std::is_same<T, OPAQUE_T>::value) {
362  return std::get<VERIFY_OPAQUE_T>(_dataVerifier)(data);
363  } else if constexpr (std::is_same<T, OBJ_LINK_T>::value) {
364  return std::get<VERIFY_OBJ_LINK_T>(_dataVerifier)(data);
365  } else if constexpr (std::is_same<T, STRING_T>::value) {
366  return std::get<VERIFY_STRING_T>(_dataVerifier)(data);
367  } else if constexpr (std::is_same<T, EXECUTE_T>::value) {
368  return std::get<VERIFY_EXECUTE_T>(_dataVerifier)(data);
369  } else {
370  return false;
371  }
372 }
373 
374 } // namespace wpp
375 
376 #endif //WPP_RESOURCE_H
#define TAG_WPP_RES
Definition: WppLogs.h:13
#define WPP_LOGE(TAG, FMT,...)
Definition: WppLogs.h:49
#define WPP_LOGW(TAG, FMT,...)
Definition: WppLogs.h:43
#define SINGLE_INSTANCE_ID
Definition: WppTypes.h:13
#define ID_T_MAX_VAL
Definition: WppTypes.h:16
The Resource class in the wpp namespace is a comprehensive and flexible class designed to handle diff...
Definition: Resource.h:49
bool clear()
Remove all instances.
Definition: Resource.cpp:155
bool isExist(ID_T resInstId) const
Check if the instance ID is exist.
Definition: Resource.cpp:104
std::variant< BOOL_T, INT_T, UINT_T, FLOAT_T, OPAQUE_T, OBJ_LINK_T, STRING_T, EXECUTE_T > DATA_T
Universal type for data.
Definition: Resource.h:54
bool isMultiple() const
Definition: Resource.cpp:96
Resource & operator=(const Resource &other)
Definition: Resource.cpp:43
bool remove(ID_T resInstId)
Remove resource instance if resource is MULTIPLE and instance exists, if the resource is SINGLE remov...
Definition: Resource.cpp:144
bool add(const T &value)
Add new instance with data value by copy for the MULTIPLE resource.
Definition: Resource.h:306
bool set(const T &value, ID_T resInstId=SINGLE_INSTANCE_ID)
Set data value by copy for the resource (instance)
Definition: Resource.h:253
ID_T getId() const
Definition: Resource.cpp:72
std::variant< VERIFY_INT_T, VERIFY_UINT_T, VERIFY_FLOAT_T, VERIFY_OPAQUE_T, VERIFY_BOOL_T, VERIFY_OBJ_LINK_T, VERIFY_STRING_T, VERIFY_EXECUTE_T > DATA_VERIFIER_T
Universal type for data validation functions.
Definition: Resource.h:68
bool isSingle() const
Definition: Resource.cpp:92
bool isMandatory() const
Definition: Resource.cpp:84
const ItemOp & getOperation() const
Definition: Resource.cpp:80
size_t instCount() const
Get the number of resource instances.
Definition: Resource.cpp:123
ID_T newInstId() const
Find first available instance ID that is not used.
Definition: Resource.cpp:134
std::vector< ID_T > instIds() const
Returns vector with available ids of resource instances.
Definition: Resource.cpp:127
bool isDataValueValid(const T &data) const
Check if the data type and value are valid.
Definition: Resource.h:349
bool setDataVerifier(const DATA_VERIFIER_T &verifier)
Set data verifier for the resource.
Definition: Resource.cpp:164
const T & get(ID_T resInstId=SINGLE_INSTANCE_ID)
Definition: Resource.h:290
TYPE_ID getTypeId() const
Definition: Resource.cpp:76
bool isOptional() const
Definition: Resource.cpp:88
The WppConnection class represents a connection interface for the Wpp library.
Definition: WppClient.cpp:14
IS_MANDATORY
Definition: WppTypes.h:116
std::function< bool(const EXECUTE_T &)> VERIFY_EXECUTE_T
Definition: WppTypes.h:101
std::function< bool(const BOOL_T &)> VERIFY_BOOL_T
Definition: WppTypes.h:98
uint16_t ID_T
Definition: WppTypes.h:15
std::function< bool(const STRING_T &)> VERIFY_STRING_T
Definition: WppTypes.h:100
std::function< bool(const INT_T &)> VERIFY_INT_T
Data validation function types.
Definition: WppTypes.h:94
std::function< bool(const OBJ_LINK_T &)> VERIFY_OBJ_LINK_T
Definition: WppTypes.h:99
std::function< bool(const UINT_T &)> VERIFY_UINT_T
Definition: WppTypes.h:95
std::function< bool(const FLOAT_T &)> VERIFY_FLOAT_T
Definition: WppTypes.h:96
std::function< bool(const OPAQUE_T &)> VERIFY_OPAQUE_T
Definition: WppTypes.h:97
IS_SINGLE
Definition: WppTypes.h:111
TYPE_ID
Wpp data types ID.
Definition: WppTypes.h:23
The ItemOp struct represents the operations that can be performed on a instance/resource.
Definition: ItemOp.h:24
Type for resource instance.
Definition: Resource.h:59