PLCnext API Documentation 23.6.0.37
RscReader.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Rsc/Services/Rsc.h"
9#include "Arp/System/Core/ByteConverter.hpp"
10#include "Arp/System/Rsc/Services/RscValueAdapter.hxx"
11#include "Arp/System/Rsc/Services/RscStream.hpp"
12#include "Arp/System/Rsc/Services/RemotingReader.hpp"
13#include "Arp/System/Rsc/Services/RscException.hpp"
14#include <vector>
15
16namespace Arp { namespace System { namespace Rsc { namespace Services
17{
18
19// forwards
20class RscClientContext;
21class RscStreamAdapter;
22
27{
28public: // construction/destruction
30 RscReader(BinaryReader2& binaryReader, RscClientContext* pClientContext = nullptr);
32 RscReader(const RscReader& arg) = default;
34 RscReader& operator=(const RscReader& arg) = default;
36 ~RscReader(void) = default;
37
38public: // setter/getter operations
43 RscStream GetStream(void);
44
49 RemotingReader& GetRemotingReader(void);
50
51public: // read operations
57
58public: // generic read operations
64 template<class T> T Read(void);
65
70 template<class T> void Read(T& result);
71
77 template<class T> void Read(T& result, bool readTag);
78
84 template<int N> void ReadString(String& result);
85
91 template<int N> void ReadString(char(&value)[N]);
92
98 template<int N> void ReadObjectString(char(&value)[N]);
99
105 template<class T> void ReadArray(std::vector<T>& result);
106
112 template<class T> void ReadArray(std::vector<std::vector<T>>& result);
113
120 template<class T, size_t N> void ReadArray(std::array<T, N>& result);
121
122private: // methods
128 template<class T> size_t BeginArray(void);
129
130private: // fields
131 RemotingReader remotingReader;
132};
133
135// inline methods of class RscReader
136inline RscReader::RscReader(BinaryReader2& binaryReader, RscClientContext* pClientContext)
137 : remotingReader(binaryReader, *this, pClientContext)
138{
139}
140
142{
143 return RscStream(this->remotingReader);
144}
145
146inline RemotingReader& RscReader::GetRemotingReader(void)
147{
148 return this->remotingReader;
149}
150
151template<class T>
152inline void RscReader::Read(T& result)
153{
154 RscValueAdapter<T> valueAdapter(result);
155 valueAdapter.Read(this->remotingReader);
156}
157
158template<class T>
159inline void RscReader::Read(T& result, bool readTag)
160{
161 RscValueAdapter<T> valueAdapter(result);
162 valueAdapter.Read(this->remotingReader, readTag);
163}
164
165template<class T>
167{
168 T value;
169 this->Read(value);
170 return value;
171}
172
173template<int N>
174inline void RscReader::ReadString(String& result)
175{
176 char buffer[N] = "";
177 this->ReadString<N>(buffer);
178 result = buffer;
179}
180
181template<int N>
182inline void RscReader::ReadString(char(&result)[N])
183{
184 this->remotingReader.ReadStringInternal(result, N, RscStringEncoding::Utf8);
185}
186
187template<class T>
188inline void RscReader::ReadArray(std::vector<T>& result)
189{
190 size_t length = this->BeginArray<T>();
191 result.reserve(length);
192
193 for (size_t i = 0; i < length; ++i)
194 {
195 T value;
196 RscValueAdapter<T> valueAdapter(value);
197 valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
198 result.push_back(value);
199 }
200}
201
202template<class T>
203inline void RscReader::ReadArray(std::vector<std::vector<T>>& result)
204{
205 this->remotingReader.ReadTag(RscType::Array);
206 size_t outerArraySize = this->BeginArray<T>();
207 result.reserve(outerArraySize);
208 for(size_t i = 0; i < outerArraySize; ++i)
209 {
210 size_t innerArraySize = this->remotingReader.ReadArrayLength();
211 std::vector<T> innerArray;
212 innerArray.reserve(innerArraySize);
213
214 for(size_t j = 0; j < innerArraySize; ++j)
215 {
216 T value;
217 RscValueAdapter<T> valueAdapter(value);
218 valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
219 innerArray.push_back(value);
220 }
221 result.push_back(std::move(innerArray));
222 }
223}
224
225template<class T, size_t N>
226inline void RscReader::ReadArray(std::array<T, N>& result)
227{
228 size_t length = this->BeginArray<T>();
229 if(length != N)
230 {
231 throw RscException((int)RscErrors::InvalidData, "Received Array doesn't contain {0} elements", N);
232 }
233
234 for(size_t i = 0; i < N; ++i)
235 {
236 RscValueAdapter<T> valueAdapter(result[i]);
237 valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
238 }
239}
240
241template<class T>
242inline size_t RscReader::BeginArray(void)
243{
244 RscType elementType = GetRscTypeFrom(T());
245 this->remotingReader.ReadTag(RscType::Array);
246 if(elementType == RscType::Struct)
247 {
248 this->remotingReader.ReadBeginStruct(StructInfo<T>().FieldCount);
249 }
250 else
251 {
252 this->remotingReader.ReadTag(elementType);
253 }
254 return this->remotingReader.ReadArrayLength();
255}
256
257template<int N>
258inline void RscReader::ReadObjectString(char(&result)[N])
259{
260 RscType type = static_cast<RscType>(this->remotingReader.ReadObjectType());
261
262 // determine encoding
263 RscStringEncoding encoding = RscStringEncoding::None;
264 if(type == RscType::Utf8String )
265 {
266 encoding = RscStringEncoding::Utf8;
267 }
268 else if (type == RscType::Utf16String)
269 {
270 encoding = RscStringEncoding::Utf16;
271 }
272 else
273 {
274 throw InvalidOperationException("Requested string type does not match read object type '{0}'", type);
275 }
276
277 if(encoding == RscStringEncoding::Utf16)
278 {
279 throw NotImplementedException("String encoding UTF16 not implemented yet");
280 }
281
282 // else
283 this->remotingReader.ReadStringInternal(result, N, encoding);
284}
285
286}}}} // 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:27
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:174
void ReadStream(RscStreamAdapter &stream)
Reads the data from remote into the supplied stream.
RemotingReader & GetRemotingReader(void)
Returns reference to RemotingReader
Definition: RscReader.hpp:146
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:258
RscReader(BinaryReader2 &binaryReader, RscClientContext *pClientContext=nullptr)
Constructs an RscReader instance.
Definition: RscReader.hpp:136
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:188
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:166
RscStream GetStream(void)
Creates an instance of RscStream initialized to read stream data.
Definition: RscReader.hpp:141
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:21
@ 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