PLCnext API Documentation 25.0.2.69
RscReader.hpp
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
8#include "Arp/Base/Core/PimplPtr.hxx"
9#include "Arp/Base/Core/Enum.hxx"
10#include "Arp/Base/Commons/Io/Stream.hpp"
11#include "Arp/Base/Rsc/Commons/Rsc.hpp"
12#include "Arp/Base/Rsc/Commons/RscString.hxx"
13#include "Arp/Base/Rsc/Commons/RscVariant.hxx"
14#include "Arp/Base/Rsc/Commons/RscStream.hpp"
15#include "Arp/Base/Rsc/Commons/RscStreamReader.hpp"
16#include "Arp/Base/Rsc/Commons/RscException.hpp"
17#include "Arp/Base/Rsc/Commons/RscTypeInfo.hpp"
18#include "Arp/Base/Rsc/Commons/RscTypeDeduction.hpp"
19#include "Arp/Base/Rsc/Commons/Services/StructInfo.hxx"
20#include "Arp/Base/Rsc/Commons/Services/RscConcepts.hpp"
21#include <array>
22#include <vector>
23
24namespace Arp::Base::Rsc::Commons::Services
25{
26
28
33class ARP_EXPORT RscReader
34{
35public: // Impl forward declaration
36 class Impl;
37
38public: // construction
39 explicit RscReader(Stream& remoteStream);
40
41 // canonical construction/destruction/assignment
42 RscReader(const RscReader& arg);
43 RscReader(RscReader&& arg)noexcept;
45 RscReader& operator=(RscReader&& arg)noexcept;
47
48public: // setter/getter operations
49 RscStream GetStream(void);
50 RscStreamReader GetStreamReader(void);
51
52public: // concrete operations used by RscGenerator
53 void Read(RscPtr& result, bool omitTag = false);
54 void Read(RscConstPtr& result, bool omitTag = false);
55 void Read(String& result, bool omitTag = false);
56 void Read(DateTime& result, bool omitTag = false);
57 void Read(RscStream& stream, bool omitTag = false);
58 void Read(SecurityToken& result, bool omitTag = false);
59 void Read(RscVariantBase& result, bool omitTag = false);
60
61public: // template operations used by RscGenerator
62 template<RscEnumType T> void Read(T& result, bool omitTag = false);
63 template<RscPrimitiveType T> void Read(T& result, bool omitTag = false);
64 template<RscClassType T> void Read(T& result, bool omitTag = false);
65 template<RscSerializableType T> void Read(T& result, bool omitTag = false);
66 template<int N> void Read(RscVariant<N>& result, bool omitTag = false);
67 template<class T> void Read(std::vector<T>& result, bool omitTag = false);
68 template<class T> void Read(std::vector<std::vector<T>>& result, bool omitTag = false);
69 template<class T, size_t N> void Read(std::array<T, N>& result, bool omitTag = false );
70
71public: // auxiliaries operations
72 RscType ReadTag(void);
73 void ReadTag(RscType expectedTag);
74 size_t ReadFieldCount(void);
75 size_t ReadArrayLength(void);
76 void ReadBeginStruct(size_t fieldCount);
77 void ReadEnumeratorTag(RscType expectedTag, bool& isEndTag);
78
79private: // methods
80 template<class T>
81 size_t ReadBeginArray(RscType& elementType, bool omitTag);
82 void ReadPrimitive(byte* pValue, RscType type);
83
84public: // internal operations
85 Impl& GetImpl(void);
86 const Impl& GetImpl(void)const;
87
88private: // Impl usings
90
91private: // Impl fields
92 Pimpl pimpl;
93};
94
96// inline implementations of class RscReader
97
101template<RscEnumType T>
102inline void RscReader::Read(T& result, bool omitTag)
103{
104 RscType type = RscTypeDeduction::GetFrom(result);
105 if (!omitTag)
106 {
107 this->ReadTag(type);
108 }
109 typename Enum<T>::U value;
110 this->ReadPrimitive(reinterpret_cast<byte*>(&value), type);
111 result = static_cast<T>(value);
112}
113
117template<RscPrimitiveType T>
118inline void RscReader::Read(T& result, bool omitTag)
119{
120 RscType type = RscTypeDeduction::GetFrom(result);
121 if (!omitTag)
122 {
123 this->ReadTag(type);
124 }
125 this->ReadPrimitive(reinterpret_cast<byte*>(&result), type);
126}
127
131template<RscClassType T>
132inline void RscReader::Read(T& result, bool omitTag)
133{
134 RscType type = RscTypeDeduction::GetFrom(result);
135 if (!omitTag)
136 {
137 this->ReadTag(type);
138 }
139 result.Read(*this);
140}
141
145template<RscSerializableType T>
146inline void RscReader::Read(T& result, bool omitTag)
147{
148 if (!omitTag)
149 {
150 this->ReadBeginStruct(StructInfo<T>().FieldCount);
151 }
152 result.Deserialize(*this);
153}
154
158template<int N>
159inline void RscReader::Read(RscVariant<N>& result, bool omitTag)
160{
161 this->Read(static_cast<RscVariantBase&>(result), omitTag);
162}
163
167template<class T>
168inline void RscReader::Read(std::vector<T>& result, bool omitTag)
169{
170 RscType elementType = RscType::None;
171 size_t arraySize = this->ReadBeginArray<T>(elementType, omitTag);
172 result.reserve(arraySize);
173 bool omitElementTag = RscTypeInfo::IsConcreteType(elementType);
174 for (size_t i = 0; i < arraySize; ++i)
175 {
176 T value;
177 this->Read(value, omitElementTag);
178 result.push_back(value);
179 }
180}
181
185template<class T>
186inline void RscReader::Read(std::vector<std::vector<T>>& result, bool omitTag)
187{
188 RscType elementType = RscType::None;
189 this->ReadTag(RscType::Array);
190 size_t outerArraySize = this->ReadBeginArray<T>(elementType, omitTag);
191 result.reserve(outerArraySize);
192
193 bool omitElementTag = RscTypeInfo::IsConcreteType(elementType);
194 for (size_t i = 0; i < outerArraySize; ++i)
195 {
196 std::vector<T> innerArray;
197 size_t innerArraySize = this->ReadArrayLength();
198 innerArray.reserve(innerArraySize);
199
200 for (size_t j = 0; j < innerArraySize; ++j)
201 {
202 T value;
203 this->Read(value, omitElementTag);
204 innerArray.push_back(value);
205 }
206 result.emplace_back(std::move(innerArray));
207 }
208}
209
213template<class T, size_t N>
214inline void RscReader::Read(std::array<T, N>& result, bool omitTag)
215{
216 RscType elementType = RscType::None;
217 size_t arraySize = this->ReadBeginArray<T>(elementType, omitTag);
218 if (arraySize != N)
219 {
220 throw RscException(RscError::InvalidServiceData, "Received array does not contain {} elements", N);
221 }
222
223 bool omitTagElementTag = RscTypeInfo::IsConcreteType(elementType);
224 for (size_t i = 0; i < N; ++i)
225 {
226 T value;
227 this->Read(value, omitTagElementTag);
228 result[i] = value;
229 }
230}
231
235template<class T>
236inline size_t RscReader::ReadBeginArray(RscType& elementType, bool omitTag)
237{
238 elementType = RscTypeDeduction().Get<T>();
239 if (!omitTag)
240 {
241 this->ReadTag(RscType::Array);
242 if (elementType == RscType::Struct)
243 {
244 this->ReadBeginStruct(StructInfo<T>().FieldCount);
245 }
246 else
247 {
248 this->ReadTag(elementType);
249 }
250 }
251 return this->ReadArrayLength();
252}
253
254} // end of namespace Arp::Base::Rsc::Commons::Services
This abstract class shall be the base class of all stream implementations.
Definition: Stream.hpp:20
This class is used for authorization of arbitrary operations.
Definition: SecurityToken.hpp:18
This class contains date and time informations.
Definition: DateTime.hpp:27
typename std::underlying_type< T >::type U
The underlying integral type of the adapted enum class type.
Definition: Enum.hxx:24
Adapter class to implement PImpl idiom.
Definition: PimplPtr.hxx:15
This class represents the Arp String. The implementation is based on std::string.
Definition: String.hpp:39
This exception class is used by RSC if any exception is thrown.
Definition: RscException.hpp:24
Enables Rsc services to marshal large data packets as stream.
Definition: RscStreamReader.hpp:23
This class might be used to marshal unstructured stream data as bytes.
Definition: RscStream.hpp:29
This class is used to deduct RSC types automatically by compilation.
Definition: RscTypeDeduction.hpp:24
constexpr RscType Get(void)
Gets the RscType of the as argument passed template parameter.
Definition: RscTypeDeduction.hpp:47
static constexpr RscType GetFrom(const T &)
Gets the RscType of the as argument passed parameter.
Definition: RscTypeDeduction.hpp:77
static bool IsConcreteType(RscType type)
Determines if the supplied type specifies a concrete type, i.e not unspecified and not object.
Definition: RscTypeInfo.cpp:242
This class is a base class of template class RscVariant.
Definition: RscVariantBase.hpp:40
Rsc class for variant data types like primitive data type, strings or information about arrays or str...
Definition: RscVariant.hxx:57
Reads marshaled data of RSC services.
Definition: RscReader.hpp:34
RscReader(RscReader &&arg) noexcept
The default move constructor.
RscReader & operator=(const RscReader &arg)
The default copy-assignment operator.
size_t ReadArrayLength(void)
Reads the array length of an array from RSC.
Definition: RscReader.cpp:155
~RscReader(void)
The default destructor.
RscReader & operator=(RscReader &&arg) noexcept
The default move-assignment operator.
RscReader(const RscReader &arg)
The default copy constructor.
RscType ReadTag(void)
Reads a data tag from RSC.
Definition: RscReader.cpp:133
void Read(RscPtr &result, bool omitTag=false)
Reads a value from RSC.
Definition: RscReader.cpp:78
void ReadBeginStruct(size_t fieldCount)
Reads the field count of a struct from RSC.
Definition: RscReader.cpp:163
@ Read
Specifies read access to the file. Data can be read from the file and the file pointer can be moved....
This class provides the number of fields of a concrete struct. This class is specialized for concrete...
Definition: StructInfo.hxx:26