PLCnext API Documentation  21.0.0.35466
RscReader.hpp
1 //
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 namespace Arp { namespace System { namespace Rsc { namespace Services
15 {
16 
17 // forwards
18 class RscClientContext;
19 
23 class RscReader
24 {
25 public: // typedefs
26 
27 public: // 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 
37 public: // setter/getter operations
42  RscStream GetStream(void);
43 
48  RemotingReader& GetRemotingReader(void);
49 
50 public: // read operations
51 
52 public: // generic read operations
58  template<class T> T Read(void);
59 
64  template<class T> void Read(T& result);
65 
71  template<class T> void Read(T& result, bool readTag);
72 
78  template<int N> void ReadString(String& result);
79 
85  template<int N> void ReadString(char(&value)[N]);
86 
92  template<int N> void ReadObjectString(char(&value)[N]);
93 
99  template<class T> void ReadArray(std::vector<T>& result);
100 
106  template<class T> void ReadArray(std::vector<std::vector<T>>& result);
107 
114  template<class T, size_t N> void ReadArray(std::array<T, N>& result);
115 
116 private: // methods
122  template<class T> size_t BeginArray(void);
123 
124 private: // fields
125  RemotingReader remotingReader;
126 };
127 
129 // inline methods of class RscReader
130 inline RscReader::RscReader(BinaryReader2& binaryReader, RscClientContext* pClientContext)
131  : remotingReader(binaryReader, *this, pClientContext)
132 {
133 }
134 
136 {
137  return RscStream(this->remotingReader);
138 }
139 
140 inline RemotingReader& RscReader::GetRemotingReader(void)
141 {
142  return this->remotingReader;
143 }
144 
145 template<class T>
146 inline void RscReader::Read(T& result)
147 {
148  RscValueAdapter<T> valueAdapter(result);
149  valueAdapter.Read(this->remotingReader);
150 }
151 
152 template<class T>
153 inline void RscReader::Read(T& result, bool readTag)
154 {
155  RscValueAdapter<T> valueAdapter(result);
156  valueAdapter.Read(this->remotingReader, readTag);
157 }
158 
159 template<class T>
160 inline T RscReader::Read()
161 {
162  T value;
163  this->Read(value);
164  return value;
165 }
166 
167 template<int N>
168 inline void RscReader::ReadString(String& result)
169 {
170  char buffer[N] = "";
171  this->ReadString<N>(buffer);
172  result = buffer;
173 }
174 
175 template<int N>
176 inline void RscReader::ReadString(char(&result)[N])
177 {
178  this->remotingReader.ReadStringInternal(result, N, RscStringEncoding::Utf8);
179 }
180 
181 template<class T>
182 inline void RscReader::ReadArray(std::vector<T>& result)
183 {
184  size_t length = this->BeginArray<T>();
185  result.reserve(length);
186 
187  for (size_t i = 0; i < length; ++i)
188  {
189  T value;
190  RscValueAdapter<T> valueAdapter(value);
191  valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
192  result.push_back(value);
193  }
194 }
195 
196 template<class T>
197 inline void RscReader::ReadArray(std::vector<std::vector<T>>& result)
198 {
199  this->remotingReader.ReadTag(RscType::Array);
200  size_t outerArraySize = this->BeginArray<T>();
201  result.reserve(outerArraySize);
202  for(size_t i = 0; i < outerArraySize; ++i)
203  {
204  size_t innerArraySize = this->remotingReader.ReadArrayLength();
205  std::vector<T> innerArray;
206  innerArray.reserve(innerArraySize);
207 
208  for(size_t j = 0; j < innerArraySize; ++j)
209  {
210  T value;
211  RscValueAdapter<T> valueAdapter(value);
212  valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
213  innerArray.push_back(value);
214  }
215  result.push_back(std::move(innerArray));
216  }
217 }
218 
219 template<class T, size_t N>
220 inline void RscReader::ReadArray(std::array<T, N>& result)
221 {
222  size_t length = this->BeginArray<T>();
223  if(length != N)
224  {
225  throw RscException((int)RscErrors::InvalidData, "Received Array doesn't contain {0} elements", N);
226  }
227 
228  for(size_t i = 0; i < N; ++i)
229  {
230  RscValueAdapter<T> valueAdapter(result[i]);
231  valueAdapter.Read(this->remotingReader, false); // Tag has already been verified
232  }
233 }
234 
235 template<class T>
236 inline size_t RscReader::BeginArray(void)
237 {
238  RscType elementType = GetRscTypeFrom(T());
239  this->remotingReader.ReadTag(RscType::Array);
240  if(elementType == RscType::Struct)
241  {
242  this->remotingReader.ReadBeginStruct(StructInfo<T>().FieldCount);
243  }
244  else
245  {
246  this->remotingReader.ReadTag(elementType);
247  }
248  return this->remotingReader.ReadArrayLength();
249 }
250 
251 template<int N>
252 inline void RscReader::ReadObjectString(char(&result)[N])
253 {
254  RscType type = static_cast<RscType>(this->remotingReader.ReadObjectType());
255 
256  // determine encoding
257  RscStringEncoding encoding = RscStringEncoding::None;
258  if(type == RscType::Utf8String )
259  {
260  encoding = RscStringEncoding::Utf8;
261  }
262  else if (type == RscType::Utf16String)
263  {
264  encoding = RscStringEncoding::Utf16;
265  }
266  else
267  {
268  throw InvalidOperationException("Requested string type does not match read object type '{0}'", type);
269  }
270 
271  if(encoding == RscStringEncoding::Utf16)
272  {
273  throw NotImplementedException("String encoding UTF16 not implemented yet");
274  }
275 
276  // else
277  this->remotingReader.ReadStringInternal(result, N, encoding);
278 }
279 
280 }}}} // end of namespace Arp::System::Rsc::Services
Reads data from Rsc
Definition: RscReader.hpp:23
RemotingReader & GetRemotingReader(void)
Returns reference to RemotingReader
Definition: RscReader.hpp:140
Complex datatype with implements IRscSerializable
RscReader(BinaryReader2 &binaryReader, RscClientContext *pClientContext=nullptr)
Constructs an RscReader instance.
Definition: RscReader.hpp:130
RscStream GetStream(void)
Creates an instance of RscStream initialized to read stream data.
Definition: RscReader.hpp:135
Utf-16 string, not implemented in Rsc context
This exception is used when a method is not implemented yet.
Definition: NotImplementedException.hpp:14
T Read(void)
Reads an element of T from Rsc. With data tagging enabled RscType of T is validated.
Definition: RscReader.hpp:160
RscType
Datatypes supported by Rsc. Values are identical with CommonRemoting::RemotingMarshalType. Only supported types of RemotingMarshalType are included.
Definition: RscType.hpp:27
This exception is used when a method call is invalid for object&#39;s current state.
Definition: InvalidOperationException.hpp:14
Enables Rsc services to marshal large data packets as stream.
Definition: RscStream.hpp:17
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:168
Root namespace for the PLCnext API
void ReadArray(std::vector< T > &result)
Reads an array from Rsc. The read data is stored as std::vector.
Definition: RscReader.hpp:182
RscStringEncoding
Determines the encoding of a Rsc String. Values are identical to CommonRemoting::StringEncoding. Rsc only supports Utf8.
Definition: RscStringEncoding.hpp:16
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:252
System components used by the System, Device, Plc or Io domains.
~RscReader(void)=default
Destructs this instance and frees all resources.
RscReader & operator=(const RscReader &arg)=default
Assignment operator.