object.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package dbus
  2. import (
  3. "errors"
  4. "strings"
  5. )
  6. // BusObject is the interface of a remote object on which methods can be
  7. // invoked.
  8. type BusObject interface {
  9. Call(method string, flags Flags, args ...interface{}) *Call
  10. Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call
  11. GetProperty(p string) (Variant, error)
  12. Destination() string
  13. Path() ObjectPath
  14. }
  15. // Object represents a remote object on which methods can be invoked.
  16. type Object struct {
  17. conn *Conn
  18. dest string
  19. path ObjectPath
  20. }
  21. // Call calls a method with (*Object).Go and waits for its reply.
  22. func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
  23. return <-o.Go(method, flags, make(chan *Call, 1), args...).Done
  24. }
  25. // Go calls a method with the given arguments asynchronously. It returns a
  26. // Call structure representing this method call. The passed channel will
  27. // return the same value once the call is done. If ch is nil, a new channel
  28. // will be allocated. Otherwise, ch has to be buffered or Go will panic.
  29. //
  30. // If the flags include FlagNoReplyExpected, ch is ignored and a Call structure
  31. // is returned of which only the Err member is valid.
  32. //
  33. // If the method parameter contains a dot ('.'), the part before the last dot
  34. // specifies the interface on which the method is called.
  35. func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
  36. iface := ""
  37. i := strings.LastIndex(method, ".")
  38. if i != -1 {
  39. iface = method[:i]
  40. }
  41. method = method[i+1:]
  42. msg := new(Message)
  43. msg.Type = TypeMethodCall
  44. msg.serial = o.conn.getSerial()
  45. msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected)
  46. msg.Headers = make(map[HeaderField]Variant)
  47. msg.Headers[FieldPath] = MakeVariant(o.path)
  48. msg.Headers[FieldDestination] = MakeVariant(o.dest)
  49. msg.Headers[FieldMember] = MakeVariant(method)
  50. if iface != "" {
  51. msg.Headers[FieldInterface] = MakeVariant(iface)
  52. }
  53. msg.Body = args
  54. if len(args) > 0 {
  55. msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...))
  56. }
  57. if msg.Flags&FlagNoReplyExpected == 0 {
  58. if ch == nil {
  59. ch = make(chan *Call, 10)
  60. } else if cap(ch) == 0 {
  61. panic("dbus: unbuffered channel passed to (*Object).Go")
  62. }
  63. call := &Call{
  64. Destination: o.dest,
  65. Path: o.path,
  66. Method: method,
  67. Args: args,
  68. Done: ch,
  69. }
  70. o.conn.callsLck.Lock()
  71. o.conn.calls[msg.serial] = call
  72. o.conn.callsLck.Unlock()
  73. o.conn.outLck.RLock()
  74. if o.conn.closed {
  75. call.Err = ErrClosed
  76. call.Done <- call
  77. } else {
  78. o.conn.out <- msg
  79. }
  80. o.conn.outLck.RUnlock()
  81. return call
  82. }
  83. o.conn.outLck.RLock()
  84. defer o.conn.outLck.RUnlock()
  85. if o.conn.closed {
  86. return &Call{Err: ErrClosed}
  87. }
  88. o.conn.out <- msg
  89. return &Call{Err: nil}
  90. }
  91. // GetProperty calls org.freedesktop.DBus.Properties.GetProperty on the given
  92. // object. The property name must be given in interface.member notation.
  93. func (o *Object) GetProperty(p string) (Variant, error) {
  94. idx := strings.LastIndex(p, ".")
  95. if idx == -1 || idx+1 == len(p) {
  96. return Variant{}, errors.New("dbus: invalid property " + p)
  97. }
  98. iface := p[:idx]
  99. prop := p[idx+1:]
  100. result := Variant{}
  101. err := o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).Store(&result)
  102. if err != nil {
  103. return Variant{}, err
  104. }
  105. return result, nil
  106. }
  107. // Destination returns the destination that calls on o are sent to.
  108. func (o *Object) Destination() string {
  109. return o.dest
  110. }
  111. // Path returns the path that calls on o are sent to.
  112. func (o *Object) Path() ObjectPath {
  113. return o.path
  114. }