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