PLCnext API Documentation  22.9.0.33
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 
15 namespace Arp { namespace System { namespace Rsc { namespace Services
16 {
17 
18 // forwards
19 class RscClientContext;
20 class RscStreamAdapter;
21 
25 class RscReader
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
56 
57 public: // 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 
121 private: // methods
127  template<class T> size_t BeginArray(void);
128 
129 private: // fields
130  RemotingReader remotingReader;
131 };
132 
134 // inline methods of class RscReader
135 inline RscReader::RscReader(BinaryReader2& binaryReader, RscClientContext* pClientContext)
136  : remotingReader(binaryReader, *this, pClientContext)
137 {
138 }
139 
141 {
142  return RscStream(this->remotingReader);
143 }
144 
145 inline RemotingReader& RscReader::GetRemotingReader(void)
146 {
147  return this->remotingReader;
148 }
149 
150 template<class T>
151 inline void RscReader::Read(T& result)
152 {
153  RscValueAdapter<T> valueAdapter(result);
154  valueAdapter.Read(this->remotingReader);
155 }
156 
157 template<class T>
158 inline void RscReader::Read(T& result, bool readTag)
159 {
160  RscValueAdapter<T> valueAdapter(result);
161  valueAdapter.Read(this->remotingReader, readTag);
162 }
163 
164 template<class T>
165 inline T RscReader::Read()
166 {
167  T value;
168  this->Read(value);
169  return value;
170 }
171 
172 template<int N>
173 inline void RscReader::ReadString(String& result)
174 {
175  char buffer[N] = "";
176  this->ReadString<N>(buffer);
177  result = buffer;
178 }
179 
180 template<int N>
181 inline void RscReader::ReadString(char(&result)[N])
182 {
183  this->remotingReader.ReadStringInternal(result, N, RscStringEncoding::Utf8);
184 }
185 
186 template<class T>
187 inline 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 
201 template<class T>
202 inline 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 
224 template<class T, size_t N>
225 inline 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 
240 template<class T>
241 inline 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 
256 template<int N>
257 inline 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(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 & operator=(const RscReader &arg)=default
Assignment operator.
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
Datatypes supported by Rsc. Values are identical with CommonRemoting::RemotingMarshalType....
Definition: RscType.hpp:37
@ Struct
Complex datatype with implements IRscSerializable
@ Utf16String
Utf-16 string, not implemented in Rsc context
Root namespace for the PLCnext API