PLCnext API Documentation  22.9.0.33
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 #include <functional>
14 namespace Arp { namespace System { namespace Rsc { namespace Services
15 {
16 
17 class RscArrayReader;
18 
23 template<int MaxStringSize>
25 {
26 public: // typedefs
27  using ReadElementFunction = RscVariant<>::ReadElementFunction;
28 
29 public: // construction/destruction
31  RscStructReader(const RscVariant<MaxStringSize>& structVariant); // Variant with struct information
33  RscStructReader(const RscStructReader& arg) = default;
35  RscStructReader& operator=(const RscStructReader& arg) = default;
37  ~RscStructReader(void) = default;
38 
39 public: // operators
40 
41 public: // static operations
46  size_t GetFieldCount(void) const;
47 
48 public: // setter/getter operations
49 
50 public: // operations
51 
57  template<class T>
58  void ReadNextField(T& currentField);
59 
64  void ReadNextField(RscString<MaxStringSize>& currentField);
65 
71 
72 private: // methods
73  RscType ReadRemotingValue(RscType expectedType, byte* pValue);
74 
75 private: // fields
76  RscStructInformation structInformation;
77  RemotingReader* pReader = nullptr;
78  ReadElementFunction readFieldFunction;
79 
80 private: // static fields
81 
82 };
83 
85 // inline methods of class RscStructReader
86 
87 template<int MaxStringSize>
89  : structInformation(structVariant.GetStructInformation())
90 {
91  if(structVariant.typeInfo.pReader == nullptr)
92  {
93  this->readFieldFunction = *structVariant.typeInfo.pReadElementFunction;
94  }
95  else
96  {
97  this->readFieldFunction = [&](RscType expectedType, byte * pValue)
98  {
99  return this->ReadRemotingValue(expectedType, pValue);
100  };
101  if(structVariant.typeInfo.pReader == nullptr)
102  {
103  throw ArgumentException("No remoting reader set in argument 'structVariant'");
104  }
105  this->pReader = structVariant.typeInfo.pReader;
106  }
107 }
108 
109 template<int MaxStringSize>
111 {
112  return this->structInformation.FieldCount;
113 }
114 
115 template<int MaxStringSize>
117 {
118  RscType readType = this->readFieldFunction(RscType::Object, value.GetDataAddress());
119  value.SetType(readType);
120  if(value.ContainsTypeInformation())
121  {
122  value.InitComplexTypeInfo();
123  value.typeInfo.pReader = this->pReader;
124  if(this->pReader == nullptr)
125  {
126  value.typeInfo.pReadElementFunction = &this->readFieldFunction;
127  }
128  }
129 }
130 
131 template<int MaxStringSize>
132 template<class T>
134 {
135  RscType expectedType = GetRscTypeFrom(currentField);
136  if(!IsPrimitiveRscType(expectedType))
137  {
138  throw InvalidOperationException("{}: This method works only for primitive types", __FUNCTION__);
139  }
140  (void)this->readFieldFunction(expectedType, reinterpret_cast<byte*>(&currentField));
141 }
142 
143 template<int MaxStringSize>
145 {
146  (void)this->readFieldFunction(RscType::Utf8String, reinterpret_cast<byte*>(currentField.CStr()));
147 }
148 
149 template<int MaxStringSize>
150 inline RscType RscStructReader<MaxStringSize>::ReadRemotingValue(RscType expectedType, byte* pValue)
151 {
152  RscType valueType = this->pReader->ReadObjectType();
153  if(expectedType != RscType::Object && expectedType != valueType)
154  {
155  throw RscException((int)RscErrors::InvalidData, "{}: Expected data type '{}', but got '{}'", __FUNCTION__, expectedType, valueType);
156  }
157  if(valueType == RscType::Array)
158  {
159  RscArrayInformation& arrayInformation = *reinterpret_cast<RscArrayInformation*>(pValue);
160  arrayInformation = this->pReader->ReadArrayInformation();
161  return RscType::Array;
162  }
163  else if(valueType == RscType::Struct)
164  {
165  RscStructInformation& nestedStructInformation = *reinterpret_cast<RscStructInformation*>(pValue);
166  nestedStructInformation.FieldCount = this->pReader->ReadFieldCount();
167  return RscType::Struct;
168  }
169  RscValue::Read(*this->pReader, valueType, pValue, MaxStringSize);
170  return valueType;
171 }
172 
173 }}}} // end of namespace Arp::System::Rsc::Services
This exception is used when an invalid argument occurs.
Definition: ArgumentException.hpp:15
This exception is used when a method call is invalid for object's current state.
Definition: InvalidOperationException.hpp:15
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
RscStructReader & operator=(const RscStructReader &arg)=default
Assignment operator.
RscStructReader(const RscVariant< MaxStringSize > &structVariant)
Constructs an RscStructReader instance.
Definition: RscStructReader.hxx:88
~RscStructReader(void)=default
Destructs this instance and frees all resources.
RscStructReader(const RscStructReader &arg)=default
Copy constructor.
size_t GetFieldCount(void) const
Gets the field count of the struct;
Definition: RscStructReader.hxx:110
void ReadNextField(T &currentField)
Reads the next field of current struct. This method if field is primitve and known.
Definition: RscStructReader.hxx:133
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
@ 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
@ Object
Object type handled by Rsc as RscVariant
@ Struct
Complex datatype with implements IRscSerializable
Root namespace for the PLCnext API
Contains information to marshall an array
Definition: RscType.hpp:130
Contains information to marshall an struct
Definition: RscType.hpp:164
size_t FieldCount
Count of struct fields
Definition: RscType.hpp:170