PLCnext API Documentation  20.0.0.24462
RscStructReader.hxx
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/Rsc/Services/RscVariant.hxx"
10 #include "Arp/System/Rsc/Services/RscString.hxx"
11 #include "Arp/System/Rsc/Services/RscValue.hpp"
12 #include "Arp/System/Rsc/Services/RscException.hpp"
13 
14 #include <functional>
15 
16 namespace Arp { namespace System { namespace Rsc { namespace Services
17 {
18 
19 class RscArrayReader;
20 
25 template<int MaxStringSize>
27 {
28 public: // typedefs
29  using ReadElementFunction = RscVariant<>::ReadElementFunction;
30 
31 public: // construction/destruction
33  RscStructReader(const RscVariant<MaxStringSize>& structVariant); // Variant with struct information
35  RscStructReader(const RscStructReader& arg) = default;
37  RscStructReader& operator=(const RscStructReader& arg) = default;
39  ~RscStructReader(void) = default;
40 
41 public: // operators
42 
43 public: // static operations
48  size_t GetFieldCount(void) const;
49 
50 public: // setter/getter operations
51 
52 public: // operations
53 
59  template<class T>
60  void ReadNextField(T& currentField);
61 
66  void ReadNextField(RscString<MaxStringSize>& currentField);
67 
73 
74 private: // methods
75  RscType ReadRemotingValue(RscType expectedType, byte* pValue);
76 
77 private: // fields
78  RscStructInformation structInformation;
79  RemotingReader* pReader = nullptr;
80  ReadElementFunction readFieldFunction;
81 
82 private: // static fields
83 
84 };
85 
87 // inline methods of class RscStructReader
88 
89 template<int MaxStringSize>
91  : structInformation(structVariant.GetStructInformation())
92 {
93  if(structVariant.typeInfo.pReader == nullptr)
94  {
95  this->readFieldFunction = *structVariant.typeInfo.pReadElementFunction;
96  }
97  else
98  {
99  this->readFieldFunction = [&](RscType expectedType, byte * pValue)
100  {
101  return this->ReadRemotingValue(expectedType, pValue);
102  };
103  if(structVariant.typeInfo.pReader == nullptr)
104  {
105  throw ArgumentException("No remoting reader set in argument 'structVariant'");
106  }
107  this->pReader = structVariant.typeInfo.pReader;
108  }
109 }
110 
111 template<int MaxStringSize>
113 {
114  return this->structInformation.FieldCount;
115 }
116 
117 template<int MaxStringSize>
119 {
120  RscType readType = this->readFieldFunction(RscType::Object, value.GetDataAddress());
121  value.SetType(readType);
122  if(value.ContainsTypeInformation())
123  {
124  value.InitComplexTypeInfo();
125  value.typeInfo.pReader = this->pReader;
126  if(this->pReader == nullptr)
127  {
128  value.typeInfo.pReadElementFunction = &this->readFieldFunction;
129  }
130  }
131 }
132 
133 template<int MaxStringSize>
134 template<class T>
136 {
137  RscType expectedType = GetRscTypeFrom(currentField);
138  if(!IsPrimitiveRscType(expectedType))
139  {
140  throw InvalidOperationException("{}: This method works only for primitive types", __FUNCTION__);
141  }
142  (void)this->readFieldFunction(expectedType, reinterpret_cast<byte*>(&currentField));
143 }
144 
145 template<int MaxStringSize>
147 {
148  (void)this->readFieldFunction(RscType::Utf8String, reinterpret_cast<byte*>(currentField.CStr()));
149 }
150 
151 template<int MaxStringSize>
153 {
154  RscType valueType = this->pReader->ReadObjectType();
155  if(expectedType != RscType::Object && expectedType != valueType)
156  {
157  throw RscException((int)RscErrors::InvalidData, "{}: Expected data type '{}', but got '{}'", __FUNCTION__, expectedType, valueType);
158  }
159  if(valueType == RscType::Array)
160  {
161  RscArrayInformation& arrayInformation = *reinterpret_cast<RscArrayInformation*>(pValue);
162  arrayInformation = this->pReader->ReadArrayInformation();
163  return RscType::Array;
164  }
165  else if(valueType == RscType::Struct)
166  {
167  RscStructInformation& nestedStructInformation = *reinterpret_cast<RscStructInformation*>(pValue);
168  nestedStructInformation.FieldCount = this->pReader->ReadFieldCount();
169  return RscType::Struct;
170  }
171  RscValue::Read(*this->pReader, valueType, pValue, MaxStringSize);
172  return valueType;
173 }
174 
175 }}}} // end of namespace Arp::System::Rsc::Services
const char * CStr(void) const
Returns pointer to internal buffer.
Definition: RscString.hxx:109
Helper class to read a struct from an RscVariant. This class uses the struct information stored in Rs...
Definition: RscStructReader.hxx:26
Complex datatype with implements IRscSerializable
size_t FieldCount
Count of struct fields
Definition: RscType.hpp:161
RscType
Datatypes supported by Rsc. Values are identical with CommonRemoting::RemotingMarshalType. Only supported types of RemotingMarshalType are included.
Definition: RscType.hpp:27
Rsc container class for primitive data type, strings or information about arrays or structs...
Definition: RscVariant.hxx:37
void ReadNextField(T &currentField)
Reads the next field of current struct. This method if field is primitve and known.
Definition: RscStructReader.hxx:135
Object type handled by Rsc as RscVariant
This exception is used when a method call is invalid for object&#39;s current state.
Definition: InvalidOperationException.hpp:14
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:490
RscStructReader & operator=(const RscStructReader &arg)=default
Assignment operator.
void SetType(RscType rscType)
Forces the internal RscType to be set to another RscType. This Method does no conversion or validatio...
Definition: RscVariant.hxx:502
This exception is used when an invalid argument occurs.
Definition: ArgumentException.hpp:14
size_t GetFieldCount(void) const
Gets the field count of the struct;
Definition: RscStructReader.hxx:112
Root namespace for the PLCnext API
Contains information to marshall an array
Definition: RscType.hpp:120
System components used by the System, Device, Plc or Io domains.
Contains information to marshall an struct
Definition: RscType.hpp:154
~RscStructReader(void)=default
Destructs this instance and frees all resources.
Contains a static string with string lentgh up to N characters. The string has to be null terminated...
Definition: RscString.hxx:18
RscStructReader(const RscVariant< MaxStringSize > &structVariant)
Constructs an RscStructReader instance.
Definition: RscStructReader.hxx:90
unsigned char byte
The Arp character type.
Definition: PrimitiveTypes.hpp:23