D-Bus
1.10.12
|
00001 /* dbus-asv-util.c - utility functions for a{sv} 00002 * 00003 * Copyright © 2011-2012 Nokia Corporation 00004 * Copyright © 2012-2013 Collabora Ltd. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00021 * 02110-1301 USA 00022 */ 00023 00024 #include <config.h> 00025 00026 #include <dbus/dbus.h> 00027 00028 #include "dbus/dbus-asv-util.h" 00029 00045 DBusMessage * 00046 _dbus_asv_new_method_return (DBusMessage *message, 00047 DBusMessageIter *iter, 00048 DBusMessageIter *arr_iter) 00049 { 00050 DBusMessage *reply = dbus_message_new_method_return (message); 00051 00052 if (reply == NULL) 00053 return NULL; 00054 00055 dbus_message_iter_init_append (reply, iter); 00056 00057 if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}", 00058 arr_iter)) 00059 { 00060 dbus_message_unref (reply); 00061 return NULL; 00062 } 00063 00064 return reply; 00065 } 00066 00067 /* 00068 * Open a new entry in an a{sv} (map from string to variant). 00069 * 00070 * This must be paired with a call to either _dbus_asv_close_entry() 00071 * or _dbus_asv_abandon_entry(). 00072 * 00073 * If this function fails, the a{sv} must be abandoned, for instance 00074 * with _dbus_asv_abandon(). 00075 * 00076 * @param arr_iter the iterator which is appending to the array 00077 * @param entry_iter will be initialized to append to the dict-entry 00078 * @param key a UTF-8 key for the map 00079 * @param type the type of the variant value, e.g. DBUS_TYPE_STRING_AS_STRING 00080 * @param var_iter will be initialized to append (i.e. write) to the variant 00081 * @returns #TRUE on success, or #FALSE if not enough memory 00082 */ 00083 static dbus_bool_t 00084 _dbus_asv_open_entry (DBusMessageIter *arr_iter, 00085 DBusMessageIter *entry_iter, 00086 const char *key, 00087 const char *type, 00088 DBusMessageIter *var_iter) 00089 { 00090 if (!dbus_message_iter_open_container (arr_iter, DBUS_TYPE_DICT_ENTRY, 00091 NULL, entry_iter)) 00092 return FALSE; 00093 00094 if (!dbus_message_iter_append_basic (entry_iter, DBUS_TYPE_STRING, &key)) 00095 { 00096 dbus_message_iter_abandon_container (arr_iter, entry_iter); 00097 return FALSE; 00098 } 00099 00100 if (!dbus_message_iter_open_container (entry_iter, DBUS_TYPE_VARIANT, 00101 type, var_iter)) 00102 { 00103 dbus_message_iter_abandon_container (arr_iter, entry_iter); 00104 return FALSE; 00105 } 00106 00107 return TRUE; 00108 } 00109 00110 /* 00111 * Closes an a{sv} entry after successfully appending the value. 00112 * 00113 * If this function fails, the a{sv} must be abandoned, for instance 00114 * with _dbus_asv_abandon(). 00115 * 00116 * @param arr_iter the iterator which is appending to the array 00117 * @param entry_iter the iterator appending to the dict-entry, will be closed 00118 * @param var_iter the iterator appending to the variant, will be closed 00119 * @returns #TRUE on success, or #FALSE if not enough memory 00120 */ 00121 static dbus_bool_t 00122 _dbus_asv_close_entry (DBusMessageIter *arr_iter, 00123 DBusMessageIter *entry_iter, 00124 DBusMessageIter *var_iter) 00125 { 00126 if (!dbus_message_iter_close_container (entry_iter, var_iter)) 00127 { 00128 dbus_message_iter_abandon_container (arr_iter, entry_iter); 00129 return FALSE; 00130 } 00131 00132 if (!dbus_message_iter_close_container (arr_iter, entry_iter)) 00133 return FALSE; 00134 00135 return TRUE; 00136 } 00137 00148 dbus_bool_t 00149 _dbus_asv_close (DBusMessageIter *iter, 00150 DBusMessageIter *arr_iter) 00151 { 00152 return dbus_message_iter_close_container (iter, arr_iter); 00153 } 00154 00155 /* 00156 * Closes an a{sv} entry after unsuccessfully appending a value. 00157 * You must also abandon the a{sv} itself (for instance with 00158 * _dbus_asv_abandon()), and abandon whatever larger data structure 00159 * the a{sv} was embedded in. 00160 * 00161 * @param iter the iterator which is appending to the message or other data structure containing the a{sv} 00162 * @param arr_iter the iterator appending to the array, will be closed 00163 * @returns #TRUE on success, or #FALSE if not enough memory 00164 */ 00165 static void 00166 _dbus_asv_abandon_entry (DBusMessageIter *arr_iter, 00167 DBusMessageIter *entry_iter, 00168 DBusMessageIter *var_iter) 00169 { 00170 dbus_message_iter_abandon_container (entry_iter, var_iter); 00171 dbus_message_iter_abandon_container (arr_iter, entry_iter); 00172 } 00173 00183 void 00184 _dbus_asv_abandon (DBusMessageIter *iter, 00185 DBusMessageIter *arr_iter) 00186 { 00187 dbus_message_iter_abandon_container (iter, arr_iter); 00188 } 00189 00202 dbus_bool_t 00203 _dbus_asv_add_uint32 (DBusMessageIter *arr_iter, 00204 const char *key, 00205 dbus_uint32_t value) 00206 { 00207 DBusMessageIter entry_iter, var_iter; 00208 00209 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, 00210 DBUS_TYPE_UINT32_AS_STRING, &var_iter)) 00211 return FALSE; 00212 00213 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_UINT32, 00214 &value)) 00215 { 00216 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); 00217 return FALSE; 00218 } 00219 00220 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter)) 00221 return FALSE; 00222 00223 return TRUE; 00224 } 00225 00238 dbus_bool_t 00239 _dbus_asv_add_string (DBusMessageIter *arr_iter, 00240 const char *key, 00241 const char *value) 00242 { 00243 DBusMessageIter entry_iter, var_iter; 00244 00245 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, 00246 DBUS_TYPE_STRING_AS_STRING, &var_iter)) 00247 return FALSE; 00248 00249 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_STRING, 00250 &value)) 00251 { 00252 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); 00253 return FALSE; 00254 } 00255 00256 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter)) 00257 return FALSE; 00258 00259 return TRUE; 00260 } 00261 00275 dbus_bool_t 00276 _dbus_asv_add_byte_array (DBusMessageIter *arr_iter, 00277 const char *key, 00278 const void *value, 00279 int n_elements) 00280 { 00281 DBusMessageIter entry_iter; 00282 DBusMessageIter var_iter; 00283 DBusMessageIter byte_array_iter; 00284 00285 if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, "ay", &var_iter)) 00286 return FALSE; 00287 00288 if (!dbus_message_iter_open_container (&var_iter, DBUS_TYPE_ARRAY, 00289 DBUS_TYPE_BYTE_AS_STRING, 00290 &byte_array_iter)) 00291 { 00292 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); 00293 return FALSE; 00294 } 00295 00296 if (!dbus_message_iter_append_fixed_array (&byte_array_iter, DBUS_TYPE_BYTE, 00297 &value, n_elements)) 00298 { 00299 dbus_message_iter_abandon_container (&var_iter, &byte_array_iter); 00300 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); 00301 return FALSE; 00302 } 00303 00304 if (!dbus_message_iter_close_container (&var_iter, &byte_array_iter)) 00305 { 00306 _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter); 00307 return FALSE; 00308 } 00309 00310 if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter)) 00311 return FALSE; 00312 00313 return TRUE; 00314 }