1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-type-utils.c: GValue and GType-related utilities
5 * Copyright (C) 2007 Red Hat, Inc.
14 #include "soup-value-utils.h"
17 * SECTION:soup-value-utils
18 * @short_description: GValue utilities
20 * These methods are useful for manipulating #GValue<!-- -->s, and in
21 * particular, arrays and hash tables of #GValue<!-- -->s, in a
22 * slightly nicer way than the standard #GValue API.
24 * They are written for use with soup-xmlrpc, but they also work with
25 * types not used by XML-RPC.
32 * @args: #va_list pointing to a value of type @type
34 * Copies an argument of type @type from @args into @val. @val will
35 * point directly to the value in @args rather than copying it, so you
36 * must g_value_copy() it if you want it to remain valid.
43 * @args: #va_list pointing to a value of type pointer-to-@type
45 * Extracts a value of type @type from @val into @args. The return
46 * value will point to the same data as @val rather than being a copy
51 soup_value_hash_value_free (gpointer val)
58 * soup_value_hash_new:
60 * Creates a #GHashTable whose keys are strings and whose values
63 * Return value: (element-type utf8 GValue) (transfer full): a new
67 soup_value_hash_new (void)
69 return g_hash_table_new_full (g_str_hash, g_str_equal,
70 g_free, soup_value_hash_value_free);
74 soup_value_hash_insert_valist (GHashTable *hash, const char *first_key,
83 type = va_arg (args, GType);
84 SOUP_VALUE_SETV (&value, type, args);
86 soup_value_hash_insert_value (hash, key, &value);
87 key = va_arg (args, const char *);
92 * soup_value_hash_new_with_vals:
93 * @first_key: the key for the first value
94 * @...: the type of @first_key, followed by the value, followed
95 * by additional key/type/value triplets, terminated by %NULL
97 * Creates a #GHashTable whose keys are strings and whose values
98 * are #GValue, and initializes it with the provided data. As
99 * with soup_value_hash_insert(), the keys and values are copied
100 * rather than being inserted directly.
102 * Return value: (element-type utf8 GValue) (transfer full): a new
103 * #GHashTable, initialized with the given values
106 soup_value_hash_new_with_vals (const char *first_key, ...)
108 GHashTable *hash = soup_value_hash_new ();
111 va_start (args, first_key);
112 soup_value_hash_insert_valist (hash, first_key, args);
119 * soup_value_hash_insert_value:
120 * @hash: (element-type utf8 GValue): a value hash
124 * Inserts @value into @hash. (Unlike with g_hash_table_insert(), both
125 * the key and the value are copied).
128 soup_value_hash_insert_value (GHashTable *hash, const char *key, GValue *value)
130 GValue *copy = g_new0 (GValue, 1);
132 g_value_init (copy, G_VALUE_TYPE (value));
133 g_value_copy (value, copy);
134 g_hash_table_insert (hash, g_strdup (key), copy);
138 * soup_value_hash_insert:
139 * @hash: (element-type utf8 GValue): a value hash
142 * @...: a value of type @type
144 * Inserts the provided value of type @type into @hash. (Unlike with
145 * g_hash_table_insert(), both the key and the value are copied).
148 soup_value_hash_insert (GHashTable *hash, const char *key, GType type, ...)
153 va_start (args, type);
154 SOUP_VALUE_SETV (&val, type, args);
156 soup_value_hash_insert_value (hash, key, &val);
160 * soup_value_hash_insert_vals:
161 * @hash: (element-type utf8 GValue): a value hash
162 * @first_key: the key for the first value
163 * @...: the type of @first_key, followed by the value, followed
164 * by additional key/type/value triplets, terminated by %NULL
166 * Inserts the given data into @hash. As with
167 * soup_value_hash_insert(), the keys and values are copied rather
168 * than being inserted directly.
171 soup_value_hash_insert_vals (GHashTable *hash, const char *first_key, ...)
175 va_start (args, first_key);
176 soup_value_hash_insert_valist (hash, first_key, args);
181 * soup_value_hash_lookup:
182 * @hash: (element-type utf8 GValue): a value hash
183 * @key: the key to look up
185 * @...: a value of type pointer-to-@type
187 * Looks up @key in @hash and stores its value into the provided
190 * Return value: %TRUE if @hash contained a value with key @key and
191 * type @type, %FALSE if not.
194 soup_value_hash_lookup (GHashTable *hash, const char *key, GType type, ...)
199 value = g_hash_table_lookup (hash, key);
200 if (!value || !G_VALUE_HOLDS (value, type))
203 va_start (args, type);
204 SOUP_VALUE_GETV (value, type, args);
211 * soup_value_hash_lookup_vals:
212 * @hash: (element-type utf8 GValue): a value hash
213 * @first_key: the first key to look up
214 * @...: the type of @first_key, a pointer to that type, and
215 * then additional key/type/pointer triplets, terminated
218 * Looks up a number of keys in @hash and returns their values.
220 * Return value: %TRUE if all of the keys were found, %FALSE
221 * if any were missing; note that you will generally need to
222 * initialize each destination variable to a reasonable default
223 * value, since there is no way to tell which keys were found
224 * and which were not.
227 soup_value_hash_lookup_vals (GHashTable *hash, const char *first_key, ...)
233 gboolean found_all = TRUE;
235 va_start (args, first_key);
238 type = va_arg (args, GType);
240 value = g_hash_table_lookup (hash, key);
241 if (!value || !G_VALUE_HOLDS (value, type)) {
244 va_arg (args, gpointer);
246 SOUP_VALUE_GETV (value, type, args);
248 key = va_arg (args, const char *);
256 #ifdef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
257 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
261 * soup_value_array_from_args:
262 * @args: arguments to create a #GValueArray from
264 * Creates a #GValueArray from the provided arguments, which must
265 * consist of pairs of a #GType and a value of that type, terminated
266 * by %G_TYPE_INVALID. (The array will contain copies of the provided
267 * data rather than pointing to the passed-in data directly.)
269 * Return value: a new #GValueArray, or %NULL if an error occurred.
272 soup_value_array_from_args (va_list args)
278 array = g_value_array_new (1);
279 while ((type = va_arg (args, GType)) != G_TYPE_INVALID) {
280 SOUP_VALUE_SETV (&val, type, args);
281 g_value_array_append (array, &val);
287 * soup_value_array_to_args:
288 * @array: a #GValueArray
289 * @args: arguments to extract @array into
291 * Extracts a #GValueArray into the provided arguments, which must
292 * consist of pairs of a #GType and a value of pointer-to-that-type,
293 * terminated by %G_TYPE_INVALID. The returned values will point to the
294 * same memory as the values in the array.
296 * Return value: success or failure
299 soup_value_array_to_args (GValueArray *array, va_list args)
305 for (i = 0; i < array->n_values; i++) {
306 type = va_arg (args, GType);
307 if (type == G_TYPE_INVALID)
309 value = g_value_array_get_nth (array, i);
310 if (!G_VALUE_HOLDS (value, type))
312 SOUP_VALUE_GETV (value, type, args);
318 * soup_value_array_new:
320 * Creates a new %GValueArray. (This is just a wrapper around
321 * g_value_array_new(), for naming consistency purposes.)
323 * Return value: a new %GValueArray
326 soup_value_array_new (void)
328 return g_value_array_new (1);
332 soup_value_array_append_valist (GValueArray *array,
333 GType first_type, va_list args)
339 while (type != G_TYPE_INVALID) {
340 SOUP_VALUE_SETV (&value, type, args);
342 g_value_array_append (array, &value);
343 type = va_arg (args, GType);
348 * soup_value_array_new_with_vals:
349 * @first_type: the type of the first value to add
350 * @...: the first value to add, followed by other type/value
351 * pairs, terminated by %G_TYPE_INVALID
353 * Creates a new %GValueArray and copies the provided values
356 * Return value: a new %GValueArray
359 soup_value_array_new_with_vals (GType first_type, ...)
361 GValueArray *array = soup_value_array_new ();
364 va_start (args, first_type);
365 soup_value_array_append_valist (array, first_type, args);
372 * soup_value_array_insert:
373 * @array: a #GValueArray
374 * @index_: the index to insert at
376 * @...: a value of type @type
378 * Inserts the provided value of type @type into @array as with
379 * g_value_array_insert(). (The provided data is copied rather than
380 * being inserted directly.)
383 soup_value_array_insert (GValueArray *array, guint index_, GType type, ...)
388 va_start (args, type);
389 SOUP_VALUE_SETV (&val, type, args);
391 g_value_array_insert (array, index_, &val);
395 * soup_value_array_append:
396 * @array: a #GValueArray
398 * @...: a value of type @type
400 * Appends the provided value of type @type to @array as with
401 * g_value_array_append(). (The provided data is copied rather than
402 * being inserted directly.)
405 soup_value_array_append (GValueArray *array, GType type, ...)
410 va_start (args, type);
411 SOUP_VALUE_SETV (&val, type, args);
413 g_value_array_append (array, &val);
417 * soup_value_array_append_vals:
418 * @array: a #GValueArray
419 * @first_type: the type of the first value to add
420 * @...: the first value to add, followed by other type/value
421 * pairs, terminated by %G_TYPE_INVALID
423 * Appends the provided values into @array as with
424 * g_value_array_append(). (The provided data is copied rather than
425 * being inserted directly.)
428 soup_value_array_append_vals (GValueArray *array, GType first_type, ...)
432 va_start (args, first_type);
433 soup_value_array_append_valist (array, first_type, args);
438 * soup_value_array_get_nth:
439 * @array: a #GValueArray
440 * @index_: the index to look up
442 * @...: a value of type pointer-to-@type
444 * Gets the @index_ element of @array and stores its value into the
447 * Return value: %TRUE if @array contained a value with index @index_
448 * and type @type, %FALSE if not.
451 soup_value_array_get_nth (GValueArray *array, guint index_, GType type, ...)
456 value = g_value_array_get_nth (array, index_);
457 if (!value || !G_VALUE_HOLDS (value, type))
460 va_start (args, type);
461 SOUP_VALUE_GETV (value, type, args);
466 #ifdef G_GNUC_END_IGNORE_DEPRECATIONS
467 G_GNUC_END_IGNORE_DEPRECATIONS
471 soup_byte_array_copy (GByteArray *ba)
475 copy = g_byte_array_sized_new (ba->len);
476 g_byte_array_append (copy, ba->data, ba->len);
481 soup_byte_array_free (GByteArray *ba)
483 g_byte_array_free (ba, TRUE);
487 * SOUP_TYPE_BYTE_ARRAY:
489 * glib did not used to define a #GType for #GByteArray, so libsoup
490 * defines this one itself.
492 typedef GByteArray SoupByteArray;
493 G_DEFINE_BOXED_TYPE (SoupByteArray, soup_byte_array, soup_byte_array_copy, soup_byte_array_free)