Commit 75d9928e authored by olivier R-D's avatar olivier R-D

fix decoding of variant containing a Null array of of a type that cannot be null

parent 91ab3c47
...@@ -742,24 +742,34 @@ class Variant(FrozenClass): ...@@ -742,24 +742,34 @@ class Variant(FrozenClass):
:vartype Value: Any supported type :vartype Value: Any supported type
:ivar VariantType: :ivar VariantType:
:vartype VariantType: VariantType :vartype VariantType: VariantType
:ivar Dimension:
:vartype Dimensions: The length of each dimensions. Usually guessed from value.
:ivar is_array:
:vartype is_array: If the variant is an array. Usually guessed from value.
""" """
def __init__(self, value=None, varianttype=None, dimensions=None): def __init__(self, value=None, varianttype=None, dimensions=None, is_array=None):
self.Value = value self.Value = value
self.VariantType = varianttype self.VariantType = varianttype
self.Dimensions = dimensions self.Dimensions = dimensions
self.is_array = is_array
if self.is_array is None:
if isinstance(value, (list, tuple)):
self.is_array = True
else:
self.is_array = False
self._freeze = True self._freeze = True
if isinstance(value, Variant): if isinstance(value, Variant):
self.Value = value.Value self.Value = value.Value
self.VariantType = value.VariantType self.VariantType = value.VariantType
if self.VariantType is None: if self.VariantType is None:
self.VariantType = self._guess_type(self.Value) self.VariantType = self._guess_type(self.Value)
if self.Value is None and self.VariantType not in ( if self.Value is None and not self.is_array and self.VariantType not in (
VariantType.Null, VariantType.Null,
VariantType.String, VariantType.String,
VariantType.DateTime): VariantType.DateTime):
raise UaError("Variant of type {0} cannot have value None".format(self.VariantType)) raise UaError("Non array Variant of type {0} cannot have value None".format(self.VariantType))
if self.Dimensions is None and type(self.Value) in (list, tuple): if self.Dimensions is None and isinstance(self.Value, (list, tuple)):
dims = get_shape(self.Value) dims = get_shape(self.Value)
if len(dims) > 1: if len(dims) > 1:
self.Dimensions = dims self.Dimensions = dims
...@@ -828,6 +838,7 @@ class Variant(FrozenClass): ...@@ -828,6 +838,7 @@ class Variant(FrozenClass):
@staticmethod @staticmethod
def from_binary(data): def from_binary(data):
dimensions = None dimensions = None
array = False
encoding = ord(data.read(1)) encoding = ord(data.read(1))
int_type = encoding & 0b00111111 int_type = encoding & 0b00111111
vtype = datatype_to_varianttype(int_type) vtype = datatype_to_varianttype(int_type)
...@@ -835,13 +846,13 @@ class Variant(FrozenClass): ...@@ -835,13 +846,13 @@ class Variant(FrozenClass):
return Variant(None, vtype, encoding) return Variant(None, vtype, encoding)
if uabin.test_bit(encoding, 7): if uabin.test_bit(encoding, 7):
value = uabin.unpack_uatype_array(vtype, data) value = uabin.unpack_uatype_array(vtype, data)
array = True
else: else:
value = uabin.unpack_uatype(vtype, data) value = uabin.unpack_uatype(vtype, data)
if uabin.test_bit(encoding, 6): if uabin.test_bit(encoding, 6):
dimensions = uabin.unpack_uatype_array(VariantType.Int32, data) dimensions = uabin.unpack_uatype_array(VariantType.Int32, data)
value = reshape(value, dimensions) value = reshape(value, dimensions)
return Variant(value, vtype, dimensions, is_array=array)
return Variant(value, vtype, dimensions)
def reshape(flat, dims): def reshape(flat, dims):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment