7#include "Arp/System/Commons/Exceptions/Exceptions.h"
8#include "Arp/System/Commons/Encoding/Utf16.hpp"
9#include "Arp/System/Rsc/Services/Rsc.h"
10#include "Arp/System/Rsc/Services/RscGuid.hpp"
11#include "Arp/System/Rsc/Services/RscVersion.hpp"
12#include "Arp/System/Rsc/Services/RscString.hxx"
13#include "Arp/System/Rsc/Services/SecureString.hxx"
19namespace Arp {
namespace System {
namespace Rsc {
namespace Services
27template<
int N>
class RscStructReader;
28template<
int N>
class RscStructWriter;
29template<
class T,
bool IsClass,
bool IsSerializable>
class RscValueAdapter;
66template<
int MaxStringSize = 0>
74 template<
class T,
bool IsClass,
bool IsSerializable>
friend class RscValueAdapter;
77 using ReadElementFunction = std::function<
RscType(
RscType expectedType,
byte* pValue)>;
78 using WriteElementFunction = std::function<void(
RscType valueType,
const byte* pValue)>;
135 RscVariant(
size_t arraySize,
RscType arrayElementType,
size_t dimensions = 1,
size_t fieldCount = 0);
146 RscVariant(
size_t arraySize,
RscType arrayElementType, ReadElementFunction* pFunction,
size_t dimensions = 1,
size_t fieldCount = 0);
157 RscVariant(
size_t arraySize,
RscType arrayElementType, WriteElementFunction* pFunction,
size_t dimensions = 1,
size_t fieldCount = 0);
162 RscVariant(
size_t fieldCount, ReadElementFunction* pFunction);
207 bool operator==(const
RscVariant& value)const;
208 bool operator!=(const
RscVariant& value)const;
311 void InitComplexTypeInfo(
void);
312 bool ContainsTypeInformation(
void) const;
313 size_t GetSize(
void)const;
316 struct ComplexTypeInfo
323 RemotingReader* pReader =
nullptr;
324 mutable RemotingWriter* pWriter =
nullptr;
325 ReadElementFunction* pReadElementFunction =
nullptr;
326 mutable WriteElementFunction* pWriteElementFunction =
nullptr;
330 static const size_t maxPrimitiveSize = 8;
331#ifdef ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT
332 static const size_t minBufferSize = std::max(maxPrimitiveSize, std::max(
sizeof(
RscGuid),
sizeof(
RscVersion)));
334 static const size_t minBufferSize = maxPrimitiveSize;
337 static const size_t bufferSize = minBufferSize < (size_t)MaxStringSize ? (
size_t)MaxStringSize : minBufferSize;
342 ComplexTypeInfo typeInfo;
343 byte buffer[bufferSize];
360template<
int MaxStringSize>
366template<
int MaxStringSize>
370 this->operator=(value);
373template<
int MaxStringSize>
377 this->operator=(value);
380template<
int MaxStringSize>
383 this->operator=(value);
386template<
int MaxStringSize>
389 this->Assign(input, length, type);
392template<
int MaxStringSize>
396 this->operator=(value);
399template<
int MaxStringSize>
403 this->operator=(value);
406template<
int MaxStringSize>
414 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
415 this->typeInfo.pReader =
nullptr;
416 this->typeInfo.pWriter =
nullptr;
417 this->typeInfo.pReadElementFunction =
nullptr;
418 this->typeInfo.pWriteElementFunction =
nullptr;
421template<
int MaxStringSize>
429 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
430 this->typeInfo.pReader =
nullptr;
431 this->typeInfo.pWriter =
nullptr;
432 this->typeInfo.pReadElementFunction = pFunction;
433 this->typeInfo.pWriteElementFunction =
nullptr;
436template<
int MaxStringSize>
444 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
445 this->typeInfo.pReader =
nullptr;
446 this->typeInfo.pWriter =
nullptr;
447 this->typeInfo.pReadElementFunction =
nullptr;
448 this->typeInfo.pWriteElementFunction = pFunction;
451template<
int MaxStringSize>
455 this->InitComplexTypeInfo();
457 this->typeInfo.pReadElementFunction = pFunction;
460template<
int MaxStringSize>
466template<
int MaxStringSize>
476 case RscType::IecTimeOfDay64:
484template<
int MaxStringSize>
487 return this->GetArrayInformation().ElementType;
490template<
int MaxStringSize>
497 return this->typeInfo.arrayInformation;
500template<
int MaxStringSize>
507 return this->typeInfo.arrayInformation;
510template<
int MaxStringSize>
511inline const RscStructInformation& RscVariant<MaxStringSize>::GetStructInformation(
void)
const
515 throw InvalidOperationException(
"RscVariant doesn't contain struct information");
517 return this->typeInfo.structInformation;
520template<
int MaxStringSize>
521inline RscStructInformation& RscVariant<MaxStringSize>::GetStructInformation(
void)
525 throw InvalidOperationException(
"RscVariant doesn't contain struct information");
527 return this->typeInfo.structInformation;
530template<
int MaxStringSize>
533 return this->GetArrayInformation().Dimensions;
536template<
int MaxStringSize>
539 return this->GetStructInformation().FieldCount;
542template<
int MaxStringSize>
548template<
int MaxStringSize>
554template<
int MaxStringSize>
557 this->type = rscType;
560template<
int MaxStringSize>
566template<
int MaxStringSize>
570 this->type = GetRscType<T>();
575#ifndef ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT
581 *
reinterpret_cast<T*
>(this->buffer) = value;
585template<
int MaxStringSize>
589 result.InitComplexTypeInfo();
590 result.GetStructInformation().
FieldCount = fieldCount;
594template<
int MaxStringSize>
601template<
int MaxStringSize>
605 result.typeInfo.pWriter = &writer;
609template<
int MaxStringSize>
613 result.typeInfo.pWriter = &writer;
617template<
int MaxStringSize>
620 size_t len = value.
Length();
621 this->Assign(value.
CStr(), len);
625template<
int MaxStringSize>
628 size_t len = strlen(value);
629 this->Assign(value, len);
633template<
int MaxStringSize>
635inline RscVariant<MaxStringSize>& RscVariant<MaxStringSize>::operator=(
const RscString<N>& value)
641template<
int MaxStringSize>
643inline RscVariant<MaxStringSize>& RscVariant<MaxStringSize>::operator=(
const SecureString<N>& value)
649template<
int MaxStringSize>
652 if (length >= MaxStringSize)
654 throw ArgumentException(
"Cannot copy string: argument string length {} exceeds MaxStringSize {}", length, MaxStringSize);
658 throw NotSupportedException(
"RscType '{}' not supported for Strings", rscType);
660 SecureStrncpy(
reinterpret_cast<char*
>(this->buffer), MaxStringSize, input, length);
661 this->buffer[length] =
'\0';
662 this->type = rscType;
665template<
int MaxStringSize>
675 this->type = rscType;
676 size_t resultLength = 0;
677 EncodingResult result = Utf16::ConvertToUtf8(input, length,
reinterpret_cast<char8*
>(this->buffer), MaxStringSize, resultLength);
678 if ((result != EncodingResult::Success) && (result != EncodingResult::NoConversion))
680 throw ArgumentException(
"Cannot convert UTF16 string, encoding result = {}", result);
682 this->buffer[resultLength] =
'\0';
685template<
int MaxStringSize>
688 if (this->GetType() != value.
GetType())
693 if (this->GetSize() != value.GetSize())
698 if (memcmp(this->buffer, value.buffer, this->GetSize()) != 0)
705 if (strcmp((
char*)this->buffer, (
char*)value.buffer) != 0)
714template<
int MaxStringSize>
717 return !(*
this == value);
720template<
int MaxStringSize>
721inline void RscVariant<MaxStringSize>::InitComplexTypeInfo(
void)
724 this->typeInfo.pReader =
nullptr;
725 this->typeInfo.pWriter =
nullptr;
726 this->typeInfo.pReadElementFunction =
nullptr;
727 this->typeInfo.pWriteElementFunction =
nullptr;
730template<
int MaxStringSize>
734 RscType argType = GetRscType<T>();
735 if(this->GetValueType() != argType)
737 throw InvalidCastException(
"Cannot copy value to argument: RscVariant contains data type {0} but arg is of type {1}", this->type, argType);
739 value = *
reinterpret_cast<const T*
>(this->buffer);
742template<
int MaxStringSize>
749 return reinterpret_cast<const char*
>(this->buffer);
752template<
int MaxStringSize>
759 this->typeInfo.pWriteElementFunction = pFunction;
762template<
int MaxStringSize>
767 this->CopyTo(result);
771template<
int MaxStringSize>
774 const byte* pValue = this->GetDataAddress();
781 return reinterpret_cast<const char*
>(pValue);
783 return reinterpret_cast<const DateTime*
>(pValue)->ToIso8601String();
786 std::ostringstream oss;
787 oss << std::boolalpha << *reinterpret_cast<const bool*>(pValue);
795 return std::to_string(*
reinterpret_cast<const char16*
>(pValue));
797 return std::to_string(*
reinterpret_cast<const int16*
>(pValue));
800 return std::to_string(*
reinterpret_cast<const int32*
>(pValue));
802 return std::to_string(*
reinterpret_cast<const int8*
>(pValue));
807 case RscType::IecTimeOfDay64:
808 return std::to_string(*
reinterpret_cast<const int64*
>(pValue));
813 return std::to_string(*
reinterpret_cast<const float*
>(pValue));
815 return std::to_string(*
reinterpret_cast<const double*
>(pValue));
817 return std::to_string(*
reinterpret_cast<const uint16*
>(pValue));
819 return std::to_string(*
reinterpret_cast<const uint32*
>(pValue));
821 return std::to_string(*
reinterpret_cast<const uint64*
>(pValue));
823 return std::to_string(*
reinterpret_cast<const uint8*
>(pValue));
825 return reinterpret_cast<const RscVersion*
>(pValue)->ToString();
827 return reinterpret_cast<const RscGuid*
>(pValue)->ToString();
836template<
int MaxStringSize>
839 switch (this->GetValueType())
867 case RscType::IecTimeOfDay64:
871 return strlen((
char*)this->buffer);
The class contains date and time informations.
Definition: DateTime.hpp:45
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:68
RscVariant(const T &value)
Creates a new instance of RscVariant with value. Gets RscType by type deduction of T.
Definition: RscVariant.hxx:368
void SetType(RscType rscType)
Forces the internal RscType to be set to another RscType. This Method does no conversion or validatio...
Definition: RscVariant.hxx:555
String ToString(void) const
Converts this instance to string if the variant type has a reasonable string representation.
Definition: RscVariant.hxx:772
RscVariant(const RscString< N > &value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:394
size_t GetArrayDimensions(void) const
Gets the count of array dimensions (1 for simple array, 2 for array of array etc.)....
Definition: RscVariant.hxx:531
RscVariant(const SecureString< N > &value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:401
void Assign(const char16 *input, size_t length, RscType rscType=RscType::Utf8String)
Assigns an UTF16 string to this instance.
Definition: RscVariant.hxx:666
RscVariant(RscType type=RscType::None)
Creates an empty instance of RscVariant
Definition: RscVariant.hxx:361
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:381
T GetValue(void) const
Converts this value to the given type T.
Definition: RscVariant.hxx:764
size_t GetFieldCount(void) const
Returns field count, if RscVariant contains struct information
Definition: RscVariant.hxx:537
RscType GetValueType(void) const
Gets the value type as RscType of the contained element
Definition: RscVariant.hxx:467
const char * GetChars(void) const
Gets pointer to internal string buffer. Operation only valid for Utf8Strings.
Definition: RscVariant.hxx:743
static RscVariant< MaxStringSize > CreateStructVariant(size_t fieldCount)
Creates a new RscVariant initialized with RscStructInformation
Definition: RscVariant.hxx:586
RscVariant(const char16 *input, size_t length, RscType type=RscType::Utf8String)
Assigns an UTF16 string to this instance.
Definition: RscVariant.hxx:387
RscVariant(size_t fieldCount, ReadElementFunction *pFunction)
For internal use only
Definition: RscVariant.hxx:452
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:595
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:753
RscVariant(const String &value)
Creates a new instance of RscVariant with value. RscType is Utf8String.
Definition: RscVariant.hxx:374
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:543
RscType GetType(void) const
Gets the RscType of the contained element
Definition: RscVariant.hxx:461
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:437
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:422
RscType GetArrayElementType(void) const
Gets the RscType of the array elements if RscVariant contains array information.
Definition: RscVariant.hxx:485
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:407
void CopyTo(T &value) const
Copies internal data to memory referenced by value. Only for primtive types. Read Strings with GetCha...
Definition: RscVariant.hxx:732
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:1039
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:1912
const CharType * CStr() const
Gets the character data of this string.
Definition: BasicString.hxx:1508
static const SelfType Empty
An emtpy static string instance.
Definition: BasicString.hxx:214
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:1876
std::uint64_t uint64
The Arp unsigned integer type of 8 byte size.
Definition: PrimitiveTypes.hpp:39
char16_t char16
The Arp character type of 2 byte size.
Definition: PrimitiveTypes.hpp:49
std::int64_t int64
The Arp integer type of 8 byte size.
Definition: PrimitiveTypes.hpp:41
char char8
The Arp character type of 1 byte size.
Definition: PrimitiveTypes.hpp:47
std::uint32_t uint32
The Arp unsigned integer type of 4 byte size.
Definition: PrimitiveTypes.hpp:35
std::int8_t int8
The Arp integer type of 1 byte size.
Definition: PrimitiveTypes.hpp:29
std::uint16_t uint16
The Arp unsigned integer type of 2 byte size.
Definition: PrimitiveTypes.hpp:31
std::uint8_t uint8
The Arp unsigned integer type of 1 byte size.
Definition: PrimitiveTypes.hpp:27
std::int32_t int32
The Arp integer type of 4 byte size.
Definition: PrimitiveTypes.hpp:37
std::int16_t int16
The Arp integer type of 2 byte size.
Definition: PrimitiveTypes.hpp:33
@ 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