PLCnext API Documentation  22.9.0.33
SpecializedPayload.hpp
1 //
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 
18 namespace Arp { namespace System { namespace Nm
19 {
20 
21 
22 class LongStringPayloadField;
23 
24 
41 template<typename PayloadType>
43 {
44  friend class LongStringPayloadField;
45 
46 public:
47  using ValueType = RawPayloadType::value_type;
49 
52  explicit SpecializedPayload(const Notification& notification);
53 
56  explicit SpecializedPayload(const GenericPayload& payloadArg);
57 
58 protected:
61  explicit SpecializedPayload(const String& formatString);
62 
63 public:
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 
85 protected: // 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 
185 private:
186  GenericPayload payload;
187 };
188 
189 
192 {
193  static INotificationManagerInfo& GetINotificationManagerInfo();
194 
195  template<typename PayloadType>
196  friend class SpecializedPayload;
197 };
198 
199 
200 template<typename PayloadType>
202  : payload(GetId(), GetName())
203 {
204  this->payload.SetFieldValue(this->payload.GetFieldIndexFormatString(), formatString);
205 }
206 
207 
208 template<typename PayloadType>
210  : payload(GetId(), GetName(), notification)
211 {
212 }
213 
214 
215 template<typename PayloadType>
217  : payload(GetId(), GetName(), payloadArg.GetAsRawPayloadType())
218 {
219 }
220 
221 
222 template<typename PayloadType>
224 
225 
226 template<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 
239 template<typename PayloadType>
241 {
242  return GetPayloadTypeId();
243 }
244 
245 
246 template<typename PayloadType>
248 {
249  return TypeName<PayloadType>().Value;
250 }
251 
252 
253 template<typename PayloadType>
255 {
256  return GetPayloadTypeName();
257 }
258 
259 
260 template<typename PayloadType>
262 {
263  return this->payload.GetAsRawPayloadType();
264 }
265 
266 
267 template<typename PayloadType>
269 {
270  return this->payload.ToString();
271 }
272 
273 template<typename PayloadType>
275 {
276  return this->payload.MoveOutRawPayload();
277 }
278 
279 template<typename PayloadType>
281 {
282  return this->payload.IsReadOnly();
283 }
284 
285 
286 template<typename PayloadType>
288 {
289  this->payload.SetFieldValue(this->payload.GetFieldIndexFormatString(), formatString);
290 }
291 
292 
293 template<typename PayloadType>
295 {
296  return fieldIndex - 1;
297 }
298 
299 
300 template<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
const ValueType & GetFieldValue(size_t fieldIndex) const
Returns the raw value of a field
size_t GetFieldIndexFormatString() const
Returnsd the field index of the format string
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)
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:56
String Value
The resulting typename.
Definition: TypeName.hxx:114
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
Datatypes supported by Rsc. Values are identical with CommonRemoting::RemotingMarshalType....
Definition: RscType.hpp:37
@ 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