Skip to content

Commit

Permalink
fix decoding of variant containing a Null array of of a type that can…
Browse files Browse the repository at this point in the history
…not be null
  • Loading branch information
oroulet committed Dec 28, 2016
1 parent d634f46 commit 727d420
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions opcua/ua/uatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,24 +742,34 @@ class Variant(FrozenClass):
:vartype Value: Any supported type
:ivar 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.VariantType = varianttype
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
if isinstance(value, Variant):
self.Value = value.Value
self.VariantType = value.VariantType
if self.VariantType is None:
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.String,
VariantType.DateTime):
raise UaError("Variant of type {0} cannot have value None".format(self.VariantType))
if self.Dimensions is None and type(self.Value) in (list, tuple):
raise UaError("Non array Variant of type {0} cannot have value None".format(self.VariantType))
if self.Dimensions is None and isinstance(self.Value, (list, tuple)):
dims = get_shape(self.Value)
if len(dims) > 1:
self.Dimensions = dims
Expand Down Expand Up @@ -828,20 +838,21 @@ def to_binary(self):
@staticmethod
def from_binary(data):
dimensions = None
array = False
encoding = ord(data.read(1))
int_type = encoding & 0b00111111
vtype = datatype_to_varianttype(int_type)
if vtype == VariantType.Null:
return Variant(None, vtype, encoding)
if uabin.test_bit(encoding, 7):
value = uabin.unpack_uatype_array(vtype, data)
array = True
else:
value = uabin.unpack_uatype(vtype, data)
if uabin.test_bit(encoding, 6):
dimensions = uabin.unpack_uatype_array(VariantType.Int32, data)
value = reshape(value, dimensions)

return Variant(value, vtype, dimensions)
return Variant(value, vtype, dimensions, is_array=array)


def reshape(flat, dims):
Expand Down

0 comments on commit 727d420

Please sign in to comment.