PLCnext API Documentation 23.0.2.9
SpecializedPayload.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6
7#pragma once
8
9#include "Arp/System/Core/TypeName.hxx"
10#include "Arp/System/Commons/Exceptions/ArgumentException.hpp"
11#include "Arp/System/Nm/GenericPayload.hpp"
12#include "Arp/System/Nm/IPayload.hpp"
13#include "Arp/System/Nm/Notification.hpp"
14#include "Arp/System/Nm/NotificationManager.hpp"
15#include "Arp/System/Nm/RscVariantHelpers.hpp"
16#include <type_traits>
17
18namespace Arp { namespace System { namespace Nm
19{
20
21
22class LongStringPayloadField;
23
24
41template<typename PayloadType>
43{
44 friend class LongStringPayloadField;
45
46public:
47 using ValueType = RawPayloadType::value_type;
49
52 explicit SpecializedPayload(const Notification& notification);
53
56 explicit SpecializedPayload(const GenericPayload& payloadArg);
57
58protected:
61 explicit SpecializedPayload(const String& formatString);
62
63public:
64 ~SpecializedPayload() override = 0;
65
69
72 static const String GetPayloadTypeName();
73
74 // Methods of IPayload
75 PayloadTypeIdType GetId() const final;
76 const String GetName() const final;
77 const RawPayloadType& GetAsRawPayloadType() const final;
78 const String ToString() const override;
79
80 RawPayloadType&& MoveOutRawPayload();
81
83 bool IsReadOnly() const;
84
85protected: // operations
89 void SetFormatString(const String& formatString);
90
91
93 static size_t FieldIndexToFormatStringIndex(size_t fieldIndex);
94
95 // The second template parameter of the following templates is used to conditionally
96 // enable the corresponding member function based on the type T.
97 // There is one variant for Enums (handeled as strings) and other types.
98 // Since GetRscType<String>() != RscVariant(String()).GetType() there is a
99 // special case for AddField<String>.
100
104 template < typename T, typename std::enable_if < (!std::is_same<T, String>::value)&&
105 (!std::is_enum<T>::value) >::type* = nullptr >
106 size_t AddField()
107 {
108 return this->payload.AddField(Arp::System::Rsc::Services::GetRscType<T>());
109 }
110
111
117 template < typename T, typename std::enable_if < std::is_same<T, String>::value ||
118 std::is_enum<T>::value >::type* = nullptr >
119 size_t AddField()
120 {
122 }
123
124
128 template < typename T, typename std::enable_if < !std::is_enum<T>::value >::type* = nullptr >
129 void SetFieldValue(size_t fieldIndex, const T& value)
130 {
131 this->payload.SetFieldValue(fieldIndex, ValueType(value));
132 }
133
139 template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
140 void SetFieldValue(size_t fieldIndex, T value)
141 {
142 try
143 {
144 this->payload.SetFieldValue(fieldIndex, Enum<T>(value).ToString());
145 }
146 catch (const std::out_of_range&)
147 {
148 throw Arp::System::Commons::ArgumentException::Create("value", static_cast<int>(value),
150 "The supplied value is not a enumerated value of {}", TypeName<T>().Value)
151 .CStr());
152 }
153 }
154
155
159 template < typename T, typename std::enable_if < !std::is_enum<T>::value >::type* = nullptr >
160 const T GetFieldValueAs(size_t fieldIndex) const
161 {
162 const ValueType& value = this->payload.GetFieldValue(fieldIndex);
163 if (value.GetType() == Rsc::Services::RscType::None)
164 {
165 return T();
166 }
167 return rscvariant_cast<T>(value);
168 }
169
175 template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
176 const T GetFieldValueAs(size_t fieldIndex) const
177 {
178 return Enum<T>::Parse(this->GetFieldValueAs<String>(fieldIndex));
179 }
180
183 size_t GetFieldCount() const;
184
185private:
186 GenericPayload payload;
187};
188
189
192{
193 static INotificationManagerInfo& GetINotificationManagerInfo();
194
195 template<typename PayloadType>
196 friend class SpecializedPayload;
197};
198
199
200template<typename PayloadType>
202 : payload(GetId(), GetName())
203{
204 this->payload.SetFieldValue(this->payload.GetFieldIndexFormatString(), formatString);
205}
206
207
208template<typename PayloadType>
210 : payload(GetId(), GetName(), notification)
211{
212}
213
214
215template<typename PayloadType>
217 : payload(GetId(), GetName(), payloadArg.GetAsRawPayloadType())
218{
219}
220
221
222template<typename PayloadType>
224
225
226template<typename PayloadType>
228{
229 static PayloadTypeIdType id;
230 if (!id.IsValid())
231 {
232 id = SpecializedPayloadHelper::GetINotificationManagerInfo().GetPayloadTypeId(
233 GetPayloadTypeName());
234 }
235 return id;
236}
237
238
239template<typename PayloadType>
241{
242 return GetPayloadTypeId();
243}
244
245
246template<typename PayloadType>
248{
250}
251
252
253template<typename PayloadType>
255{
256 return GetPayloadTypeName();
257}
258
259
260template<typename PayloadType>
262{
263 return this->payload.GetAsRawPayloadType();
264}
265
266
267template<typename PayloadType>
269{
270 return this->payload.ToString();
271}
272
273template<typename PayloadType>
275{
276 return this->payload.MoveOutRawPayload();
277}
278
279template<typename PayloadType>
281{
282 return this->payload.IsReadOnly();
283}
284
285
286template<typename PayloadType>
288{
289 this->payload.SetFieldValue(this->payload.GetFieldIndexFormatString(), formatString);
290}
291
292
293template<typename PayloadType>
295{
296 return fieldIndex - 1;
297}
298
299
300template<typename PayloadType>
302{
303 return this->payload.GetFieldCount();
304}
305
306
307}}} // 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:19
size_t GetFieldIndexFormatString() const
Returnsd the field index of the format string
const ValueType & GetFieldValue(size_t fieldIndex) const
Returns the raw value of a field
size_t AddField(FieldType type)
Adds a field with the given FieldType
Interface for information about the Notification Manager
Definition: INotificationManagerInfo.hpp:21
Interface for Paylo objects
Definition: IPayload.hpp:19
Definition: LongStringPayloadField.hpp:17
Contains meta data and paylod of a Notification
Definition: Notification.hpp:22
Helper class to get access to INotificationManagerInfo
Definition: SpecializedPayload.hpp:192
Base class for custom Payload classes
Definition: SpecializedPayload.hpp:43
bool IsReadOnly() const
Returns true if this object is a view on a Payload
Definition: SpecializedPayload.hpp:280
size_t AddField()
Adds a payload field
Definition: SpecializedPayload.hpp:106
void SetFieldValue(size_t fieldIndex, const T &value)
Sets the value of a payload field
Definition: SpecializedPayload.hpp:129
PayloadTypeIdType GetId() const final
Returns the PayloadTypeId
Definition: SpecializedPayload.hpp:240
static const String GetPayloadTypeName()
Returns the PayloadType name
Definition: SpecializedPayload.hpp:247
const RawPayloadType & GetAsRawPayloadType() const final
Returns a reference to the raw payload object
Definition: SpecializedPayload.hpp:261
const String GetName() const final
Returns the PayloadTypeName
Definition: SpecializedPayload.hpp:254
size_t GetFieldCount() const
Gets the number of fields in the payload
Definition: SpecializedPayload.hpp:301
void SetFieldValue(size_t fieldIndex, T value)
Sets the value of a payload field
Definition: SpecializedPayload.hpp:140
void SetFormatString(const String &formatString)
summary>Retuns the index in the format string for a given payload field
Definition: SpecializedPayload.hpp:287
const T GetFieldValueAs(size_t fieldIndex) const
Gets a field value with the specified type
Definition: SpecializedPayload.hpp:160
const String ToString() const override
Get a human readable string representation
Definition: SpecializedPayload.hpp:268
SpecializedPayload(const Notification &notification)
Creates a view on a Notification object
Definition: SpecializedPayload.hpp:209
static PayloadTypeIdType GetPayloadTypeId()
Returns the PayloadTypeId
Definition: SpecializedPayload.hpp:227
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:67
String Value
The resulting typename.
Definition: TypeName.hxx:125
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:1483
@ 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