PLCnext API Documentation 25.0.2.69
RscWriter.hpp
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
8#include "Arp/Base/Core/PimplPtr.hxx"
9#include "Arp/Base/Core/Enum.hxx"
10#include "Arp/Base/Commons/Io/Stream.hpp"
11#include "Arp/Base/Rsc/Commons/Rsc.hpp"
12#include "Arp/Base/Rsc/Commons/RscString.hxx"
13#include "Arp/Base/Rsc/Commons/RscVariant.hxx"
14#include "Arp/Base/Rsc/Commons/RscStream.hpp"
15#include "Arp/Base/Rsc/Commons/RscStreamWriter.hpp"
16#include "Arp/Base/Rsc/Commons/RscException.hpp"
17#include "Arp/Base/Rsc/Commons/RscTypeInfo.hpp"
18#include "Arp/Base/Rsc/Commons/RscTypeDeduction.hpp"
19#include "Arp/Base/Rsc/Commons/Services/StructInfo.hxx"
20#include "Arp/Base/Rsc/Commons/Services/RscConcepts.hpp"
21#include <array>
22#include <vector>
23
24namespace Arp::Base::Rsc::Commons::Services
25{
26
28
33class ARP_EXPORT RscWriter
34{
35public: // Impl forward declaration
36 class Impl;
37
38public: // construction
39 explicit RscWriter(Stream& remoteStream);
40
41 // canonical construction/destruction/assignment
42 RscWriter(const RscWriter& arg);
43 RscWriter(RscWriter&& arg)noexcept;
45 RscWriter& operator=(RscWriter&& arg)noexcept;
47
48public: // setter/getter operations
49 RscStream GetStream(void);
50 RscStreamWriter GetStreamWriter(void);
51
52public: // concrete operations used by RscGenerator
53 void Write(const RscPtr& value, bool omitTag = false);
54 void Write(const RscConstPtr& value, bool omitTag = false);
55 void Write(const String& value, bool omitTag = false);
56 void Write(const DateTime& value, bool omitTag = false);
57 void Write(const SecurityToken& value, bool omitTag = false);
58 void Write(RscStream stream, bool omitTag = false);
59 void Write(RscVariantBase& result, bool omitTag = false);
60
61public: // generic operations used by RscGenerator
62 template<RscEnumType T> void Write(const T& value, bool omitTag = false);
63 template<RscPrimitiveType T> void Write(const T& value, bool omitTag = false);
64 template<RscClassType T> void Write(const T& value, bool omitTag = false);
65 template<RscSerializableType T> void Write(const T& value, bool omitTag = false);
66 template<int N> void Write(const RscVariant<N>& result, bool omitTag = false);
67 template<class T> void Write(const std::vector<T>& data, bool omitTag = false);
68 template<class T> void Write(const std::vector<std::vector<T>>& data, bool omitTag = false);
69 template<class T, size_t N> void Write(const std::array<T, N>& data, bool omitTag = false);
70
71public: // auxiliaries operations
72 void WriteTag(RscType tag);
73 void WriteFieldCount(size_t fieldCount);
74 void WriteArrayLength(size_t arraySize);
75 void WriteStructInfo(size_t fieldCount);
76 void WriteEnumeratorTag(RscType tag);
77 void WriteConfirmation(bool flush = false);
78
79private: // methods
80 template<class T>
81 void WriteBeginArray(size_t arraySize, RscType& elementType, bool omitTag = false);
82 void WritePrimitive(const byte* pValue, RscType type);
83 void Write(const RscVariantBase& value, bool omitTag = false);
84
85public: // internal operations
86 Impl& GetImpl(void);
87 const Impl& GetImpl(void)const;
88
89private: // Impl usings
91
92private: // Impl fields
93 Pimpl pimpl;
94};
95
97// inline implementations of class RscWriter
98
102template<RscEnumType T>
103inline void RscWriter::Write(const T& value, bool omitTag)
104{
105 RscType tag = RscTypeDeduction::GetFrom(value);
106 if (!omitTag)
107 {
108 this->WriteTag(tag);
109 }
110 typename Enum<T>::U primitiveValue = make_enum(value).ToUnderlyingType();
111 this->WritePrimitive(reinterpret_cast<const byte*>(&primitiveValue), tag);
112}
113
117template<RscPrimitiveType T>
118inline void RscWriter::Write(const T& value, bool omitTag)
119{
120 RscType tag = RscTypeDeduction::GetFrom(value);
121 if (!omitTag)
122 {
123 this->WriteTag(tag);
124 }
125 this->WritePrimitive(reinterpret_cast<const byte*>(&value), tag);
126}
127
131template<RscClassType T>
132inline void RscWriter::Write(const T& value, bool omitTag)
133{
134 RscType tag = RscTypeDeduction::GetFrom(value);
135 if (!omitTag && tag != RscType::Object) // do not write tag for RscVariant (objects), this is done by RscVariant impl itself
136 {
137 this->WriteTag(tag);
138 }
139 value.Write(*this);
140}
141
145template<RscSerializableType T>
146inline void RscWriter::Write(const T& value, bool omitTag)
147{
148 if (!omitTag)
149 {
150 this->WriteStructInfo(StructInfo<T>().FieldCount);
151 }
152 value.Serialize(*this);
153}
154
158template<int N>
159inline void RscWriter::Write(const RscVariant<N>& value, bool omitTag)
160{
161 this->Write(static_cast<const RscVariantBase&>(value), omitTag);
162}
163
168template<class T>
169inline void RscWriter::Write(const std::vector<T>& data, bool omitTag)
170{
171 RscType elementType = RscType::None;
172 size_t arraySize = data.size();
173 this->WriteBeginArray<T>(arraySize, elementType, omitTag);
174
175 bool omitElementTag = RscTypeInfo::IsConcreteType(elementType);
176 for (size_t i = 0; i < arraySize; ++i)
177 {
178 this->Write(data[i], omitElementTag);
179 }
180}
181
186template<class T>
187inline void RscWriter::Write(const std::vector<std::vector<T>>& data, bool omitTag)
188{
189 RscType elementType = RscType::None;
190 size_t arraySize = data.size();
191 this->WriteTag(RscType::Array);
192 this->WriteBeginArray<T>(arraySize, elementType, omitTag);
193
194 bool omitElementTag = RscTypeInfo::IsConcreteType(elementType);
195 for (size_t i = 0; i < arraySize; ++i)
196 {
197 const std::vector<T>& innerArray = data[i];
198 size_t innerArraySize = innerArray.size();
199 this->WriteArrayLength(innerArraySize);
200
201 for (size_t j = 0; j < innerArraySize; ++j)
202 {
203 this->Write(innerArray[j], omitElementTag);
204 }
205 }
206}
207
213template<class T, size_t N>
214inline void RscWriter::Write(const std::array<T, N>& data, bool omitTag)
215{
216 RscType elementType = RscType::None;
217 size_t arraySize = data.size();
218 this->WriteBeginArray<T>(arraySize, elementType, omitTag);
219
220 bool omitElementTag = RscTypeInfo::IsConcreteType(elementType);
221 for (size_t i = 0; i < arraySize; ++i)
222 {
223 this->Write(data[i], omitElementTag);
224 }
225}
226
232template<class T>
233inline void RscWriter::WriteBeginArray(size_t arraySize, RscType& elementType, bool omitTag)
234{
235 elementType = RscTypeDeduction().Get<T>();
236 if (!omitTag)
237 {
238 this->WriteTag(RscType::Array);
239 if (elementType == RscType::Struct)
240 {
241 this->WriteStructInfo(StructInfo<T>().FieldCount);
242 }
243 else
244 {
245 this->WriteTag(elementType);
246 }
247 }
248 this->WriteArrayLength(arraySize);
249}
250
251} // end of namespace Arp::Base::Rsc::Commons::Services
This abstract class shall be the base class of all stream implementations.
Definition: Stream.hpp:20
This class is used for authorization of arbitrary operations.
Definition: SecurityToken.hpp:18
This class contains date and time informations.
Definition: DateTime.hpp:27
typename std::underlying_type< T >::type U
The underlying integral type of the adapted enum class type.
Definition: Enum.hxx:24
Adapter class to implement PImpl idiom.
Definition: PimplPtr.hxx:15
This class represents the Arp String. The implementation is based on std::string.
Definition: String.hpp:39
Enables Rsc services to marshal large data packets as stream.
Definition: RscStreamWriter.hpp:23
This class might be used to marshal unstructured stream data as bytes.
Definition: RscStream.hpp:29
This class is used to deduct RSC types automatically by compilation.
Definition: RscTypeDeduction.hpp:24
constexpr RscType Get(void)
Gets the RscType of the as argument passed template parameter.
Definition: RscTypeDeduction.hpp:47
static constexpr RscType GetFrom(const T &)
Gets the RscType of the as argument passed parameter.
Definition: RscTypeDeduction.hpp:77
static bool IsConcreteType(RscType type)
Determines if the supplied type specifies a concrete type, i.e not unspecified and not object.
Definition: RscTypeInfo.cpp:242
This class is a base class of template class RscVariant.
Definition: RscVariantBase.hpp:40
Rsc class for variant data types like primitive data type, strings or information about arrays or str...
Definition: RscVariant.hxx:57
Writes marshalled data of RSC services.
Definition: RscWriter.hpp:34
void WriteTag(RscType tag)
Writes a data tag to RSC.
Definition: RscWriter.cpp:125
RscWriter(const RscWriter &arg)
The default copy constructor.
void WriteArrayLength(size_t arraySize)
Writes the length of an array to RSC.
Definition: RscWriter.cpp:139
RscWriter & operator=(RscWriter &&arg) noexcept
The default move-assignment operator.
RscWriter & operator=(const RscWriter &arg)
The default copy-assignment operator.
RscWriter(RscWriter &&arg) noexcept
The default move constructor.
void Write(const RscPtr &value, bool omitTag=false)
Writes a value to RSC.
Definition: RscWriter.cpp:78
~RscWriter(void)
The default destructor.
void WriteStructInfo(size_t fieldCount)
Writes the struct info to RSC.
Definition: RscWriter.cpp:146
Enum< T > make_enum(T value)
Global make function to adapt any enum class by class Enum.
Definition: Enum.ipp:222
@ Write
Specifies write access to the file. Data can be written to the file and the file pointer can be moved...
This class provides the number of fields of a concrete struct. This class is specialized for concrete...
Definition: StructInfo.hxx:26