D-Bus 1.13.18

dbus-asv-util.c
1 /* dbus-asv-util.c - utility functions for a{sv}
2 *
3 * Copyright © 2011-2012 Nokia Corporation
4 * Copyright © 2012-2013 Collabora Ltd.
5 *
6 * Licensed under the Academic Free License version 2.1
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24 #include <config.h>
25
26 #include <dbus/dbus.h>
27
28 #include "dbus/dbus-asv-util.h"
29
45 DBusMessage *
46 _dbus_asv_new_method_return (DBusMessage *message,
47 DBusMessageIter *iter,
48 DBusMessageIter *arr_iter)
49 {
50 DBusMessage *reply = dbus_message_new_method_return (message);
51
52 if (reply == NULL)
53 return NULL;
54
55 dbus_message_iter_init_append (reply, iter);
56
57 if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}",
58 arr_iter))
59 {
60 dbus_message_unref (reply);
61 return NULL;
62 }
63
64 return reply;
65 }
66
67 /*
68 * Open a new entry in an a{sv} (map from string to variant).
69 *
70 * This must be paired with a call to either _dbus_asv_close_entry()
71 * or _dbus_asv_abandon_entry().
72 *
73 * If this function fails, the a{sv} must be abandoned, for instance
74 * with _dbus_asv_abandon().
75 *
76 * @param arr_iter the iterator which is appending to the array
77 * @param entry_iter will be initialized to append to the dict-entry
78 * @param key a UTF-8 key for the map
79 * @param type the type of the variant value, e.g. DBUS_TYPE_STRING_AS_STRING
80 * @param var_iter will be initialized to append (i.e. write) to the variant
81 * @returns #TRUE on success, or #FALSE if not enough memory
82 */
83 dbus_bool_t
84 _dbus_asv_open_entry (DBusMessageIter *arr_iter,
85 DBusMessageIter *entry_iter,
86 const char *key,
87 const char *type,
88 DBusMessageIter *var_iter)
89 {
90 if (!dbus_message_iter_open_container (arr_iter, DBUS_TYPE_DICT_ENTRY,
91 NULL, entry_iter))
92 return FALSE;
93
94 if (!dbus_message_iter_append_basic (entry_iter, DBUS_TYPE_STRING, &key))
95 {
96 dbus_message_iter_abandon_container (arr_iter, entry_iter);
97 return FALSE;
98 }
99
100 if (!dbus_message_iter_open_container (entry_iter, DBUS_TYPE_VARIANT,
101 type, var_iter))
102 {
103 dbus_message_iter_abandon_container (arr_iter, entry_iter);
104 return FALSE;
105 }
106
107 return TRUE;
108 }
109
110 /*
111 * Closes an a{sv} entry after successfully appending the value.
112 *
113 * If this function fails, the a{sv} must be abandoned, for instance
114 * with _dbus_asv_abandon().
115 *
116 * @param arr_iter the iterator which is appending to the array
117 * @param entry_iter the iterator appending to the dict-entry, will be closed
118 * @param var_iter the iterator appending to the variant, will be closed
119 * @returns #TRUE on success, or #FALSE if not enough memory
120 */
121 dbus_bool_t
122 _dbus_asv_close_entry (DBusMessageIter *arr_iter,
123 DBusMessageIter *entry_iter,
124 DBusMessageIter *var_iter)
125 {
126 if (!dbus_message_iter_close_container (entry_iter, var_iter))
127 {
128 dbus_message_iter_abandon_container (arr_iter, entry_iter);
129 return FALSE;
130 }
131
132 if (!dbus_message_iter_close_container (arr_iter, entry_iter))
133 return FALSE;
134
135 return TRUE;
136 }
137
148 dbus_bool_t
149 _dbus_asv_close (DBusMessageIter *iter,
150 DBusMessageIter *arr_iter)
151 {
152 return dbus_message_iter_close_container (iter, arr_iter);
153 }
154
155 /*
156 * Closes an a{sv} entry after unsuccessfully appending a value.
157 * You must also abandon the a{sv} itself (for instance with
158 * _dbus_asv_abandon()), and abandon whatever larger data structure
159 * the a{sv} was embedded in.
160 *
161 * @param iter the iterator which is appending to the message or other data structure containing the a{sv}
162 * @param arr_iter the iterator appending to the array, will be closed
163 * @returns #TRUE on success, or #FALSE if not enough memory
164 */
165 void
166 _dbus_asv_abandon_entry (DBusMessageIter *arr_iter,
167 DBusMessageIter *entry_iter,
168 DBusMessageIter *var_iter)
169 {
170 dbus_message_iter_abandon_container (entry_iter, var_iter);
171 dbus_message_iter_abandon_container (arr_iter, entry_iter);
172 }
173
183 void
184 _dbus_asv_abandon (DBusMessageIter *iter,
185 DBusMessageIter *arr_iter)
186 {
187 dbus_message_iter_abandon_container (iter, arr_iter);
188 }
189
202 dbus_bool_t
203 _dbus_asv_add_uint32 (DBusMessageIter *arr_iter,
204 const char *key,
205 dbus_uint32_t value)
206 {
207 DBusMessageIter entry_iter, var_iter;
208
209 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key,
210 DBUS_TYPE_UINT32_AS_STRING, &var_iter))
211 return FALSE;
212
213 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_UINT32,
214 &value))
215 {
216 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
217 return FALSE;
218 }
219
220 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
221 return FALSE;
222
223 return TRUE;
224 }
225
238 dbus_bool_t
239 _dbus_asv_add_string (DBusMessageIter *arr_iter,
240 const char *key,
241 const char *value)
242 {
243 DBusMessageIter entry_iter, var_iter;
244
245 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key,
246 DBUS_TYPE_STRING_AS_STRING, &var_iter))
247 return FALSE;
248
249 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_STRING,
250 &value))
251 {
252 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
253 return FALSE;
254 }
255
256 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
257 return FALSE;
258
259 return TRUE;
260 }
261
274 dbus_bool_t
275 _dbus_asv_add_object_path (DBusMessageIter *arr_iter,
276 const char *key,
277 const char *value)
278 {
279 DBusMessageIter entry_iter, var_iter;
280
281 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key,
282 DBUS_TYPE_OBJECT_PATH_AS_STRING, &var_iter))
283 return FALSE;
284
285 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_OBJECT_PATH,
286 &value))
287 {
288 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
289 return FALSE;
290 }
291
292 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
293 return FALSE;
294
295 return TRUE;
296 }
297
311 dbus_bool_t
312 _dbus_asv_add_fixed_array (DBusMessageIter *arr_iter,
313 const char *key,
314 char element_type,
315 const void *value,
316 int n_elements)
317 {
318 const char type[] = { DBUS_TYPE_ARRAY, element_type, 0 };
319 DBusMessageIter entry_iter;
320 DBusMessageIter var_iter;
321 DBusMessageIter array_iter;
322
323 _dbus_assert (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD);
324
325 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, type, &var_iter))
326 return FALSE;
327
328 if (!dbus_message_iter_open_container (&var_iter, DBUS_TYPE_ARRAY, type + 1,
329 &array_iter))
330 {
331 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
332 return FALSE;
333 }
334
335 if (!dbus_message_iter_append_fixed_array (&array_iter, element_type,
336 &value, n_elements))
337 {
338 dbus_message_iter_abandon_container (&var_iter, &array_iter);
339 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
340 return FALSE;
341 }
342
343 if (!dbus_message_iter_close_container (&var_iter, &array_iter))
344 {
345 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
346 return FALSE;
347 }
348
349 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
350 return FALSE;
351
352 return TRUE;
353 }
354
368 dbus_bool_t
369 _dbus_asv_add_byte_array (DBusMessageIter *arr_iter,
370 const char *key,
371 const void *value,
372 int n_elements)
373 {
374 return _dbus_asv_add_fixed_array (arr_iter, key, DBUS_TYPE_BYTE, value,
375 n_elements);
376 }
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
dbus_message_iter_close_container
dbus_bool_t dbus_message_iter_close_container(DBusMessageIter *iter, DBusMessageIter *sub)
Closes a container-typed value appended to the message; may write out more information to the message...
Definition: dbus-message.c:3067
dbus_message_iter_append_fixed_array
dbus_bool_t dbus_message_iter_append_fixed_array(DBusMessageIter *iter, int element_type, const void *value, int n_elements)
Appends a block of fixed-length values to an array.
Definition: dbus-message.c:2900
dbus_message_iter_open_container
dbus_bool_t dbus_message_iter_open_container(DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub)
Appends a container-typed value to the message.
Definition: dbus-message.c:2964
dbus_message_unref
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0.
Definition: dbus-message.c:1723
dbus_message_new_method_return
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
Definition: dbus-message.c:1406
DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition: dbus-protocol.h:114
TRUE
#define TRUE
dbus_message_iter_abandon_container
void dbus_message_iter_abandon_container(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
Definition: dbus-message.c:3101
dbus_message_iter_append_basic
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
Definition: dbus-message.c:2749
DBUS_TYPE_OBJECT_PATH_AS_STRING
#define DBUS_TYPE_OBJECT_PATH_AS_STRING
DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal
Definition: dbus-protocol.h:108
dbus_uint32_t
unsigned int dbus_uint32_t
Definition: dbus-arch-deps.h:43
dbus_message_iter_init_append
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
Definition: dbus-message.c:2511
DBUS_TYPE_BYTE
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
DBUS_TYPE_DICT_ENTRY
#define DBUS_TYPE_DICT_ENTRY
Type code used to represent a dict entry; however, this type code does not appear in type signatures,...
Definition: dbus-protocol.h:143
DBUS_TYPE_STRING_AS_STRING
#define DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING as a string literal instead of a int literal
Definition: dbus-protocol.h:104
FALSE
#define FALSE
DBusMessage
Internals of DBusMessage.
Definition: dbus-message-private.h:100
dbus_type_is_fixed
dbus_bool_t dbus_type_is_fixed(int typecode)
Tells you whether values of this type can change length if you set them to some other value.
Definition: dbus-signature.c:353
_dbus_assert
#define _dbus_assert(condition)
Definition: dbus-internals.h:153
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:62
DBUS_TYPE_UINT32_AS_STRING
#define DBUS_TYPE_UINT32_AS_STRING
DBUS_TYPE_UINT32 as a string literal instead of a int literal
Definition: dbus-protocol.h:88
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
dbus_bool_t
dbus_uint32_t dbus_bool_t
Definition: dbus-types.h:35
NULL
#define NULL