PLCnext API Documentation 25.0.2.69
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/RscTypeDeduction.hpp"
11#include "Arp/Base/Rsc/Commons/RscArrayInfo.hpp"
12#include "Arp/Base/Rsc/Commons/RscStructInfo.hpp"
13#include "Arp/Base/Commons/Exceptions/InvalidCastException.hpp"
14#include "Arp/Base/Commons/Exceptions/NotSupportedException.hpp"
15
16// forwards
17namespace Arp::Base::Rsc::Commons::Internal
18{
19class RscVariantAccessor;
20}
21
22namespace Arp::Base::Rsc::Commons
23{
24
25// forwards
26class RscStringBase;
27
28// type imports
31
32
39class ARP_EXPORT RscVariantBase
40{
41 friend class Arp::Base::Rsc::Commons::Internal::RscVariantAccessor;
42
43public: // usings
44 using ReadFieldFunction = std::function<void(RscType fieldType, RscVariantBase& value)>;
45 using WriteFieldFunction = std::function<void(RscType fieldType, const RscVariantBase& value)>;
46 using ReadElementFunction = std::function<void(RscType elementType, RscVariantBase& value)>;
47 using WriteElementFunction = std::function<void(RscType elementType, const RscVariantBase& value)>;
48
49public: // construction
50 RscVariantBase(RscType type = RscType::None);
51 RscVariantBase(RscType type, byte* pBuffer);
52 RscVariantBase(RscType type, char* pBuffer, size_t bufferSize);
53 RscVariantBase(const RscStringBase& data);
54 RscVariantBase(const RscArrayInfo& arrayInfo);
55 RscVariantBase(const RscStructInfo& structInfo);
56
57 // canonical construction/destruction/assignment
63
64public: // assign operators
65 RscVariantBase& operator=(const String& value);
66 RscVariantBase& operator=(const char* value);
67 RscVariantBase& operator=(const char8u* value);
68
69 template<class T> RscVariantBase& operator=(const T& value);
70 template<int N> RscVariantBase& operator=(const RscString<N>& value);
71 template<int N> RscVariantBase& operator=(const RscSecureString<N>& value);
72
73public: // setter/getter operations
74 void SetType(RscType value);
75 RscType GetType(void)const;
76 RscType GetValueType(void)const;
77 bool IsComplexType(void)const;
78 bool IsArray(void)const;
79 bool IsStruct(void)const;
80 bool IsFormattable(void)const;
81 size_t GetDataSize(void)const;
82 size_t GetMaxStringSize(void)const;
83 size_t GetBufferSize(void)const;
84 RscType GetArrayElementType(void)const;
85 size_t GetArraySize(void)const;
86 size_t GetArrayDimensions(void)const;
87 size_t GetArrayFieldCount(void)const;
88 size_t GetFieldCount(void) const;
89 byte* GetDataAddress(void);
90 const byte* GetDataAddress(void)const;
91 const char* GetChars(void)const;
92
93public: // operations
94 void Assign(const char* input, RscType rscType = RscType::String);
95 void Assign(const char* input, size_t length, RscType rscType = RscType::String);
96 void Assign(const char16* input, size_t length);
97 void Assign(const String& value);
98 void CopyTo(String& value)const;
99 String ToString(void)const;
100 void Clear(bool clearBuffer = false);
101 bool Equals(const RscVariantBase& arg)const;
102
103public: // RSC operations
104 void Read(RscReader& reader, bool omitTag);
105 void Write(RscWriter& writer, bool omitTag)const;
106
107public: // type-info operations
108 bool HasArrayInfo(void)const;
109 void SetArrayInfo(const RscArrayInfo& arrayInfo);
110 void SetArrayInfo(size_t size, RscType elementType = RscType::None, size_t dimensions = 1, size_t fieldCount = 0);
111 RscArrayInfo& GetArrayInfo(void);
112 const RscArrayInfo& GetArrayInfo(void)const;
113 bool HasStructInfo(void)const;
114 void SetStructInfo(size_t fieldCount);
115 RscStructInfo& GetStructInfo(void);
116 const RscStructInfo& GetStructInfo(void)const;
117 bool HasReadElementFunction(void)const;
118 ReadElementFunction GetReadElementFunction(void)const;
119 void SetReadElementFunction(ReadElementFunction& function);
120 bool HasWriteElementFunction(void)const;
121 WriteElementFunction GetWriteElementFunction(void)const;
122 void SetWriteElementFunction(WriteElementFunction& function)const;
123 void ResetComplexTypeInfo(void);
124
125public: // template operations
126 template<int N> void Assign(char value[N]);
127 template<int N> void Assign(const char value[N]);
128 template<int N> void Assign(const RscString<N>& value);
129 template<int N> void Assign(const RscSecureString<N>& value);
130 template<class T> void Assign(const T& value);
131 template<class T> void CopyTo(T& value)const;
132 template<class T> T GetValue(void)const;
133 template<class T> T* GetValueAddress(void);
134 template<class T> const T* GetValueAddress(void)const;
135
136protected: // methods accessible by RscVariantAccessor and derived class RscVariant<N>
137 void SetBufferInfo(byte* pDataBuffer, size_t dataBufferSize, bool isDynamicString);
138 bool HasReader(void)const;
139 bool HasWriter(void)const;
140 void SetReader(RscReader& reader);
141 void SetWriter(RscWriter& writer)const;
142 RscReader* GetReader(void)const;
143 RscWriter* GetWriter(void)const;
144
145private: // methods
146 bool ProvidesDynamicString(void)const;
147 String& GetDynamicString(void);
148 const String& GetDynamicString(void)const;
149
150private: // static methods
151 static size_t DetermineBufferSize(RscType type);
152
153private: // nested types
154 struct ComplexTypeInfo
155 {
157 {
158 RscArrayInfo arrayInfo{};
159 RscStructInfo structInfo{};
160 };
161 ComplexVariantInfo complexVariantInfo{};
162 RscReader* pReader = nullptr;
163 mutable RscWriter* pWriter = nullptr;
164 ReadElementFunction* pReadElementFunction = nullptr;
165 mutable WriteElementFunction* pWriteElementFunction = nullptr;
166 };
167
168protected: // fields
169 RscType type = RscType::None;
170 byte* pBuffer = nullptr;
171 size_t bufferSize = 0;
172 bool providesDynamicString = false;
174 ComplexTypeInfo typeInfo;
175};
176
178// inline methods of class RscVariantBase
179
182template<int N>
183inline void RscVariantBase::Assign(char value[N])
184{
185 this->Assign(value, 0);
186}
187
190template<int N>
191inline void RscVariantBase::Assign(const char value[N])
192{
193 this->Assign(value, 0);
194}
195
198template<int N>
199inline void RscVariantBase::Assign(const RscString<N>& value)
200{
201 this->Assign(value.CStr(), value.GetLength());
202}
203
206template<int N>
208{
209 this->Assign(value.CStr(), value.GetLength(), RscType::SecureString);
210}
211
215template<class T>
216inline void RscVariantBase::Assign(const T& value)
217{
218 RscType rscType = RscTypeDeduction::GetFrom(value);
219 if (rscType == RscType::None)
220 {
221 throw NotSupportedException("RscVariant does not support type '{}'.", TypeName<T>());
222 }
223 // else
224 *this->GetValueAddress<T>() = value;
225 this->SetType(rscType);
226}
227
231template<class T>
233{
234 T result;
235 this->CopyTo(result);
236 return result;
237}
238
242template<class T>
244{
245 return reinterpret_cast<T*>(this->pBuffer);
246}
247
251template<class T>
253{
254 return reinterpret_cast<const T*>(this->pBuffer);
255}
256
260template<class T>
261inline void RscVariantBase::CopyTo(T& value)const
262{
263 RscType argType = RscTypeDeduction::GetFrom(value);
264 if (this->GetValueType() != argType)
265 {
266 throw InvalidCastException("Cannot copy value to argument: RscVariant contains data type {0} but arg is of type {1}", this->GetType(), argType);
267 }
268 value = *this->GetValueAddress<T>();
269}
270
275template<class T>
277{
278 this->Assign(value);
279 return *this;
280}
281
286template<int N>
288{
289 this->Assign(value.CStr(), value.GetLength());
290 return *this;
291}
292
297template<int N>
299{
300 this->Assign(value.CStr(), value.GetLength());
301 return *this;
302}
303
304} // 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
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
This class is a base class of template class RscVariant.
Definition: RscVariantBase.hpp:40
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.
~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:45
RscVariantBase(RscVariantBase &&arg) noexcept
The move constructor.
std::function< void(RscType elementType, const RscVariantBase &value)> WriteElementFunction
The write element delegate type.
Definition: RscVariantBase.hpp:47
ComplexTypeInfo typeInfo
The type info of this variant.
Definition: RscVariantBase.hpp:174
T GetValue(void) const
Converts this value to the given type T .
Definition: RscVariantBase.hpp:232
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:173
std::function< void(RscType elementType, RscVariantBase &value)> ReadElementFunction
The read element delegate type.
Definition: RscVariantBase.hpp:46
byte * pBuffer
The buffer of this variant (usually applied by RscVariant<T>)
Definition: RscVariantBase.hpp:170
RscVariantBase & operator=(const RscVariantBase &arg)
The assign operator.
std::function< void(RscType fieldType, RscVariantBase &value)> ReadFieldFunction
The read field delegate type.
Definition: RscVariantBase.hpp:44
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:858
T * GetValueAddress(void)
Gets the address of the contained value as type T *.
Definition: RscVariantBase.hpp:243
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....