41 lines
1.9 KiB
C#
41 lines
1.9 KiB
C#
using Opc.Ua;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer;
|
|
|
|
/// <summary>Copies supported SDK payloads at the server's CLR value boundary.</summary>
|
|
internal static class SdkValueBoundary
|
|
{
|
|
/// <summary>Build a detached Variant for an existing supported scalar or one-dimensional array.</summary>
|
|
internal static Variant FromClr(object? value, bool byteArray = false)
|
|
{
|
|
if (value is null) return Variant.Null;
|
|
if (value is Array array)
|
|
{
|
|
if (array.Rank != 1) throw new ArgumentException("Only one-dimensional values are supported.", nameof(value));
|
|
value = array.Clone();
|
|
}
|
|
if (value is byte[] bytes) return byteArray
|
|
? Variant.From((ArrayOf<byte>)bytes)
|
|
: Variant.From(ByteString.From(bytes));
|
|
if (VariantHelper.TryCastFrom(value, out var variant)) return variant;
|
|
throw new ArgumentException("Unsupported OPC UA value type.", nameof(value));
|
|
}
|
|
|
|
/// <summary>Map the UA zero timestamp to the application's existing unspecified-bound sentinel.</summary>
|
|
internal static DateTime ToClrTimestamp(DateTimeUtc value) => value == DateTimeUtc.MinValue
|
|
? DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc) : value.ToDateTime();
|
|
|
|
/// <summary>Restore existing CLR payload types and detach mutable arrays.</summary>
|
|
internal static object? ToClr(Variant value) => value.AsBoxedObject(Variant.BoxingBehavior.Legacy) switch
|
|
{
|
|
ByteString bytes => bytes.IsNull ? null : bytes.ToArray(),
|
|
DateTimeUtc time => time.ToDateTime(),
|
|
Uuid id => (Guid)id,
|
|
DateTimeUtc[] times => times.Select(x => x.ToDateTime()).ToArray(),
|
|
Uuid[] ids => ids.Select(x => (Guid)x).ToArray(),
|
|
ByteString[] strings => strings.Select(x => x.IsNull ? null : x.ToArray()).ToArray(),
|
|
Array array => array.Clone(),
|
|
var scalar => scalar,
|
|
};
|
|
}
|