PdCom  5.3
Process data communication client
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 
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 
38 namespace PdCom {
49 template <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));
79  details::copyData(
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");
92  details::copyData(
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 
121 template <class Derived>
122 template <typename T>
123 inline typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
124 DataDeserializer<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) {
145  details::copyData(
146  &dest[i], dst_type, src, src_type.type, 1, offset + i);
147  }
148  }
149  else {
150  details::copyData(
151  &dest[0], dst_type, src, src_type.type, count, offset);
152  }
153 }
154 
155 } // namespace PdCom
156 
157 
158 #endif // PDCOM5_DATADESERIALIZER_H
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
Definition: details.h:43
Definition: details.h:183
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
Data Deserialisation helper.
Definition: DataDeserializer.h:50
Definition: ClientStatistics.h:31
Definition: Exception.h:46