Merge pull request #5039 from CEikermann/patch-1
[vuplus_xbmc] / xbmc / linux / DBusUtil.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 #include "DBusUtil.h"
21 #ifdef HAS_DBUS
22 #include "utils/log.h"
23
24 CVariant CDBusUtil::GetVariant(const char *destination, const char *object, const char *interface, const char *property)
25 {
26 //dbus-send --system --print-reply --dest=destination object org.freedesktop.DBus.Properties.Get string:interface string:property
27   CDBusMessage message(destination, object, "org.freedesktop.DBus.Properties", "Get");
28   CVariant result;
29
30   if (message.AppendArgument(interface) && message.AppendArgument(property))
31   {
32     DBusMessage *reply = message.SendSystem();
33
34     if (reply)
35     {
36       DBusMessageIter iter;
37
38       if (dbus_message_iter_init(reply, &iter))
39       {
40         if (!dbus_message_has_signature(reply, "v"))
41           CLog::Log(LOGERROR, "DBus: wrong signature on Get - should be \"v\" but was %s", dbus_message_iter_get_signature(&iter));
42         else
43           result = ParseVariant(&iter);
44       }
45     }
46   }
47   else
48     CLog::Log(LOGERROR, "DBus: append arguments failed");
49
50   return result;
51 }
52
53 CVariant CDBusUtil::GetAll(const char *destination, const char *object, const char *interface)
54 {
55   CDBusMessage message(destination, object, "org.freedesktop.DBus.Properties", "GetAll");
56   CVariant properties;
57   message.AppendArgument(interface);
58   DBusMessage *reply = message.SendSystem();
59   if (reply)
60   {
61     DBusMessageIter iter;
62     if (dbus_message_iter_init(reply, &iter))
63     {
64       if (!dbus_message_has_signature(reply, "a{sv}"))
65         CLog::Log(LOGERROR, "DBus: wrong signature on GetAll - should be \"a{sv}\" but was %s", dbus_message_iter_get_signature(&iter));
66       else
67       {
68         do
69         {
70           DBusMessageIter sub;
71           dbus_message_iter_recurse(&iter, &sub);
72           do
73           {
74             DBusMessageIter dict;
75             dbus_message_iter_recurse(&sub, &dict);
76             do
77             {
78               const char * key = NULL;
79
80               dbus_message_iter_get_basic(&dict, &key);
81               if (!dbus_message_iter_next(&dict))
82                 break;
83
84               CVariant value = ParseVariant(&dict);
85
86               if (!value.isNull())
87                 properties[key] = value;
88
89             } while (dbus_message_iter_next(&dict));
90
91           } while (dbus_message_iter_next(&sub));
92
93         } while (dbus_message_iter_next(&iter));
94       }
95     }
96   }
97
98   return properties;
99 }
100
101 CVariant CDBusUtil::ParseVariant(DBusMessageIter *itr)
102 {
103   DBusMessageIter variant;
104   dbus_message_iter_recurse(itr, &variant);
105
106   return ParseType(&variant);
107 }
108
109 CVariant CDBusUtil::ParseType(DBusMessageIter *itr)
110 {
111   CVariant value;
112   const char *    string  = NULL;
113   dbus_int32_t    int32   = 0;
114   dbus_uint32_t   uint32  = 0;
115   dbus_int64_t    int64   = 0;
116   dbus_uint64_t   uint64  = 0;
117   dbus_bool_t     boolean = false;
118   double          doublev = 0;
119
120   int type = dbus_message_iter_get_arg_type(itr);
121   switch (type)
122   {
123   case DBUS_TYPE_OBJECT_PATH:
124   case DBUS_TYPE_STRING:
125     dbus_message_iter_get_basic(itr, &string);
126     value = string;
127     break;
128   case DBUS_TYPE_UINT32:
129     dbus_message_iter_get_basic(itr, &uint32);
130     value = (uint64_t)uint32;
131     break;
132   case DBUS_TYPE_BYTE:
133   case DBUS_TYPE_INT32:
134     dbus_message_iter_get_basic(itr, &int32);
135     value = (int64_t)int32;
136     break;
137   case DBUS_TYPE_UINT64:
138     dbus_message_iter_get_basic(itr, &uint64);
139     value = (uint64_t)uint64;
140     break;
141   case DBUS_TYPE_INT64:
142     dbus_message_iter_get_basic(itr, &int64);
143     value = (int64_t)int64;
144     break;
145   case DBUS_TYPE_BOOLEAN:
146     dbus_message_iter_get_basic(itr, &boolean);
147     value = (bool)boolean;
148     break;
149   case DBUS_TYPE_DOUBLE:
150     dbus_message_iter_get_basic(itr, &doublev);
151     value = (double)doublev;
152     break;
153   case DBUS_TYPE_ARRAY:
154     DBusMessageIter array;
155     dbus_message_iter_recurse(itr, &array);
156
157     value = CVariant::VariantTypeArray;
158
159     do
160     {
161       CVariant item = ParseType(&array);
162       if (!item.isNull())
163         value.push_back(item);
164     } while (dbus_message_iter_next(&array));
165     break;
166   }
167
168   return value;
169 }
170 #endif