PLCnext API Documentation 25.0.2.69
SpecializedPayload.hpp
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
8#include "Arp/System/Core/TypeName.hxx"
9#include "Arp/System/Commons/Exceptions/ArgumentException.hpp"
10#include "Arp/System/Nm/GenericPayload.hpp"
11#include "Arp/System/Nm/IPayload.hpp"
12#include "Arp/System/Nm/Notification.hpp"
13#include "Arp/System/Nm/NotificationManager.hpp"
14#include "Arp/System/Nm/RscVariantHelpers.hpp"
15#include "Arp/Base/Rsc/Commons/RscTypeDeduction.hpp"
16#include <type_traits>
17
18namespace Arp { namespace System { namespace Nm
19{
20
22
23class LongStringPayloadField;
24
25
42template<typename PayloadType>
43class ARP_CXX_SYMBOL_EXPORT SpecializedPayload : public IPayload
44{
45 friend class LongStringPayloadField;
46
47public:
48 using ValueType = RawPayloadType::value_type;
49 using RscType = Arp::Base::Rsc::Commons::RscType;
50 using FieldType = RscType;
51
54 explicit SpecializedPayload(const Notification& notification);
55
58 explicit SpecializedPayload(const GenericPayload& payloadArg);
59
60protected:
63 explicit SpecializedPayload(const String& formatString);
64
65public:
66 ~SpecializedPayload() override = 0;
67
71
74 static const String GetPayloadTypeName();
75
76 // Methods of IPayload
77 PayloadTypeIdType GetId() const final;
78 const String GetName() const final;
79 const RawPayloadType& GetAsRawPayloadType() const final;
80 const String ToString() const override;
81
82 RawPayloadType&& MoveOutRawPayload();
83
85 bool IsReadOnly() const;
86
87protected: // operations
91 void SetFormatString(const String& formatString);
92
93
95 static size_t FieldIndexToFormatStringIndex(size_t fieldIndex);
96
97 // The second template parameter of the following templates is used to conditionally
98 // enable the corresponding member function based on the type T.
99 // There is one variant for Enums (handeled as strings) and other types.
100 // Since GetRscType<String>() != RscVariant(String()).GetType() there is a
101 // special case for AddField<String>.
102
106 template < typename T, typename std::enable_if < (!std::is_same<T, String>::value)&&
107 (!std::is_enum<T>::value) >::type* = nullptr >
108 size_t AddField()
109 {
110 return this->payload.AddField(RscTypeDeduction().Get<T>());
111 }
112
113
119 template < typename T, typename std::enable_if < std::is_same<T, String>::value ||
120 std::is_enum<T>::value >::type* = nullptr >
121 size_t AddField()
122 {
123 return this->payload.AddField(Arp::Base::Rsc::Commons::RscType::String);
124 }
125
126
130 template < typename T, typename std::enable_if < !std::is_enum<T>::value >::type* = nullptr >
131 void SetFieldValue(size_t fieldIndex, const T& value)
132 {
133 this->payload.SetFieldValue(fieldIndex, ValueType(value));
134 }
135
141 template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
142 void SetFieldValue(size_t fieldIndex, T value)
143 {
144 try
145 {
146 this->payload.SetFieldValue(fieldIndex, static_cast<GenericPayload::ValueType>(Enum<T>(value).ToString()));
147 }
148 catch (const std::out_of_range&)
149 {
151 "value",
152 static_cast<int>(value),
153 String::Format("The supplied value is not an enumerated value of {}", TypeName<T>().GetFullName()).CStr());
154 }
155 }
156
157
161 template < typename T, typename std::enable_if < !std::is_enum<T>::value >::type* = nullptr >
162 const T GetFieldValueAs(size_t fieldIndex) const
163 {
164 const ValueType& value = this->payload.GetFieldValue(fieldIndex);
165 if (value.GetType() == RscType::None)
166 {
167 return T();
168 }
169 return rscvariant_cast<T>(value);
170 }
171
177 template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
178 const T GetFieldValueAs(size_t fieldIndex) const
179 {
180 return Enum<T>::Parse(this->GetFieldValueAs<String>(fieldIndex));
181 }
182
185 size_t GetFieldCount() const;
186
187private:
188 GenericPayload payload;
189};
190
191
193class ARP_CXX_SYMBOL_EXPORT SpecializedPayloadHelper
194{
195 static INotificationManagerInfo& GetINotificationManagerInfo();
196
197 template<typename PayloadType>
198 friend class SpecializedPayload;
199};
200
201
202template<typename PayloadType>
204 : payload(GetId(), GetName())
205{
206 this->payload.SetFieldValue(this->payload.GetFieldIndexFormatString(), static_cast<GenericPayload::ValueType>(formatString));
207}
208
209
210template<typename PayloadType>
212 : payload(GetId(), GetName(), notification)
213{
214}
215
216
217template<typename PayloadType>
219 : payload(GetId(), GetName(), payloadArg.GetAsRawPayloadType())
220{
221}
222
223
224template<typename PayloadType>
226
227
228template<typename PayloadType>
230{
231 static PayloadTypeIdType id;
232 if (!id.IsValid())
233 {
234 id = SpecializedPayloadHelper::GetINotificationManagerInfo().GetPayloadTypeId(
235 GetPayloadTypeName());
236 }
237 return id;
238}
239
240
241template<typename PayloadType>
243{
244 return GetPayloadTypeId();
245}
246
247
248template<typename PayloadType>
250{
251 return TypeName<PayloadType>();
252}
253
254
255template<typename PayloadType>
257{
258 return GetPayloadTypeName();
259}
260
261
262template<typename PayloadType>
264{
265 return this->payload.GetAsRawPayloadType();
266}
267
268
269template<typename PayloadType>
271{
272 return this->payload.ToString();
273}
274
275template<typename PayloadType>
277{
278 return this->payload.MoveOutRawPayload();
279}
280
281template<typename PayloadType>
283{
284 return this->payload.IsReadOnly();
285}
286
287
288template<typename PayloadType>
290{
291 this->payload.SetFieldValue(this->payload.GetFieldIndexFormatString(), static_cast<GenericPayload::ValueType>(formatString));
292}
293
294
295template<typename PayloadType>
297{
298 return fieldIndex - 1;
299}
300
301
302template<typename PayloadType>
304{
305 return this->payload.GetFieldCount();
306}
307
308
309}}} // end of namespace Arp::System::Nm
static ArgumentException Create(const char *paramName, const T &paramValue)
Creates an ArgumentException using a default message.
Definition: ArgumentException.hpp:92
Adapter class for enums to make them loggable and parsable from e.g. XML files.
Definition: Enum.hxx:21
This class represents the Arp String. The implementation is based on std::string.
Definition: String.hpp:39
static String Format(const String &format, const Args &... args)
Formats the format string using the .NET/Python syntax with the given variadic arguments.
Definition: String.inl:18
This (meta programming) class provides the C++ type-name of the as template argument passed type.
Definition: TypeName.hxx:20
This class is used to deduct RSC types automatically by compilation.
Definition: RscTypeDeduction.hpp:24
Generic access to a IPayload
Definition: GenericPayload.hpp:20
size_t GetFieldIndexFormatString() const
Returnsd the field index of the format string
Definition: GenericPayload.cpp:148
Interface for information about the Notification Manager
Definition: INotificationManagerInfo.hpp:22
Interface for Paylo objects
Definition: IPayload.hpp:19
Definition: LongStringPayloadField.hpp:19
Contains meta data and paylod of a Notification
Definition: Notification.hpp:20
Helper class to get access to INotificationManagerInfo
Definition: SpecializedPayload.hpp:194
Base class for custom Payload classes
Definition: SpecializedPayload.hpp:44
bool IsReadOnly() const
Returns true if this object is a view on a Payload
Definition: SpecializedPayload.hpp:282
size_t AddField()
Adds a payload field
Definition: SpecializedPayload.hpp:121
void SetFieldValue(size_t fieldIndex, const T &value)
Sets the value of a payload field
Definition: SpecializedPayload.hpp:131
PayloadTypeIdType GetId() const final
Returns the PayloadTypeId
Definition: SpecializedPayload.hpp:242
static const String GetPayloadTypeName()
Returns the PayloadType name
Definition: SpecializedPayload.hpp:249
const RawPayloadType & GetAsRawPayloadType() const final
Returns a reference to the raw payload object
Definition: SpecializedPayload.hpp:263
const String GetName() const final
Returns the PayloadTypeName
Definition: SpecializedPayload.hpp:256
size_t GetFieldCount() const
Gets the number of fields in the payload
Definition: SpecializedPayload.hpp:303
void SetFieldValue(size_t fieldIndex, T value)
Sets the value of a payload field
Definition: SpecializedPayload.hpp:142
void SetFormatString(const String &formatString)
summary>Retuns the index in the format string for a given payload field
Definition: SpecializedPayload.hpp:289
const T GetFieldValueAs(size_t fieldIndex) const
Gets a field value with the specified type
Definition: SpecializedPayload.hpp:162
const String ToString() const override
Get a human readable string representation
Definition: SpecializedPayload.hpp:270
SpecializedPayload(const Notification &notification)
Creates a view on a Notification object
Definition: SpecializedPayload.hpp:211
static PayloadTypeIdType GetPayloadTypeId()
Returns the PayloadTypeId
Definition: SpecializedPayload.hpp:229
static Enum Parse(const String &input)
Parses the given input string.
Definition: Enum.ipp:90
std::vector< Arp::Base::Rsc::Commons::RscVariant< RawPayloadTypeLength > > RawPayloadType
type for the internally transferred payloads
Definition: NotificationManagerTypes.hpp:32
Root namespace for the PLCnext API
Namespace of the C++ standard library