diff --git a/decoder.go b/decoder.go index 881f0d5..7f64db0 100644 --- a/decoder.go +++ b/decoder.go @@ -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. @@ -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 { @@ -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() @@ -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 @@ -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. diff --git a/decoder_test.go b/decoder_test.go index bbd9f5c..3bac37f 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -10,7 +10,6 @@ import ( "time" "github.com/go-ole/go-ole" - "github.com/go-ole/go-ole/oleutil" ) var ( @@ -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") }