diff --git a/examples/accesslevel/accesslevel.go b/examples/accesslevel/accesslevel.go index 65755282..1a882db2 100644 --- a/examples/accesslevel/accesslevel.go +++ b/examples/accesslevel/accesslevel.go @@ -56,6 +56,6 @@ func main() { case v == nil: log.Print("v == nil") default: - log.Print(v.Value) + log.Print(v.Value()) } } diff --git a/examples/crypto/crypto.go b/examples/crypto/crypto.go index 7461cb89..a473dec0 100644 --- a/examples/crypto/crypto.go +++ b/examples/crypto/crypto.go @@ -72,7 +72,7 @@ func main() { log.Fatal(err) } if v != nil { - fmt.Printf("Server's Time | Conn 1 %s | ", v.Value) + fmt.Printf("Server's Time | Conn 1 %s | ", v.Value()) } else { log.Print("v == nil") } @@ -101,7 +101,7 @@ func main() { log.Fatal(err) } if v != nil { - fmt.Printf("Conn 2: %s\n", v.Value) + fmt.Printf("Conn 2: %s\n", v.Value()) } else { log.Print("v == nil") } diff --git a/examples/datetime/datetime.go b/examples/datetime/datetime.go index b4ab3292..cc5bff75 100644 --- a/examples/datetime/datetime.go +++ b/examples/datetime/datetime.go @@ -60,6 +60,6 @@ func main() { case v == nil: log.Print("v == nil") default: - log.Print(v.Value) + log.Print(v.Value()) } } diff --git a/examples/history-read/history-read.go b/examples/history-read/history-read.go index fc509fbf..b971de78 100644 --- a/examples/history-read/history-read.go +++ b/examples/history-read/history-read.go @@ -95,7 +95,7 @@ func main() { "%s - %s - %v \n", nodes[nodeNum].NodeID.String(), value.SourceTimestamp.Format(time.RFC3339), - value.Value.Value, + value.Value.Value(), ) } } diff --git a/examples/read/read.go b/examples/read/read.go index 4a953593..93105402 100644 --- a/examples/read/read.go +++ b/examples/read/read.go @@ -51,5 +51,5 @@ func main() { if resp.Results[0].Status != ua.StatusOK { log.Fatalf("Status not OK: %v", resp.Results[0].Status) } - log.Print(resp.Results[0].Value.Value) + log.Print(resp.Results[0].Value.Value()) } diff --git a/examples/subscribe/subscribe.go b/examples/subscribe/subscribe.go index 1692de2b..23948585 100644 --- a/examples/subscribe/subscribe.go +++ b/examples/subscribe/subscribe.go @@ -99,7 +99,7 @@ func main() { switch x := res.Value.(type) { case *ua.DataChangeNotification: for _, item := range x.MonitoredItems { - data := item.Value.Value.Value + data := item.Value.Value.Value() log.Printf("MonitoredItem with client handle %v = %v", item.ClientHandle, data) } diff --git a/examples/udt/udt.go b/examples/udt/udt.go index 8b2fa406..14eb0423 100644 --- a/examples/udt/udt.go +++ b/examples/udt/udt.go @@ -68,7 +68,7 @@ func main() { case v == nil: log.Print("v == nil") default: - log.Printf("val: %#v", v.Value.(*ua.ExtensionObject).Value) + log.Printf("val: %#v", v.Value().(*ua.ExtensionObject).Value) } } diff --git a/node.go b/node.go index ddf10117..e8993718 100644 --- a/node.go +++ b/node.go @@ -41,7 +41,7 @@ func (n *Node) BrowseName() (*ua.QualifiedName, error) { if err != nil { return nil, err } - return v.Value.(*ua.QualifiedName), nil + return v.Value().(*ua.QualifiedName), nil } // DisplayName returns the display name of the node. @@ -50,7 +50,7 @@ func (n *Node) DisplayName() (*ua.LocalizedText, error) { if err != nil { return nil, err } - return v.Value.(*ua.LocalizedText), nil + return v.Value().(*ua.LocalizedText), nil } // AccessLevel returns the access level of the node. @@ -61,7 +61,7 @@ func (n *Node) AccessLevel() (ua.AccessLevelType, error) { if err != nil { return 0, err } - return ua.AccessLevelType(v.Value.(uint8)), nil + return ua.AccessLevelType(v.Value().(uint8)), nil } // HasAccessLevel returns true if all bits from mask are @@ -80,7 +80,7 @@ func (n *Node) UserAccessLevel() (ua.AccessLevelType, error) { if err != nil { return 0, err } - return ua.AccessLevelType(v.Value.(uint8)), nil + return ua.AccessLevelType(v.Value().(uint8)), nil } // HasUserAccessLevel returns true if all bits from mask are diff --git a/ua/variant.go b/ua/variant.go index 090b7560..901950bb 100644 --- a/ua/variant.go +++ b/ua/variant.go @@ -23,13 +23,13 @@ const ( // // Specification: Part 6, 5.2.2.16 type Variant struct { - // EncodingMask contains the type and the array flags + // mask contains the type and the array flags // bits 0:5: built-in type id 1-25 // bit 6: array dimensions // bit 7: array values - EncodingMask byte + mask byte - // ArrayLength is the number of elements in the array. + // arrayLength is the number of elements in the array. // This field is only present if the 'array values' // flag is set. // @@ -37,24 +37,24 @@ type Variant struct { // field specifies the total number of elements. The original array can be // reconstructed from the dimensions that are encoded after the value // field. - ArrayLength int32 + arrayLength int32 - // ArrayDimensionsLength is the numer of dimensions. + // arrayDimensionsLength is the numer of dimensions. // This field is only present if the 'array dimensions' flag // is set. - ArrayDimensionsLength int32 + arrayDimensionsLength int32 - // ArrayDimensions is the size for each dimension. + // arrayDimensions is the size for each dimension. // This field is only present if the 'array dimensions' flag // is set. - ArrayDimensions []int32 + arrayDimensions []int32 - Value interface{} + value interface{} } func NewVariant(v interface{}) (*Variant, error) { va := &Variant{} - if err := va.Set(v); err != nil { + if err := va.set(v); err != nil { return nil, err } return va, nil @@ -68,23 +68,44 @@ func MustVariant(v interface{}) *Variant { return va } +func (m *Variant) EncodingMask() byte { + return m.mask +} + // Type returns the type id of the value. func (m *Variant) Type() TypeID { - return TypeID(m.EncodingMask & 0x3f) + return TypeID(m.mask & 0x3f) } func (m *Variant) setType(t TypeID) { - m.EncodingMask |= byte(t & 0x3f) + m.mask |= byte(t & 0x3f) } +// Has returns whether given encoding mask bits are set. func (m *Variant) Has(mask byte) bool { - return m.EncodingMask&mask == mask + return m.mask&mask == mask +} + +// ArrayLength returns the total number of elements for one and multi-dimensional +// array values. +func (m *Variant) ArrayLength() int32 { + return m.arrayLength +} + +// ArrayDimensions returns the dimensions of multi-dimensional arrays. +func (m *Variant) ArrayDimensions() []int32 { + return m.arrayDimensions +} + +// Value returns the value. +func (m *Variant) Value() interface{} { + return m.Value } // Decode implements the codec interface. func (m *Variant) Decode(b []byte) (int, error) { buf := NewBuffer(b) - m.EncodingMask = buf.ReadByte() + m.mask = buf.ReadByte() // check the type typ, ok := variantTypeIDToType[m.Type()] @@ -94,15 +115,15 @@ func (m *Variant) Decode(b []byte) (int, error) { // read single value and return if !m.Has(VariantArrayValues) { - m.Value = m.decodeValue(buf) + m.value = m.decodeValue(buf) return buf.Pos(), buf.Error() } // get total array length (flattened for multi-dimensional arrays) - m.ArrayLength = buf.ReadInt32() + m.arrayLength = buf.ReadInt32() // read flattened array elements - n := int(m.ArrayLength) + n := int(m.arrayLength) vals := reflect.MakeSlice(reflect.SliceOf(typ), n, n) for i := 0; i < n; i++ { vals.Index(i).Set(reflect.ValueOf(m.decodeValue(buf))) @@ -110,10 +131,10 @@ func (m *Variant) Decode(b []byte) (int, error) { // check for dimensions of multi-dimensional array if m.Has(VariantArrayDimensions) { - m.ArrayDimensionsLength = buf.ReadInt32() - m.ArrayDimensions = make([]int32, m.ArrayDimensionsLength) - for i := 0; i < int(m.ArrayDimensionsLength); i++ { - m.ArrayDimensions[i] = buf.ReadInt32() + m.arrayDimensionsLength = buf.ReadInt32() + m.arrayDimensions = make([]int32, m.arrayDimensionsLength) + for i := 0; i < int(m.arrayDimensionsLength); i++ { + m.arrayDimensions[i] = buf.ReadInt32() } } @@ -126,29 +147,29 @@ func (m *Variant) Decode(b []byte) (int, error) { // validate that the total number of elements // matches the product of the array dimensions - if m.ArrayDimensionsLength > 0 { + if m.arrayDimensionsLength > 0 { count := int32(1) - for i := range m.ArrayDimensions { - count *= m.ArrayDimensions[i] + for i := range m.arrayDimensions { + count *= m.arrayDimensions[i] } - if count != m.ArrayLength { + if count != m.arrayLength { return buf.Pos(), errUnbalancedSlice } } // handle one-dimensional arrays - if m.ArrayDimensionsLength < 2 { - m.Value = vals.Interface() + if m.arrayDimensionsLength < 2 { + m.value = vals.Interface() return buf.Pos(), buf.Error() } // handle multi-dimensional arrays // convert dimensions to []int to avoid lots of type casts - dims := make([]int, len(m.ArrayDimensions)) - for i := range m.ArrayDimensions { - dims[i] = int(m.ArrayDimensions[i]) + dims := make([]int, len(m.arrayDimensions)) + for i := range m.arrayDimensions { + dims[i] = int(m.arrayDimensions[i]) } - m.Value = split(0, 0, vals.Len(), dims, vals).Interface() + m.value = split(0, 0, vals.Len(), dims, vals).Interface() return buf.Pos(), buf.Error() } @@ -267,18 +288,18 @@ func (m *Variant) decodeValue(buf *Buffer) interface{} { func (m *Variant) Encode() ([]byte, error) { buf := NewBuffer(nil) - buf.WriteByte(m.EncodingMask) + buf.WriteByte(m.mask) if m.Has(VariantArrayValues) { - buf.WriteInt32(m.ArrayLength) + buf.WriteInt32(m.arrayLength) } - m.encode(buf, reflect.ValueOf(m.Value)) + m.encode(buf, reflect.ValueOf(m.value)) if m.Has(VariantArrayDimensions) { - buf.WriteInt32(m.ArrayDimensionsLength) - for i := 0; i < int(m.ArrayDimensionsLength); i++ { - buf.WriteInt32(m.ArrayDimensions[i]) + buf.WriteInt32(m.arrayDimensionsLength) + for i := 0; i < int(m.arrayDimensionsLength); i++ { + buf.WriteInt32(m.arrayDimensions[i]) } } @@ -391,8 +412,8 @@ func sliceDim(v reflect.Value) (typ reflect.Type, dim []int32, count int32, err return typ, append([]int32{int32(v.Len())}, dim...), count * int32(v.Len()), nil } -// Set sets the value and updates the flags according to the type. -func (m *Variant) Set(v interface{}) error { +// set sets the value and updates the flags according to the type. +func (m *Variant) set(v interface{}) error { // set array length and dimensions if value is a slice et, dim, count, err := sliceDim(reflect.ValueOf(v)) if err != nil { @@ -400,14 +421,14 @@ func (m *Variant) Set(v interface{}) error { } if len(dim) > 0 { - m.EncodingMask |= VariantArrayValues - m.ArrayLength = count + m.mask |= VariantArrayValues + m.arrayLength = count } if len(dim) > 1 { - m.EncodingMask |= VariantArrayDimensions - m.ArrayDimensionsLength = int32(len(dim)) - m.ArrayDimensions = dim + m.mask |= VariantArrayDimensions + m.arrayDimensionsLength = int32(len(dim)) + m.arrayDimensions = dim } typeid, ok := variantTypeToTypeID[et] @@ -415,7 +436,7 @@ func (m *Variant) Set(v interface{}) error { return fmt.Errorf("opcua: cannot set variant to %T", v) } m.setType(typeid) - m.Value = v + m.value = v return nil } @@ -424,14 +445,14 @@ func (m *Variant) Set(v interface{}) error { func (m *Variant) String() string { switch m.Type() { case TypeIDString: - return m.Value.(string) + return m.value.(string) case TypeIDLocalizedText: - return m.Value.(*LocalizedText).Text + return m.value.(*LocalizedText).Text case TypeIDQualifiedName: - return m.Value.(*QualifiedName).Name + return m.value.(*QualifiedName).Name default: return "" - //return fmt.Sprintf("%v", m.Value) + //return fmt.Sprintf("%v", m.value) } } @@ -439,7 +460,7 @@ func (m *Variant) String() string { func (m *Variant) Bool() bool { switch m.Type() { case TypeIDBoolean: - return m.Value.(bool) + return m.value.(bool) default: return false } @@ -449,9 +470,9 @@ func (m *Variant) Bool() bool { func (m *Variant) Float() float64 { switch m.Type() { case TypeIDFloat: - return float64(m.Value.(float32)) + return float64(m.value.(float32)) case TypeIDDouble: - return m.Value.(float64) + return m.value.(float64) default: return 0 } @@ -461,13 +482,13 @@ func (m *Variant) Float() float64 { func (m *Variant) Int() int64 { switch m.Type() { case TypeIDSByte: - return int64(m.Value.(int8)) + return int64(m.value.(int8)) case TypeIDInt16: - return int64(m.Value.(int16)) + return int64(m.value.(int16)) case TypeIDInt32: - return int64(m.Value.(int32)) + return int64(m.value.(int32)) case TypeIDInt64: - return m.Value.(int64) + return m.value.(int64) default: return 0 } @@ -477,13 +498,13 @@ func (m *Variant) Int() int64 { func (m *Variant) Uint() uint64 { switch m.Type() { case TypeIDByte: - return uint64(m.Value.(byte)) + return uint64(m.value.(byte)) case TypeIDUint16: - return uint64(m.Value.(uint16)) + return uint64(m.value.(uint16)) case TypeIDUint32: - return uint64(m.Value.(uint32)) + return uint64(m.value.(uint32)) case TypeIDUint64: - return m.Value.(uint64) + return m.value.(uint64) default: return 0 } @@ -493,7 +514,7 @@ func (m *Variant) Uint() uint64 { func (m *Variant) Time() time.Time { switch m.Type() { case TypeIDDateTime: - return m.Value.(time.Time) + return m.value.(time.Time) default: return time.Time{} } diff --git a/ua/variant_test.go b/ua/variant_test.go index a1f92fc8..362fb48c 100644 --- a/ua/variant_test.go +++ b/ua/variant_test.go @@ -261,7 +261,7 @@ func TestVariant(t *testing.T) { 0x16, // TypeID 0x01, 0x00, 0x41, 0x01, - // EncodingMask + // mask 0x01, // Length 0x0d, 0x00, 0x00, 0x00, @@ -293,7 +293,7 @@ func TestVariant(t *testing.T) { 0x16, // TypeID 0x01, 0x00, 0x60, 0x03, - // EncodingMask + // mask 0x01, // Length 0x86, 0x00, 0x00, 0x00, @@ -348,9 +348,9 @@ func TestVariant(t *testing.T) { Bytes: []byte{ // variant encoding mask 0x17, - // EncodingMask + // mask 0x01, - // Value + // value 0x0a, // type 0x19, 0x04, 0x20, 0x40, // value }, @@ -477,41 +477,41 @@ func TestSet(t *testing.T) { { v: []byte{0xca, 0xfe}, va: &Variant{ - EncodingMask: byte(TypeIDByteString), - Value: []byte{0xca, 0xfe}, + mask: byte(TypeIDByteString), + value: []byte{0xca, 0xfe}, }, }, { v: [][]byte{{0xca, 0xfe}, {0xaf, 0xfe}}, va: &Variant{ - EncodingMask: byte(VariantArrayValues | TypeIDByteString), - ArrayLength: 2, - Value: [][]byte{{0xca, 0xfe}, {0xaf, 0xfe}}, + mask: byte(VariantArrayValues | TypeIDByteString), + arrayLength: 2, + value: [][]byte{{0xca, 0xfe}, {0xaf, 0xfe}}, }, }, { v: int32(5), va: &Variant{ - EncodingMask: byte(TypeIDInt32), - Value: int32(5), + mask: byte(TypeIDInt32), + value: int32(5), }, }, { v: []int32{5}, va: &Variant{ - EncodingMask: byte(VariantArrayValues | TypeIDInt32), - ArrayLength: 1, - Value: []int32{5}, + mask: byte(VariantArrayValues | TypeIDInt32), + arrayLength: 1, + value: []int32{5}, }, }, { v: [][]int32{{5}, {5}, {5}}, va: &Variant{ - EncodingMask: byte(VariantArrayDimensions | VariantArrayValues | TypeIDInt32), - ArrayLength: 3, - ArrayDimensionsLength: 2, - ArrayDimensions: []int32{3, 1}, - Value: [][]int32{{5}, {5}, {5}}, + mask: byte(VariantArrayDimensions | VariantArrayValues | TypeIDInt32), + arrayLength: 3, + arrayDimensionsLength: 2, + arrayDimensions: []int32{3, 1}, + value: [][]int32{{5}, {5}, {5}}, }, }, { @@ -521,11 +521,11 @@ func TestSet(t *testing.T) { {{}, {}}, }, va: &Variant{ - EncodingMask: byte(VariantArrayDimensions | VariantArrayValues | TypeIDInt32), - ArrayLength: 0, - ArrayDimensionsLength: 3, - ArrayDimensions: []int32{3, 2, 0}, - Value: [][][]int32{ + mask: byte(VariantArrayDimensions | VariantArrayValues | TypeIDInt32), + arrayLength: 0, + arrayDimensionsLength: 3, + arrayDimensions: []int32{3, 2, 0}, + value: [][][]int32{ {{}, {}}, {{}, {}}, {{}, {}},