8#include "Arp/System/Commons/Exceptions/Exceptions.h"
9#include "Arp/System/Commons/Encoding/Utf16.hpp"
10#include "Arp/System/Rsc/Services/Rsc.h"
11#include "Arp/System/Rsc/Services/RscGuid.hpp"
12#include "Arp/System/Rsc/Services/RscVersion.hpp"
13#include "Arp/System/Rsc/Services/RscString.hxx"
14#include "Arp/System/Rsc/Services/SecureString.hxx"
20namespace Arp {
namespace System {
namespace Rsc {
namespace Services
28template<
int N>
class RscStructReader;
29template<
int N>
class RscStructWriter;
30template<
class T,
bool IsClass,
bool IsSerializable>
class RscValueAdapter;
67template<
int MaxStringSize = 0>
75 template<
class T,
bool IsClass,
bool IsSerializable>
friend class RscValueAdapter;
78 using ReadElementFunction = std::function<
RscType(
RscType expectedType,
byte* pValue)>;
79 using WriteElementFunction = std::function<void(
RscType valueType,
const byte* pValue)>;
136 RscVariant(
size_t arraySize,
RscType arrayElementType,
size_t dimensions = 1,
size_t fieldCount = 0);
147 RscVariant(
size_t arraySize,
RscType arrayElementType, ReadElementFunction* pFunction,
size_t dimensions = 1,
size_t fieldCount = 0);
158 RscVariant(
size_t arraySize,
RscType arrayElementType, WriteElementFunction* pFunction,
size_t dimensions = 1,
size_t fieldCount = 0);
163 RscVariant(
size_t fieldCount, ReadElementFunction* pFunction);
208 bool operator==(const
RscVariant& value)const;
209 bool operator!=(const
RscVariant& value)const;
312 void InitComplexTypeInfo(
void);
313 bool ContainsTypeInformation(
void) const;
314 size_t GetSize(
void)const;
317 struct ComplexTypeInfo
324 RemotingReader* pReader =
nullptr;
325 mutable RemotingWriter* pWriter =
nullptr;
326 ReadElementFunction* pReadElementFunction =
nullptr;
327 mutable WriteElementFunction* pWriteElementFunction =
nullptr;
331 static const size_t maxPrimitiveSize = 8;
332#ifdef ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT
333 static const size_t minBufferSize = std::max(maxPrimitiveSize, std::max(
sizeof(
RscGuid),
sizeof(
RscVersion)));
335 static const size_t minBufferSize = maxPrimitiveSize;
338 static const size_t bufferSize = minBufferSize < (size_t)MaxStringSize ? (
size_t)MaxStringSize : minBufferSize;
343 ComplexTypeInfo typeInfo;
344 byte buffer[bufferSize];
353inline constexpr RscType GetRscTypeFrom(
const RscVariant<N>& )
361template<
int MaxStringSize>
367template<
int MaxStringSize>
371 this->operator=(value);
374template<
int MaxStringSize>
378 this->operator=(value);
381template<
int MaxStringSize>
384 this->operator=(value);
387template<
int MaxStringSize>
390 this->Assign(input, length, type);
393template<
int MaxStringSize>
397 this->operator=(value);
400template<
int MaxStringSize>
404 this->operator=(value);
407template<
int MaxStringSize>
415 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
416 this->typeInfo.pReader =
nullptr;
417 this->typeInfo.pWriter =
nullptr;
418 this->typeInfo.pReadElementFunction =
nullptr;
419 this->typeInfo.pWriteElementFunction =
nullptr;
422template<
int MaxStringSize>
430 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
431 this->typeInfo.pReader =
nullptr;
432 this->typeInfo.pWriter =
nullptr;
433 this->typeInfo.pReadElementFunction = pFunction;
434 this->typeInfo.pWriteElementFunction =
nullptr;
437template<
int MaxStringSize>
445 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
446 this->typeInfo.pReader =
nullptr;
447 this->typeInfo.pWriter =
nullptr;
448 this->typeInfo.pReadElementFunction =
nullptr;
449 this->typeInfo.pWriteElementFunction = pFunction;
452template<
int MaxStringSize>
456 this->InitComplexTypeInfo();
458 this->typeInfo.pReadElementFunction = pFunction;
461template<
int MaxStringSize>
467template<
int MaxStringSize>
477 case RscType::IecTimeOfDay64:
485template<
int MaxStringSize>
488 return this->GetArrayInformation().ElementType;
491template<
int MaxStringSize>
498 return this->typeInfo.arrayInformation;
501template<
int MaxStringSize>
502inline RscArrayInformation& RscVariant<MaxStringSize>::GetArrayInformation(
void)
508 return this->typeInfo.arrayInformation;
511template<
int MaxStringSize>
512inline const RscStructInformation& RscVariant<MaxStringSize>::GetStructInformation(
void)
const
516 throw InvalidOperationException(
"RscVariant doesn't contain struct information");
518 return this->typeInfo.structInformation;
521template<
int MaxStringSize>
522inline RscStructInformation& RscVariant<MaxStringSize>::GetStructInformation(
void)
526 throw InvalidOperationException(
"RscVariant doesn't contain struct information");
528 return this->typeInfo.structInformation;
531template<
int MaxStringSize>
534 return this->GetArrayInformation().Dimensions;
537template<
int MaxStringSize>
540 return this->GetStructInformation().FieldCount;
543template<
int MaxStringSize>
549template<
int MaxStringSize>
555template<
int MaxStringSize>
558 this->type = rscType;
561template<
int MaxStringSize>
567template<
int MaxStringSize>
571 this->type = GetRscType<T>();
576#ifndef ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT
582 *
reinterpret_cast<T*
>(this->buffer) = value;
586template<
int MaxStringSize>
590 result.InitComplexTypeInfo();
591 result.GetStructInformation().
FieldCount = fieldCount;
595template<
int MaxStringSize>
602template<
int MaxStringSize>
606 result.typeInfo.pWriter = &writer;
610template<
int MaxStringSize>
614 result.typeInfo.pWriter = &writer;
618template<
int MaxStringSize>
619inline RscVariant<MaxStringSize>& RscVariant<MaxStringSize>::operator=(
const String& value)
621 size_t len = value.
Length();
622 this->Assign(value.
CStr(), len);
626template<
int MaxStringSize>
627inline RscVariant<MaxStringSize>& RscVariant<MaxStringSize>::operator=(
const char* value)
629 size_t len = std::char_traits<char>::length(value);
630 this->Assign(value, len);
634template<
int MaxStringSize>
636inline RscVariant<MaxStringSize>& RscVariant<MaxStringSize>::operator=(
const RscString<N>& value)
642template<
int MaxStringSize>
644inline RscVariant<MaxStringSize>& RscVariant<MaxStringSize>::operator=(
const SecureString<N>& value)
650template<
int MaxStringSize>
653 if (length >= MaxStringSize)
655 throw ArgumentException(
"Cannot copy string: argument string length {} exceeds MaxStringSize {}", length, MaxStringSize);
659 throw NotSupportedException(
"RscType '{}' not supported for Strings", rscType);
661 SecureStrncpy(
reinterpret_cast<char*
>(this->buffer), MaxStringSize, input, length);
662 this->buffer[length] =
static_cast<byte>(0);
663 this->type = rscType;
666template<
int MaxStringSize>
676 this->type = rscType;
677 size_t resultLength = 0;
678 EncodingResult result = Utf16::ConvertToUtf8(input, length,
reinterpret_cast<char*
>(this->buffer), MaxStringSize - 1, resultLength);
679 if ((result != EncodingResult::Success) && (result != EncodingResult::NoConversion))
681 throw ArgumentException(
"Cannot convert UTF16 string, encoding result = {}", result);
683 this->buffer[resultLength] = 0_b;
686template<
int MaxStringSize>
689 if (this->GetType() != value.
GetType())
694 if (this->GetSize() != value.GetSize())
699 if (memcmp(this->buffer, value.buffer, this->GetSize()) != 0)
706 if (strcmp((
char*)this->buffer, (
char*)value.buffer) != 0)
715template<
int MaxStringSize>
718 return !(*
this == value);
721template<
int MaxStringSize>
722inline void RscVariant<MaxStringSize>::InitComplexTypeInfo(
void)
725 this->typeInfo.pReader =
nullptr;
726 this->typeInfo.pWriter =
nullptr;
727 this->typeInfo.pReadElementFunction =
nullptr;
728 this->typeInfo.pWriteElementFunction =
nullptr;
731template<
int MaxStringSize>
735 RscType argType = GetRscType<T>();
736 if(this->GetValueType() != argType)
738 throw InvalidCastException(
"Cannot copy value to argument: RscVariant contains data type {0} but arg is of type {1}", this->type, argType);
740 value = *
reinterpret_cast<const T*
>(this->buffer);
743template<
int MaxStringSize>
750 return reinterpret_cast<const char*
>(this->buffer);
753template<
int MaxStringSize>
760 this->typeInfo.pWriteElementFunction = pFunction;
763template<
int MaxStringSize>
768 this->CopyTo(result);
772template<
int MaxStringSize>
775 const byte* pValue = this->GetDataAddress();
782 return reinterpret_cast<const char*
>(pValue);
784 return reinterpret_cast<const DateTime*
>(pValue)->ToIso8601String();
787 std::ostringstream oss;
788 oss << std::boolalpha << *reinterpret_cast<const bool*>(pValue);
796 return std::to_string(*
reinterpret_cast<const char16*
>(pValue));
798 return std::to_string(*
reinterpret_cast<const int16*
>(pValue));
801 return std::to_string(*
reinterpret_cast<const int32*
>(pValue));
803 return std::to_string(*
reinterpret_cast<const int8*
>(pValue));
808 case RscType::IecTimeOfDay64:
809 return std::to_string(*
reinterpret_cast<const int64*
>(pValue));
814 return std::to_string(*
reinterpret_cast<const float*
>(pValue));
816 return std::to_string(*
reinterpret_cast<const double*
>(pValue));
818 return std::to_string(*
reinterpret_cast<const uint16*
>(pValue));
820 return std::to_string(*
reinterpret_cast<const uint32*
>(pValue));
822 return std::to_string(*
reinterpret_cast<const uint64*
>(pValue));
824 return std::to_string(*
reinterpret_cast<const uint8*
>(pValue));
826 return reinterpret_cast<const RscVersion*
>(pValue)->ToString();
828 return reinterpret_cast<const RscGuid*
>(pValue)->ToString();
837template<
int MaxStringSize>
840 switch (this->GetValueType())
868 case RscType::IecTimeOfDay64:
872 return strlen((
char*)this->buffer);
The class contains date and time informations.
Definition: DateTime.hpp:46
This exception is used when an invalid argument occurs.
Definition: ArgumentException.hpp:15
static ArgumentException Create(const char *paramName, const T ¶mValue)
Creates an ArgumentException instance using a default message text.
Definition: ArgumentException.hpp:112
This is a small immutable wrapper around the boost::uuids::uuid class and represents a universal uniq...
Definition: Uuid.hpp:19
This static class provides encoding string operations from UTF8 to UTF16 or vice versa.
Definition: Utf16.hpp:15
This exception is used when an invalid cast occurs.
Definition: InvalidCastException.hpp:15
This exception is used when a method call is invalid for object's current state.
Definition: InvalidOperationException.hpp:15
This exception is used when a method is not implemented yet.
Definition: NotImplementedException.hpp:15
This exception is used when a method is not supported.
Definition: NotSupportedException.hpp:15
Helper class to read an array of primtive types from an RscVariant. This class uses the array informa...
Definition: RscArrayReader.hpp:23
Helper class to read an array of primtive types from an RscVariant. This class uses the array informa...
Definition: RscArrayWriter.hpp:22
Definition: RscGuid.hpp:18
Contains a static string with string lentgh up to N characters. The string has to be null terminated.
Definition: RscString.hxx:21
Helper class to read a struct from an RscVariant. This class uses the struct information stored in Rs...
Definition: RscStructReader.hxx:25
Helper class to write a struct from an RscVariant. This class uses the struct information stored in R...
Definition: RscStructWriter.hxx:19
Rsc container class for primitive data type, strings or information about arrays or structs....
Definition: RscVariant.hxx:69
RscVariant(const T &value)
Creates a new instance of RscVariant with value. Gets RscType by type deduction of T.
Definition: RscVariant.hxx:369
void SetType(RscType rscType)
Forces the internal RscType to be set to another RscType. This Method does no conversion or validatio...
Definition: RscVariant.hxx:556
String ToString(void) const
Converts this instance to string if the variant type has a reasonable string representation.
Definition: RscVariant.hxx:773
RscVariant(const RscString< N > &value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:395
size_t GetArrayDimensions(void) const
Gets the count of array dimensions (1 for simple array, 2 for array of array etc.)....
Definition: RscVariant.hxx:532
RscVariant(const SecureString< N > &value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:402
void Assign(const char16 *input, size_t length, RscType rscType=RscType::Utf8String)
Assigns an UTF16 string to this instance.
Definition: RscVariant.hxx:667
RscVariant(RscType type=RscType::None)
Creates an empty instance of RscVariant
Definition: RscVariant.hxx:362
RscVariant(const RscVariant< MaxStringSize > &)=default
Copy constructor
RscVariant(const char *value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:382
T GetValue(void) const
Converts this value to the given type T.
Definition: RscVariant.hxx:765
size_t GetFieldCount(void) const
Returns field count, if RscVariant contains struct information
Definition: RscVariant.hxx:538
RscType GetValueType(void) const
Gets the value type as RscType of the contained element
Definition: RscVariant.hxx:468
const char * GetChars(void) const
Gets pointer to internal string buffer. Operation only valid for Utf8Strings.
Definition: RscVariant.hxx:744
static RscVariant< MaxStringSize > CreateStructVariant(size_t fieldCount)
Creates a new RscVariant initialized with RscStructInformation
Definition: RscVariant.hxx:587
RscVariant(const char16 *input, size_t length, RscType type=RscType::Utf8String)
Assigns an UTF16 string to this instance.
Definition: RscVariant.hxx:388
RscVariant(size_t fieldCount, ReadElementFunction *pFunction)
For internal use only
Definition: RscVariant.hxx:453
static RscVariant< MaxStringSize > CreateArrayVariant(size_t arraySize, RscType elementType, size_t dimensions=1, size_t fieldCount=0)
Creates a new RscVariant initialized with RscArrayInformation
Definition: RscVariant.hxx:596
void SetWriteElementFunction(WriteElementFunction *pFunction) const
Sets callback for write function to write a single array element. This could only be used for Variant...
Definition: RscVariant.hxx:754
RscVariant(const String &value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:375
const byte * GetDataAddress(void) const
Gets a raw pointer to internal data buffer. To read data prefer CopyTo and to write prefer assignment...
Definition: RscVariant.hxx:544
RscType GetType(void) const
Gets the RscType of the contained element
Definition: RscVariant.hxx:462
RscVariant(size_t arraySize, RscType arrayElementType, WriteElementFunction *pFunction, size_t dimensions=1, size_t fieldCount=0)
Creates a new instance of RscVariant containing an array with arraySize elements of RscType arrayElem...
Definition: RscVariant.hxx:438
RscVariant(RscVariant &&) noexcept=default
Move constructor
RscVariant(size_t arraySize, RscType arrayElementType, ReadElementFunction *pFunction, size_t dimensions=1, size_t fieldCount=0)
Creates a new instance of RscVariant containing an array with arraySize elements of RscType arrayElem...
Definition: RscVariant.hxx:423
RscType GetArrayElementType(void) const
Gets the RscType of the array elements if RscVariant contains array information.
Definition: RscVariant.hxx:486
RscVariant(size_t arraySize, RscType arrayElementType, size_t dimensions=1, size_t fieldCount=0)
Creates a new instance of RscVariant containing an array with arraySize elements of RscType arrayElem...
Definition: RscVariant.hxx:408
void CopyTo(T &value) const
Copies internal data to memory referenced by value. Only for primtive types. Read Strings with GetCha...
Definition: RscVariant.hxx:733
Specifies a version with 4 version numbers and is marshalled to .NET type System.Version.
Definition: RscVersion.hpp:21
Specialized version of RscString for security context. Not implemented in this version....
Definition: SecureString.hxx:19
size_type Length() const
Returns the number of char elements in this string.
Definition: BasicString.hxx:1049
bool operator!=(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string on inequality.
Definition: BasicString.hxx:1935
const CharType * CStr() const
Gets the character data of this string.
Definition: BasicString.hxx:1518
static const SelfType Empty
An emtpy static string instance.
Definition: BasicString.hxx:224
bool operator==(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string on equality.
Definition: BasicString.hxx:1899
std::uint64_t uint64
The Arp unsigned integer type of 8 byte size.
Definition: PrimitiveTypes.hpp:40
char16_t char16
The Arp character type of 2 byte size.
Definition: PrimitiveTypes.hpp:50
std::int64_t int64
The Arp integer type of 8 byte size.
Definition: PrimitiveTypes.hpp:42
std::uint32_t uint32
The Arp unsigned integer type of 4 byte size.
Definition: PrimitiveTypes.hpp:36
std::int8_t int8
The Arp integer type of 1 byte size.
Definition: PrimitiveTypes.hpp:30
std::uint16_t uint16
The Arp unsigned integer type of 2 byte size.
Definition: PrimitiveTypes.hpp:32
std::uint8_t uint8
The Arp unsigned integer type of 1 byte size.
Definition: PrimitiveTypes.hpp:28
std::int32_t int32
The Arp integer type of 4 byte size.
Definition: PrimitiveTypes.hpp:38
std::int16_t int16
The Arp integer type of 2 byte size.
Definition: PrimitiveTypes.hpp:34
@ System
System components used by the System, Device, Plc or Io domains.
EncodingResult
This enum defines encoding results for operations of class Utf16.
Definition: EncodingResult.hpp:16
RscType
Data types supported by RSC.
Definition: RscType.hpp:36
@ Version
Arp::System::Rsc::Services::RscVersion
@ Array
std::vector<T> or RSC enumerators
@ Object
Object type as Arp::System::Rsc::Services::RscVariant
@ Void
void or null object
@ Struct
struct derived by IRscSerializable
@ AnsiString
Ansi string, not supported in Rsc context
@ IecTime
summary>IEC type: LTIME [int64]
@ Guid
Universal unique ID Arp::System::Rsc::Services::RscGuid
@ SecureString
String for security context, handled by Rsc with Arp::System::Rsc::Services::SecureString
@ Utf8String
Utf-8 string, Arp::System::Rsc::Services::RscString
Root namespace for the PLCnext API
size_t SecureStrnlen(const char *str, size_t maxSize)
Warpper for strnlen_s
void SecureStrncpy(char *dest, size_t destMaxSize, const char *src, size_t count)
Wrapper for strncpy_s