~ubuntu-branches/ubuntu/precise/rhythmbox/precise-201203091205

« back to all changes in this revision

Viewing changes to metadata/rb-metadata-dbus.c

Tags: upstream-0.9.5
ImportĀ upstreamĀ versionĀ 0.9.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2006 Jonathan Matthew <jonathan@kaolin.hn.org>
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
17
 *
 
18
 */
 
19
 
 
20
/*
 
21
 * Common junk for the out-of-process metadata reader.
 
22
 */
 
23
 
 
24
#include <config.h>
 
25
#include <glib.h>
 
26
 
 
27
#include "rb-metadata.h"
 
28
#include "rb-metadata-dbus.h"
 
29
#include "rb-debug.h"
 
30
 
 
31
static gboolean
 
32
_get_basic_checked (DBusMessageIter *iter, gpointer value, int type)
 
33
{
 
34
        if (dbus_message_iter_get_arg_type (iter) != type) {
 
35
                rb_debug ("Expected D-BUS type '%c', got '%c'",
 
36
                          type, dbus_message_iter_get_arg_type (iter));
 
37
                return FALSE;
 
38
        }
 
39
        dbus_message_iter_get_basic (iter, value);
 
40
        dbus_message_iter_next (iter);
 
41
        return TRUE;
 
42
}
 
43
 
 
44
gboolean 
 
45
rb_metadata_dbus_get_boolean (DBusMessageIter *iter, gboolean *value)
 
46
{
 
47
        return _get_basic_checked (iter, value, DBUS_TYPE_BOOLEAN);
 
48
}
 
49
 
 
50
gboolean
 
51
rb_metadata_dbus_get_uint32 (DBusMessageIter *iter, guint32 *value)
 
52
{
 
53
        return _get_basic_checked (iter, value, DBUS_TYPE_UINT32);
 
54
}
 
55
 
 
56
 
 
57
gboolean 
 
58
rb_metadata_dbus_get_string (DBusMessageIter *iter, gchar **value)
 
59
{
 
60
        gchar *msg_value;
 
61
        if (!_get_basic_checked (iter, &msg_value, DBUS_TYPE_STRING))
 
62
                return FALSE;
 
63
        *value = g_strdup (msg_value);
 
64
        return TRUE;
 
65
}
 
66
 
 
67
gboolean 
 
68
rb_metadata_dbus_add_to_message (RBMetaData *md, DBusMessageIter *iter)
 
69
{
 
70
        DBusMessageIter a_iter;
 
71
        RBMetaDataField field;
 
72
        const char *etype = 
 
73
                DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 
 
74
                        DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 
 
75
                DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
 
76
        rb_debug ("opening container type %s", etype);
 
77
        if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, etype, &a_iter)) {
 
78
                return FALSE;
 
79
        }
 
80
 
 
81
        for (field = RB_METADATA_FIELD_TITLE; field < RB_METADATA_FIELD_LAST; field++) {
 
82
                GType vtype = rb_metadata_get_field_type (field);
 
83
                GValue v = {0,};
 
84
                DBusMessageIter d_iter;
 
85
                DBusMessageIter v_iter;
 
86
                const char *v_sig = NULL;
 
87
                
 
88
                if (!rb_metadata_get (md, field, &v))
 
89
                        continue;
 
90
 
 
91
                if (!dbus_message_iter_open_container (&a_iter, DBUS_TYPE_DICT_ENTRY, NULL, &d_iter)) {
 
92
                        return FALSE;
 
93
                }
 
94
 
 
95
                if (!dbus_message_iter_append_basic (&d_iter, DBUS_TYPE_UINT32, &field)) {
 
96
                        return FALSE;
 
97
                }
 
98
 
 
99
                switch (vtype) {
 
100
                case G_TYPE_ULONG:
 
101
                        v_sig = DBUS_TYPE_UINT32_AS_STRING;
 
102
                        break;
 
103
                case G_TYPE_DOUBLE:
 
104
                        v_sig = DBUS_TYPE_DOUBLE_AS_STRING;
 
105
                        break;
 
106
                case G_TYPE_STRING:
 
107
                        v_sig = DBUS_TYPE_STRING_AS_STRING;
 
108
                        break;
 
109
                }
 
110
                if (!dbus_message_iter_open_container (&d_iter, DBUS_TYPE_VARIANT, v_sig, &v_iter)) {
 
111
                        return FALSE;
 
112
                }
 
113
 
 
114
                /* not exactly stolen from dbus-gvalue.c */
 
115
                switch (vtype) {
 
116
                case G_TYPE_ULONG:
 
117
                        {
 
118
                                dbus_uint32_t n = g_value_get_ulong (&v);
 
119
                                if (!dbus_message_iter_append_basic (&v_iter, DBUS_TYPE_UINT32, &n)) {
 
120
                                        return FALSE;
 
121
                                }
 
122
                                break;
 
123
                        }
 
124
 
 
125
                case G_TYPE_DOUBLE:
 
126
                        {
 
127
                                double n = g_value_get_double (&v);
 
128
                                if (!dbus_message_iter_append_basic (&v_iter, DBUS_TYPE_DOUBLE, &n)) {
 
129
                                        return FALSE;
 
130
                                }
 
131
                                break;
 
132
                        }
 
133
 
 
134
                case G_TYPE_STRING:
 
135
                        {
 
136
                                const char *s = g_value_get_string (&v);
 
137
                                if (!s)
 
138
                                        s = "";
 
139
                                if (!dbus_message_iter_append_basic (&v_iter, DBUS_TYPE_STRING, &s)) {
 
140
                                        return FALSE;
 
141
                                }
 
142
                                break;
 
143
                        }
 
144
 
 
145
                default:
 
146
                        g_assert_not_reached ();
 
147
                        break;
 
148
                }
 
149
 
 
150
                g_value_unset (&v);
 
151
                if (!dbus_message_iter_close_container (&d_iter, &v_iter)) {
 
152
                        return FALSE;
 
153
                }
 
154
 
 
155
                if (!dbus_message_iter_close_container (&a_iter, &d_iter)) {
 
156
                        return FALSE;
 
157
                }
 
158
        }
 
159
        
 
160
        if (!dbus_message_iter_close_container (iter, &a_iter)) {
 
161
                return FALSE;
 
162
        }
 
163
 
 
164
        return TRUE;
 
165
}
 
166
 
 
167
gboolean 
 
168
rb_metadata_dbus_read_from_message (RBMetaData *md, GHashTable *metadata, DBusMessageIter *iter)
 
169
{
 
170
        DBusMessageIter a_iter;
 
171
        int current_type;
 
172
        
 
173
        if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_ARRAY) {
 
174
                rb_debug ("Expected D-BUS array, got type '%c'",
 
175
                          dbus_message_iter_get_arg_type (iter));
 
176
                return FALSE;
 
177
        }
 
178
 
 
179
        dbus_message_iter_recurse (iter, &a_iter);
 
180
        
 
181
        current_type = dbus_message_iter_get_arg_type (&a_iter);
 
182
        if (current_type != DBUS_TYPE_INVALID && current_type != DBUS_TYPE_DICT_ENTRY) {
 
183
                rb_debug ("Expected D-BUS dict entry, got type '%c'", (guchar) current_type);
 
184
                return FALSE;
 
185
        }
 
186
 
 
187
        while (current_type != DBUS_TYPE_INVALID) {
 
188
                DBusMessageIter e_iter;
 
189
                DBusMessageIter v_iter;
 
190
                RBMetaDataField field;
 
191
                GValue *val;
 
192
 
 
193
                dbus_message_iter_recurse (&a_iter, &e_iter);
 
194
 
 
195
                if (!rb_metadata_dbus_get_uint32 (&e_iter, &field)) {
 
196
                        return FALSE;
 
197
                }
 
198
 
 
199
                if (dbus_message_iter_get_arg_type (&e_iter) != DBUS_TYPE_VARIANT) {
 
200
                        rb_debug ("Expected D-BUS variant type for value; got type '%c'",
 
201
                                  dbus_message_iter_get_arg_type (&e_iter));
 
202
                        return FALSE;
 
203
                }
 
204
 
 
205
                dbus_message_iter_recurse (&e_iter, &v_iter);
 
206
                val = g_new0 (GValue, 1);
 
207
                switch (dbus_message_iter_get_arg_type (&v_iter)) {
 
208
                case DBUS_TYPE_UINT32:
 
209
                        {
 
210
                                dbus_uint32_t n;
 
211
                                dbus_message_iter_get_basic (&v_iter, &n);
 
212
                                g_value_init (val, G_TYPE_ULONG);
 
213
                                g_value_set_ulong (val, n);
 
214
                                break;
 
215
                        }
 
216
 
 
217
                case DBUS_TYPE_DOUBLE:
 
218
                        {
 
219
                                double n;
 
220
                                dbus_message_iter_get_basic (&v_iter, &n);
 
221
                                g_value_init (val, G_TYPE_DOUBLE);
 
222
                                g_value_set_double (val, n);
 
223
                                break;
 
224
                        }
 
225
 
 
226
                case DBUS_TYPE_STRING:
 
227
                        {
 
228
                                const gchar *n;
 
229
                                dbus_message_iter_get_basic (&v_iter, &n);
 
230
                                g_value_init (val, G_TYPE_STRING);
 
231
                                g_value_set_string (val, n);
 
232
                                break;
 
233
                        }
 
234
 
 
235
                default:
 
236
                        g_assert_not_reached ();
 
237
                        break;
 
238
                }
 
239
 
 
240
                g_hash_table_insert (metadata, GINT_TO_POINTER (field), val);
 
241
                
 
242
                dbus_message_iter_next (&a_iter);
 
243
                current_type = dbus_message_iter_get_arg_type (&a_iter);
 
244
        }
 
245
 
 
246
        return TRUE;
 
247
}
 
248