7 #include "Arp/System/Commons/Exceptions/Exceptions.h" 8 #include "Arp/System/Rsc/Services/Rsc.h" 9 #include "Arp/System/Rsc/Services/RscGuid.hpp" 10 #include "Arp/System/Rsc/Services/RscVersion.hpp" 11 #include "Arp/System/Rsc/Services/RscString.hxx" 12 #include "Arp/System/Rsc/Services/SecureString.hxx" 16 namespace Arp {
namespace System {
namespace Rsc {
namespace Services
26 template<
int N>
class RscStructReader;
27 template<
int N>
class RscStructWriter;
28 template<
class T,
bool IsClass,
bool IsSerializable>
class RscValueAdapter;
36 template<
int MaxStringSize = 0>
44 template<
class T,
bool IsClass,
bool IsSerializable>
friend class RscValueAdapter;
47 using ReadElementFunction = std::function<RscType(RscType expectedType, byte* pValue)>;
48 using WriteElementFunction = std::function<void(RscType valueType, const byte* pValue)>;
98 RscVariant(
size_t arraySize,
RscType arrayElementType,
size_t dimensions = 1,
size_t fieldCount = 0);
109 RscVariant(
size_t arraySize,
RscType arrayElementType, ReadElementFunction* pFunction,
size_t dimensions = 1,
size_t fieldCount = 0);
120 RscVariant(
size_t arraySize,
RscType arrayElementType, WriteElementFunction* pFunction,
size_t dimensions = 1,
size_t fieldCount = 0);
122 RscVariant(
size_t fieldCount, ReadElementFunction* pFunction);
132 RscVariant(RscVariant&&) =
default;
154 static RscVariant<MaxStringSize> CreateArrayVariant(
size_t arraySize,
RscType elementType, RemotingWriter& writer,
size_t dimensions = 1,
size_t fieldCount = 0);
158 RscVariant& operator=(
const T& value);
159 RscVariant& operator=(
const String& value);
160 RscVariant& operator=(
const char* value);
165 RscVariant& operator=(
const RscVariant& value) =
default;
166 RscVariant& operator=(RscVariant&&) =
default;
167 bool operator==(
const RscVariant& value)
const;
168 bool operator!=(
const RscVariant& value)
const;
181 RscType GetValueType(
void)
const;
188 RscType GetArrayElementType(
void)
const;
195 size_t GetArrayDimensions(
void)
const;
202 size_t GetFieldCount(
void)
const;
208 const char* GetChars(
void)
const;
215 void SetWriteElementFunction(WriteElementFunction* pFunction)
const;
221 const byte* GetDataAddress(
void)
const;
227 byte* GetDataAddress(
void);
241 T GetValue(
void)
const;
248 void CopyTo(T& value)
const;
254 String ToString(
void)
const;
264 void InitComplexTypeInfo(
void);
265 bool ContainsTypeInformation(
void)
const;
266 size_t GetSize(
void)
const;
269 struct ComplexTypeInfo
276 RemotingReader* pReader =
nullptr;
277 mutable RemotingWriter* pWriter =
nullptr;
278 ReadElementFunction* pReadElementFunction =
nullptr;
279 mutable WriteElementFunction* pWriteElementFunction =
nullptr;
283 static const size_t maxPrimitiveSize = 8;
284 #ifdef ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT 285 static const size_t minBufferSize = std::max(maxPrimitiveSize, std::max(
sizeof(
RscGuid),
sizeof(
RscVersion)));
287 static const size_t minBufferSize = maxPrimitiveSize;
288 #endif // ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT 290 static const size_t bufferSize = minBufferSize < (size_t)MaxStringSize ? (
size_t)MaxStringSize : minBufferSize;
295 ComplexTypeInfo typeInfo;
296 byte buffer[bufferSize];
313 template<
int MaxStringSize>
319 template<
int MaxStringSize>
323 this->operator=(value);
326 template<
int MaxStringSize>
330 this->operator=(value);
333 template<
int MaxStringSize>
336 this->operator=(value);
339 template<
int MaxStringSize>
343 this->operator=(value);
346 template<
int MaxStringSize>
350 this->operator=(value);
353 template<
int MaxStringSize>
357 if(arrayElementType == RscType::Struct && fieldCount == 0)
359 throw ArgumentException::Create(
"fieldCount", fieldCount,
"fieldCount has to be set for struct element types");
361 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
362 this->typeInfo.pReader =
nullptr;
363 this->typeInfo.pWriter =
nullptr;
364 this->typeInfo.pReadElementFunction =
nullptr;
365 this->typeInfo.pWriteElementFunction =
nullptr;
368 template<
int MaxStringSize>
372 if(arrayElementType == RscType::Struct && fieldCount == 0)
374 throw ArgumentException::Create(
"fieldCount", fieldCount,
"fieldCount has to be set for struct element types");
376 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
377 this->typeInfo.pReader =
nullptr;
378 this->typeInfo.pWriter =
nullptr;
379 this->typeInfo.pReadElementFunction = pFunction;
380 this->typeInfo.pWriteElementFunction =
nullptr;
383 template<
int MaxStringSize>
387 if(arrayElementType == RscType::Struct && fieldCount == 0)
389 throw ArgumentException::Create(
"fieldCount", fieldCount,
"fieldCount has to be set for struct element types");
391 this->GetArrayInformation() =
RscArrayInformation(arraySize, arrayElementType, dimensions, fieldCount);
392 this->typeInfo.pReader =
nullptr;
393 this->typeInfo.pWriter =
nullptr;
394 this->typeInfo.pReadElementFunction =
nullptr;
395 this->typeInfo.pWriteElementFunction = pFunction;
398 template<
int MaxStringSize>
400 : type(RscType::Struct)
402 this->InitComplexTypeInfo();
404 this->typeInfo.pReadElementFunction = pFunction;
407 template<
int MaxStringSize>
413 template<
int MaxStringSize>
418 case RscType::IecTime:
419 return RscType::Int32;
420 case RscType::IecTime64:
421 case RscType::IecDate64:
422 case RscType::IecDateTime64:
423 case RscType::IecTimeOfDay64:
424 return RscType::Int64;
431 template<
int MaxStringSize>
434 return this->GetArrayInformation().ElementType;
437 template<
int MaxStringSize>
440 if(this->GetType() != RscType::Array)
444 return this->typeInfo.arrayInformation;
447 template<
int MaxStringSize>
450 if(this->GetType() != RscType::Array)
454 return this->typeInfo.arrayInformation;
457 template<
int MaxStringSize>
460 if(this->GetType() != RscType::Struct)
464 return this->typeInfo.structInformation;
467 template<
int MaxStringSize>
470 if(this->GetType() != RscType::Struct)
474 return this->typeInfo.structInformation;
477 template<
int MaxStringSize>
480 return this->GetArrayInformation().Dimensions;
483 template<
int MaxStringSize>
486 return this->GetStructInformation().FieldCount;
489 template<
int MaxStringSize>
495 template<
int MaxStringSize>
501 template<
int MaxStringSize>
504 this->type = rscType;
507 template<
int MaxStringSize>
510 return (this->type == RscType::Struct || this->type == RscType::Array);
513 template<
int MaxStringSize>
517 this->type = GetRscType<T>();
518 if(this->type == RscType::None)
522 #ifndef ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT 527 #endif // ARP_SYSTEM_RSC_SUPPORT_VERSION_GUID_AS_OBJECT 528 *
reinterpret_cast<T*
>(this->buffer) = value;
532 template<
int MaxStringSize>
536 result.InitComplexTypeInfo();
537 result.GetStructInformation().FieldCount = fieldCount;
541 template<
int MaxStringSize>
548 template<
int MaxStringSize>
552 result.typeInfo.pWriter = &writer;
556 template<
int MaxStringSize>
560 result.typeInfo.pWriter = &writer;
564 template<
int MaxStringSize>
567 size_t len = value.Length();
568 this->Assign(value.CStr(), len);
572 template<
int MaxStringSize>
575 size_t len = strlen(value);
576 this->Assign(value, len);
580 template<
int MaxStringSize>
584 this->Assign(value.
CStr(), strlen(value.
CStr()), RscType::Utf8String);
588 template<
int MaxStringSize>
592 this->Assign(value.
CStr(), strlen(value.
CStr()), RscType::SecureString);
596 template<
int MaxStringSize>
599 if (len >= MaxStringSize)
601 throw ArgumentException(
"Cannot copy string: argument string length {0} exceeds MaxStringSize {1}", len, MaxStringSize);
603 if (typeArg != RscType::Utf8String && typeArg != RscType::SecureString)
607 memcpy(this->buffer, value, len);
608 this->buffer[len] =
'\0';
609 this->type = typeArg;
612 template<
int MaxStringSize>
615 if (this->GetType() != value.
GetType())
620 if (this->GetSize() != value.GetSize())
625 if (memcmp(this->buffer, value.buffer, this->GetSize()) != 0)
630 if (this->GetType() == RscType::Utf8String)
632 if (strcmp((
char*)this->buffer, (
char*)value.buffer) != 0)
641 template<
int MaxStringSize>
644 return !(*
this == value);
647 template<
int MaxStringSize>
651 this->typeInfo.pReader =
nullptr;
652 this->typeInfo.pWriter =
nullptr;
653 this->typeInfo.pReadElementFunction =
nullptr;
654 this->typeInfo.pWriteElementFunction =
nullptr;
657 template<
int MaxStringSize>
661 RscType argType = GetRscType<T>();
662 if(this->GetValueType() != argType)
664 throw InvalidCastException(
"Cannot copy value to argument: RscVariant contains data type {0} but arg is of type {1}", this->type, argType);
666 value = *
reinterpret_cast<const T*
>(this->buffer);
669 template<
int MaxStringSize>
672 if (this->type != RscType::Utf8String && this->type != RscType::SecureString && this->type != RscType::AnsiString)
676 return reinterpret_cast<const char*
>(this->buffer);
679 template<
int MaxStringSize>
682 if(this->type != RscType::Array && this->type != RscType::Struct)
686 this->typeInfo.pWriteElementFunction = pFunction;
689 template<
int MaxStringSize>
694 this->CopyTo(result);
698 template<
int MaxStringSize>
701 const byte* pValue = this->GetDataAddress();
705 case RscType::SecureString:
706 case RscType::AnsiString:
707 case RscType::Utf8String:
708 return reinterpret_cast<const char*
>(pValue);
709 case RscType::DateTime:
712 return std::to_string(*reinterpret_cast<const bool*>(pValue));
714 return std::to_string(*reinterpret_cast<const char16*>(pValue));
716 return std::to_string(*reinterpret_cast<const int16*>(pValue));
718 case RscType::IecTime:
719 return std::to_string(*reinterpret_cast<const int32*>(pValue));
721 return std::to_string(*reinterpret_cast<const int8*>(pValue));
723 case RscType::IecTime64:
724 case RscType::IecDate64:
725 case RscType::IecDateTime64:
726 case RscType::IecTimeOfDay64:
727 return std::to_string(*reinterpret_cast<const int64*>(pValue));
730 return String::Empty;
731 case RscType::Real32:
732 return std::to_string(*reinterpret_cast<const float*>(pValue));
733 case RscType::Real64:
734 return std::to_string(*reinterpret_cast<const double*>(pValue));
735 case RscType::Uint16:
736 return std::to_string(*reinterpret_cast<const uint16*>(pValue));
737 case RscType::Uint32:
738 return std::to_string(*reinterpret_cast<const uint32*>(pValue));
739 case RscType::Uint64:
740 return std::to_string(*reinterpret_cast<const uint64*>(pValue));
742 return std::to_string(*reinterpret_cast<const uint8*>(pValue));
744 return reinterpret_cast<const RscVersion*
>(pValue)->ToString();
746 return reinterpret_cast<const RscGuid*
>(pValue)->ToString();
748 return String::Empty;
755 template<
int MaxStringSize>
758 switch (this->GetValueType())
770 case RscType::Uint16:
774 case RscType::Uint32:
775 case RscType::Real32:
776 case RscType::IecTime:
780 case RscType::Uint64:
781 case RscType::Real64:
782 case RscType::DateTime:
783 case RscType::IecTime64:
784 case RscType::IecDate64:
785 case RscType::IecDateTime64:
786 case RscType::IecTimeOfDay64:
789 case RscType::Utf8String:
790 return strlen((
char*)this->buffer);
797 case RscType::Struct:
802 case RscType::SecureString:
const char * CStr(void) const
Returns pointer to internal buffer.
Definition: RscString.hxx:109
Definition: RscGuid.hpp:17
Helper class to read a struct from an RscVariant. This class uses the struct information stored in Rs...
Definition: RscStructReader.hxx:26
Helper class to read an array of primtive types from an RscVariant. This class uses the array informa...
Definition: RscArrayWriter.hpp:21
This exception is used when a method is not supported.
Definition: NotSupportedException.hpp:14
Arp::BasicVersion Version
The Arp Version class.
Definition: TypeSystem.h:29
This exception is used when a method is not implemented yet.
Definition: NotImplementedException.hpp:14
Helper class to read an array of primtive types from an RscVariant. This class uses the array informa...
Definition: RscArrayReader.hpp:22
This exception is used when an invalid cast occurs.
Definition: InvalidCastException.hpp:14
RscType
Datatypes supported by Rsc. Values are identical with CommonRemoting::RemotingMarshalType. Only supported types of RemotingMarshalType are included.
Definition: RscType.hpp:27
Rsc container class for primitive data type, strings or information about arrays or structs...
Definition: RscVariant.hxx:37
Object type handled by Rsc as RscVariant
Specifies a version with 4 version numbers and is marshalled to .NET type System.Version.
Definition: RscVersion.hpp:20
This exception is used when a method call is invalid for object's current state.
Definition: InvalidOperationException.hpp:14
This exception is used when an invalid argument occurs.
Definition: ArgumentException.hpp:14
Specialized version of RscString for security context. Not implemented in this version. Wraps only RscString
Definition: RscType.hpp:18
Root namespace for the PLCnext API
RscType GetType(void) const
Gets the RscType of the contained element
Definition: RscVariant.hxx:408
System components used by the System, Device, Plc or Io domains.
Helper class to write a struct from an RscVariant. This class uses the struct information stored in R...
Definition: RscStructWriter.hxx:18
bool operator==(Enum< T > lhs, Enum< T > rhs)
Equality operator for class Enum.
Definition: Enum.hxx:218
Contains a static string with string lentgh up to N characters. The string has to be null terminated...
Definition: RscString.hxx:18
This is a small immutable wrapper around the boost::uuids::uuid class and represents a universal uniq...
Definition: Uuid.hpp:18
Namespace for basic functions of the framework
RscVariant(RscType type=RscType::None)
Creates an empty instance of RscVariant
Definition: RscVariant.hxx:314
unsigned char byte
The Arp character type.
Definition: PrimitiveTypes.hpp:23