From 624658ab7cdf8171fdeb95e639524e01542b73ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Wed, 1 Feb 2023 16:17:31 +0100 Subject: [PATCH] ua: decode types that convert to time.Time The codec does not handle types that can be converted to time.Time correctly since it is too strict in determining what a time.Time type is. This patch relaxes this by checking if a type can be converted to time.Time. Fixes #633 --- ua/decode.go | 4 ++-- ua/decode_test.go | 13 +++++++++++++ ua/encode.go | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ua/decode.go b/ua/decode.go index 78399ac3..0a679d5d 100644 --- a/ua/decode.go +++ b/ua/decode.go @@ -23,7 +23,7 @@ func isBinaryDecoder(val reflect.Value) bool { } func isTime(val reflect.Value) bool { - return val.Type() == timeType + return val.CanConvert(timeType) } type BinaryDecoder interface { @@ -49,7 +49,7 @@ func decode(b []byte, val reflect.Value, name string) (n int, err error) { v := val.Interface().(BinaryDecoder) return v.Decode(b) case isTime(val): - val.Set(reflect.ValueOf(buf.ReadTime())) + val.Set(reflect.ValueOf(buf.ReadTime()).Convert(val.Type())) default: // fmt.Printf("decode: %s is a %s\n", name, val.Kind()) switch val.Kind() { diff --git a/ua/decode_test.go b/ua/decode_test.go index 5574407e..acdc04f0 100644 --- a/ua/decode_test.go +++ b/ua/decode_test.go @@ -25,7 +25,10 @@ type C struct { B [2]byte } +type Timestamp time.Time + func TestCodec(t *testing.T) { + tests := []struct { name string v interface{} @@ -205,6 +208,16 @@ func TestCodec(t *testing.T) { v: &struct{ V time.Time }{time.Time{}}, b: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }, + { + name: "DateTime as Timestamp", + v: &struct{ V Timestamp }{Timestamp(time.Date(2018, time.August, 10, 23, 0, 0, 0, time.UTC))}, + b: []byte{0x00, 0x98, 0x67, 0xdd, 0xfd, 0x30, 0xd4, 0x01}, + }, + { + name: "DateTimeZero as Timestamp", + v: &struct{ V Timestamp }{Timestamp{}}, + b: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }, { name: "[]uint32==nil", v: &struct{ V []uint32 }{}, diff --git a/ua/encode.go b/ua/encode.go index d116c647..e02d1db2 100644 --- a/ua/encode.go +++ b/ua/encode.go @@ -46,7 +46,7 @@ func encode(val reflect.Value, name string) ([]byte, error) { return v.Encode() case isTime(val): - buf.WriteTime(val.Interface().(time.Time)) + buf.WriteTime(val.Convert(timeType).Interface().(time.Time)) default: switch val.Kind() {