D-Bus: dbus-asv-util.c Source File

D-Bus 1.14.10

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 */
83dbus_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 */
121dbus_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
148dbus_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 */
165void
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
183void
184_dbus_asv_abandon (DBusMessageIter *iter,
185 DBusMessageIter *arr_iter)
186{
187 dbus_message_iter_abandon_container (iter, arr_iter);
188}
189
202dbus_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
238dbus_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
274dbus_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
311dbus_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
368dbus_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_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition dbus-internals.h:153
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
Definition dbus-macros.h:49
TRUE
#define TRUE
Expands to "1".
Definition dbus-macros.h:39
FALSE
#define FALSE
Expands to "0".
Definition dbus-macros.h:42
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:2753
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:2904
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:3105
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:2968
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_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_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:3071
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:2515
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition dbus-protocol.h:106
DBUS_TYPE_BYTE
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition dbus-protocol.h:66
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition dbus-protocol.h:124
DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition dbus-protocol.h:114
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition dbus-protocol.h:102
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_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition dbus-protocol.h:120
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
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_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_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
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition dbus-message.h:62
DBusMessage
Internals of DBusMessage.
Definition dbus-message-private.h:100