Skip to content

Commit

Permalink
refactor: extract readToSlice and readToStruct method
Browse files Browse the repository at this point in the history
Signed-off-by: ZhangJian He <shoothzj@gmail.com>
  • Loading branch information
shoothzj committed Oct 28, 2024
1 parent 2ff8b0f commit eea5542
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 58 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ go 1.20

require (
github.com/libgox/addr v0.2.0
github.com/libgox/buffer v0.0.0-20241015042438-2a8f016fc865
github.com/libgox/gocollections v0.0.0-20241015042445-f5331b9e5556
github.com/libgox/buffer v0.0.0-20241024142853-0102c7922ab2
github.com/libgox/gocollections v0.0.0-20241024144716-59fe0afe6953

Check warning on line 8 in go.mod

View workflow job for this annotation

GitHub Actions / typo check

"afe" should be "safe".
github.com/stretchr/testify v1.9.0
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948
)
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/libgox/addr v0.2.0 h1:he4Vv7lzcGy/1qNpjJufEWRql0S23Ki/j0XpTDMDu3s=
github.com/libgox/addr v0.2.0/go.mod h1:j0hEfpRqTZy4BsstS9Egsn1U0JmNdj/VkbF2VBmJlFw=
github.com/libgox/buffer v0.0.0-20241015042438-2a8f016fc865 h1:Qk14CPqIuf6+geOE6NmItHg9gtgmP91ir9tWS5d1b2E=
github.com/libgox/buffer v0.0.0-20241015042438-2a8f016fc865/go.mod h1:VAuNNs9Mp5NttnP8etLB4FI4ZZ67sRUnk/jTb/BnSqo=
github.com/libgox/gocollections v0.0.0-20241015042445-f5331b9e5556 h1:NbndOXKVReG/ex7tV6p/CMNNC+QWOtjrkzH3w89u/EI=
github.com/libgox/gocollections v0.0.0-20241015042445-f5331b9e5556/go.mod h1:Y4udpR8lStv1f67hVWbMCrcTyTvf98bFFsu/ZXvAvZ0=
github.com/libgox/buffer v0.0.0-20241024142853-0102c7922ab2 h1:L12VlOPRQ5qMkD8H2swxYhUir+MBkbo9CKZdNfY5QdQ=
github.com/libgox/buffer v0.0.0-20241024142853-0102c7922ab2/go.mod h1:VAuNNs9Mp5NttnP8etLB4FI4ZZ67sRUnk/jTb/BnSqo=
github.com/libgox/gocollections v0.0.0-20241024144716-59fe0afe6953 h1:qnlK5i5xCbMjQLqFa6JfNn3r7mtRMwMtuqJjyhgAYK8=
github.com/libgox/gocollections v0.0.0-20241024144716-59fe0afe6953/go.mod h1:Y4udpR8lStv1f67hVWbMCrcTyTvf98bFFsu/ZXvAvZ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
Expand Down
1 change: 0 additions & 1 deletion opcua/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (

"github.com/libgox/addr"
"github.com/libgox/buffer"

"github.com/protocol-laboratory/opcua-go/opcua/ua"
)

Expand Down
120 changes: 69 additions & 51 deletions opcua/enc/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func (d *bufferedDecoder) fillMessageBody(msg *uamsg.Message) error {
return err
}
messageBody.Service = service
case uamsg.ObjectCreateSessionResponse_Encoding_DefaultBinary:
case uamsg.ObjectCreateSessionResponse_Encoding_DefaultBinary.Identifier:

Check warning on line 190 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L190

Added line #L190 was not covered by tests
service := &uamsg.CreateSessionResponse{}
err = d.readTo(reflect.ValueOf(service).Elem())
if err != nil {
Expand All @@ -214,6 +214,12 @@ func (d *bufferedDecoder) readTo(value reflect.Value) error {
return err
}
value.SetUint(uint64(dataByte))
case reflect.Uint16:
b, err := d.r.readN(2)
if err != nil {
return err
}
value.SetUint(uint64(binary.LittleEndian.Uint16(b)))

Check warning on line 222 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L217-L222

Added lines #L217 - L222 were not covered by tests
case reflect.Uint32:
b, err := d.r.readN(4)
if err != nil {
Expand Down Expand Up @@ -265,75 +271,87 @@ func (d *bufferedDecoder) readTo(value reflect.Value) error {
}
value.SetString(string(b))
case reflect.Slice:
b, err := d.r.readN(4)
err, done := d.readToSlice(value, valueType)
if done {
return err
}
case reflect.Ptr, reflect.Interface:
if value.IsNil() {
return errors.New("ptr or interface{} variant can not be nil")
}
err := d.readTo(value.Elem())
if err != nil {
return err
}

Check warning on line 285 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L274-L285

Added lines #L274 - L285 were not covered by tests
case reflect.Struct:
err := readToStruct(value, valueType, d)
if err != nil {
return err
}
sliceLen := int32(binary.LittleEndian.Uint32(b))
default:
return errors.New("unsupported type")

Check warning on line 292 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L291-L292

Added lines #L291 - L292 were not covered by tests
}

if sliceLen == -1 {
return nil
return nil
}

func (d *bufferedDecoder) readToSlice(value reflect.Value, valueType reflect.Type) (error, bool) {
b, err := d.r.readN(4)
if err != nil {
return err, true
}
sliceLen := int32(binary.LittleEndian.Uint32(b))

if sliceLen == -1 {
return nil, true
}

Check warning on line 307 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L298-L307

Added lines #L298 - L307 were not covered by tests

sliceValue := reflect.MakeSlice(valueType, int(sliceLen), int(sliceLen))
for i := 0; i < sliceValue.Len(); i++ {
if valueType.Elem().Kind() == reflect.Ptr {
structPtr := reflect.New(valueType.Elem().Elem())
err = d.readTo(structPtr.Elem())
if err != nil {
return err, true
}
sliceValue.Index(i).Set(structPtr)
} else {
// simple slice, like []uint32
err = d.readTo(sliceValue.Index(i))
if err != nil {
return err, true
}

Check warning on line 323 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L309-L323

Added lines #L309 - L323 were not covered by tests
}
}
value.Set(sliceValue)
return nil, false

Check warning on line 327 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L326-L327

Added lines #L326 - L327 were not covered by tests
}

sliceValue := reflect.MakeSlice(valueType, int(sliceLen), int(sliceLen))
for i := 0; i < sliceValue.Len(); i++ {
if valueType.Elem().Kind() == reflect.Ptr {
// valueType = []*MyStruct
// valueType.Elem() = *MyStruct
// valueType.Elem().Elem() = MyStruct,
structPtr := reflect.New(valueType.Elem().Elem())
err = d.readTo(structPtr.Elem())
func readToStruct(value reflect.Value, valueType reflect.Type, d *bufferedDecoder) error {
decoder, ok := SpecialStructDecoderMap[value.Type().Name()]
if !ok {
// recursively construct all members
for i := 0; i < value.NumField(); i++ {
if value.Field(i).Kind() == reflect.Ptr && value.Field(i).IsNil() {
structPtr := reflect.New(valueType.Field(i).Type.Elem())
err := d.readTo(structPtr.Elem())

Check warning on line 337 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L336-L337

Added lines #L336 - L337 were not covered by tests
if err != nil {
return err
}
sliceValue.Index(i).Set(structPtr)
value.Field(i).Set(structPtr)

Check warning on line 341 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L341

Added line #L341 was not covered by tests
} else {
// simple slice, like []uint32
err = d.readTo(sliceValue.Index(i))
err := d.readTo(value.Field(i))
if err != nil {
return err
}
}
}
value.Set(sliceValue)
case reflect.Ptr, reflect.Interface:
if value.IsNil() {
return errors.New("ptr or interface{} variant can not be nil")
}
err := d.readTo(value.Elem())
} else {
err := decoder(d.r, value)

Check warning on line 350 in opcua/enc/decoder.go

View check run for this annotation

Codecov / codecov/patch

opcua/enc/decoder.go#L349-L350

Added lines #L349 - L350 were not covered by tests
if err != nil {
return err
}
case reflect.Struct:
decoder, ok := SpecialStructDecoderMap[value.Type().Name()]
if !ok {
// recursively construct all members
for i := 0; i < value.NumField(); i++ {
if value.Field(i).Kind() == reflect.Ptr && value.Field(i).IsNil() {
structPtr := reflect.New(valueType.Field(i).Type.Elem())
err := d.readTo(structPtr.Elem())
if err != nil {
return err
}
value.Field(i).Set(structPtr)
} else {
err := d.readTo(value.Field(i))
if err != nil {
return err
}
}
}
} else {
err := decoder(d.r, value)
if err != nil {
return err
}
}

default:
return errors.New("unsupported type")
}

return nil
}

Expand Down

0 comments on commit eea5542

Please sign in to comment.