PLCnext API Documentation 26.6.0.38
RscVariantBase.hpp
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
8#include "Arp/Base/Rsc/Commons/Rsc.hpp"
9#include "Arp/Base/Rsc/Commons/RscType.hpp"
10#include "Arp/Base/Rsc/Commons/RscTypeInfo.hpp"
11#include "Arp/Base/Rsc/Commons/RscTypeDeduction.hpp"
12#include "Arp/Base/Rsc/Commons/RscArrayInfo.hpp"
13#include "Arp/Base/Rsc/Commons/RscStructInfo.hpp"
14#include "Arp/Base/Commons/Exceptions/InvalidCastException.hpp"
15#include "Arp/Base/Commons/Exceptions/NotSupportedException.hpp"
16
17// forwards
18namespace Arp::Base::Rsc::Commons::Internal
19{
20class RscVariantAccessor;
21}
22
23namespace Arp::Base::Rsc::Commons
24{
25
26// forwards
27class RscStringBase;
28
29// type imports
32
33
40class ARP_EXPORT RscVariantBase
41{
42 friend class Arp::Base::Rsc::Commons::Internal::RscVariantAccessor;
43
44public: // usings
45 using ReadFieldFunction = std::function<void(RscType fieldType, RscVariantBase& value)>;
46 using WriteFieldFunction = std::function<void(RscType fieldType, const RscVariantBase& value)>;
47 using ReadElementFunction = std::function<void(RscType elementType, RscVariantBase& value)>;
48 using WriteElementFunction = std::function<void(RscType elementType, const RscVariantBase& value)>;
49
50public: // construction
51 RscVariantBase(RscType type = RscType::None);
52 RscVariantBase(RscType type, byte* pBuffer);
53 RscVariantBase(RscType type, char* pBuffer, size_t bufferSize);
54 RscVariantBase(const RscStringBase& data);
55 RscVariantBase(const RscArrayInfo& arrayInfo);
56 RscVariantBase(const RscStructInfo& structInfo);
57
58 // canonical construction/destruction/assignment
64
65public: // assign operators
66 RscVariantBase& operator=(const String& value);
67 RscVariantBase& operator=(const char* value);
68 RscVariantBase& operator=(const char8u* value);
69
70 template<class T> RscVariantBase& operator=(const T& value);
71 template<int N> RscVariantBase& operator=(const RscString<N>& value);
72 template<int N> RscVariantBase& operator=(const RscSecureString<N>& value);
73
74public: // setter/getter operations
75 void SetType(RscType value);
76 RscType GetType(void)const;
77 RscType GetValueType(void)const;
78 bool IsComplexType(void)const;
79 bool IsArray(void)const;
80 bool IsStruct(void)const;
81 bool IsFormattable(void)const;
82 size_t GetDataSize(void)const;
83 size_t GetMaxStringSize(void)const;
84 size_t GetBufferSize(void)const;
85 RscType GetArrayElementType(void)const;
86 size_t GetArraySize(void)const;
87 size_t GetArrayDimensions(void)const;
88 size_t GetArrayFieldCount(void)const;
89 size_t GetFieldCount(void) const;
90 byte* GetDataAddress(void);
91 const byte* GetDataAddress(void)const;
92 const char* GetChars(void)const;
93
94public: // operations
95 void Assign(const char* input, RscType rscType = RscType::String);
96 void Assign(const char* input, size_t length, RscType rscType = RscType::String);
97 void Assign(const char16* input, size_t length);
98 void Assign(const String& value);
99 void CopyTo(String& value)const;
100 String ToString(void)const;
101 void Clear(bool clearBuffer = false);
102 bool Equals(const RscVariantBase& arg)const;
103
104public: // RSC operations
105 void Read(RscReader& reader, bool omitTag);
106 void Write(RscWriter& writer, bool omitTag)const;
107
108public: // type-info operations
109 bool HasArrayInfo(void)const;
110 void SetArrayInfo(const RscArrayInfo& arrayInfo);
111 void SetArrayInfo(size_t size, RscType elementType = RscType::None, size_t dimensions = 1, size_t fieldCount = 0);
112 RscArrayInfo& GetArrayInfo(void);
113 const RscArrayInfo& GetArrayInfo(void)const;
114 bool HasStructInfo(void)const;
115 void SetStructInfo(size_t fieldCount);
116 RscStructInfo& GetStructInfo(void);
117 const RscStructInfo& GetStructInfo(void)const;
118 bool HasReadElementFunction(void)const;
119 ReadElementFunction GetReadElementFunction(void)const;
120 void SetReadElementFunction(ReadElementFunction& function);
121 bool HasWriteElementFunction(void)const;
122 WriteElementFunction GetWriteElementFunction(void)const;
123 void SetWriteElementFunction(WriteElementFunction& function)const;
124 void ResetComplexTypeInfo(void);
125
126public: // template operations
127 template<int N> void Assign(char value[N]);
128 template<int N> void Assign(const char value[N]);
129 template<int N> void Assign(const RscString<N>& value);
130 template<int N> void Assign(const RscSecureString<N>& value);
131 template<class T> void Assign(const T& value);
132 template<class T> void CopyTo(T& value)const;
133 template<int N> void CopyTo(RscString<N>& value)const;
134 template<int N> void CopyTo(RscSecureString<N>& value)const;
135 template<class T> T GetValue(void)const;
136 template<class T> T* GetValueAddress(void);
137 template<class T> const T* GetValueAddress(void)const;
138
139protected: // methods accessible by RscVariantAccessor and derived class RscVariant<N>
140 void SetBufferInfo(byte* pDataBuffer, size_t dataBufferSize, bool isDynamicString);
141 bool HasReader(void)const;
142 bool HasWriter(void)const;
143 void SetReader(RscReader& reader);
144 void SetWriter(RscWriter& writer)const;
145 RscReader* GetReader(void)const;
146 RscWriter* GetWriter(void)const;
147
148private: // methods
149 bool ProvidesDynamicString(void)const;
150 String& GetDynamicString(void);
151 const String& GetDynamicString(void)const;
152
153private: // static methods
154 static size_t DetermineBufferSize(RscType type);
155
156private: // nested types
157 struct ComplexTypeInfo
158 {
159 friend class RscVariantBase;
160
161 private: // nested types
162 struct ComplexVariantInfo
163 {
164 RscArrayInfo arrayInfo{};
165 RscStructInfo structInfo{};
166 };
167 ComplexVariantInfo complexVariantInfo{};
168 RscReader* pReader = nullptr;
169 mutable RscWriter* pWriter = nullptr;
170 ReadElementFunction* pReadElementFunction = nullptr;
171 mutable WriteElementFunction* pWriteElementFunction = nullptr;
172 };
173
174protected: // fields
175 RscType type = RscType::None;
176 byte* pBuffer = nullptr;
177 size_t bufferSize = 0;
178 bool providesDynamicString = false;
180 ComplexTypeInfo typeInfo;
181};
182
184// inline methods of class RscVariantBase
185
188template<int N>
189inline void RscVariantBase::Assign(char value[N])
190{
191 this->Assign(value, 0);
192}
193
196template<int N>
197inline void RscVariantBase::Assign(const char value[N])
198{
199 this->Assign(value, 0);
200}
201
204template<int N>
205inline void RscVariantBase::Assign(const RscString<N>& value)
206{
207 this->Assign(value.CStr(), value.GetLength());
208}
209
212template<int N>
214{
215 this->Assign(value.CStr(), value.GetLength(), RscType::SecureString);
216}
217
221template<class T>
222inline void RscVariantBase::Assign(const T& value)
223{
224 RscType rscType = RscTypeDeduction::GetFrom(value);
225 if (rscType == RscType::None)
226 {
227 throw NotSupportedException("RscVariant does not support type '{}'.", TypeName<T>());
228 }
229 // else
230 if constexpr (std::is_trivially_copy_assignable_v<T>&& (alignof(T) > alignof(RscVariantBase)))
231 {
232 std::memcpy(GetValueAddress<T>(), std::addressof(value), sizeof(T));
233 }
234 else
235 {
236 *this->GetValueAddress<T>() = value;
237 }
238 this->SetType(rscType);
239}
240
244template<class T>
246{
247 T result;
248 this->CopyTo(result);
249 return result;
250}
251
255template<class T>
257{
258 return reinterpret_cast<T*>(this->pBuffer);
259}
260
264template<class T>
266{
267 return reinterpret_cast<const T*>(this->pBuffer);
268}
269
273template<class T>
274inline void RscVariantBase::CopyTo(T& value)const
275{
276 RscType argType = RscTypeDeduction::GetFrom(value);
277 if (this->GetValueType() != argType)
278 {
279 throw InvalidCastException("Cannot copy value to argument: RscVariant contains data type {0} but arg is of type {1}", this->GetType(), argType);
280 }
281 if constexpr (std::is_trivially_copy_assignable_v<T>&& (alignof(T) > alignof(RscVariantBase)))
282 {
283 std::memcpy(std::addressof(value), this->GetValueAddress<T>(), sizeof(T));
284 }
285 else
286 {
287 value = *this->GetValueAddress<T>();
288 }
289}
290
294template<int N>
295inline void RscVariantBase::CopyTo(RscString<N>& value)const
296{
298 {
299 throw InvalidCastException("Cannot copy to string: RscVariant is of type {0}", this->type);
300 }
301
302 if (this->ProvidesDynamicString())
303 {
304 value = this->GetDynamicString();
305 }
306 else
307 {
308 value.Assign(this->GetChars());
309 }
310}
311
315template<int N>
317{
318 this->CopyTo(static_cast<RscString<N>&>(value));
319}
320
325template<class T>
327{
328 this->Assign(value);
329 return *this;
330}
331
336template<int N>
338{
339 this->Assign(value.CStr(), value.GetLength());
340 return *this;
341}
342
347template<int N>
349{
350 this->Assign(value.CStr(), value.GetLength(), RscType::SecureString);
351 return *this;
352}
353
354} // end of namespace Arp::Base::Rsc::Commons
This exception is thrown when an invalid cast occurs.
Definition: InvalidCastException.hpp:17
This exception is thrown when a not supported operation is invoked.
Definition: NotSupportedException.hpp:16
This class represents the Arp String. The implementation is based on std::string.
Definition: String.hpp:39
This (meta programming) class provides the C++ type-name of the as template argument passed type.
Definition: TypeName.hxx:20
Contains information to marshal dynamic arrays.
Definition: RscArrayInfo.hpp:14
Specialized implementation of RscString for secure context.
Definition: RscSecureString.hxx:16
This class is a base class of template class RscString.
Definition: RscStringBase.hpp:27
size_t GetLength(void) const
Gets the length of this string.
Definition: RscStringBase.cpp:49
const char * CStr(void) const
Returns a const char pointer to the internal string buffer.
Definition: RscStringBase.cpp:63
void Assign(const char *pChars)
Assigns the char buffer to this instance.
Definition: RscStringBase.cpp:127
Contains a static string with string lentgh up to N characters. The string shall be null terminated.
Definition: RscString.hxx:24
Contains information to marshal structs.
Definition: RscStructInfo.hpp:17
static constexpr RscType GetFrom(const T &)
Gets the RscType of the as argument passed parameter.
Definition: RscTypeDeduction.hpp:77
static bool IsStringType(RscType type)
Determines if the supplied RscType is a string type.
Definition: RscTypeInfo.cpp:182
This class is a base class of template class RscVariant.
Definition: RscVariantBase.hpp:41
void SetType(RscType value)
Forces the internal RscType to be set to another RscType.
Definition: RscVariantBase.cpp:139
RscVariantBase & operator=(RscVariantBase &&arg) noexcept
The move-assign operator.
const char * GetChars(void) const
Gets a readable pointer to internal string buffer.
Definition: RscVariantBase.cpp:392
~RscVariantBase(void)
The default destructor.
RscType GetType(void) const
Gets the RscType of the contained element
Definition: RscVariantBase.cpp:290
std::function< void(RscType fieldType, const RscVariantBase &value)> WriteFieldFunction
The write field delegate type.
Definition: RscVariantBase.hpp:46
RscVariantBase(RscVariantBase &&arg) noexcept
The move constructor.
std::function< void(RscType elementType, const RscVariantBase &value)> WriteElementFunction
The write element delegate type.
Definition: RscVariantBase.hpp:48
ComplexTypeInfo typeInfo
The type info of this variant.
Definition: RscVariantBase.hpp:180
T GetValue(void) const
Converts this value to the given type T .
Definition: RscVariantBase.hpp:245
RscType type
The RSC type of this variant.
Definition: RscVariantBase.hpp:175
RscVariantBase(const RscVariantBase &arg)
The copy constructor.
RscType GetValueType(void) const
Gets the raw value type as RscType of the contained element.
Definition: RscVariantBase.cpp:301
String dynamicString
The dynamic string storage.
Definition: RscVariantBase.hpp:179
std::function< void(RscType elementType, RscVariantBase &value)> ReadElementFunction
The read element delegate type.
Definition: RscVariantBase.hpp:47
byte * pBuffer
The buffer of this variant (usually applied by RscVariant<T>)
Definition: RscVariantBase.hpp:176
RscVariantBase & operator=(const RscVariantBase &arg)
The assign operator.
std::function< void(RscType fieldType, RscVariantBase &value)> ReadFieldFunction
The read field delegate type.
Definition: RscVariantBase.hpp:45
void Assign(const char *input, RscType rscType=RscType::String)
Assigns an UTF8 string to this instance.
Definition: RscVariantBase.cpp:776
void CopyTo(String &value) const
Copies the content of this variant to a string.
Definition: RscVariantBase.cpp:857
T * GetValueAddress(void)
Gets the address of the contained value as type T *.
Definition: RscVariantBase.hpp:256
Reads marshaled data of RSC services.
Definition: RscReader.hpp:34
Writes marshalled data of RSC services.
Definition: RscWriter.hpp:34
char16_t char16
The Arp character type of 2 byte size.
Definition: PrimitiveTypes.hpp:49
char8_t char8u
The Arp UTF8 character type of 1 byte size.
Definition: PrimitiveTypes.hpp:47
@ Equals
Start recording if TriggerVariable1 is equal to TriggerVariable2.
@ Write
Specifies write access to the file. Data can be written to the file and the file pointer can be moved...
@ Read
Specifies read access to the file. Data can be read from the file and the file pointer can be moved....