PLCnext API Documentation 23.0.2.9
RscReader.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
7#include "Arp/System/Rsc/Services/Rsc.h"
8#include "Arp/System/Core/ByteConverter.hpp"
9#include "Arp/System/Rsc/Services/RscValueAdapter.hxx"
10#include "Arp/System/Rsc/Services/RscStream.hpp"
11#include "Arp/System/Rsc/Services/RemotingReader.hpp"
12#include "Arp/System/Rsc/Services/RscException.hpp"
13#include <vector>
14
15namespace Arp { namespace System { namespace Rsc { namespace Services
16{
17
18// forwards
19class RscClientContext;
20class RscStreamAdapter;
21
26{
27public: // construction/destruction
29 RscReader(BinaryReader2& binaryReader, RscClientContext* pClientContext = nullptr);
31 RscReader(const RscReader& arg) = default;
33 RscReader& operator=(const RscReader& arg) = default;
35 ~RscReader(void) = default;
36
37public: // setter/getter operations
42 RscStream GetStream(void);
43
48 RemotingReader& GetRemotingReader(void);
49
50public: // read operations
56
57public: // generic read operations
63 template<class T> T Read(void);
64
69 template<class T> void Read(T& result);
70
76 template<class T> void Read(T& result, bool readTag);
77
83 template<int N> void ReadString(String& result);
84
90 template<int N> void ReadString(char(&value)[N]);
91
97 template<int N> void ReadObjectString(char(&value)[N]);
98
104 template<class T> void ReadArray(std::vector<T>& result);
105
111 template<class T> void ReadArray(std::vector<std::vector<T>>& result);
112
119 template<class T, size_t N> void ReadArray(std::array<T, N>& result);
120
121private: // methods
127 template<class T> size_t BeginArray(void);
128
129private: // fields
130 RemotingReader remotingReader;
131};
132
134// inline methods of class RscReader
135inline RscReader::RscReader(BinaryReader2& binaryReader, RscClientContext* pClientContext)
136 : remotingReader(binaryReader, *this, pClientContext)
137{
138}
139
141{
142 return RscStream(this->remotingReader);
143}
144
145inline RemotingReader& RscReader::GetRemotingReader(void)
146{
147 return this->remotingReader;
148}
149
150template<class T>
151inline void RscReader::Read(T& result)
152{
153 RscValueAdapter<T> valueAdapter(result);
154 valueAdapter.Read(this->remotingReader);
155}
156
157template<class T>
158inline void RscReader::Read(T& result, bool readTag)
159{
160 RscValueAdapter<T> valueAdapter(result);
161 valueAdapter.Read(this->remotingReader, readTag);
162}
163
164template<class T>
166{
167 T value;
168 this->Read(value);
169 return value;
170}
171
172template<int N>
173inline void RscReader::ReadString(String& result)
174{
175 char buffer[N] = "";
176 this->ReadString<N>(buffer);
177 result = buffer;
178}
179
180template<int N>
181inline void RscReader::ReadString(char(&result)[N])
182{
183 this->remotingReader.ReadStringInternal(result, N, RscStringEncoding::Utf8);
184}
185
186template<class T>
187inline void RscReader::ReadArray(std::vector<T>& result)
188{
189 size_t length = this->BeginArray<T>();
190 result.reserve(length);
191
192 for (size_t i = 0; i < length; ++i)
193 {
194 T value;
195 RscValueAdapter<T> valueAdapter(value);
196 valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
197 result.push_back(value);
198 }
199}
200
201template<class T>
202inline void RscReader::ReadArray(std::vector<std::vector<T>>& result)
203{
204 this->remotingReader.ReadTag(RscType::Array);
205 size_t outerArraySize = this->BeginArray<T>();
206 result.reserve(outerArraySize);
207 for(size_t i = 0; i < outerArraySize; ++i)
208 {
209 size_t innerArraySize = this->remotingReader.ReadArrayLength();
210 std::vector<T> innerArray;
211 innerArray.reserve(innerArraySize);
212
213 for(size_t j = 0; j < innerArraySize; ++j)
214 {
215 T value;
216 RscValueAdapter<T> valueAdapter(value);
217 valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
218 innerArray.push_back(value);
219 }
220 result.push_back(std::move(innerArray));
221 }
222}
223
224template<class T, size_t N>
225inline void RscReader::ReadArray(std::array<T, N>& result)
226{
227 size_t length = this->BeginArray<T>();
228 if(length != N)
229 {
230 throw RscException((int)RscErrors::InvalidData, "Received Array doesn't contain {0} elements", N);
231 }
232
233 for(size_t i = 0; i < N; ++i)
234 {
235 RscValueAdapter<T> valueAdapter(result[i]);
236 valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
237 }
238}
239
240template<class T>
241inline size_t RscReader::BeginArray(void)
242{
243 RscType elementType = GetRscTypeFrom(T());
244 this->remotingReader.ReadTag(RscType::Array);
245 if(elementType == RscType::Struct)
246 {
247 this->remotingReader.ReadBeginStruct(StructInfo<T>().FieldCount);
248 }
249 else
250 {
251 this->remotingReader.ReadTag(elementType);
252 }
253 return this->remotingReader.ReadArrayLength();
254}
255
256template<int N>
257inline void RscReader::ReadObjectString(char(&result)[N])
258{
259 RscType type = static_cast<RscType>(this->remotingReader.ReadObjectType());
260
261 // determine encoding
262 RscStringEncoding encoding = RscStringEncoding::None;
263 if(type == RscType::Utf8String )
264 {
265 encoding = RscStringEncoding::Utf8;
266 }
267 else if (type == RscType::Utf16String)
268 {
269 encoding = RscStringEncoding::Utf16;
270 }
271 else
272 {
273 throw InvalidOperationException("Requested string type does not match read object type '{0}'", type);
274 }
275
276 if(encoding == RscStringEncoding::Utf16)
277 {
278 throw NotImplementedException("String encoding UTF16 not implemented yet");
279 }
280
281 // else
282 this->remotingReader.ReadStringInternal(result, N, encoding);
283}
284
285}}}} // end of namespace Arp::System::Rsc::Services
This exception is used when a method call is invalid for object's current state.
Definition: InvalidOperationException.hpp:15
This exception is used when a method is not implemented yet.
Definition: NotImplementedException.hpp:15
Reads data from Rsc
Definition: RscReader.hpp:26
void ReadString(String &result)
Reads a string from Rsc. The String will be read in format Utf-8. The template parameter gives the ma...
Definition: RscReader.hpp:173
void ReadStream(RscStreamAdapter &stream)
Reads the data from remote into the supplied stream.
RemotingReader & GetRemotingReader(void)
Returns reference to RemotingReader
Definition: RscReader.hpp:145
void ReadObjectString(char(&value)[N])
Reads a string in object format from Rsc. The template parameter gives the maximum number of characte...
Definition: RscReader.hpp:257
RscReader(BinaryReader2 &binaryReader, RscClientContext *pClientContext=nullptr)
Constructs an RscReader instance.
Definition: RscReader.hpp:135
RscReader & operator=(const RscReader &arg)=default
Assignment operator.
~RscReader(void)=default
Destructs this instance and frees all resources.
void ReadArray(std::vector< T > &result)
Reads an array from Rsc. The read data is stored as std::vector.
Definition: RscReader.hpp:187
RscReader(const RscReader &arg)=default
Copy constructor.
T Read(void)
Reads an element of T from Rsc. With data tagging enabled RscType of T is validated.
Definition: RscReader.hpp:165
RscStream GetStream(void)
Creates an instance of RscStream initialized to read stream data.
Definition: RscReader.hpp:140
This class serves as adapter between Rsc streams and streams from Arp::System::Commons::Io,...
Definition: RscStreamAdapter.hpp:20
Enables Rsc services to marshal large data packets as stream.
Definition: RscStream.hpp:20
@ System
System components used by the System, Device, Plc or Io domains.
RscStringEncoding
Determines the encoding of a Rsc String. Values are identical to CommonRemoting::StringEncoding.
Definition: RscStringEncoding.hpp:18
RscType
Data types supported by RSC.
Definition: RscType.hpp:36
@ Array
std::vector<T> or RSC enumerators
@ Struct
struct derived by IRscSerializable
@ Utf8String
Utf-8 string, Arp::System::Rsc::Services::RscString
@ Utf16String
Utf-16 string, not implemented in Rsc context
Root namespace for the PLCnext API