dbus.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. package dbus
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. )
  8. var (
  9. byteType = reflect.TypeOf(byte(0))
  10. boolType = reflect.TypeOf(false)
  11. uint8Type = reflect.TypeOf(uint8(0))
  12. int16Type = reflect.TypeOf(int16(0))
  13. uint16Type = reflect.TypeOf(uint16(0))
  14. intType = reflect.TypeOf(int(0))
  15. uintType = reflect.TypeOf(uint(0))
  16. int32Type = reflect.TypeOf(int32(0))
  17. uint32Type = reflect.TypeOf(uint32(0))
  18. int64Type = reflect.TypeOf(int64(0))
  19. uint64Type = reflect.TypeOf(uint64(0))
  20. float64Type = reflect.TypeOf(float64(0))
  21. stringType = reflect.TypeOf("")
  22. signatureType = reflect.TypeOf(Signature{""})
  23. objectPathType = reflect.TypeOf(ObjectPath(""))
  24. variantType = reflect.TypeOf(Variant{Signature{""}, nil})
  25. interfacesType = reflect.TypeOf([]interface{}{})
  26. interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
  27. unixFDType = reflect.TypeOf(UnixFD(0))
  28. unixFDIndexType = reflect.TypeOf(UnixFDIndex(0))
  29. )
  30. // An InvalidTypeError signals that a value which cannot be represented in the
  31. // D-Bus wire format was passed to a function.
  32. type InvalidTypeError struct {
  33. Type reflect.Type
  34. }
  35. func (e InvalidTypeError) Error() string {
  36. return "dbus: invalid type " + e.Type.String()
  37. }
  38. // Store copies the values contained in src to dest, which must be a slice of
  39. // pointers. It converts slices of interfaces from src to corresponding structs
  40. // in dest. An error is returned if the lengths of src and dest or the types of
  41. // their elements don't match.
  42. func Store(src []interface{}, dest ...interface{}) error {
  43. if len(src) != len(dest) {
  44. return errors.New("dbus.Store: length mismatch")
  45. }
  46. for i := range src {
  47. if err := storeInterfaces(src[i], dest[i]); err != nil {
  48. return err
  49. }
  50. }
  51. return nil
  52. }
  53. func storeInterfaces(src, dest interface{}) error {
  54. return store(reflect.ValueOf(dest), reflect.ValueOf(src))
  55. }
  56. func store(dest, src reflect.Value) error {
  57. if dest.Kind() == reflect.Ptr {
  58. return store(dest.Elem(), src)
  59. }
  60. switch src.Kind() {
  61. case reflect.Slice:
  62. return storeSlice(dest, src)
  63. case reflect.Map:
  64. return storeMap(dest, src)
  65. default:
  66. return storeBase(dest, src)
  67. }
  68. }
  69. func storeBase(dest, src reflect.Value) error {
  70. return setDest(dest, src)
  71. }
  72. func setDest(dest, src reflect.Value) error {
  73. if !isVariant(src.Type()) && isVariant(dest.Type()) {
  74. //special conversion for dbus.Variant
  75. dest.Set(reflect.ValueOf(MakeVariant(src.Interface())))
  76. return nil
  77. }
  78. if isVariant(src.Type()) && !isVariant(dest.Type()) {
  79. src = getVariantValue(src)
  80. }
  81. if !src.Type().ConvertibleTo(dest.Type()) {
  82. return fmt.Errorf(
  83. "dbus.Store: type mismatch: cannot convert %s to %s",
  84. src.Type(), dest.Type())
  85. }
  86. dest.Set(src.Convert(dest.Type()))
  87. return nil
  88. }
  89. func kindsAreCompatible(dest, src reflect.Type) bool {
  90. switch {
  91. case isVariant(dest):
  92. return true
  93. case dest.Kind() == reflect.Interface:
  94. return true
  95. default:
  96. return dest.Kind() == src.Kind()
  97. }
  98. }
  99. func isConvertibleTo(dest, src reflect.Type) bool {
  100. switch {
  101. case isVariant(dest):
  102. return true
  103. case dest.Kind() == reflect.Interface:
  104. return true
  105. case dest.Kind() == reflect.Slice:
  106. return src.Kind() == reflect.Slice &&
  107. isConvertibleTo(dest.Elem(), src.Elem())
  108. case dest.Kind() == reflect.Struct:
  109. return src == interfacesType
  110. default:
  111. return src.ConvertibleTo(dest)
  112. }
  113. }
  114. func storeMap(dest, src reflect.Value) error {
  115. switch {
  116. case !kindsAreCompatible(dest.Type(), src.Type()):
  117. return fmt.Errorf(
  118. "dbus.Store: type mismatch: "+
  119. "map: cannot store a value of %s into %s",
  120. src.Type(), dest.Type())
  121. case isVariant(dest.Type()):
  122. return storeMapIntoVariant(dest, src)
  123. case dest.Kind() == reflect.Interface:
  124. return storeMapIntoInterface(dest, src)
  125. case isConvertibleTo(dest.Type().Key(), src.Type().Key()) &&
  126. isConvertibleTo(dest.Type().Elem(), src.Type().Elem()):
  127. return storeMapIntoMap(dest, src)
  128. default:
  129. return fmt.Errorf(
  130. "dbus.Store: type mismatch: "+
  131. "map: cannot convert a value of %s into %s",
  132. src.Type(), dest.Type())
  133. }
  134. }
  135. func storeMapIntoVariant(dest, src reflect.Value) error {
  136. dv := reflect.MakeMap(src.Type())
  137. err := store(dv, src)
  138. if err != nil {
  139. return err
  140. }
  141. return storeBase(dest, dv)
  142. }
  143. func storeMapIntoInterface(dest, src reflect.Value) error {
  144. var dv reflect.Value
  145. if isVariant(src.Type().Elem()) {
  146. //Convert variants to interface{} recursively when converting
  147. //to interface{}
  148. dv = reflect.MakeMap(
  149. reflect.MapOf(src.Type().Key(), interfaceType))
  150. } else {
  151. dv = reflect.MakeMap(src.Type())
  152. }
  153. err := store(dv, src)
  154. if err != nil {
  155. return err
  156. }
  157. return storeBase(dest, dv)
  158. }
  159. func storeMapIntoMap(dest, src reflect.Value) error {
  160. if dest.IsNil() {
  161. dest.Set(reflect.MakeMap(dest.Type()))
  162. }
  163. keys := src.MapKeys()
  164. for _, key := range keys {
  165. dkey := key.Convert(dest.Type().Key())
  166. dval := reflect.New(dest.Type().Elem()).Elem()
  167. err := store(dval, getVariantValue(src.MapIndex(key)))
  168. if err != nil {
  169. return err
  170. }
  171. dest.SetMapIndex(dkey, dval)
  172. }
  173. return nil
  174. }
  175. func storeSlice(dest, src reflect.Value) error {
  176. switch {
  177. case src.Type() == interfacesType && dest.Kind() == reflect.Struct:
  178. //The decoder always decodes structs as slices of interface{}
  179. return storeStruct(dest, src)
  180. case !kindsAreCompatible(dest.Type(), src.Type()):
  181. return fmt.Errorf(
  182. "dbus.Store: type mismatch: "+
  183. "slice: cannot store a value of %s into %s",
  184. src.Type(), dest.Type())
  185. case isVariant(dest.Type()):
  186. return storeSliceIntoVariant(dest, src)
  187. case dest.Kind() == reflect.Interface:
  188. return storeSliceIntoInterface(dest, src)
  189. case isConvertibleTo(dest.Type().Elem(), src.Type().Elem()):
  190. return storeSliceIntoSlice(dest, src)
  191. default:
  192. return fmt.Errorf(
  193. "dbus.Store: type mismatch: "+
  194. "slice: cannot convert a value of %s into %s",
  195. src.Type(), dest.Type())
  196. }
  197. }
  198. func storeStruct(dest, src reflect.Value) error {
  199. if isVariant(dest.Type()) {
  200. return storeBase(dest, src)
  201. }
  202. dval := make([]interface{}, 0, dest.NumField())
  203. dtype := dest.Type()
  204. for i := 0; i < dest.NumField(); i++ {
  205. field := dest.Field(i)
  206. ftype := dtype.Field(i)
  207. if ftype.PkgPath != "" {
  208. continue
  209. }
  210. if ftype.Tag.Get("dbus") == "-" {
  211. continue
  212. }
  213. dval = append(dval, field.Addr().Interface())
  214. }
  215. if src.Len() != len(dval) {
  216. return fmt.Errorf(
  217. "dbus.Store: type mismatch: "+
  218. "destination struct does not have "+
  219. "enough fields need: %d have: %d",
  220. src.Len(), len(dval))
  221. }
  222. return Store(src.Interface().([]interface{}), dval...)
  223. }
  224. func storeSliceIntoVariant(dest, src reflect.Value) error {
  225. dv := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
  226. err := store(dv, src)
  227. if err != nil {
  228. return err
  229. }
  230. return storeBase(dest, dv)
  231. }
  232. func storeSliceIntoInterface(dest, src reflect.Value) error {
  233. var dv reflect.Value
  234. if isVariant(src.Type().Elem()) {
  235. //Convert variants to interface{} recursively when converting
  236. //to interface{}
  237. dv = reflect.MakeSlice(reflect.SliceOf(interfaceType),
  238. src.Len(), src.Cap())
  239. } else {
  240. dv = reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
  241. }
  242. err := store(dv, src)
  243. if err != nil {
  244. return err
  245. }
  246. return storeBase(dest, dv)
  247. }
  248. func storeSliceIntoSlice(dest, src reflect.Value) error {
  249. if dest.IsNil() || dest.Len() < src.Len() {
  250. dest.Set(reflect.MakeSlice(dest.Type(), src.Len(), src.Cap()))
  251. }
  252. if dest.Len() != src.Len() {
  253. return fmt.Errorf(
  254. "dbus.Store: type mismatch: "+
  255. "slices are different lengths "+
  256. "need: %d have: %d",
  257. src.Len(), dest.Len())
  258. }
  259. for i := 0; i < src.Len(); i++ {
  260. err := store(dest.Index(i), getVariantValue(src.Index(i)))
  261. if err != nil {
  262. return err
  263. }
  264. }
  265. return nil
  266. }
  267. func getVariantValue(in reflect.Value) reflect.Value {
  268. if isVariant(in.Type()) {
  269. return reflect.ValueOf(in.Interface().(Variant).Value())
  270. }
  271. return in
  272. }
  273. func isVariant(t reflect.Type) bool {
  274. return t == variantType
  275. }
  276. // An ObjectPath is an object path as defined by the D-Bus spec.
  277. type ObjectPath string
  278. // IsValid returns whether the object path is valid.
  279. func (o ObjectPath) IsValid() bool {
  280. s := string(o)
  281. if len(s) == 0 {
  282. return false
  283. }
  284. if s[0] != '/' {
  285. return false
  286. }
  287. if s[len(s)-1] == '/' && len(s) != 1 {
  288. return false
  289. }
  290. // probably not used, but technically possible
  291. if s == "/" {
  292. return true
  293. }
  294. split := strings.Split(s[1:], "/")
  295. for _, v := range split {
  296. if len(v) == 0 {
  297. return false
  298. }
  299. for _, c := range v {
  300. if !isMemberChar(c) {
  301. return false
  302. }
  303. }
  304. }
  305. return true
  306. }
  307. // A UnixFD is a Unix file descriptor sent over the wire. See the package-level
  308. // documentation for more information about Unix file descriptor passsing.
  309. type UnixFD int32
  310. // A UnixFDIndex is the representation of a Unix file descriptor in a message.
  311. type UnixFDIndex uint32
  312. // alignment returns the alignment of values of type t.
  313. func alignment(t reflect.Type) int {
  314. switch t {
  315. case variantType:
  316. return 1
  317. case objectPathType:
  318. return 4
  319. case signatureType:
  320. return 1
  321. case interfacesType:
  322. return 4
  323. }
  324. switch t.Kind() {
  325. case reflect.Uint8:
  326. return 1
  327. case reflect.Uint16, reflect.Int16:
  328. return 2
  329. case reflect.Uint, reflect.Int, reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice, reflect.Map:
  330. return 4
  331. case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
  332. return 8
  333. case reflect.Ptr:
  334. return alignment(t.Elem())
  335. }
  336. return 1
  337. }
  338. // isKeyType returns whether t is a valid type for a D-Bus dict.
  339. func isKeyType(t reflect.Type) bool {
  340. switch t.Kind() {
  341. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
  342. reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64,
  343. reflect.String, reflect.Uint, reflect.Int:
  344. return true
  345. }
  346. return false
  347. }
  348. // isValidInterface returns whether s is a valid name for an interface.
  349. func isValidInterface(s string) bool {
  350. if len(s) == 0 || len(s) > 255 || s[0] == '.' {
  351. return false
  352. }
  353. elem := strings.Split(s, ".")
  354. if len(elem) < 2 {
  355. return false
  356. }
  357. for _, v := range elem {
  358. if len(v) == 0 {
  359. return false
  360. }
  361. if v[0] >= '0' && v[0] <= '9' {
  362. return false
  363. }
  364. for _, c := range v {
  365. if !isMemberChar(c) {
  366. return false
  367. }
  368. }
  369. }
  370. return true
  371. }
  372. // isValidMember returns whether s is a valid name for a member.
  373. func isValidMember(s string) bool {
  374. if len(s) == 0 || len(s) > 255 {
  375. return false
  376. }
  377. i := strings.Index(s, ".")
  378. if i != -1 {
  379. return false
  380. }
  381. if s[0] >= '0' && s[0] <= '9' {
  382. return false
  383. }
  384. for _, c := range s {
  385. if !isMemberChar(c) {
  386. return false
  387. }
  388. }
  389. return true
  390. }
  391. func isMemberChar(c rune) bool {
  392. return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
  393. (c >= 'a' && c <= 'z') || c == '_'
  394. }