dbus.go 11 KB

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