README: add deprecation notice
[nautilus-actions.git] / src / core / fma-boxed.c
blob21e5b027be1befa6e43273267a2fd5403185a2de
1 /*
2 * FileManager-Actions
3 * A file-manager extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009-2015 Pierre Wieser and others (see AUTHORS)
9 * FileManager-Actions is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * FileManager-Actions is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with FileManager-Actions; see the file COPYING. If not, see
21 * <http://www.gnu.org/licenses/>.
23 * Authors:
24 * Frederic Ruaudel <grumz@grumz.net>
25 * Rodrigo Moya <rodrigo@gnome-db.org>
26 * Pierre Wieser <pwieser@trychlos.org>
27 * ... and many others (see AUTHORS)
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
34 #include <stdlib.h>
35 #include <string.h>
37 #include <api/fma-boxed.h>
38 #include <api/fma-data-types.h>
39 #include <api/fma-core-utils.h>
41 /* private class data
43 struct _FMABoxedClassPrivate {
44 void *empty; /* so that gcc -pedantic is happy */
47 /* sBoxedDef:
48 * This is the structure which fully defines the behavior of this data type.
50 typedef struct {
51 guint type;
52 const gchar *label;
53 gboolean ( *are_equal ) ( const FMABoxed *, const FMABoxed * );
54 void ( *copy ) ( FMABoxed *, const FMABoxed * );
55 void ( *free ) ( FMABoxed * );
56 void ( *from_string ) ( FMABoxed *, const gchar * );
57 void ( *from_value ) ( FMABoxed *, const GValue * );
58 void ( *from_void ) ( FMABoxed *, const void * );
59 gboolean ( *to_bool ) ( const FMABoxed * );
60 gconstpointer ( *to_pointer ) ( const FMABoxed * );
61 gchar * ( *to_string ) ( const FMABoxed * );
62 GSList * ( *to_string_list )( const FMABoxed * );
63 guint ( *to_uint ) ( const FMABoxed * );
64 GList * ( *to_uint_list ) ( const FMABoxed * );
65 void ( *to_value ) ( const FMABoxed *, GValue * );
66 void * ( *to_void ) ( const FMABoxed * );
68 sBoxedDef;
70 /* private instance data
72 struct _FMABoxedPrivate {
73 gboolean dispose_has_run;
74 const sBoxedDef *def;
75 gboolean is_set;
76 union {
77 gboolean boolean;
78 void *pointer;
79 gchar *string;
80 GSList *string_list;
81 guint uint;
82 GList *uint_list;
83 } u;
86 #define LIST_SEPARATOR ";"
87 #define DEBUG if( 0 ) g_debug
89 static GObjectClass *st_parent_class = NULL;
91 static GType register_type( void );
92 static void class_init( FMABoxedClass *klass );
93 static void instance_init( GTypeInstance *instance, gpointer klass );
94 static void instance_dispose( GObject *object );
95 static void instance_finalize( GObject *object );
97 static FMABoxed *boxed_new( const sBoxedDef *def );
98 static const sBoxedDef *get_boxed_def( guint type );
99 static gchar **string_to_array( const gchar *string );
101 static gboolean bool_are_equal( const FMABoxed *a, const FMABoxed *b );
102 static void bool_copy( FMABoxed *dest, const FMABoxed *src );
103 static void bool_free( FMABoxed *boxed );
104 static void bool_from_string( FMABoxed *boxed, const gchar *string );
105 static void bool_from_value( FMABoxed *boxed, const GValue *value );
106 static void bool_from_void( FMABoxed *boxed, const void *value );
107 static gchar *bool_to_string( const FMABoxed *boxed );
108 static gboolean bool_to_bool( const FMABoxed *boxed );
109 static gconstpointer bool_to_pointer( const FMABoxed *boxed );
110 static gchar *bool_to_string( const FMABoxed *boxed );
111 static void bool_to_value( const FMABoxed *boxed, GValue *value );
112 static void *bool_to_void( const FMABoxed *boxed );
114 static gboolean pointer_are_equal( const FMABoxed *a, const FMABoxed *b );
115 static void pointer_copy( FMABoxed *dest, const FMABoxed *src );
116 static void pointer_free( FMABoxed *boxed );
117 static void pointer_from_string( FMABoxed *boxed, const gchar *string );
118 static void pointer_from_value( FMABoxed *boxed, const GValue *value );
119 static void pointer_from_void( FMABoxed *boxed, const void *value );
120 static gconstpointer pointer_to_pointer( const FMABoxed *boxed );
121 static gchar *pointer_to_string( const FMABoxed *boxed );
122 static void pointer_to_value( const FMABoxed *boxed, GValue *value );
123 static void *pointer_to_void( const FMABoxed *boxed );
125 static gboolean string_are_equal( const FMABoxed *a, const FMABoxed *b );
126 static void string_copy( FMABoxed *dest, const FMABoxed *src );
127 static void string_free( FMABoxed *boxed );
128 static void string_from_string( FMABoxed *boxed, const gchar *string );
129 static void string_from_value( FMABoxed *boxed, const GValue *value );
130 static void string_from_void( FMABoxed *boxed, const void *value );
131 static gconstpointer string_to_pointer( const FMABoxed *boxed );
132 static gchar *string_to_string( const FMABoxed *boxed );
133 static void string_to_value( const FMABoxed *boxed, GValue *value );
134 static void *string_to_void( const FMABoxed *boxed );
136 static gboolean string_list_are_equal( const FMABoxed *a, const FMABoxed *b );
137 static void string_list_copy( FMABoxed *dest, const FMABoxed *src );
138 static void string_list_free( FMABoxed *boxed );
139 static void string_list_from_string( FMABoxed *boxed, const gchar *string );
140 static void string_list_from_value( FMABoxed *boxed, const GValue *value );
141 static void string_list_from_void( FMABoxed *boxed, const void *value );
142 static gconstpointer string_list_to_pointer( const FMABoxed *boxed );
143 static gchar *string_list_to_string( const FMABoxed *boxed );
144 static GSList *string_list_to_string_list( const FMABoxed *boxed );
145 static void string_list_to_value( const FMABoxed *boxed, GValue *value );
146 static void *string_list_to_void( const FMABoxed *boxed );
148 static gboolean locale_are_equal( const FMABoxed *a, const FMABoxed *b );
150 static gboolean uint_are_equal( const FMABoxed *a, const FMABoxed *b );
151 static void uint_copy( FMABoxed *dest, const FMABoxed *src );
152 static void uint_free( FMABoxed *boxed );
153 static void uint_from_string( FMABoxed *boxed, const gchar *string );
154 static void uint_from_value( FMABoxed *boxed, const GValue *value );
155 static void uint_from_void( FMABoxed *boxed, const void *value );
156 static gconstpointer uint_to_pointer( const FMABoxed *boxed );
157 static gchar *uint_to_string( const FMABoxed *boxed );
158 static guint uint_to_uint( const FMABoxed *boxed );
159 static void uint_to_value( const FMABoxed *boxed, GValue *value );
160 static void *uint_to_void( const FMABoxed *boxed );
162 static gboolean uint_list_are_equal( const FMABoxed *a, const FMABoxed *b );
163 static void uint_list_copy( FMABoxed *dest, const FMABoxed *src );
164 static void uint_list_free( FMABoxed *boxed );
165 static void uint_list_from_string( FMABoxed *boxed, const gchar *string );
166 static void uint_list_from_value( FMABoxed *boxed, const GValue *value );
167 static void uint_list_from_void( FMABoxed *boxed, const void *value );
168 static gconstpointer uint_list_to_pointer( const FMABoxed *boxed );
169 static gchar *uint_list_to_string( const FMABoxed *boxed );
170 static GList *uint_list_to_uint_list( const FMABoxed *boxed );
171 static void uint_list_to_value( const FMABoxed *boxed, GValue *value );
172 static void *uint_list_to_void( const FMABoxed *boxed );
174 static sBoxedDef st_boxed_def[] = {
175 { FMA_DATA_TYPE_BOOLEAN,
176 "boolean",
177 bool_are_equal,
178 bool_copy,
179 bool_free,
180 bool_from_string,
181 bool_from_value,
182 bool_from_void,
183 bool_to_bool,
184 bool_to_pointer,
185 bool_to_string,
186 NULL,
187 NULL,
188 NULL,
189 bool_to_value,
190 bool_to_void
192 { FMA_DATA_TYPE_POINTER,
193 "pointer",
194 pointer_are_equal,
195 pointer_copy,
196 pointer_free,
197 pointer_from_string,
198 pointer_from_value,
199 pointer_from_void,
200 NULL,
201 pointer_to_pointer,
202 pointer_to_string,
203 NULL,
204 NULL,
205 NULL,
206 pointer_to_value,
207 pointer_to_void
209 { FMA_DATA_TYPE_STRING,
210 "string",
211 string_are_equal,
212 string_copy,
213 string_free,
214 string_from_string,
215 string_from_value,
216 string_from_void,
217 NULL, /* to_bool */
218 string_to_pointer,
219 string_to_string,
220 NULL, /* to_string_list */
221 NULL, /* to_uint */
222 NULL, /* to_uint_list */
223 string_to_value,
224 string_to_void
226 { FMA_DATA_TYPE_STRING_LIST,
227 "string_list",
228 string_list_are_equal,
229 string_list_copy,
230 string_list_free,
231 string_list_from_string,
232 string_list_from_value,
233 string_list_from_void,
234 NULL,
235 string_list_to_pointer,
236 string_list_to_string,
237 string_list_to_string_list,
238 NULL,
239 NULL,
240 string_list_to_value,
241 string_list_to_void
243 { FMA_DATA_TYPE_LOCALE_STRING,
244 "locale_string",
245 locale_are_equal,
246 string_copy,
247 string_free,
248 string_from_string,
249 string_from_value,
250 string_from_void,
251 NULL, /* to_bool */
252 string_to_pointer,
253 string_to_string,
254 NULL, /* to_string_list */
255 NULL, /* to_uint */
256 NULL, /* to_uint_list */
257 string_to_value,
258 string_to_void
260 { FMA_DATA_TYPE_UINT,
261 "uint",
262 uint_are_equal,
263 uint_copy,
264 uint_free,
265 uint_from_string,
266 uint_from_value,
267 uint_from_void,
268 NULL,
269 uint_to_pointer,
270 uint_to_string,
271 NULL,
272 uint_to_uint,
273 NULL,
274 uint_to_value,
275 uint_to_void
277 { FMA_DATA_TYPE_UINT_LIST,
278 "uint_list",
279 uint_list_are_equal,
280 uint_list_copy,
281 uint_list_free,
282 uint_list_from_string,
283 uint_list_from_value,
284 uint_list_from_void,
285 NULL,
286 uint_list_to_pointer,
287 uint_list_to_string,
288 NULL,
289 NULL,
290 uint_list_to_uint_list,
291 uint_list_to_value,
292 uint_list_to_void
294 { 0 }
297 GType
298 fma_boxed_get_type( void )
300 static GType item_type = 0;
302 if( item_type == 0 ){
303 item_type = register_type();
306 return( item_type );
309 static GType
310 register_type( void )
312 static const gchar *thisfn = "fma_boxed_register_type";
313 GType type;
315 static GTypeInfo info = {
316 sizeof( FMABoxedClass ),
317 NULL,
318 NULL,
319 ( GClassInitFunc ) class_init,
320 NULL,
321 NULL,
322 sizeof( FMABoxed ),
324 ( GInstanceInitFunc ) instance_init
327 g_debug( "%s", thisfn );
329 type = g_type_register_static( G_TYPE_OBJECT, "FMABoxed", &info, 0 );
331 return( type );
334 static void
335 class_init( FMABoxedClass *klass )
337 static const gchar *thisfn = "fma_boxed_class_init";
338 GObjectClass *object_class;
340 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
342 st_parent_class = g_type_class_peek_parent( klass );
344 object_class = G_OBJECT_CLASS( klass );
345 object_class->dispose = instance_dispose;
346 object_class->finalize = instance_finalize;
348 klass->private = g_new0( FMABoxedClassPrivate, 1 );
351 static void
352 instance_init( GTypeInstance *instance, gpointer klass )
354 static const gchar *thisfn = "fma_boxed_instance_init";
355 FMABoxed *self;
357 g_return_if_fail( FMA_IS_BOXED( instance ));
359 DEBUG( "%s: instance=%p (%s), klass=%p",
360 thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
362 self = FMA_BOXED( instance );
364 self->private = g_new0( FMABoxedPrivate, 1 );
366 self->private->dispose_has_run = FALSE;
367 self->private->def = NULL;
368 self->private->is_set = FALSE;
371 static void
372 instance_dispose( GObject *object )
374 FMABoxed *self;
376 g_return_if_fail( FMA_IS_BOXED( object ));
378 self = FMA_BOXED( object );
380 if( !self->private->dispose_has_run ){
382 self->private->dispose_has_run = TRUE;
384 /* chain up to the parent class */
385 if( G_OBJECT_CLASS( st_parent_class )->dispose ){
386 G_OBJECT_CLASS( st_parent_class )->dispose( object );
391 static void
392 instance_finalize( GObject *object )
394 static const gchar *thisfn = "fma_boxed_instance_finalize";
395 FMABoxed *self;
397 g_return_if_fail( FMA_IS_BOXED( object ));
399 DEBUG( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
401 self = FMA_BOXED( object );
403 if( self->private->def ){
404 if( self->private->def->free ){
405 ( *self->private->def->free )( self );
409 g_free( self->private );
411 /* chain call to parent class */
412 if( G_OBJECT_CLASS( st_parent_class )->finalize ){
413 G_OBJECT_CLASS( st_parent_class )->finalize( object );
417 static FMABoxed *
418 boxed_new( const sBoxedDef *def )
420 FMABoxed *boxed;
422 boxed = g_object_new( FMA_TYPE_BOXED, NULL );
423 boxed->private->def = def;
425 return( boxed );
428 static const sBoxedDef *
429 get_boxed_def( guint type )
431 static const gchar *thisfn = "fma_boxed_get_boxed_def";
432 sBoxedDef *def;
434 for( def = st_boxed_def ; def->type ; ++def ){
435 if( def->type == type ){
436 return(( const sBoxedDef * ) def );
440 g_warning( "%s: unmanaged data type: %d", thisfn, type );
441 return( NULL );
445 * converts a string to an array of strings
446 * accepts both:
447 * - a semi-comma-separated list of strings (the last separator, if any, is not counted)
448 * - a comma-separated list of strings between square brackets (à la GConf)
451 static gchar **
452 string_to_array( const gchar *string )
454 gchar *sdup;
455 gchar **array;
457 array = NULL;
459 if( string && strlen( string )){
460 sdup = g_strstrip( g_strdup( string ));
462 /* GConf-style string list [value,value]
464 if( sdup[0] == '[' && sdup[strlen(sdup)-1] == ']' ){
465 sdup[0] = ' ';
466 sdup[strlen(sdup)-1] = ' ';
467 sdup = g_strstrip( sdup );
468 array = g_strsplit( sdup, ",", -1 );
470 /* semi-comma-separated list of strings
472 } else {
473 if( g_str_has_suffix( string, LIST_SEPARATOR )){
474 sdup[strlen(sdup)-1] = ' ';
475 sdup = g_strstrip( sdup );
477 array = g_strsplit( sdup, LIST_SEPARATOR, -1 );
479 g_free( sdup );
482 return( array );
486 * fma_boxed_set_type:
487 * @boxed: this #FMABoxed object.
488 * @type: the required type as defined in fma-data-types.h
490 * Set the type of the just-allocated @boxed object.
492 * Since: 3.1
494 void
495 fma_boxed_set_type( FMABoxed *boxed, guint type )
497 g_return_if_fail( FMA_IS_BOXED( boxed ));
498 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
499 g_return_if_fail( boxed->private->def == NULL );
501 boxed->private->def = get_boxed_def( type );
505 * fma_boxed_are_equal:
506 * @a: the first #FMABoxed object.
507 * @b: the second #FMABoxed object.
509 * Returns: %TRUE if @a and @b are equal, %FALSE else.
511 * Since: 3.1
513 gboolean
514 fma_boxed_are_equal( const FMABoxed *a, const FMABoxed *b )
516 gboolean are_equal;
518 g_return_val_if_fail( FMA_IS_BOXED( a ), FALSE );
519 g_return_val_if_fail( a->private->dispose_has_run == FALSE, FALSE );
520 g_return_val_if_fail( FMA_IS_BOXED( b ), FALSE );
521 g_return_val_if_fail( b->private->dispose_has_run == FALSE, FALSE );
522 g_return_val_if_fail( a->private->def, FALSE );
523 g_return_val_if_fail( a->private->def == b->private->def, FALSE );
524 g_return_val_if_fail( a->private->def->are_equal, FALSE );
526 are_equal = FALSE;
528 if( a->private->is_set == b->private->is_set ){
529 are_equal = TRUE;
530 if( a->private->is_set ){
531 are_equal = ( *a->private->def->are_equal )( a, b );
535 return( are_equal );
539 * fma_boxed_copy:
540 * @boxed: the source #FMABoxed box.
542 * Returns: a copy of @boxed, as a newly allocated #FMABoxed which should
543 * be g_object_unref() by the caller.
545 * Since: 3.1
547 FMABoxed *
548 fma_boxed_copy( const FMABoxed *boxed )
550 FMABoxed *dest;
552 g_return_val_if_fail( FMA_IS_BOXED( boxed ), NULL );
553 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
554 g_return_val_if_fail( boxed->private->def, NULL );
555 g_return_val_if_fail( boxed->private->def->copy, NULL );
557 dest = boxed_new( boxed->private->def );
558 if( boxed->private->is_set ){
559 ( *boxed->private->def->copy )( dest, boxed );
560 dest->private->is_set = TRUE;
563 return( dest );
567 * fma_boxed_dump:
568 * @boxed: the #FMABoxed box to be dumped.
570 * Dumps the @boxed box.
572 * Since: 3.1
574 void
575 fma_boxed_dump( const FMABoxed *boxed )
577 static const gchar *thisfn = "fma_boxed_dump";
578 gchar *str;
580 g_return_if_fail( FMA_IS_BOXED( boxed ));
581 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
582 g_return_if_fail( boxed->private->def );
583 g_return_if_fail( boxed->private->def->to_string );
585 str = ( boxed->private->is_set ) ? ( *boxed->private->def->to_string )( boxed ) : NULL;
586 g_debug( "%s: boxed=%p, type=%u, is_set=%s, value=%s",
587 thisfn, ( void * ) boxed, boxed->private->def->type,
588 boxed->private->is_set ? "True":"False", str );
589 g_free( str );
593 * fma_boxed_new_from_string:
594 * @type: the type of the #FMABoxed to be allocated.
595 * @string: the initial value of the #FMABoxed as a string.
597 * Allocates a new #FMABoxed of the specified @type, and initializes it
598 * with @string.
600 * If the type is a list, then the last separator is automatically stripped.
602 * Returns: a newly allocated #FMABoxed, which should be g_object_unref()
603 * by the caller, or %NULL if the type is unknowned, or does not provide
604 * the 'from_string' function.
606 * Since: 3.1
608 FMABoxed *
609 fma_boxed_new_from_string( guint type, const gchar *string )
611 const sBoxedDef *def;
612 FMABoxed *boxed;
614 def = get_boxed_def( type );
616 g_return_val_if_fail( def, NULL );
617 g_return_val_if_fail( def->from_string, NULL );
619 boxed = boxed_new( def );
620 ( *def->from_string )( boxed, string );
621 boxed->private->is_set = TRUE;
623 return( boxed );
627 * fma_boxed_get_boolean:
628 * @boxed: the #FMABoxed structure.
630 * Returns: the boolean value if @boxed is of %FMA_DATA_TYPE_BOOLEAN type,
631 * %FALSE else.
633 * Since: 3.1
635 gboolean
636 fma_boxed_get_boolean( const FMABoxed *boxed )
638 gboolean value;
640 g_return_val_if_fail( FMA_IS_BOXED( boxed ), FALSE );
641 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, FALSE );
642 g_return_val_if_fail( boxed->private->def, FALSE );
643 g_return_val_if_fail( boxed->private->def->type == FMA_DATA_TYPE_BOOLEAN, FALSE );
644 g_return_val_if_fail( boxed->private->def->to_bool, FALSE );
646 value = ( *boxed->private->def->to_bool )( boxed );
648 return( value );
652 * fma_boxed_get_pointer:
653 * @boxed: the #FMABoxed structure.
655 * Returns: a const pointer to the data if @boxed is of %FMA_DATA_TYPE_POINTER
656 * type, %NULL else.
658 * Since: 3.1
660 gconstpointer
661 fma_boxed_get_pointer( const FMABoxed *boxed )
663 gconstpointer value;
665 g_return_val_if_fail( FMA_IS_BOXED( boxed ), NULL );
666 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
667 g_return_val_if_fail( boxed->private->def, NULL );
668 g_return_val_if_fail( boxed->private->def->to_pointer, NULL );
670 value = ( *boxed->private->def->to_pointer )( boxed );
672 return( value );
676 * fma_boxed_get_string:
677 * @boxed: the #FMABoxed structure.
679 * Returns: a newly allocated string if @boxed is of %FMA_DATA_TYPE_STRING
680 * type, which should be g_free() by the caller, %NULL else.
682 * Since: 3.1
684 gchar *
685 fma_boxed_get_string( const FMABoxed *boxed )
687 gchar *value;
689 g_return_val_if_fail( FMA_IS_BOXED( boxed ), NULL );
690 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
691 g_return_val_if_fail( boxed->private->def, NULL );
692 g_return_val_if_fail( boxed->private->def->to_string, NULL );
694 value = ( *boxed->private->def->to_string )( boxed );
696 return( value );
700 * fma_boxed_get_string_list:
701 * @boxed: the #FMABoxed structure.
703 * Returns: a newly allocated string list if @boxed is of %FMA_DATA_TYPE_STRING_LIST
704 * type, which should be fma_core_utils_slist_free() by the caller, %NULL else.
706 * Since: 3.1
708 GSList *
709 fma_boxed_get_string_list( const FMABoxed *boxed )
711 GSList *value;
713 g_return_val_if_fail( FMA_IS_BOXED( boxed ), NULL );
714 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
715 g_return_val_if_fail( boxed->private->def, NULL );
716 g_return_val_if_fail( boxed->private->def->type == FMA_DATA_TYPE_STRING_LIST, NULL );
717 g_return_val_if_fail( boxed->private->def->to_string_list, NULL );
719 value = ( *boxed->private->def->to_string_list )( boxed );
721 return( value );
725 * fma_boxed_get_uint:
726 * @boxed: the #FMABoxed structure.
728 * Returns: an unsigned integer if @boxed is of %FMA_DATA_TYPE_UINT type,
729 * zero else.
731 * Since: 3.1
733 guint
734 fma_boxed_get_uint( const FMABoxed *boxed )
736 guint value;
738 g_return_val_if_fail( FMA_IS_BOXED( boxed ), 0 );
739 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, 0 );
740 g_return_val_if_fail( boxed->private->def, 0 );
741 g_return_val_if_fail( boxed->private->def->type == FMA_DATA_TYPE_UINT, 0 );
742 g_return_val_if_fail( boxed->private->def->to_uint, 0 );
744 value = ( *boxed->private->def->to_uint )( boxed );
746 return( value );
750 * fma_boxed_get_uint_list:
751 * @boxed: the #FMABoxed structure.
753 * Returns: a newly allocated list if @boxed is of %FMA_DATA_TYPE_UINT_LIST
754 * type, which should be g_list_free() by the caller, %FALSE else.
756 * Since: 3.1
758 GList *
759 fma_boxed_get_uint_list( const FMABoxed *boxed )
761 GList *value;
763 g_return_val_if_fail( FMA_IS_BOXED( boxed ), NULL );
764 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
765 g_return_val_if_fail( boxed->private->def, NULL );
766 g_return_val_if_fail( boxed->private->def->type == FMA_DATA_TYPE_UINT_LIST, NULL );
767 g_return_val_if_fail( boxed->private->def->to_uint_list, NULL );
769 value = ( *boxed->private->def->to_uint_list )( boxed );
771 return( value );
775 * fma_boxed_get_as_value:
776 * @boxed: the #FMABoxed whose value is to be got.
777 * @value: the #GValue which holds the string to be set.
779 * Setup @value with the content of the @boxed.
781 * Since: 3.1
783 void
784 fma_boxed_get_as_value( const FMABoxed *boxed, GValue *value )
786 g_return_if_fail( FMA_IS_BOXED( boxed ));
787 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
788 g_return_if_fail( boxed->private->def );
789 g_return_if_fail( boxed->private->def->to_value );
791 ( *boxed->private->def->to_value )( boxed, value );
795 * fma_boxed_get_as_void:
796 * @boxed: the #FMABoxed whose value is to be got.
798 * Returns: the content of the @boxed.
800 * If of type FMA_DATA_TYPE_STRING (resp. FMA_DATA_TYPE_LOCALE_STRING,
801 * FMA_DATA_TYPE_STRING_LIST or FMA_DATA_TYPE_UINT_LIST), then the content
802 * is returned in a newly allocated value, which should be g_free() (resp.
803 * g_free(), fma_core_utils_slist_free(), g_list_free()) by the caller.
805 * Since: 3.1
807 void *
808 fma_boxed_get_as_void( const FMABoxed *boxed )
810 g_return_val_if_fail( FMA_IS_BOXED( boxed ), NULL );
811 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
812 g_return_val_if_fail( boxed->private->def, NULL );
813 g_return_val_if_fail( boxed->private->def->to_void, NULL );
815 return(( *boxed->private->def->to_void )( boxed ));
819 * fma_boxed_set_from_boxed:
820 * @boxed: the #FMABoxed whose value is to be set.
821 * @value: the source #FMABoxed.
823 * Copy value from @value to @boxed.
825 * Since: 3.1
827 void
828 fma_boxed_set_from_boxed( FMABoxed *boxed, const FMABoxed *value )
830 g_return_if_fail( FMA_IS_BOXED( boxed ));
831 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
832 g_return_if_fail( FMA_IS_BOXED( value ));
833 g_return_if_fail( value->private->dispose_has_run == FALSE );
834 g_return_if_fail( boxed->private->def );
835 g_return_if_fail( boxed->private->def == value->private->def );
836 g_return_if_fail( boxed->private->def->copy );
837 g_return_if_fail( boxed->private->def->free );
839 ( *boxed->private->def->free )( boxed );
840 ( *boxed->private->def->copy )( boxed, value );
841 boxed->private->is_set = TRUE;
845 * fma_boxed_set_from_string:
846 * @boxed: the #FMABoxed whose value is to be set.
847 * @value: the string to be set.
849 * Evaluates the @value and set it to the @boxed.
851 * Since: 3.1
853 void
854 fma_boxed_set_from_string( FMABoxed *boxed, const gchar *value )
856 g_return_if_fail( FMA_IS_BOXED( boxed ));
857 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
858 g_return_if_fail( boxed->private->def );
859 g_return_if_fail( boxed->private->def->free );
860 g_return_if_fail( boxed->private->def->from_string );
862 ( *boxed->private->def->free )( boxed );
863 ( *boxed->private->def->from_string )( boxed, value );
864 boxed->private->is_set = TRUE;
868 * fma_boxed_set_from_value:
869 * @boxed: the #FMABoxed whose value is to be set.
870 * @value: the value whose content is to be got.
872 * Evaluates the @value and set it to the @boxed.
874 * Since: 3.1
876 void
877 fma_boxed_set_from_value( FMABoxed *boxed, const GValue *value )
879 g_return_if_fail( FMA_IS_BOXED( boxed ));
880 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
881 g_return_if_fail( boxed->private->def );
882 g_return_if_fail( boxed->private->def->free );
883 g_return_if_fail( boxed->private->def->from_value );
885 ( *boxed->private->def->free )( boxed );
886 ( *boxed->private->def->from_value )( boxed, value );
887 boxed->private->is_set = TRUE;
891 * fma_boxed_set_from_void:
892 * @boxed: the #FMABoxed whose value is to be set.
893 * @value: the value whose content is to be got.
895 * Evaluates the @value and set it to the @boxed.
897 * Since: 3.1
899 void
900 fma_boxed_set_from_void( FMABoxed *boxed, const void *value )
902 g_return_if_fail( FMA_IS_BOXED( boxed ));
903 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
904 g_return_if_fail( boxed->private->def );
905 g_return_if_fail( boxed->private->def->free );
906 g_return_if_fail( boxed->private->def->from_void );
908 ( *boxed->private->def->free )( boxed );
909 ( *boxed->private->def->from_void )( boxed, value );
910 boxed->private->is_set = TRUE;
913 static gboolean
914 bool_are_equal( const FMABoxed *a, const FMABoxed *b )
916 return( a->private->u.boolean == b->private->u.boolean );
919 static void
920 bool_copy( FMABoxed *dest, const FMABoxed *src )
922 dest->private->u.boolean = src->private->u.boolean;
925 static void
926 bool_free( FMABoxed *boxed )
928 boxed->private->u.boolean = FALSE;
929 boxed->private->is_set = FALSE;
932 static void
933 bool_from_string( FMABoxed *boxed, const gchar *string )
935 boxed->private->u.boolean = fma_core_utils_boolean_from_string( string );
938 static void
939 bool_from_value( FMABoxed *boxed, const GValue *value )
941 boxed->private->u.boolean = g_value_get_boolean( value );
944 static void
945 bool_from_void( FMABoxed *boxed, const void *value )
947 boxed->private->u.boolean = GPOINTER_TO_UINT( value );
950 static gboolean
951 bool_to_bool( const FMABoxed *boxed )
953 return( boxed->private->u.boolean );
956 static gconstpointer
957 bool_to_pointer( const FMABoxed *boxed )
959 return(( gconstpointer ) GUINT_TO_POINTER( boxed->private->u.boolean ));
962 static gchar *
963 bool_to_string( const FMABoxed *boxed )
965 return( g_strdup_printf( "%s", boxed->private->u.boolean ? "true":"false" ));
968 static void
969 bool_to_value( const FMABoxed *boxed, GValue *value )
971 g_value_set_boolean( value, boxed->private->u.boolean );
974 static void *
975 bool_to_void( const FMABoxed *boxed )
977 return( GUINT_TO_POINTER( boxed->private->u.boolean ));
980 static gboolean
981 pointer_are_equal( const FMABoxed *a, const FMABoxed *b )
983 return( a->private->u.pointer == b->private->u.pointer );
987 * note that copying a pointer is not safe
989 static void
990 pointer_copy( FMABoxed *dest, const FMABoxed *src )
992 dest->private->u.pointer = src->private->u.pointer;
995 static void
996 pointer_free( FMABoxed *boxed )
998 boxed->private->u.pointer = NULL;
999 boxed->private->is_set = FALSE;
1002 static void
1003 pointer_from_string( FMABoxed *boxed, const gchar *pointer )
1005 g_warning( "fma_boxed_pointer_from_string: unrelevant function call" );
1008 static void
1009 pointer_from_value( FMABoxed *boxed, const GValue *value )
1011 boxed->private->u.pointer = g_value_get_pointer( value );
1014 static void
1015 pointer_from_void( FMABoxed *boxed, const void *value )
1017 boxed->private->u.pointer = ( void * ) value;
1020 static gconstpointer
1021 pointer_to_pointer( const FMABoxed *boxed )
1023 return( boxed->private->u.pointer );
1026 static gchar *
1027 pointer_to_string( const FMABoxed *boxed )
1029 return( g_strdup_printf( "%p", boxed->private->u.pointer ));
1032 static void
1033 pointer_to_value( const FMABoxed *boxed, GValue *value )
1035 g_value_set_pointer( value, boxed->private->u.pointer );
1038 static void *
1039 pointer_to_void( const FMABoxed *boxed )
1041 return( boxed->private->u.pointer );
1044 static gboolean
1045 string_are_equal( const FMABoxed *a, const FMABoxed *b )
1047 if( a->private->u.string && b->private->u.string ){
1048 return( strcmp( a->private->u.string, b->private->u.string ) == 0 );
1050 if( !a->private->u.string && !b->private->u.string ){
1051 return( TRUE );
1053 return( FALSE );
1056 static void
1057 string_copy( FMABoxed *dest, const FMABoxed *src )
1059 dest->private->u.string = g_strdup( src->private->u.string );
1062 static void
1063 string_free( FMABoxed *boxed )
1065 g_free( boxed->private->u.string );
1066 boxed->private->u.string = NULL;
1067 boxed->private->is_set = FALSE;
1070 static void
1071 string_from_string( FMABoxed *boxed, const gchar *string )
1073 boxed->private->u.string = g_strdup( string ? string : "" );
1076 static void
1077 string_from_value( FMABoxed *boxed, const GValue *value )
1079 if( g_value_get_string( value )){
1080 boxed->private->u.string = g_value_dup_string( value );
1081 } else {
1082 boxed->private->u.string = g_strdup( "" );
1086 static void
1087 string_from_void( FMABoxed *boxed, const void *value )
1089 boxed->private->u.string = g_strdup( value ? ( const gchar * ) value : "" );
1092 static gconstpointer
1093 string_to_pointer( const FMABoxed *boxed )
1095 return(( gconstpointer ) boxed->private->u.string );
1098 static gchar *
1099 string_to_string( const FMABoxed *boxed )
1101 return( g_strdup( boxed->private->u.string ));
1104 static void
1105 string_to_value( const FMABoxed *boxed, GValue *value )
1107 gchar *str;
1109 str = string_to_string( boxed );
1110 g_value_set_string( value, str );
1111 g_free( str );
1114 static void *
1115 string_to_void( const FMABoxed *boxed )
1117 return(( void * ) string_to_string( boxed ));
1120 /* the two string lists are equal if they have the same elements in the
1121 * same order
1123 static gboolean
1124 string_list_are_equal( const FMABoxed *a, const FMABoxed *b )
1126 GSList *ia, *ib;
1127 gboolean diff = FALSE;
1129 guint na = g_slist_length( a->private->u.string_list );
1130 guint nb = g_slist_length( b->private->u.string_list );
1132 if( na != nb ) return( FALSE );
1134 for( ia=a->private->u.string_list, ib=b->private->u.string_list ; ia && ib && !diff ; ia=ia->next, ib=ib->next ){
1135 if( strcmp( ia->data, ib->data ) != 0 ){
1136 diff = TRUE;
1140 return( !diff );
1143 static void
1144 string_list_copy( FMABoxed *dest, const FMABoxed *src )
1146 if( dest->private->is_set ){
1147 string_list_free( dest );
1149 dest->private->u.string_list = fma_core_utils_slist_duplicate( src->private->u.string_list );
1150 dest->private->is_set = TRUE;
1153 static void
1154 string_list_free( FMABoxed *boxed )
1156 fma_core_utils_slist_free( boxed->private->u.string_list );
1157 boxed->private->u.string_list = NULL;
1158 boxed->private->is_set = FALSE;
1162 * accept string list both:
1163 * - as a semi-comma-separated list of strings
1164 * - as a comma-separated list of string, between two square brackets (à la GConf)
1166 static void
1167 string_list_from_string( FMABoxed *boxed, const gchar *string )
1169 gchar **array;
1170 gchar **i;
1172 array = string_to_array( string );
1174 if( array ){
1175 i = ( gchar ** ) array;
1176 while( *i ){
1177 if( !fma_core_utils_slist_count( boxed->private->u.string_list, ( const gchar * )( *i ))){
1178 boxed->private->u.string_list = g_slist_prepend( boxed->private->u.string_list, g_strdup( *i ));
1180 i++;
1182 boxed->private->u.string_list = g_slist_reverse( boxed->private->u.string_list );
1185 g_strfreev( array );
1188 static void
1189 string_list_from_value( FMABoxed *boxed, const GValue *value )
1191 string_list_from_void( boxed, ( const void * ) g_value_get_pointer( value ));
1194 static void
1195 string_list_from_void( FMABoxed *boxed, const void *value )
1197 GSList *value_slist;
1198 GSList *it;
1200 value_slist = ( GSList * ) value;
1201 for( it = value_slist ; it ; it = it->next ){
1202 if( !fma_core_utils_slist_count( boxed->private->u.string_list, ( const gchar * ) it->data )){
1203 boxed->private->u.string_list = g_slist_prepend( boxed->private->u.string_list, g_strdup(( const gchar * ) it->data ));
1206 boxed->private->u.string_list = g_slist_reverse( boxed->private->u.string_list );
1209 static gconstpointer
1210 string_list_to_pointer( const FMABoxed *boxed )
1212 return(( gconstpointer ) boxed->private->u.string_list );
1215 static gchar *
1216 string_list_to_string( const FMABoxed *boxed )
1218 GSList *is;
1219 GString *str = g_string_new( "" );
1220 gboolean first;
1222 first = TRUE;
1223 for( is = boxed->private->u.string_list ; is ; is = is->next ){
1224 if( !first ){
1225 str = g_string_append( str, LIST_SEPARATOR );
1227 str = g_string_append( str, ( const gchar * ) is->data );
1228 first = FALSE;
1231 return( g_string_free( str, FALSE ));
1234 static GSList *
1235 string_list_to_string_list( const FMABoxed *boxed )
1237 return( fma_core_utils_slist_duplicate( boxed->private->u.string_list ));
1240 static void
1241 string_list_to_value( const FMABoxed *boxed, GValue *value )
1243 g_value_set_pointer( value, fma_core_utils_slist_duplicate( boxed->private->u.string_list ));
1246 static void *
1247 string_list_to_void( const FMABoxed *boxed )
1249 void *value = NULL;
1251 if( boxed->private->u.string_list ){
1252 value = fma_core_utils_slist_duplicate( boxed->private->u.string_list );
1255 return( value );
1258 static gboolean
1259 locale_are_equal( const FMABoxed *a, const FMABoxed *b )
1261 if( !a->private->u.string && !b->private->u.string ){
1262 return( TRUE );
1264 if( !a->private->u.string || !b->private->u.string ){
1265 return( FALSE );
1267 return( fma_core_utils_str_collate( a->private->u.string, b->private->u.string ) == 0 );
1270 static gboolean
1271 uint_are_equal( const FMABoxed *a, const FMABoxed *b )
1273 return( a->private->u.uint == b->private->u.uint );
1276 static void
1277 uint_copy( FMABoxed *dest, const FMABoxed *src )
1279 dest->private->u.uint = src->private->u.uint;
1280 dest->private->is_set = TRUE;
1283 static void
1284 uint_free( FMABoxed *boxed )
1286 boxed->private->u.uint = 0;
1287 boxed->private->is_set = FALSE;
1290 static void
1291 uint_from_string( FMABoxed *boxed, const gchar *string )
1293 boxed->private->u.uint = string ? atoi( string ) : 0;
1296 static void
1297 uint_from_value( FMABoxed *boxed, const GValue *value )
1299 boxed->private->u.uint = g_value_get_uint( value );
1302 static void
1303 uint_from_void( FMABoxed *boxed, const void *value )
1305 boxed->private->u.uint = GPOINTER_TO_UINT( value );
1308 static gconstpointer
1309 uint_to_pointer( const FMABoxed *boxed )
1311 return(( gconstpointer ) GUINT_TO_POINTER( boxed->private->u.uint ));
1314 static gchar *
1315 uint_to_string( const FMABoxed *boxed )
1317 return( g_strdup_printf( "%u", boxed->private->u.uint ));
1320 static guint
1321 uint_to_uint( const FMABoxed *boxed )
1323 return( boxed->private->u.uint );
1326 static void
1327 uint_to_value( const FMABoxed *boxed, GValue *value )
1329 g_value_set_uint( value, boxed->private->u.uint );
1332 static void *
1333 uint_to_void( const FMABoxed *boxed )
1335 return( GUINT_TO_POINTER( boxed->private->u.uint ));
1338 /* compare uint list as string list:
1339 * if the two list do not have the same count, then one is lesser than the other
1340 * if they have same count and same elements in same order, they are equal
1341 * else just arbitrarily return -1
1343 static gboolean
1344 uint_list_are_equal( const FMABoxed *a, const FMABoxed *b )
1346 GList *ia, *ib;
1347 gboolean diff = FALSE;
1349 guint na = g_list_length( a->private->u.uint_list );
1350 guint nb = g_list_length( b->private->u.uint_list );
1352 if( na != nb ) return( FALSE );
1354 for( ia=a->private->u.uint_list, ib=b->private->u.uint_list ; ia && ib && !diff ; ia=ia->next, ib=ib->next ){
1355 if( GPOINTER_TO_UINT( ia->data ) != GPOINTER_TO_UINT( ib->data )){
1356 diff = TRUE;
1360 return( !diff );
1363 static void
1364 uint_list_copy( FMABoxed *dest, const FMABoxed *src )
1366 GList *isrc;
1368 dest->private->u.uint_list = NULL;
1369 for( isrc = src->private->u.uint_list ; isrc ; isrc = isrc->next ){
1370 dest->private->u.uint_list = g_list_prepend( dest->private->u.uint_list, isrc->data );
1372 dest->private->u.uint_list = g_list_reverse( dest->private->u.uint_list );
1375 static void
1376 uint_list_free( FMABoxed *boxed )
1378 g_list_free( boxed->private->u.uint_list );
1379 boxed->private->u.uint_list = NULL;
1380 boxed->private->is_set = FALSE;
1383 static void
1384 uint_list_from_string( FMABoxed *boxed, const gchar *string )
1386 gchar **array;
1387 gchar **i;
1389 array = string_to_array( string );
1391 if( array ){
1392 i = ( gchar ** ) array;
1393 while( *i ){
1394 boxed->private->u.uint_list = g_list_prepend( boxed->private->u.uint_list, GINT_TO_POINTER( atoi( *i )));
1395 i++;
1397 boxed->private->u.uint_list = g_list_reverse( boxed->private->u.uint_list );
1398 } else {
1399 boxed->private->u.uint_list = NULL;
1402 g_strfreev( array );
1405 static void
1406 uint_list_from_value( FMABoxed *boxed, const GValue *value )
1408 if( g_value_get_pointer( value )){
1409 boxed->private->u.uint_list = g_list_copy( g_value_get_pointer( value ));
1413 static void
1414 uint_list_from_void( FMABoxed *boxed, const void *value )
1416 if( value ){
1417 boxed->private->u.uint_list = g_list_copy(( GList * ) value );
1421 static gconstpointer
1422 uint_list_to_pointer( const FMABoxed *boxed )
1424 return(( gconstpointer ) boxed->private->u.uint_list );
1427 static gchar *
1428 uint_list_to_string( const FMABoxed *boxed )
1430 GList *is;
1431 GString *str = g_string_new( "" );
1432 gboolean first;
1434 first = TRUE;
1435 for( is = boxed->private->u.uint_list ; is ; is = is->next ){
1436 if( !first ){
1437 str = g_string_append( str, LIST_SEPARATOR );
1439 g_string_append_printf( str, "%u", GPOINTER_TO_UINT( is->data ));
1440 first = FALSE;
1443 return( g_string_free( str, FALSE ));
1446 static GList *
1447 uint_list_to_uint_list( const FMABoxed *boxed )
1449 return( g_list_copy( boxed->private->u.uint_list ));
1452 static void
1453 uint_list_to_value( const FMABoxed *boxed, GValue *value )
1455 g_value_set_pointer( value, g_list_copy( boxed->private->u.uint_list ));
1458 static void *
1459 uint_list_to_void( const FMABoxed *boxed )
1461 void *value = NULL;
1463 if( boxed->private->u.uint_list ){
1464 value = g_list_copy( boxed->private->u.uint_list );
1467 return( value );