PLCnext API Documentation  22.9.0.33
RscArrayReader.hpp
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Rsc/Services/Rsc.h"
9 #include "Arp/System/Commons/Exceptions/Exceptions.h"
10 #include "Arp/System/Rsc/Services/RscValueAdapter.hxx"
11 #include "Arp/System/Rsc/Services/RscVariant.hxx"
12 #include "Arp/System/Rsc/Services/RscStructReader.hxx"
13 #include <functional>
14 
15 namespace Arp { namespace System { namespace Rsc { namespace Services
16 {
17 
23 {
24 public: // typedefs
25  //using ReadElementFunction = std::function<RscType(RscType expectedType, byte*)>;
26  using ReadElementFunction = RscVariant<>::ReadElementFunction;
27 
28 public: // construction/destruction
32  template<int N>
33  RscArrayReader(const RscVariant<N>& value);
34 
36  RscArrayReader(size_t size, RscType elementType, ReadElementFunction readFunction);
37 
39  RscArrayReader(size_t size, RscType elementType, RemotingReader& reader);
40 
42  RscArrayReader(const RscArrayReader& arg) = default;
43 
45  RscArrayReader& operator=(const RscArrayReader& arg) = default;
47  ~RscArrayReader(void) = default;
48 
49 public: // setter/getter operations
54  size_t GetSize(void)const;
55 
60  RscType GetElementType(void)const;
61 
66  size_t GetDimensions(void)const;
67 
72  size_t GetPosition(void)const;
73 
78  size_t GetFieldCount(void)const;
79 
80 public: // operations
87  template<class T>
88  void ReadNext(T& current);
89 
95  template<int N>
96  void ReadNext(RscString<N>& current);
97 
103  template<int N>
104  void ReadNext(RscVariant<N>& current);
105 
111  void ReadNext(byte* pCurrent);
112 
118 
124  template<int MaxStringSize>
126 
127 private: // methods
128  RscType ReadRemotingValue(RscType expectedType, byte* pValue);
129  void CheckReadArgument(RscType argumentType, size_t maxLength);
130 
131 private: // fields
132  RscArrayInformation arrayInformation;
133  size_t position = 0;
134  size_t maxStringSize = 0;
135  RemotingReader* pReader = nullptr;
136  ReadElementFunction readElementFunction;
137 };
138 
140 // inline methods of class RscArrayReader<T>
141 
142 template<int N>
144  : arrayInformation(value.GetArrayInformation())
145  , pReader(value.typeInfo.pReader)
146  , maxStringSize(N)
147 {
148  if(value.GetType() != RscType::Array)
149  {
150  throw ArgumentException("'value' doesn't contain an array");
151  }
152  if (this->GetElementType() == RscType::None)
153  {
154  throw ArgumentException::Create("arrayElementType", this->GetElementType());
155  }
156 
157  if(this->GetDimensions() == 0)
158  {
159  throw ArgumentException("{0}: dimension size has to be >= 0", __FUNCTION__);
160  }
161 
162  if (value.typeInfo.pReadElementFunction != nullptr)
163  {
164  this->readElementFunction = *value.typeInfo.pReadElementFunction;
165  }
166  else if(this->pReader != nullptr)
167  {
168  this->readElementFunction = [&](RscType expectedType, byte * pValue)
169  {
170  return ReadRemotingValue(expectedType, pValue);
171  };
172  }
173  else
174  {
175  throw ArgumentException("ReadElementFunction in RscVariant has to be defined");
176  }
177 }
178 
179 inline size_t RscArrayReader::GetSize()const
180 {
181  return this->arrayInformation.Size;
182 }
183 
185 {
186  return this->arrayInformation.ElementType;
187 }
188 
189 inline size_t RscArrayReader::GetDimensions(void) const
190 {
191  return this->arrayInformation.Dimensions;
192 }
193 
194 inline size_t RscArrayReader::GetPosition()const
195 {
196  return this->position;
197 }
198 
199 inline size_t RscArrayReader::GetFieldCount(void) const
200 {
201  return this->arrayInformation.FieldCount;
202 }
203 
204 template<class T>
205 inline void RscArrayReader::ReadNext(T& current)
206 {
207  if(!IsPrimitiveRscType(this->GetElementType()))
208  {
209  throw InvalidOperationException("This method can only be used with primitve Types");
210  }
211  if(this->GetDimensions() > 1)
212  {
213  throw InvalidOperationException("This element contains subarrays, please use ReadNextArray instead");
214  }
215  this->ReadNext(reinterpret_cast<byte*>(&current));
216 }
217 
218 template<>
219 inline void RscArrayReader::ReadNext(DateTime& current)
220 {
221  if(this->GetElementType() != RscType::DateTime)
222  {
223  throw InvalidOperationException("This method can only handle arrays of DateTime");
224  }
225  if(this->GetDimensions() > 1)
226  {
227  throw InvalidOperationException("This element contains subarrays, please use ReadNextArray instead");
228  }
229  this->ReadNext(reinterpret_cast<byte*>(&current));
230 }
231 
232 template<int N>
234 {
235  this->CheckReadArgument(RscType::Utf8String, N);
236  this->readElementFunction(this->GetElementType(), (byte*)current.CStr());
237  ++this->position;
238 }
239 
240 template<int N>
242 {
243  if(this->maxStringSize != N)
244  {
245  throw InvalidOperationException("Size of current doesn't fit to N");
246  }
247  RscType readType = this->readElementFunction(this->GetElementType(), current.GetDataAddress()); // in case of array info DataAdress starts wir ArrayInformation::size, in case of struct buffer starts with StructInformation::FieldCount
248  current.SetType(readType);
249  if(current.ContainsTypeInformation())
250  {
251  current.typeInfo.pReader = this->pReader;
252  current.typeInfo.pReadElementFunction = &this->readElementFunction;
253  }
254  ++this->position;
255 }
256 
257 template<int MaxStringSize>
259 {
260  if(this->GetElementType() != RscType ::Struct)
261  {
262  throw InvalidOperationException("{}: Method only valid for array of struct", __FUNCTION__);
263  }
264  if(this->GetDimensions() != 1)
265  {
266  throw InvalidOperationException("{}: Array Dimensions != 1, please read subarray information first", __FUNCTION__);
267  }
268  RscVariant<MaxStringSize> structVariant;
269  this->ReadNext(structVariant);
270 
271  structVariant.GetStructInformation().FieldCount = this->arrayInformation.FieldCount;
272 
273  return RscStructReader<MaxStringSize>(structVariant);
274 }
275 
276 }}}} // end of namespace Arp::System::Rsc::Services
The class contains date and time informations.
Definition: DateTime.hpp:45
This exception is used when an invalid argument occurs.
Definition: ArgumentException.hpp:15
static ArgumentException Create(const char *paramName, const T &paramValue)
Creates an ArgumentException instance using a default message text.
Definition: ArgumentException.hpp:112
This exception is used when a method call is invalid for object's current state.
Definition: InvalidOperationException.hpp:15
Helper class to read an array of primtive types from an RscVariant. This class uses the array informa...
Definition: RscArrayReader.hpp:23
size_t GetDimensions(void) const
Gets the count of array dimensions.
Definition: RscArrayReader.hpp:189
RscArrayReader ReadNextArray(void)
Reads the next subarray for arrays with more than one dimension. The next subarray is read with a new...
size_t GetSize(void) const
Returns number of Elements contained in array
Definition: RscArrayReader.hpp:179
~RscArrayReader(void)=default
Destructs this instance and frees all resources.
RscType GetElementType(void) const
Returns the element type
Definition: RscArrayReader.hpp:184
void ReadNext(byte *pCurrent)
Reads the next single array element using the callback function given by ArrayInformation of RscVaria...
size_t GetFieldCount(void) const
Returns field count if array contains struct elements
Definition: RscArrayReader.hpp:199
RscArrayReader(size_t size, RscType elementType, RemotingReader &reader)
///
RscArrayReader(const RscArrayReader &arg)=default
///
size_t GetPosition(void) const
Returns current reading position in array
Definition: RscArrayReader.hpp:194
RscArrayReader(const RscVariant< N > &value)
Constructs an RscArray instance.
Definition: RscArrayReader.hpp:143
void ReadNext(T &current)
Reads the next single array element using the callback function given by ArrayInformation of RscVaria...
Definition: RscArrayReader.hpp:205
RscStructReader< MaxStringSize > ReadNextStruct(void)
Reads the next struct element.
Definition: RscArrayReader.hpp:258
RscArrayReader & operator=(const RscArrayReader &arg)=default
Assignment operator.
RscArrayReader(size_t size, RscType elementType, ReadElementFunction readFunction)
Constructs an RscArrayReader instance.
Contains a static string with string lentgh up to N characters. The string has to be null terminated.
Definition: RscString.hxx:21
const char * CStr(void) const
Returns pointer to internal buffer.
Definition: RscString.hxx:111
Helper class to read a struct from an RscVariant. This class uses the struct information stored in Rs...
Definition: RscStructReader.hxx:25
Rsc container class for primitive data type, strings or information about arrays or structs....
Definition: RscVariant.hxx:39
void SetType(RscType rscType)
Forces the internal RscType to be set to another RscType. This Method does no conversion or validatio...
Definition: RscVariant.hxx:526
const byte * GetDataAddress(void) const
Gets a raw pointer to internal data buffer. To read data prefer CopyTo and to write prefer assignment...
Definition: RscVariant.hxx:514
RscType GetType(void) const
Gets the RscType of the contained element
Definition: RscVariant.hxx:432
@ System
System components used by the System, Device, Plc or Io domains.
RscType
Datatypes supported by Rsc. Values are identical with CommonRemoting::RemotingMarshalType....
Definition: RscType.hpp:37
@ DateTime
Datetime, handled by Rsc with DateTime
Root namespace for the PLCnext API
Contains information to marshall an array
Definition: RscType.hpp:130
size_t Size
Count of array elements
Definition: RscType.hpp:142
size_t FieldCount
Count of Fields of struct element type
Definition: RscType.hpp:157
size_t Dimensions
Array Dimensions
Definition: RscType.hpp:147
RscType ElementType
Array element type
Definition: RscType.hpp:152
size_t FieldCount
Count of struct fields
Definition: RscType.hpp:170