private Variant ReadVariantFromArray()

in src/Azure.IIoT.OpcUa/src/Encoders/JsonDecoderEx.cs [1384:1488]


        private Variant ReadVariantFromArray(JArray array, bool unsigned = false)
        {
            if (array.Count == 0)
            {
                return Variant.Null; // Give up
            }

            // Try to decode non reversible encoding first.
            var dimensions = GetDimensions(array, out var type);
            if (dimensions.Length > 1)
            {
                var builtInType = BuiltInType.Variant;
                switch (type)
                {
                    case JTokenType.Integer:
                        builtInType = BuiltInType.Int64;
                        break;
                    case JTokenType.Boolean:
                        builtInType = BuiltInType.Boolean;
                        break;
                    case JTokenType.Bytes:
                        builtInType = BuiltInType.ByteString;
                        break;
                    case JTokenType.Date:
                    case JTokenType.TimeSpan:
                        builtInType = BuiltInType.DateTime;
                        break;
                    case JTokenType.Float:
                        builtInType = BuiltInType.Double;
                        break;
                    case JTokenType.Guid:
                        builtInType = BuiltInType.Guid;
                        break;
                    case JTokenType.String:
                        builtInType = BuiltInType.String;
                        break;
                }
                return ReadVariantMatrixBody(array, dimensions, builtInType);
            }

            if (type != JTokenType.Object && array.All(j => j.Type == type))
            {
                try
                {
                    switch (array[0].Type)
                    {
                        case JTokenType.Integer:
                            return !unsigned ? new Variant(array
                                .Select(t => (long)t)
                                .ToArray()) : new Variant(array
                                .Select(t => (ulong)t)
                                .ToArray());
                        case JTokenType.Boolean:
                            return new Variant(array
                                .Select(t => (bool)t)
                                .ToArray());
                        case JTokenType.Bytes:
                            return new Variant(array
                                .Select(t => (byte[]?)t)
                                .ToArray());
                        case JTokenType.Date:
                            return new Variant(array
                                .Select(t => (DateTime)t)
                                .ToArray());
                        case JTokenType.TimeSpan:
                            return new Variant(array
                                .Select(t => ((TimeSpan)t).TotalMilliseconds)
                                .ToArray());
                        case JTokenType.Float:
                            return new Variant(array
                                .Select(t => (double)t)
                                .ToArray());
                        case JTokenType.Guid:
                            return new Variant(array
                                .Select(t => (Guid)t)
                                .ToArray());
                        case JTokenType.String:
                            return new Variant(array
                                .Select(t => (string?)t)
                                .ToArray());
                    }
                }
                catch
                {
                    // TODO Log or throw for bad type
                    return Variant.Null; // Give up
                }
            }
            var result = array
                .Select(t => ReadVariantFromToken(t, unsigned))
                .ToArray();
            var validBuiltInType = Array.Find(result, v => v.TypeInfo?.BuiltInType != null).TypeInfo?.BuiltInType;
            if (validBuiltInType == null)
            {
                return Variant.Null;
            }
            if (result
                .Where(v => v != Variant.Null)
                .All(v => v.TypeInfo.BuiltInType == validBuiltInType))
            {
                // TODO: This needs tests as it should not work.
                return new Variant(result.Select(v => v.Value).ToArray());
            }
            return new Variant(result);
        }