From bada93d634a08e0cb639fa00de6c620ddc1ab777 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Mon, 9 Dec 2024 13:49:06 +0100 Subject: [PATCH] Issue #722: Set DataValue.Value to Variant(nil) for no value This patch ensures that DataValue.Value contains a Variant(nil) if there is no value. Closes #722 --- ua/datatypes.go | 2 +- ua/datatypes_test.go | 45 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/ua/datatypes.go b/ua/datatypes.go index c298841c..47117c00 100644 --- a/ua/datatypes.go +++ b/ua/datatypes.go @@ -39,8 +39,8 @@ type DataValue struct { func (d *DataValue) Decode(b []byte) (int, error) { buf := NewBuffer(b) d.EncodingMask = buf.ReadByte() + d.Value = new(Variant) if d.Has(DataValueValue) { - d.Value = new(Variant) buf.ReadStruct(d.Value) } if d.Has(DataValueStatusCode) { diff --git a/ua/datatypes_test.go b/ua/datatypes_test.go index 937bb1bf..180a59ea 100644 --- a/ua/datatypes_test.go +++ b/ua/datatypes_test.go @@ -11,6 +11,17 @@ import ( func TestDataValue(t *testing.T) { cases := []CodecTestCase{ + { + Name: "no value", + Struct: &DataValue{ + EncodingMask: 0x00, + Value: MustVariant(nil), + }, + Bytes: []byte{ + // EncodingMask + 0x00, + }, + }, { Name: "value only", Struct: &DataValue{ @@ -45,6 +56,23 @@ func TestDataValue(t *testing.T) { 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, }, }, + { + Name: "source timestamp, server timestamp", + Struct: &DataValue{ + EncodingMask: 0x0c, + Value: MustVariant(nil), + SourceTimestamp: time.Date(2018, time.September, 17, 14, 28, 29, 112000000, time.UTC), + ServerTimestamp: time.Date(2018, time.September, 17, 14, 28, 29, 112000000, time.UTC), + }, + Bytes: []byte{ + // EncodingMask + 0x0c, + // SourceTimestamp + 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, + // SeverTimestamp + 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, + }, + }, } RunCodecTest(t, cases) } @@ -52,7 +80,7 @@ func TestDataValue(t *testing.T) { func TestDataValueArray(t *testing.T) { cases := []CodecTestCase{ { - Name: "value only and value, source timestamp, server timestamp", + Name: "value only; value, source timestamp, server timestamp; source timestamp, server timestamp", Struct: []*DataValue{ { EncodingMask: 0x01, @@ -64,10 +92,16 @@ func TestDataValueArray(t *testing.T) { SourceTimestamp: time.Date(2018, time.September, 17, 14, 28, 29, 112000000, time.UTC), ServerTimestamp: time.Date(2018, time.September, 17, 14, 28, 29, 112000000, time.UTC), }, + { + EncodingMask: 0x0c, + Value: MustVariant(nil), + SourceTimestamp: time.Date(2018, time.September, 17, 14, 28, 29, 112000000, time.UTC), + ServerTimestamp: time.Date(2018, time.September, 17, 14, 28, 29, 112000000, time.UTC), + }, }, Bytes: []byte{ // length - 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, // EncodingMask 0x01, @@ -84,6 +118,13 @@ func TestDataValueArray(t *testing.T) { 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, // ServerTimestamp 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, + + // EncodingMask + 0x0c, + // SourceTimestamp + 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, + // ServerTimestamp + 0x80, 0x3b, 0xe8, 0xb3, 0x92, 0x4e, 0xd4, 0x01, }, }, }