PLCnext API Documentation  22.9.0.33
RscWriteEnumerator.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Rsc/Services/Rsc.h"
8 #include "Arp/System/Commons/Logging.h"
9 #include "Arp/System/Commons/Exceptions/Exceptions.h"
10 #include "Arp/System/Rsc/Services/RscException.hpp"
11 #include "Arp/System/Rsc/Services/IRscWriteEnumerator.hxx"
12 #include "Arp/System/Rsc/Services/RscWriter.hpp"
13 #include "Arp/System/Rsc/Services/RscArrayWriter.hpp"
14 
15 
16 namespace Arp { namespace System { namespace Rsc { namespace Services
17 {
18 
22 template<class T>
24 {
25 public: // typedefs
26 
27 public: // construction/destruction
29  RscWriteEnumerator(RscWriter& rscWriter, bool isArrayEnumerator);
31  RscWriteEnumerator(const RscWriteEnumerator& arg) = default;
33  ~RscWriteEnumerator(void);
34 
35 public: // operations of IRscWriteEnumerator
36  void BeginWrite(size_t arrayLengthArg = (size_t) -1)override;
37  void WriteNext(const T& current)override;
38  RscArrayWriter WriteNext(size_t arraySize, RscType arrayElementType)override;
39  void EndWrite(void)override;
40 
41 private: // deleted methods
42  RscWriteEnumerator& operator=(const RscWriteEnumerator& arg) = delete;
43 
44 private: // fields
45  RemotingWriter& remotingWriter;
46  bool isArrayEnumerator;
47  RscType rscType;
48  size_t arrayLength = 0;
49  bool endWritten = false;
50  size_t fieldCount = 0;
51 };
52 
54 // inline methods of class RscEnumerator
55 template<class T>
56 inline RscWriteEnumerator<T>::RscWriteEnumerator(RscWriter& rscWriter, bool isArrayEnumeratorArg)
57  : isArrayEnumerator(isArrayEnumeratorArg)
58  , remotingWriter(rscWriter.GetRemotingWriter())
59  , rscType(GetRscTypeFrom(T()))
60  , fieldCount(StructInfo<T>().FieldCount)
61 {
62 }
63 
64 template<class T>
66 {
67  if(!this->endWritten)
68  {
69  Log::Error("Rsc Enumerating was not ended properly, call EndWrite() method when writing was finished.");
70  }
71 }
72 
73 template<class T>
74 inline void RscWriteEnumerator<T>::BeginWrite(size_t arrayLengthArg)
75 {
76  this->arrayLength = arrayLengthArg;
77 
78  if(this->isArrayEnumerator)
79  {
80  if(this->arrayLength == (size_t) -1)
81  {
82  throw ArgumentException("Array length has to be defined for array enumerators.");
83  }
84  this->remotingWriter.WriteTag(RscType::Array);
85  // Write element Tag
86  if(this->rscType == RscType::Struct)
87  {
88  this->remotingWriter.WriteBeginStruct(this->fieldCount);
89  }
90  else
91  {
92  this->remotingWriter.WriteTag(this->rscType);
93  }
94  this->remotingWriter.WriteArrayLength(this->arrayLength);
95  }
96  else // standard enumerator
97  {
98  if(this->arrayLength != (size_t) -1)
99  {
100  throw ArgumentException("Array length could not be defined for standard enumerators.");
101  }
102  this->remotingWriter.WriteTag(RscType::Enumerator);
103  }
104 }
105 
106 template<class T>
107 inline void RscWriteEnumerator<T>::WriteNext(const T& current)
108 {
109  if(this->isArrayEnumerator)
110  {
111  if(this->arrayLength == 0)
112  {
113  throw InvalidOperationException("End of array enumerator reached");
114  }
115  // else
116  --this->arrayLength;
117  }
118  else // use standard enumerator
119  {
120  this->remotingWriter.WriteEnumeratorTag(this->rscType);
121  if(this->rscType == RscType::Struct)
122  {
123  this->remotingWriter.WriteFieldCount(this->fieldCount);
124  }
125  }
126  RscValueAdapter<T> valueAdapter(current);
127  valueAdapter.Write(this->remotingWriter, false);
128 }
129 
130 template<class T>
131 inline RscArrayWriter RscWriteEnumerator<T>::WriteNext(size_t arraySize, RscType arrayElementType)
132 {
133  this->remotingWriter.WriteTag(RscType::Array);
134  this->remotingWriter.WriteTag(arrayElementType);
135  this->remotingWriter.WriteArrayLength(arraySize);
136  return RscArrayWriter(arraySize, arrayElementType, this->remotingWriter);
137 }
138 
139 template<class T>
141 {
142  if(this->isArrayEnumerator)
143  {
144  if(this->arrayLength != 0)
145  {
146  throw InvalidOperationException("End of array enumerator was not reached yet");
147  }
148  }
149  else // use standard enumerator
150  {
151  this->remotingWriter.WriteEnumeratorTag(RscType::End);
152  }
153 
154  this->endWritten = true;
155 }
156 
157 }}}} // 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
Interface for writing an array or an enumerator. For regular enumerators UndefinedArrayLength is used...
Definition: IRscWriteEnumerator.hxx:23
Helper class to read an array of primtive types from an RscVariant. This class uses the array informa...
Definition: RscArrayWriter.hpp:22
Implementation of IRscWriteEnumerator used on client side.
Definition: RscWriteEnumerator.hxx:24
void BeginWrite(size_t arrayLengthArg=(size_t) -1) override
Begins the operation to write the enumerator.
Definition: RscWriteEnumerator.hxx:74
void EndWrite(void) override
Ends the enumerator. With an array enumerator all enumerator elements had to be written
Definition: RscWriteEnumerator.hxx:140
void WriteNext(const T &current) override
Writes the next enumerator element.
Definition: RscWriteEnumerator.hxx:107
RscWriteEnumerator(RscWriter &rscWriter, bool isArrayEnumerator)
Constructs an RscEnumeratorBase instance.
Definition: RscWriteEnumerator.hxx:56
~RscWriteEnumerator(void)
Destructs this instance and frees all resources.
Definition: RscWriteEnumerator.hxx:65
RscWriteEnumerator(const RscWriteEnumerator &arg)=default
Copy constructor.
Writes data to Rsc.
Definition: RscWriter.hpp:31
@ 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
@ Enumerator
Enumerator type, handled by Rsc with IRscReadEnumerator and IRscWriteEnumerator
@ Struct
Complex datatype with implements IRscSerializable
Root namespace for the PLCnext API