ADTF
Loading...
Searching...
No Matches
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
24namespace ddl {
25namespace access_element {
26// define all needed error types and values locally
28_MAKE_RESULT(-3, ERR_UNEXPECTED);
29_MAKE_RESULT(-20, ERR_NOT_FOUND);
31
32namespace detail {
33
35template <typename T>
36using is_factory = std::is_member_function_pointer<decltype(&T::getStaticElementCount)>;
37
38template <typename T, typename Enable = void>
39struct 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
53template <typename T>
54struct 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
68template <typename T>
69a_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_ERROR_DESCRIPTION(ERR_NOT_FOUND, "element was not found");
93}
94
96
97} // namespace detail
98
106template <typename T>
107a_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_ERROR_DESCRIPTION(ERR_NOT_FOUND, "element was not found");
121}
122
130template <typename T>
132 const std::string& struct_name,
133 size_t& index)
134{
135 return detail::findComplexIndex<T>(decoder, struct_name, index, ".");
136}
137
145template <typename T>
147 const std::string& array_name,
148 size_t& index)
149{
150 return detail::findComplexIndex<T>(decoder, array_name, index, "[");
151}
152
160template <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
189template <typename T>
190a_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
204template <typename T>
205a_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
218template <typename T>
219a_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
236template <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
252template <typename T>
253a_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
269template <typename T>
270const 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
286template <typename T>
287void* 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
303template <typename STRUCT, typename T>
304const 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
320template <typename STRUCT, typename T>
321STRUCT* 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
338template <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_ERROR_DESCRIPTION(ERR_NOT_FOUND, "address of struct was not found");
346 }
347
348 a_util::memory::copy(struct_value, sizeof(T), address, sizeof(T));
349 return a_util::result::SUCCESS;
350}
351
359template <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_ERROR_DESCRIPTION(ERR_NOT_FOUND, "address of struct was not found");
367 }
368
369 a_util::memory::copy(address, sizeof(T), struct_value, sizeof(T));
370 return a_util::result::SUCCESS;
371}
372
379template <typename ARRAY_TYPE, typename T>
380const 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
396template <typename ARRAY_TYPE, typename T>
397ARRAY_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
415template <typename CODEC>
416a_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_ERROR_DESCRIPTION(ERR_UNEXPECTED, "address of element was not found");
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
457template <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
478template <typename T>
479a_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
510template <typename T>
511std::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
546template <typename T>
547std::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
Definition result_type_decl.h:34
Definition variant.h:46
VariantType getType() const
Returns the current underlying data type of the instance.
std::string asString() const
#define RETURN_ERROR_DESCRIPTION(_errcode,...)
Definition error_def.h:39
#define DDL_GET_ENUM_CASE(__variant_type, __data_type)
For internal use only.
Definition access_element.h:491
bool copy(void *dest, std::size_t dest_size, const void *source, std::size_t bytes_to_copy)
int compare(const char *left, const char *right)
definition of the access_element namespace (codecs)
Definition access_element.h:25
a_util::result::Result findArrayEndIndex(const T &decoder, const std::string &array_name, size_t &index)
Definition access_element.h:161
const void * getValueAddress(const T &decoder, const std::string &element_name)
Definition access_element.h:270
std::string getValueAsString(const T &decoder, size_t element_index)
Definition access_element.h:511
a_util::result::Result reset(T &codec, const std::string &element_name)
Definition access_element.h:479
const STRUCT * getStructAddress(const T &decoder, const std::string &struct_name)
Definition access_element.h:304
const ARRAY_TYPE * getArrayAddress(const T &decoder, const std::string &array_name)
Definition access_element.h:380
a_util::result::Result getStructValue(const CODEC &decoder, const std::string &struct_name, T *struct_value)
Definition access_element.h:339
a_util::result::Result findArrayIndex(const T &decoder, const std::string &array_name, size_t &index)
Definition access_element.h:146
a_util::result::Result setStructValue(CODEC &codec, const std::string &struct_name, const T *struct_value)
Definition access_element.h:360
a_util::result::Result getArrayValue(const CODEC &decoder, const std::string &array_name, T *array_value)
Definition access_element.h:458
a_util::result::Result findIndex(const T &decoder, const std::string &element_name, size_t &index)
Definition access_element.h:107
a_util::result::Result getValue(const T &decoder, const std::string &element_name, void *value)
Definition access_element.h:190
a_util::result::Result findStructIndex(const T &decoder, const std::string &struct_name, size_t &index)
Definition access_element.h:131
a_util::result::Result setValue(T &codec, const std::string &element_name, const void *value)
Definition access_element.h:205
a_util::result::Result getArray(const CODEC &decoder, const std::string &array_name, const void *&start_address, size_t &size)
Definition access_element.h:416
Namespace for the new faster CodecFactory/Decoder/Codec implementation.
Definition codec.h:22
definition of the ddl namespace
Definition codec.h:21
#define _MAKE_RESULT(_no, _label)
Definition result_info_decl.h:36
Definition struct_element.h:32
std::string name
The full name of the element.
Definition struct_element.h:33