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