PLCnext API Documentation 23.6.0.37
RscArrayReader.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/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
15namespace Arp { namespace System { namespace Rsc { namespace Services
16{
17
23{
24public: // typedefs
25 //using ReadElementFunction = std::function<RscType(RscType expectedType, byte*)>;
26 using ReadElementFunction = RscVariant<>::ReadElementFunction;
27
28public: // 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
49public: // 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
80public: // 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
127private: // methods
128 RscType ReadRemotingValue(RscType expectedType, byte* pValue);
129 void CheckReadArgument(RscType argumentType, size_t maxLength);
130
131private: // 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
142template<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
179inline size_t RscArrayReader::GetSize()const
180{
181 return this->arrayInformation.Size;
182}
183
185{
186 return this->arrayInformation.ElementType;
187}
188
189inline size_t RscArrayReader::GetDimensions(void) const
190{
191 return this->arrayInformation.Dimensions;
192}
193
194inline size_t RscArrayReader::GetPosition()const
195{
196 return this->position;
197}
198
199inline size_t RscArrayReader::GetFieldCount(void) const
200{
201 return this->arrayInformation.FieldCount;
202}
203
204template<class T>
205inline 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
218template<>
219inline 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
232template<int N>
234{
235 this->CheckReadArgument(RscType::Utf8String, N);
236 this->readElementFunction(this->GetElementType(), (byte*)current.CStr());
237 ++this->position;
238}
239
240template<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
257template<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:46
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...
RscArrayReader & operator=(const RscArrayReader &arg)=default
Assignment operator.
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(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:69
void SetType(RscType rscType)
Forces the internal RscType to be set to another RscType. This Method does no conversion or validatio...
Definition: RscVariant.hxx:556
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:544
RscType GetType(void) const
Gets the RscType of the contained element
Definition: RscVariant.hxx:462
@ System
System components used by the System, Device, Plc or Io domains.
RscType
Data types supported by RSC.
Definition: RscType.hpp:36
@ Array
std::vector<T> or RSC enumerators
@ Utf8String
Utf-8 string, Arp::System::Rsc::Services::RscString
Root namespace for the PLCnext API
Contains information to marshall an array
Definition: RscType.hpp:129
size_t Size
Count of array elements
Definition: RscType.hpp:141
size_t FieldCount
Count of Fields of struct element type
Definition: RscType.hpp:156
size_t Dimensions
Array Dimensions
Definition: RscType.hpp:146
RscType ElementType
Array element type
Definition: RscType.hpp:151
size_t FieldCount
Count of struct fields
Definition: RscType.hpp:167