78 lines
2.2 KiB
Go
78 lines
2.2 KiB
Go
|
package introspect
|
||
|
|
||
|
import (
|
||
|
"encoding/xml"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/godbus/dbus/v5"
|
||
|
)
|
||
|
|
||
|
// Introspectable implements org.freedesktop.Introspectable.
|
||
|
//
|
||
|
// You can create it by converting the XML-formatted introspection data from a
|
||
|
// string to an Introspectable or call NewIntrospectable with a Node. Then,
|
||
|
// export it as org.freedesktop.Introspectable on you object.
|
||
|
type Introspectable string
|
||
|
|
||
|
// NewIntrospectable returns an Introspectable that returns the introspection
|
||
|
// data that corresponds to the given Node. If n.Interfaces doesn't contain the
|
||
|
// data for org.freedesktop.DBus.Introspectable, it is added automatically.
|
||
|
func NewIntrospectable(n *Node) Introspectable {
|
||
|
found := false
|
||
|
for _, v := range n.Interfaces {
|
||
|
if v.Name == "org.freedesktop.DBus.Introspectable" {
|
||
|
found = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !found {
|
||
|
n.Interfaces = append(n.Interfaces, IntrospectData)
|
||
|
}
|
||
|
b, err := xml.Marshal(n)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return Introspectable(strings.TrimSpace(IntrospectDeclarationString) + string(b))
|
||
|
}
|
||
|
|
||
|
// Introspect implements org.freedesktop.Introspectable.Introspect.
|
||
|
func (i Introspectable) Introspect() (string, *dbus.Error) {
|
||
|
return string(i), nil
|
||
|
}
|
||
|
|
||
|
// Methods returns the description of the methods of v. This can be used to
|
||
|
// create a Node which can be passed to NewIntrospectable.
|
||
|
func Methods(v interface{}) []Method {
|
||
|
t := reflect.TypeOf(v)
|
||
|
ms := make([]Method, 0, t.NumMethod())
|
||
|
for i := 0; i < t.NumMethod(); i++ {
|
||
|
if t.Method(i).PkgPath != "" {
|
||
|
continue
|
||
|
}
|
||
|
mt := t.Method(i).Type
|
||
|
if mt.NumOut() == 0 ||
|
||
|
mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{}) {
|
||
|
|
||
|
continue
|
||
|
}
|
||
|
var m Method
|
||
|
m.Name = t.Method(i).Name
|
||
|
m.Args = make([]Arg, 0, mt.NumIn()+mt.NumOut()-2)
|
||
|
for j := 1; j < mt.NumIn(); j++ {
|
||
|
if mt.In(j) != reflect.TypeOf((*dbus.Sender)(nil)).Elem() &&
|
||
|
mt.In(j) != reflect.TypeOf((*dbus.Message)(nil)).Elem() {
|
||
|
arg := Arg{"", dbus.SignatureOfType(mt.In(j)).String(), "in"}
|
||
|
m.Args = append(m.Args, arg)
|
||
|
}
|
||
|
}
|
||
|
for j := 0; j < mt.NumOut()-1; j++ {
|
||
|
arg := Arg{"", dbus.SignatureOfType(mt.Out(j)).String(), "out"}
|
||
|
m.Args = append(m.Args, arg)
|
||
|
}
|
||
|
m.Annotations = make([]Annotation, 0)
|
||
|
ms = append(ms, m)
|
||
|
}
|
||
|
return ms
|
||
|
}
|