PLCnext API Documentation  22.9.0.33
RscStructWriter.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/RscVariant.hxx"
9 #include "Arp/System/Rsc/Services/RscValue.hpp"
10 namespace Arp { namespace System { namespace Rsc { namespace Services
11 {
12 
17 template<int MaxStringSize>
19 {
20 public: // typedefs
21  using WriteElementFunction = RscVariant<>::WriteElementFunction;
22 
23 public: // construction/destruction
25  RscStructWriter(const RscVariant<MaxStringSize>& structVariant);
27  RscStructWriter(const RscStructWriter& arg) = default;
29  RscStructWriter& operator=(const RscStructWriter& arg) = default;
31  ~RscStructWriter(void) = default;
32 
33 public: // operations
39  template<class T> void WriteNextField(const T& currentField);
40 
45  void WriteNextField(const RscVariant<MaxStringSize>& currentField);
46 
51  void WriteNextField(const RscString<MaxStringSize>& currentField);
52 
53 protected: // operations
54 
55 private: // static methods
56 
57 private: // methods
58  void WriteRemotingValue(RscType valueType, const byte* pValue);
59 
60 private: // fields
61  RscStructInformation structInformation;
62  WriteElementFunction writeFieldFunction;
63  RemotingWriter* pWriter = nullptr;;
64 private: // static fields
65 
66 };
67 
69 // inline methods of class RscStructWriter
70 
71 template<int MaxStringSize>
73  : structInformation(structVariant.GetStructInformation())
74 {
75  if(structVariant.typeInfo.pWriteElementFunction != nullptr)
76  {
77  this->writeFieldFunction = *structVariant.typeInfo.pWriteElementFunction;
78  }
79  else
80  {
81  this->writeFieldFunction = [&](RscType valueType, const byte * pValue)
82  {
83  this->WriteRemotingValue(valueType, pValue);
84  };
85  if(structVariant.typeInfo.pWriter == nullptr)
86  {
87  throw ArgumentException("No remoting writer set in argument 'structVariant'");
88  }
89  this->pWriter = structVariant.typeInfo.pWriter;
90  }
91 }
92 
93 template<int MaxStringSize>
95 {
96  if(currentField.GetType() == RscType::Array)
97  {
98  const RscArrayInformation& arrayInformation = currentField.GetArrayInformation();
99  this->writeFieldFunction(RscType::Array, reinterpret_cast<const byte*>(&arrayInformation));
100  currentField.typeInfo.pWriter = this->pWriter;
101  if(this->pWriter == nullptr)
102  {
103  currentField.typeInfo.pWriteElementFunction = &this->writeFieldFunction;
104  }
105  }
106  else if (currentField.GetType() == RscType::Struct)
107  {
108  const RscStructInformation& currenttructInformation = currentField.GetStructInformation();
109  this->writeFieldFunction(RscType::Struct, reinterpret_cast<const byte*>(&currenttructInformation));
110  currentField.typeInfo.pWriter = this->pWriter;
111  if (this->pWriter == nullptr)
112  {
113  currentField.typeInfo.pWriteElementFunction = &this->writeFieldFunction;
114  }
115  }
116  else
117  {
118  this->writeFieldFunction(currentField.GetType(), currentField.GetDataAddress());
119  }
120 }
121 
122 template<int MaxStringSize>
124 {
125  this->writeFieldFunction(RscType::Utf8String, reinterpret_cast<const byte*>(currentField.CStr()));
126 }
127 
128 template<int MaxStringSize>
129 template<class T>
130 inline void RscStructWriter<MaxStringSize>::WriteNextField(const T& currentField)
131 {
132  RscType type = GetRscTypeFrom(currentField);
133  if(!IsPrimitiveRscType(type))
134  {
135  throw InvalidOperationException("{}: This method is only for primtive types", __FUNCTION__);
136  }
137  this->writeFieldFunction(type, reinterpret_cast<const byte*>(&currentField));
138 }
139 
140 template<int MaxStringSize>
141 inline void RscStructWriter<MaxStringSize>::WriteRemotingValue(RscType valueType, const byte* pValue)
142 {
143  if(valueType == RscType::Array)
144  {
145  this->pWriter->WriteArrayInformation(*reinterpret_cast<const RscArrayInformation*>(pValue));
146  return;
147  }
148  this->pWriter->WriteObjectType(valueType);
149  RscValue::Write(*this->pWriter, valueType, pValue, MaxStringSize);
150 }
151 
152 }}}} // 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 write a struct from an RscVariant. This class uses the struct information stored in R...
Definition: RscStructWriter.hxx:19
RscStructWriter(const RscStructWriter &arg)=default
Copy constructor.
void WriteNextField(const T &currentField)
Writes the next field with primitive Type.
Definition: RscStructWriter.hxx:130
~RscStructWriter(void)=default
Destructs this instance and frees all resources.
RscStructWriter & operator=(const RscStructWriter &arg)=default
Assignment operator.
RscStructWriter(const RscVariant< MaxStringSize > &structVariant)
Constructs an RscStructWriter instance.
Definition: RscStructWriter.hxx:72
Rsc container class for primitive data type, strings or information about arrays or structs....
Definition: RscVariant.hxx:39
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
@ 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