PLCnext API Documentation 23.0.2.9
RscWriteEnumerator.hxx
1
2//
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
16namespace Arp { namespace System { namespace Rsc { namespace Services
17{
18
22template<class T>
24{
25public: // typedefs
26
27public: // construction/destruction
29 RscWriteEnumerator(RscWriter& rscWriter, bool isArrayEnumerator);
34
35public: // 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
41private: // deleted methods
42 RscWriteEnumerator& operator=(const RscWriteEnumerator& arg) = delete;
43
44private: // 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
55template<class T>
56inline 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
64template<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
73template<class T>
74inline 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
106template<class T>
107inline 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
130template<class T>
131inline 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
139template<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
Data types supported by RSC.
Definition: RscType.hpp:36
@ Enumerator
Enumerator type implemented as IRscReadEnumerator or IRscWriteEnumerator
@ Array
std::vector<T> or RSC enumerators
@ Struct
struct derived by IRscSerializable
Root namespace for the PLCnext API