Skip to content

Commit

Permalink
Change wmi.Unmarshaler interface
Browse files Browse the repository at this point in the history
Looks like having a Decoder instance with a `.Dereferencer` set is
always better that not having it.
  • Loading branch information
yalegko committed Mar 25, 2019
1 parent 88930c5 commit 4a9d139
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 32 deletions.
12 changes: 7 additions & 5 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import (

// Unmarshaler is the interface implemented by types that can unmarshal COM
// object of themselves.
//
// N.B. Unmarshaler currently can't be implemented to non structure types!
type Unmarshaler interface {
UnmarshalOLE(src *ole.IDispatch) error
UnmarshalOLE(d Decoder, src *ole.IDispatch) error
}

// Dereferencer is anything that can fetch WMI objects using its object path.
Expand Down Expand Up @@ -130,7 +132,7 @@ var timeType = reflect.TypeOf(time.Time{})
// Field int
// Field1 int `wmi:"Field"`
// Field2 int `wmi:"Field"`
func (d *Decoder) Unmarshal(src *ole.IDispatch, dst interface{}) (err error) {
func (d Decoder) Unmarshal(src *ole.IDispatch, dst interface{}) (err error) {
defer func() {
// We use lots of reflection, so always be alert!
if r := recover(); r != nil {
Expand All @@ -140,7 +142,7 @@ func (d *Decoder) Unmarshal(src *ole.IDispatch, dst interface{}) (err error) {

// Checks whether the type can handle unmarshalling of himself.
if u, ok := dst.(Unmarshaler); ok {
return u.UnmarshalOLE(src)
return u.UnmarshalOLE(d, src)
}

v := reflect.ValueOf(dst).Elem()
Expand All @@ -160,7 +162,7 @@ func (d *Decoder) Unmarshal(src *ole.IDispatch, dst interface{}) (err error) {
return nil
}

func (d *Decoder) unmarshalField(src *ole.IDispatch, f reflect.Value, fType reflect.StructField) (err error) {
func (d Decoder) unmarshalField(src *ole.IDispatch, f reflect.Value, fType reflect.StructField) (err error) {
fieldName, options := getFieldName(fType)
if !f.CanSet() || fieldName == "-" {
return nil
Expand Down Expand Up @@ -198,7 +200,7 @@ func (d *Decoder) unmarshalField(src *ole.IDispatch, f reflect.Value, fType refl
return d.unmarshalValue(f, prop)
}

func (d *Decoder) unmarshalValue(dst reflect.Value, prop *ole.VARIANT) error {
func (d Decoder) unmarshalValue(dst reflect.Value, prop *ole.VARIANT) error {
isPtr := dst.Kind() == reflect.Ptr
fieldDstOrig := dst
if isPtr { // Create empty object for pointer receiver.
Expand Down
35 changes: 8 additions & 27 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"time"

"github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
)

var (
Expand Down Expand Up @@ -166,40 +165,22 @@ type selfMadeProcess struct {
}

// Example of `wmi.Unmarshaler` interface implementation.
func (p *selfMadeProcess) UnmarshalOLE(src *ole.IDispatch) (err error) {
getProperty := func(name string) (value interface{}, err error) {
prop, err := oleutil.GetProperty(src, name)
if err != nil {
return nil, err
}
return prop.Value(), prop.Clear()
func (p *selfMadeProcess) UnmarshalOLE(d Decoder, src *ole.IDispatch) (err error) {
var dto struct {
Name string
ProcessId uint32
}

val, err := getProperty("ProcessId")
if err != nil {
if err := d.Unmarshal(src, &dto); err != nil {
return err
}
pid, ok := val.(int32)
if !ok {
return fmt.Errorf("incorrect ProcessId type (%T)", val)
}
p.HexPID = fmt.Sprintf("0x%x", pid)

val, err = getProperty("Name")
if err != nil {
return err
}
name, ok := val.(string)
if !ok {
return fmt.Errorf("incorrect Name type (%T)", val)
}
p.CoolProcessName = fmt.Sprintf("-=%s=-", name)
p.HexPID = fmt.Sprintf("0x%x", dto.ProcessId)
p.CoolProcessName = fmt.Sprintf("-=%s=-", dto.Name)
return nil
}

type dumbUnmarshaller struct{}

func (dumbUnmarshaller) UnmarshalOLE(src *ole.IDispatch) error {
func (dumbUnmarshaller) UnmarshalOLE(d Decoder, src *ole.IDispatch) error {
return errors.New("always fail")
}

Expand Down

0 comments on commit 4a9d139

Please sign in to comment.