ADTF  3.18.2
workspace/conan/dev_essential/1.3.3/dw/stable/package/37682420cd166e229516a41c8d6a139a0b13e1e1/include/ddl/codec/legacy/access_element.h
Go to the documentation of this file.
1 
14 #ifndef DDL_STRUCT_ELEMENT_ACCESS_CLASS_HEADER
15 #define DDL_STRUCT_ELEMENT_ACCESS_CLASS_HEADER
16 
17 #include <a_util/result.h>
18 #include <a_util/strings.h>
21 
22 #include <type_traits>
23 
24 namespace ddl {
25 namespace access_element {
26 // define all needed error types and values locally
28 _MAKE_RESULT(-3, ERR_UNEXPECTED);
29 _MAKE_RESULT(-20, ERR_NOT_FOUND);
32 namespace detail {
33 
35 template <typename T>
36 using is_factory = std::is_member_function_pointer<decltype(&T::getStaticElementCount)>;
37 
38 template <typename T, typename Enable = void>
39 struct Accessor {
40  static inline size_t getElementCount(const T& access_type)
41  {
42  return access_type.getElementCount();
43  }
44 
45  static inline a_util::result::Result getElement(const T& access_type,
46  size_t element_idx,
47  const StructElement*& element)
48  {
49  return access_type.getElement(element_idx, element);
50  }
51 };
52 
53 template <typename T>
54 struct Accessor<T, typename std::enable_if<is_factory<T>::value>::type> {
55  static inline size_t getElementCount(const T& access_type)
56  {
57  return access_type.getStaticElementCount();
58  }
59 
60  static inline a_util::result::Result getElement(const T& access_type,
61  size_t element_idx,
62  const StructElement*& element)
63  {
64  return access_type.getStaticElement(element_idx, element);
65  }
66 };
67 
68 template <typename T>
69 a_util::result::Result findComplexIndex(const T& decoder,
70  const std::string& struct_name,
71  size_t& index,
72  const char* post_fix)
73 {
74  if (struct_name.empty()) {
75  index = 0;
76  return a_util::result::SUCCESS;
77  }
78 
79  size_t element_count = detail::Accessor<T>::getElementCount(decoder);
80  std::string prefix = struct_name + post_fix;
81  for (size_t element_index = 0; element_index < element_count; ++element_index) {
82  const StructElement* element;
83  if (detail::Accessor<T>::getElement(decoder, element_index, element)) {
84  if (a_util::strings::compare(element->name.c_str(), prefix.c_str(), 0, prefix.size()) ==
85  0) {
86  index = element_index;
87  return a_util::result::SUCCESS;
88  }
89  }
90  }
91 
92  return ERR_NOT_FOUND;
93 }
94 
97 } // namespace detail
98 
106 template <typename T>
107 a_util::result::Result findIndex(const T& decoder, const std::string& element_name, size_t& index)
108 {
109  size_t element_count = detail::Accessor<T>::getElementCount(decoder);
110  for (size_t element_index = 0; element_index < element_count; ++element_index) {
111  const StructElement* element;
112  if (detail::Accessor<T>::getElement(decoder, element_index, element)) {
113  if (element->name == element_name) {
114  index = element_index;
115  return a_util::result::SUCCESS;
116  }
117  }
118  }
119 
120  return ERR_NOT_FOUND;
121 }
122 
130 template <typename T>
132  const std::string& struct_name,
133  size_t& index)
134 {
135  return detail::findComplexIndex<T>(decoder, struct_name, index, ".");
136 }
137 
145 template <typename T>
147  const std::string& array_name,
148  size_t& index)
149 {
150  return detail::findComplexIndex<T>(decoder, array_name, index, "[");
151 }
152 
160 template <typename T>
162  const std::string& array_name,
163  size_t& index)
164 {
165  size_t element_count = detail::Accessor<T>::getElementCount(decoder);
166  std::string prefix = array_name + "[";
167  for (index += 1; index < element_count; ++index) {
168  const StructElement* element;
169  if (!detail::Accessor<T>::getElement(decoder, index, element)) {
170  return a_util::result::SUCCESS;
171  }
172 
173  if (a_util::strings::compare(element->name.c_str(), prefix.c_str(), 0, prefix.size()) !=
174  0) {
175  return a_util::result::SUCCESS;
176  }
177  }
178 
179  return a_util::result::SUCCESS;
180 }
181 
189 template <typename T>
190 a_util::result::Result getValue(const T& decoder, const std::string& element_name, void* value)
191 {
192  auto element_index{static_cast<std::size_t>(-1)};
193  const a_util::result::Result res = findIndex(decoder, element_name, element_index);
194  return res ? decoder.getElementValue(element_index, value) : res;
195 }
196 
204 template <typename T>
205 a_util::result::Result setValue(T& codec, const std::string& element_name, const void* value)
206 {
207  auto element_index{static_cast<std::size_t>(-1)};
208  const a_util::result::Result res = findIndex(codec, element_name, element_index);
209  return res ? codec.setElementValue(element_index, value) : res;
210 }
211 
218 template <typename T>
219 a_util::variant::Variant getValue(const T& decoder, const std::string& element_name)
220 {
222  auto element_index{static_cast<std::size_t>(-1)};
223  if (findIndex(decoder, element_name, element_index)) {
224  decoder.getElementValue(element_index, result);
225  }
226  return result;
227 }
228 
236 template <typename T>
238  const std::string& element_name,
239  const a_util::variant::Variant& value)
240 {
241  auto element_index{static_cast<std::size_t>(-1)};
242  const a_util::result::Result res = findIndex(codec, element_name, element_index);
243  return res ? codec.setElementValue(element_index, value) : res;
244 }
245 
252 template <typename T>
253 a_util::variant::Variant getValue(const T& decoder, size_t element_index)
254 {
256  if (decoder.getElementValue(element_index, result)) {
257  return result;
258  }
259 
260  return a_util::variant::Variant(static_cast<int32_t>(0));
261 }
262 
269 template <typename T>
270 const void* getValueAddress(const T& decoder, const std::string& element_name)
271 {
272  auto element_index{static_cast<std::size_t>(-1)};
273  if (find_index(decoder, element_name, element_index)) {
274  return decoder.getElementAddress(element_index);
275  }
276 
277  return NULL;
278 }
279 
286 template <typename T>
287 void* getValueAddress(T& codec, const std::string& element_name)
288 {
289  auto element_index{static_cast<std::size_t>(-1)};
290  if (findIndex(codec, element_name, element_index)) {
291  return codec.getElementAddress(element_index);
292  }
293 
294  return NULL;
295 }
296 
303 template <typename STRUCT, typename T>
304 const STRUCT* getStructAddress(const T& decoder, const std::string& struct_name)
305 {
306  auto element_index{static_cast<std::size_t>(-1)};
307  if (findStructIndex(decoder, struct_name, element_index)) {
308  return reinterpret_cast<const STRUCT*>(decoder.getElementAddress(element_index));
309  }
310 
311  return NULL;
312 }
313 
320 template <typename STRUCT, typename T>
321 STRUCT* getStructAddress(T& codec, const std::string& struct_name)
322 {
323  auto element_index{static_cast<std::size_t>(-1)};
324  if (findStructIndex(codec, struct_name, element_index)) {
325  return reinterpret_cast<STRUCT*>(codec.getElementAddress(element_index));
326  }
327 
328  return NULL;
329 }
330 
338 template <typename T, typename CODEC>
340  const std::string& struct_name,
341  T* struct_value)
342 {
343  const T* address = getStructAddress<T>(decoder, struct_name);
344  if (!address) {
345  return ERR_NOT_FOUND;
346  }
347 
348  a_util::memory::copy(struct_value, sizeof(T), address, sizeof(T));
349  return a_util::result::SUCCESS;
350 }
351 
359 template <typename T, typename CODEC>
361  const std::string& struct_name,
362  const T* struct_value)
363 {
364  T* address = getStructAddress<T>(codec, struct_name);
365  if (!address) {
366  return ERR_NOT_FOUND;
367  }
368 
369  a_util::memory::copy(address, sizeof(T), struct_value, sizeof(T));
370  return a_util::result::SUCCESS;
371 }
372 
379 template <typename ARRAY_TYPE, typename T>
380 const ARRAY_TYPE* getArrayAddress(const T& decoder, const std::string& array_name)
381 {
382  auto element_index{static_cast<std::size_t>(-1)};
383  if (find_array_index(decoder, array_name, element_index)) {
384  return reinterpret_cast<const ARRAY_TYPE*>(decoder.getElementAddress(element_index));
385  }
386 
387  return NULL;
388 }
389 
396 template <typename ARRAY_TYPE, typename T>
397 ARRAY_TYPE* getArrayAddress(T& codec, const std::string& array_name)
398 {
399  auto element_index{static_cast<std::size_t>(-1)};
400  if (findArrayIndex(codec, array_name, element_index)) {
401  return reinterpret_cast<ARRAY_TYPE*>(codec.getElementAddress(element_index));
402  }
403 
404  return NULL;
405 }
406 
415 template <typename CODEC>
416 a_util::result::Result getArray(const CODEC& decoder,
417  const std::string& array_name,
418  const void*& start_address,
419  size_t& size)
420 {
421  size_t start_index = 0;
422  a_util::result::Result res = findArrayIndex(decoder, array_name, start_index);
423  if (!res)
424  return res;
425 
426  size_t end_index = start_index;
427  res = findArrayEndIndex(decoder, array_name, end_index);
428  if (!res)
429  return res;
430 
431  start_address = decoder.getElementAddress(start_index);
432  if (!start_address) {
433  return ERR_UNEXPECTED;
434  }
435 
436  const void* end_adress = decoder.getElementAddress(end_index);
437  if (end_adress) {
438  size = static_cast<const uint8_t*>(end_adress) - static_cast<const uint8_t*>(start_address);
439  }
440  else {
441  // it reaches til the end
442  size_t start_offset = static_cast<const uint8_t*>(start_address) -
443  static_cast<const uint8_t*>(decoder.getElementAddress(0));
444  size = decoder.getBufferSize(decoder.getRepresentation()) - start_offset;
445  }
446 
447  return a_util::result::SUCCESS;
448 }
449 
457 template <typename T, typename CODEC>
459  const std::string& array_name,
460  T* array_value)
461 {
462  const void* start_address = nullptr;
463  size_t size = 0;
464  a_util::result::Result res = getArray(decoder, array_name, start_address, size);
465  if (!res)
466  return res;
467 
468  a_util::memory::copy(array_value, size, start_address, size);
469  return a_util::result::SUCCESS;
470 }
471 
478 template <typename T>
479 a_util::result::Result reset(T& codec, const std::string& element_name)
480 {
481  auto element_index{static_cast<std::size_t>(-1)};
482  a_util::result::Result res = findIndex(codec, element_name, element_index);
483  if (!res)
484  return res;
485 
486  uint64_t zero = 0;
487  return codec.setElementValue(element_index, &zero);
488 }
489 
491 #define DDL_GET_ENUM_CASE(__variant_type, __data_type) \
492  case a_util::variant::VT_##__variant_type: { \
493  __data_type xValue = value.get##__variant_type(); \
494  for (AccessEnumType::const_iterator it = element->p_enum->begin(); \
495  it != element->p_enum->end(); \
496  ++it) { \
497  if (xValue == it->second.as##__variant_type()) { \
498  return it->first; \
499  } \
500  } \
501  break; \
502  }
503 
510 template <typename T>
511 std::string getValueAsString(const T& decoder, size_t element_index)
512 {
514  const StructElement* element{};
515  if (decoder.getElement(element_index, element)) {
516  if (decoder.getElementValue(element_index, value)) {
517  if (element->p_enum) {
518  switch (value.getType()) {
519  DDL_GET_ENUM_CASE(Bool, bool)
520  DDL_GET_ENUM_CASE(Int8, int8_t)
521  DDL_GET_ENUM_CASE(UInt8, uint8_t)
522  DDL_GET_ENUM_CASE(Int16, int16_t)
523  DDL_GET_ENUM_CASE(UInt16, uint16_t)
524  DDL_GET_ENUM_CASE(Int32, int32_t)
525  DDL_GET_ENUM_CASE(UInt32, uint32_t)
526  DDL_GET_ENUM_CASE(Int64, int64_t)
527  DDL_GET_ENUM_CASE(UInt64, uint64_t)
528  DDL_GET_ENUM_CASE(Float, float)
529  DDL_GET_ENUM_CASE(Double, double)
530  default:
531  break;
532  }
533  }
534  }
535  }
536 
537  return value.asString();
538 }
539 
546 template <typename T>
547 std::string getValueAsString(const T& decoder, const std::string& element_name)
548 {
549  auto element_index{static_cast<std::size_t>(-1)};
550  if (findIndex(decoder, element_name, element_index)) {
551  return getValueAsString(decoder, element_index);
552  }
553  return "";
554 }
555 
556 } // namespace access_element
557 
558 } // namespace ddl
559 
560 #endif // DDL_STRUCT_ELEMENT_ACCESS_CLASS_HEADER
A common result class usable as return value throughout.
std::string asString() const
Convert the value of the variant.
VariantType getType() const
Returns the current underlying data type of the instance.
Definition of old CodecFactory legacy header for old Codec API.
bool copy(void *dest, std::size_t dest_size, const void *source, std::size_t bytes_to_copy)
Portable safe memcopy.
bool zero(void *dest, std::size_t dest_size, std::size_t bytes_to_zero)
Portable safe memzero.
int compare(const char *left, const char *right)
Compares two 0-terminated C-strings.
tResult find_index(const T &oDecoder, const A_UTILS_NS::cString &strElementName, size_t &nIndex)
Find the index of an element by name.
tResult find_array_index(const T &oDecoder, const A_UTILS_NS::cString &strArrayName, size_t &nIndex)
Find the index of the first element of an array by name.
a_util::result::Result findArrayEndIndex(const T &decoder, const std::string &array_name, size_t &index)
find the index of the first element after an array by name.
std::string getValueAsString(const T &decoder, size_t element_index)
Get the value of an element as a string, using enum value names if available.
a_util::result::Result reset(T &codec, const std::string &element_name)
Set the value of the requested element to zero.
const ARRAY_TYPE * getArrayAddress(const T &decoder, const std::string &array_name)
Get a pointer to an array by name.
a_util::result::Result getStructValue(const CODEC &decoder, const std::string &struct_name, T *struct_value)
Copy a sub-structure out of the structure.
const void * getValueAddress(const T &decoder, const std::string &element_name)
Get a pointer to an element by name.
const STRUCT * getStructAddress(const T &decoder, const std::string &struct_name)
Get a pointer to a sub-structure by name.
a_util::result::Result findArrayIndex(const T &decoder, const std::string &array_name, size_t &index)
find the index of the first element of an array by name.
a_util::result::Result setStructValue(CODEC &codec, const std::string &struct_name, const T *struct_value)
Copy a sub-structure into the structure.
a_util::result::Result getArrayValue(const CODEC &decoder, const std::string &array_name, T *array_value)
Copy an array out of the structure.
a_util::result::Result findIndex(const T &decoder, const std::string &element_name, size_t &index)
find the index of an element by name.
a_util::result::Result getValue(const T &decoder, const std::string &element_name, void *value)
Get the value of an element by name.
a_util::result::Result findStructIndex(const T &decoder, const std::string &struct_name, size_t &index)
find the index of the first element of a sub-structure by name.
a_util::result::Result setValue(T &codec, const std::string &element_name, const void *value)
Set the value of an element by name.
a_util::result::Result getArray(const CODEC &decoder, const std::string &array_name, const void *&start_address, size_t &size)
Get information about an array.
_MAKE_RESULT(-20, ERR_STRUCT_ELEMENT_NOT_FOUND)
Creates an a_util error ERR_AUTIL_NOT_FOUND.
Common include for component a_util::strings.
Definition of old StructElement legacy header for old Codec API.
Common include for component a_util::result.