PdCom  5.3
Process data communication client
Loading...
Searching...
No Matches
DataDeserializer.h
Go to the documentation of this file.
1/*****************************************************************************
2 * vim:tw=78
3 *
4 * Copyright (C) 2022 Richard Hacker (lerichi at gmx dot net),
5 * Florian Pose (fp at igh dot de),
6 * Bjarne von Horn (vh at igh dot de).
7 *
8 * This file is part of the PdCom library.
9 *
10 * The PdCom library is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or (at your
13 * option) any later version.
14 *
15 * The PdCom library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the PdCom library. If not, see <http://www.gnu.org/licenses/>.
22 *
23 *****************************************************************************/
24
26
27#ifndef PDCOM5_DATADESERIALIZER_H
28#define PDCOM5_DATADESERIALIZER_H
29
30#include "Exception.h"
31#include "details.h"
32
33#include <cstdint>
34#include <string>
35#include <type_traits>
36#include <vector>
37
38namespace PdCom {
48
49template <class Derived>
51{
61 template <typename T>
62 typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
63 getValue(T &dest, size_t offset = 0) const;
64
69 template <typename T>
70 typename std::enable_if<std::is_arithmetic<T>::value, void>::type
71 getValue(T &dest, size_t offset = 0) const
72 {
73 const auto var = static_cast<const Derived &>(*this).getVariable();
74 const auto total_elements = var.getSizeInfo().totalElements();
75 if (offset >= total_elements)
76 throw InvalidArgument(
77 "offset too large, must be less than "
78 + std::to_string(total_elements));
81 static_cast<const Derived &>(*this).getData(),
82 var.getTypeInfo().type, 1, offset);
83 }
84
85 template <typename T, size_t M, size_t N>
86 void getValue(T (&dest)[M][N]) const
87 {
88 const auto var = static_cast<const Derived &>(*this).getVariable();
89 if (var.getSizeInfo().totalElements() != M * N)
90 throw InvalidArgument(
91 "Size mismatch between destination and source");
94 static_cast<const Derived &>(*this).getData(),
95 var.getTypeInfo().type, M * N);
96 }
97 template <typename T, size_t N>
98 void getValue(T (&dest)[N], size_t offset = 0) const
99 {
100 const auto var = static_cast<const Derived &>(*this).getVariable();
101 const auto total_elements = var.getSizeInfo().totalElements();
102 if (offset >= total_elements)
103 throw InvalidArgument(
104 "offset too large, must be less than "
105 + std::to_string(total_elements));
106 details::copyData(
107 dest, details::TypeInfoTraits<T>::type_info.type,
108 static_cast<const Derived &>(*this).getData(),
109 var.getTypeInfo().type,
110 std::min<size_t>(N, total_elements - offset), offset);
111 }
112 template <typename T>
113 T getValue() const
114 {
115 T ans;
116 this->getValue(ans);
117 return ans;
118 }
119};
120
121template <class Derived>
122template <typename T>
123inline typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
124DataDeserializer<Derived>::getValue(T &dest, size_t offset) const
125{
126 const auto var = static_cast<const Derived &>(*this).getVariable();
127 const auto total_elements = var.getSizeInfo().totalElements();
128 static_assert(
129 std::is_same<
130 decltype(dest[0]),
131 typename std::add_lvalue_reference<
132 typename T::value_type>::type>::value,
133 "Index operator does not return a lvalue reference of an "
134 "integral");
135 if (offset >= total_elements)
136 throw InvalidArgument("Offset too large");
137 const auto count = std::min<size_t>(dest.size(), total_elements - offset);
138 const auto src_type = var.getTypeInfo();
139 const auto dst_type =
141
142 const auto src = static_cast<const Derived &>(*this).getData();
144 for (unsigned int i = 0; i < count; ++i) {
146 &dest[i], dst_type, src, src_type.type, 1, offset + i);
147 }
148 }
149 else {
151 &dest[0], dst_type, src, src_type.type, count, offset);
152 }
153}
154
155} // namespace PdCom
156
157
158#endif // PDCOM5_DATADESERIALIZER_H
void PDCOM5_PUBLIC copyData(void *dst, TypeInfo::DataType dst_type, const void *src, TypeInfo::DataType src_type, size_t nelem, size_t offset=0)
Data Conversion Matrix.
Data Deserialisation helper.
Definition DataDeserializer.h:51
std::enable_if< std::is_arithmetic< T >::value, void >::type getValue(T &dest, size_t offset=0) const
Copy the values into a custom buffer.
Definition DataDeserializer.h:71
std::enable_if<!std::is_arithmetic< T >::value, void >::type getValue(T &dest, size_t offset=0) const
Copy the values into a custom buffer.
Definition DataDeserializer.h:124
Definition Exception.h:47
Definition details.h:44
Definition details.h:184