• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-type-utils.c: GValue and GType-related utilities
4  *
5  * Copyright (C) 2007 Red Hat, Inc.
6  */
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <string.h>
13 
14 #include "soup-value-utils.h"
15 
16 /**
17  * SECTION:soup-value-utils
18  * @short_description: GValue utilities
19  *
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.
23  *
24  * They are written for use with soup-xmlrpc, but they also work with
25  * types not used by XML-RPC.
26  *
27  * Deprecated: Use #GVariant API instead.
28  **/
29 
30 /**
31  * SOUP_VALUE_SETV:
32  * @val: a #GValue
33  * @type: a #GType
34  * @args: #va_list pointing to a value of type @type
35  *
36  * Copies an argument of type @type from @args into @val. @val will
37  * point directly to the value in @args rather than copying it, so you
38  * must g_value_copy() it if you want it to remain valid.
39  *
40  * Deprecated: Use #GVariant API instead.
41  **/
42 
43 /**
44  * SOUP_VALUE_GETV:
45  * @val: a #GValue
46  * @type: a #GType
47  * @args: #va_list pointing to a value of type pointer-to-@type
48  *
49  * Extracts a value of type @type from @val into @args. The return
50  * value will point to the same data as @val rather than being a copy
51  * of it.
52  *
53  * Deprecated: Use #GVariant API instead.
54  **/
55 
56 /* This whole file is deprecated and replaced by GVariant API */
57 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
58 
59 static void
soup_value_hash_value_free(gpointer val)60 soup_value_hash_value_free (gpointer val)
61 {
62 	g_value_unset (val);
63 	g_free (val);
64 }
65 
66 /**
67  * soup_value_hash_new:
68  *
69  * Creates a #GHashTable whose keys are strings and whose values
70  * are #GValue.
71  *
72  * Return value: (element-type utf8 GValue) (transfer full): a new
73  * empty #GHashTable
74  *
75  * Deprecated: Use #GVariant API instead.
76  **/
77 GHashTable *
soup_value_hash_new(void)78 soup_value_hash_new (void)
79 {
80 	return g_hash_table_new_full (g_str_hash, g_str_equal,
81 				      g_free, soup_value_hash_value_free);
82 }
83 
84 static void
soup_value_hash_insert_valist(GHashTable * hash,const char * first_key,va_list args)85 soup_value_hash_insert_valist (GHashTable *hash, const char *first_key,
86 			       va_list args)
87 {
88 	const char *key;
89 	GType type;
90 	GValue value;
91 
92 	key = first_key;
93 	while (key) {
94 		type = va_arg (args, GType);
95 		SOUP_VALUE_SETV (&value, type, args);
96 
97 		soup_value_hash_insert_value (hash, key, &value);
98 		key = va_arg (args, const char *);
99 	}
100 }
101 
102 /**
103  * soup_value_hash_new_with_vals:
104  * @first_key: the key for the first value
105  * @...: the type of @first_key, followed by the value, followed
106  * by additional key/type/value triplets, terminated by %NULL
107  *
108  * Creates a #GHashTable whose keys are strings and whose values
109  * are #GValue, and initializes it with the provided data. As
110  * with soup_value_hash_insert(), the keys and values are copied
111  * rather than being inserted directly.
112  *
113  * Return value: (element-type utf8 GValue) (transfer full): a new
114  * #GHashTable, initialized with the given values
115  *
116  * Deprecated: Use #GVariant API instead.
117  **/
118 GHashTable *
soup_value_hash_new_with_vals(const char * first_key,...)119 soup_value_hash_new_with_vals (const char *first_key, ...)
120 {
121 	GHashTable *hash = soup_value_hash_new ();
122 	va_list args;
123 
124 	va_start (args, first_key);
125 	soup_value_hash_insert_valist (hash, first_key, args);
126 	va_end (args);
127 
128 	return hash;
129 }
130 
131 /**
132  * soup_value_hash_insert_value:
133  * @hash: (element-type utf8 GValue): a value hash
134  * @key: the key
135  * @value: a value
136  *
137  * Inserts @value into @hash. (Unlike with g_hash_table_insert(), both
138  * the key and the value are copied).
139  *
140  * Deprecated: Use #GVariant API instead.
141  **/
142 void
soup_value_hash_insert_value(GHashTable * hash,const char * key,GValue * value)143 soup_value_hash_insert_value (GHashTable *hash, const char *key, GValue *value)
144 {
145 	GValue *copy = g_new0 (GValue, 1);
146 
147 	g_value_init (copy, G_VALUE_TYPE (value));
148 	g_value_copy (value, copy);
149 	g_hash_table_insert (hash, g_strdup (key), copy);
150 }
151 
152 /**
153  * soup_value_hash_insert:
154  * @hash: (element-type utf8 GValue): a value hash
155  * @key: the key
156  * @type: a #GType
157  * @...: a value of type @type
158  *
159  * Inserts the provided value of type @type into @hash. (Unlike with
160  * g_hash_table_insert(), both the key and the value are copied).
161  *
162  * Deprecated: Use #GVariant API instead.
163  **/
164 void
soup_value_hash_insert(GHashTable * hash,const char * key,GType type,...)165 soup_value_hash_insert (GHashTable *hash, const char *key, GType type, ...)
166 {
167 	va_list args;
168 	GValue val;
169 
170 	va_start (args, type);
171 	SOUP_VALUE_SETV (&val, type, args);
172 	va_end (args);
173 	soup_value_hash_insert_value (hash, key, &val);
174 }
175 
176 /**
177  * soup_value_hash_insert_vals:
178  * @hash: (element-type utf8 GValue): a value hash
179  * @first_key: the key for the first value
180  * @...: the type of @first_key, followed by the value, followed
181  * by additional key/type/value triplets, terminated by %NULL
182  *
183  * Inserts the given data into @hash. As with
184  * soup_value_hash_insert(), the keys and values are copied rather
185  * than being inserted directly.
186  *
187  * Deprecated: Use #GVariant API instead.
188  **/
189 void
soup_value_hash_insert_vals(GHashTable * hash,const char * first_key,...)190 soup_value_hash_insert_vals (GHashTable *hash, const char *first_key, ...)
191 {
192 	va_list args;
193 
194 	va_start (args, first_key);
195 	soup_value_hash_insert_valist (hash, first_key, args);
196 	va_end (args);
197 }
198 
199 /**
200  * soup_value_hash_lookup:
201  * @hash: (element-type utf8 GValue): a value hash
202  * @key: the key to look up
203  * @type: a #GType
204  * @...: a value of type pointer-to-@type
205  *
206  * Looks up @key in @hash and stores its value into the provided
207  * location.
208  *
209  * Return value: %TRUE if @hash contained a value with key @key and
210  * type @type, %FALSE if not.
211  *
212  * Deprecated: Use #GVariant API instead.
213  **/
214 gboolean
soup_value_hash_lookup(GHashTable * hash,const char * key,GType type,...)215 soup_value_hash_lookup (GHashTable *hash, const char *key, GType type, ...)
216 {
217 	va_list args;
218 	GValue *value;
219 
220 	value = g_hash_table_lookup (hash, key);
221 	if (!value || !G_VALUE_HOLDS (value, type))
222 		return FALSE;
223 
224 	va_start (args, type);
225 	SOUP_VALUE_GETV (value, type, args);
226 	va_end (args);
227 
228 	return TRUE;
229 }
230 
231 /**
232  * soup_value_hash_lookup_vals:
233  * @hash: (element-type utf8 GValue): a value hash
234  * @first_key: the first key to look up
235  * @...: the type of @first_key, a pointer to that type, and
236  * then additional key/type/pointer triplets, terminated
237  * by %NULL.
238  *
239  * Looks up a number of keys in @hash and returns their values.
240  *
241  * Return value: %TRUE if all of the keys were found, %FALSE
242  * if any were missing; note that you will generally need to
243  * initialize each destination variable to a reasonable default
244  * value, since there is no way to tell which keys were found
245  * and which were not.
246  *
247  * Deprecated: Use #GVariant API instead.
248  **/
249 gboolean
soup_value_hash_lookup_vals(GHashTable * hash,const char * first_key,...)250 soup_value_hash_lookup_vals (GHashTable *hash, const char *first_key, ...)
251 {
252 	va_list args;
253 	GValue *value;
254 	const char *key;
255 	GType type;
256 	gboolean found_all = TRUE;
257 
258 	va_start (args, first_key);
259 	key = first_key;
260 	while (key) {
261 		type = va_arg (args, GType);
262 
263 		value = g_hash_table_lookup (hash, key);
264 		if (!value || !G_VALUE_HOLDS (value, type)) {
265 			found_all = FALSE;
266 			/* skip a pointer */
267 			va_arg (args, gpointer);
268 		} else
269 			SOUP_VALUE_GETV (value, type, args);
270 
271 		key = va_arg (args, const char *);
272 	}
273 	va_end (args);
274 
275 	return found_all;
276 }
277 
278 
279 /**
280  * soup_value_array_from_args:
281  * @args: arguments to create a #GValueArray from
282  *
283  * Creates a #GValueArray from the provided arguments, which must
284  * consist of pairs of a #GType and a value of that type, terminated
285  * by %G_TYPE_INVALID. (The array will contain copies of the provided
286  * data rather than pointing to the passed-in data directly.)
287  *
288  * Return value: (nullable): a new #GValueArray, or %NULL if an error
289  * occurred.
290  *
291  * Deprecated: Use #GVariant API instead.
292  **/
293 GValueArray *
soup_value_array_from_args(va_list args)294 soup_value_array_from_args (va_list args)
295 {
296 	GValueArray *array;
297 	GType type;
298 	GValue val;
299 
300 	array = g_value_array_new (1);
301 	while ((type = va_arg (args, GType)) != G_TYPE_INVALID) {
302 		SOUP_VALUE_SETV (&val, type, args);
303 		g_value_array_append (array, &val);
304 	}
305 	return array;
306 }
307 
308 /**
309  * soup_value_array_to_args:
310  * @array: a #GValueArray
311  * @args: arguments to extract @array into
312  *
313  * Extracts a #GValueArray into the provided arguments, which must
314  * consist of pairs of a #GType and a value of pointer-to-that-type,
315  * terminated by %G_TYPE_INVALID. The returned values will point to the
316  * same memory as the values in the array.
317  *
318  * Return value: success or failure
319  *
320  * Deprecated: Use #GVariant API instead.
321  **/
322 gboolean
soup_value_array_to_args(GValueArray * array,va_list args)323 soup_value_array_to_args (GValueArray *array, va_list args)
324 {
325 	GType type;
326 	GValue *value;
327 	guint i;
328 
329 	for (i = 0; i < array->n_values; i++) {
330 		type = va_arg (args, GType);
331 		if (type == G_TYPE_INVALID)
332 			return FALSE;
333 		value = g_value_array_get_nth (array, i);
334 		if (!G_VALUE_HOLDS (value, type))
335 			return FALSE;
336 		SOUP_VALUE_GETV (value, type, args);
337 	}
338 	return TRUE;
339 }
340 
341 /**
342  * soup_value_array_new:
343  *
344  * Creates a new %GValueArray. (This is just a wrapper around
345  * g_value_array_new(), for naming consistency purposes.)
346  *
347  * Return value: a new %GValueArray
348  *
349  * Deprecated: Use #GVariant API instead.
350  **/
351 GValueArray *
soup_value_array_new(void)352 soup_value_array_new (void)
353 {
354 	return g_value_array_new (1);
355 }
356 
357 static void
soup_value_array_append_valist(GValueArray * array,GType first_type,va_list args)358 soup_value_array_append_valist (GValueArray *array,
359 				GType first_type, va_list args)
360 {
361 	GType type;
362 	GValue value;
363 
364 	type = first_type;
365 	while (type != G_TYPE_INVALID) {
366 		SOUP_VALUE_SETV (&value, type, args);
367 
368 		g_value_array_append (array, &value);
369 		type = va_arg (args, GType);
370 	}
371 }
372 
373 /**
374  * soup_value_array_new_with_vals:
375  * @first_type: the type of the first value to add
376  * @...: the first value to add, followed by other type/value
377  * pairs, terminated by %G_TYPE_INVALID
378  *
379  * Creates a new %GValueArray and copies the provided values
380  * into it.
381  *
382  * Return value: a new %GValueArray
383  *
384  * Deprecated: Use #GVariant API instead.
385  **/
386 GValueArray *
soup_value_array_new_with_vals(GType first_type,...)387 soup_value_array_new_with_vals (GType first_type, ...)
388 {
389 	GValueArray *array = soup_value_array_new ();
390 	va_list args;
391 
392 	va_start (args, first_type);
393 	soup_value_array_append_valist (array, first_type, args);
394 	va_end (args);
395 
396 	return array;
397 }
398 
399 /**
400  * soup_value_array_insert:
401  * @array: a #GValueArray
402  * @index_: the index to insert at
403  * @type: a #GType
404  * @...: a value of type @type
405  *
406  * Inserts the provided value of type @type into @array as with
407  * g_value_array_insert(). (The provided data is copied rather than
408  * being inserted directly.)
409  *
410  * Deprecated: Use #GVariant API instead.
411  **/
412 void
soup_value_array_insert(GValueArray * array,guint index_,GType type,...)413 soup_value_array_insert (GValueArray *array, guint index_, GType type, ...)
414 {
415 	va_list args;
416 	GValue val;
417 
418 	va_start (args, type);
419 	SOUP_VALUE_SETV (&val, type, args);
420 	va_end (args);
421 	g_value_array_insert (array, index_, &val);
422 }
423 
424 /**
425  * soup_value_array_append:
426  * @array: a #GValueArray
427  * @type: a #GType
428  * @...: a value of type @type
429  *
430  * Appends the provided value of type @type to @array as with
431  * g_value_array_append(). (The provided data is copied rather than
432  * being inserted directly.)
433  *
434  * Deprecated: Use #GVariant API instead.
435  **/
436 void
soup_value_array_append(GValueArray * array,GType type,...)437 soup_value_array_append (GValueArray *array, GType type, ...)
438 {
439 	va_list args;
440 	GValue val;
441 
442 	va_start (args, type);
443 	SOUP_VALUE_SETV (&val, type, args);
444 	va_end (args);
445 	g_value_array_append (array, &val);
446 }
447 
448 /**
449  * soup_value_array_append_vals:
450  * @array: a #GValueArray
451  * @first_type: the type of the first value to add
452  * @...: the first value to add, followed by other type/value
453  * pairs, terminated by %G_TYPE_INVALID
454  *
455  * Appends the provided values into @array as with
456  * g_value_array_append(). (The provided data is copied rather than
457  * being inserted directly.)
458  *
459  * Deprecated: Use #GVariant API instead.
460  **/
461 void
soup_value_array_append_vals(GValueArray * array,GType first_type,...)462 soup_value_array_append_vals (GValueArray *array, GType first_type, ...)
463 {
464 	va_list args;
465 
466 	va_start (args, first_type);
467 	soup_value_array_append_valist (array, first_type, args);
468 	va_end (args);
469 }
470 
471 /**
472  * soup_value_array_get_nth:
473  * @array: a #GValueArray
474  * @index_: the index to look up
475  * @type: a #GType
476  * @...: a value of type pointer-to-@type
477  *
478  * Gets the @index_ element of @array and stores its value into the
479  * provided location.
480  *
481  * Return value: %TRUE if @array contained a value with index @index_
482  * and type @type, %FALSE if not.
483  *
484  * Deprecated: Use #GVariant API instead.
485  **/
486 gboolean
soup_value_array_get_nth(GValueArray * array,guint index_,GType type,...)487 soup_value_array_get_nth (GValueArray *array, guint index_, GType type, ...)
488 {
489 	GValue *value;
490 	va_list args;
491 
492 	value = g_value_array_get_nth (array, index_);
493 	if (!value || !G_VALUE_HOLDS (value, type))
494 		return FALSE;
495 
496 	va_start (args, type);
497 	SOUP_VALUE_GETV (value, type, args);
498 	va_end (args);
499 	return TRUE;
500 }
501 
502 static GByteArray *
soup_byte_array_copy(GByteArray * ba)503 soup_byte_array_copy (GByteArray *ba)
504 {
505 	GByteArray *copy;
506 
507 	copy = g_byte_array_sized_new (ba->len);
508 	g_byte_array_append (copy, ba->data, ba->len);
509 	return copy;
510 }
511 
512 static void
soup_byte_array_free(GByteArray * ba)513 soup_byte_array_free (GByteArray *ba)
514 {
515 	g_byte_array_free (ba, TRUE);
516 }
517 
518 /**
519  * SOUP_TYPE_BYTE_ARRAY:
520  *
521  * glib did not used to define a #GType for #GByteArray, so libsoup
522  * defines this one itself.
523  *
524  * Deprecated: Use #GVariant API instead.
525  **/
526 typedef GByteArray SoupByteArray;
527 G_DEFINE_BOXED_TYPE (SoupByteArray, soup_byte_array, soup_byte_array_copy, soup_byte_array_free)
528 
529 G_GNUC_END_IGNORE_DEPRECATIONS
530