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/>.
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)
37 #include <api/fma-boxed.h>
38 #include <api/fma-data-types.h>
39 #include <api/fma-core-utils.h>
43 struct _FMABoxedClassPrivate
{
44 void *empty
; /* so that gcc -pedantic is happy */
48 * This is the structure which fully defines the behavior of this data type.
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
* );
70 /* private instance data
72 struct _FMABoxedPrivate
{
73 gboolean dispose_has_run
;
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
,
192 { FMA_DATA_TYPE_POINTER
,
209 { FMA_DATA_TYPE_STRING
,
220 NULL
, /* to_string_list */
222 NULL
, /* to_uint_list */
226 { FMA_DATA_TYPE_STRING_LIST
,
228 string_list_are_equal
,
231 string_list_from_string
,
232 string_list_from_value
,
233 string_list_from_void
,
235 string_list_to_pointer
,
236 string_list_to_string
,
237 string_list_to_string_list
,
240 string_list_to_value
,
243 { FMA_DATA_TYPE_LOCALE_STRING
,
254 NULL
, /* to_string_list */
256 NULL
, /* to_uint_list */
260 { FMA_DATA_TYPE_UINT
,
277 { FMA_DATA_TYPE_UINT_LIST
,
282 uint_list_from_string
,
283 uint_list_from_value
,
286 uint_list_to_pointer
,
290 uint_list_to_uint_list
,
298 fma_boxed_get_type( void )
300 static GType item_type
= 0;
302 if( item_type
== 0 ){
303 item_type
= register_type();
310 register_type( void )
312 static const gchar
*thisfn
= "fma_boxed_register_type";
315 static GTypeInfo info
= {
316 sizeof( FMABoxedClass
),
319 ( GClassInitFunc
) class_init
,
324 ( GInstanceInitFunc
) instance_init
327 g_debug( "%s", thisfn
);
329 type
= g_type_register_static( G_TYPE_OBJECT
, "FMABoxed", &info
, 0 );
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 );
352 instance_init( GTypeInstance
*instance
, gpointer klass
)
354 static const gchar
*thisfn
= "fma_boxed_instance_init";
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
;
372 instance_dispose( GObject
*object
)
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
);
392 instance_finalize( GObject
*object
)
394 static const gchar
*thisfn
= "fma_boxed_instance_finalize";
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
);
418 boxed_new( const sBoxedDef
*def
)
422 boxed
= g_object_new( FMA_TYPE_BOXED
, NULL
);
423 boxed
->private->def
= def
;
428 static const sBoxedDef
*
429 get_boxed_def( guint type
)
431 static const gchar
*thisfn
= "fma_boxed_get_boxed_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
);
445 * converts a string to an array of strings
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)
452 string_to_array( const gchar
*string
)
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] == ']' ){
466 sdup
[strlen(sdup
)-1] = ' ';
467 sdup
= g_strstrip( sdup
);
468 array
= g_strsplit( sdup
, ",", -1 );
470 /* semi-comma-separated list of strings
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 );
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.
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.
514 fma_boxed_are_equal( const FMABoxed
*a
, const FMABoxed
*b
)
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
);
528 if( a
->private->is_set
== b
->private->is_set
){
530 if( a
->private->is_set
){
531 are_equal
= ( *a
->private->def
->are_equal
)( a
, b
);
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.
548 fma_boxed_copy( const FMABoxed
*boxed
)
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
;
568 * @boxed: the #FMABoxed box to be dumped.
570 * Dumps the @boxed box.
575 fma_boxed_dump( const FMABoxed
*boxed
)
577 static const gchar
*thisfn
= "fma_boxed_dump";
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
);
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
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.
609 fma_boxed_new_from_string( guint type
, const gchar
*string
)
611 const sBoxedDef
*def
;
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
;
627 * fma_boxed_get_boolean:
628 * @boxed: the #FMABoxed structure.
630 * Returns: the boolean value if @boxed is of %FMA_DATA_TYPE_BOOLEAN type,
636 fma_boxed_get_boolean( const FMABoxed
*boxed
)
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
);
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
661 fma_boxed_get_pointer( const FMABoxed
*boxed
)
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
);
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.
685 fma_boxed_get_string( const FMABoxed
*boxed
)
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
);
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.
709 fma_boxed_get_string_list( const FMABoxed
*boxed
)
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
);
725 * fma_boxed_get_uint:
726 * @boxed: the #FMABoxed structure.
728 * Returns: an unsigned integer if @boxed is of %FMA_DATA_TYPE_UINT type,
734 fma_boxed_get_uint( const FMABoxed
*boxed
)
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
);
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.
759 fma_boxed_get_uint_list( const FMABoxed
*boxed
)
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
);
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.
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.
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.
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.
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.
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.
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
;
914 bool_are_equal( const FMABoxed
*a
, const FMABoxed
*b
)
916 return( a
->private->u
.boolean
== b
->private->u
.boolean
);
920 bool_copy( FMABoxed
*dest
, const FMABoxed
*src
)
922 dest
->private->u
.boolean
= src
->private->u
.boolean
;
926 bool_free( FMABoxed
*boxed
)
928 boxed
->private->u
.boolean
= FALSE
;
929 boxed
->private->is_set
= FALSE
;
933 bool_from_string( FMABoxed
*boxed
, const gchar
*string
)
935 boxed
->private->u
.boolean
= fma_core_utils_boolean_from_string( string
);
939 bool_from_value( FMABoxed
*boxed
, const GValue
*value
)
941 boxed
->private->u
.boolean
= g_value_get_boolean( value
);
945 bool_from_void( FMABoxed
*boxed
, const void *value
)
947 boxed
->private->u
.boolean
= GPOINTER_TO_UINT( value
);
951 bool_to_bool( const FMABoxed
*boxed
)
953 return( boxed
->private->u
.boolean
);
957 bool_to_pointer( const FMABoxed
*boxed
)
959 return(( gconstpointer
) GUINT_TO_POINTER( boxed
->private->u
.boolean
));
963 bool_to_string( const FMABoxed
*boxed
)
965 return( g_strdup_printf( "%s", boxed
->private->u
.boolean
? "true":"false" ));
969 bool_to_value( const FMABoxed
*boxed
, GValue
*value
)
971 g_value_set_boolean( value
, boxed
->private->u
.boolean
);
975 bool_to_void( const FMABoxed
*boxed
)
977 return( GUINT_TO_POINTER( boxed
->private->u
.boolean
));
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
990 pointer_copy( FMABoxed
*dest
, const FMABoxed
*src
)
992 dest
->private->u
.pointer
= src
->private->u
.pointer
;
996 pointer_free( FMABoxed
*boxed
)
998 boxed
->private->u
.pointer
= NULL
;
999 boxed
->private->is_set
= FALSE
;
1003 pointer_from_string( FMABoxed
*boxed
, const gchar
*pointer
)
1005 g_warning( "fma_boxed_pointer_from_string: unrelevant function call" );
1009 pointer_from_value( FMABoxed
*boxed
, const GValue
*value
)
1011 boxed
->private->u
.pointer
= g_value_get_pointer( value
);
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
);
1027 pointer_to_string( const FMABoxed
*boxed
)
1029 return( g_strdup_printf( "%p", boxed
->private->u
.pointer
));
1033 pointer_to_value( const FMABoxed
*boxed
, GValue
*value
)
1035 g_value_set_pointer( value
, boxed
->private->u
.pointer
);
1039 pointer_to_void( const FMABoxed
*boxed
)
1041 return( boxed
->private->u
.pointer
);
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
){
1057 string_copy( FMABoxed
*dest
, const FMABoxed
*src
)
1059 dest
->private->u
.string
= g_strdup( src
->private->u
.string
);
1063 string_free( FMABoxed
*boxed
)
1065 g_free( boxed
->private->u
.string
);
1066 boxed
->private->u
.string
= NULL
;
1067 boxed
->private->is_set
= FALSE
;
1071 string_from_string( FMABoxed
*boxed
, const gchar
*string
)
1073 boxed
->private->u
.string
= g_strdup( string
? string
: "" );
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
);
1082 boxed
->private->u
.string
= g_strdup( "" );
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
);
1099 string_to_string( const FMABoxed
*boxed
)
1101 return( g_strdup( boxed
->private->u
.string
));
1105 string_to_value( const FMABoxed
*boxed
, GValue
*value
)
1109 str
= string_to_string( boxed
);
1110 g_value_set_string( value
, str
);
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
1124 string_list_are_equal( const FMABoxed
*a
, const FMABoxed
*b
)
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 ){
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
;
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)
1167 string_list_from_string( FMABoxed
*boxed
, const gchar
*string
)
1172 array
= string_to_array( string
);
1175 i
= ( gchar
** ) array
;
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
));
1182 boxed
->private->u
.string_list
= g_slist_reverse( boxed
->private->u
.string_list
);
1185 g_strfreev( array
);
1189 string_list_from_value( FMABoxed
*boxed
, const GValue
*value
)
1191 string_list_from_void( boxed
, ( const void * ) g_value_get_pointer( value
));
1195 string_list_from_void( FMABoxed
*boxed
, const void *value
)
1197 GSList
*value_slist
;
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
);
1216 string_list_to_string( const FMABoxed
*boxed
)
1219 GString
*str
= g_string_new( "" );
1223 for( is
= boxed
->private->u
.string_list
; is
; is
= is
->next
){
1225 str
= g_string_append( str
, LIST_SEPARATOR
);
1227 str
= g_string_append( str
, ( const gchar
* ) is
->data
);
1231 return( g_string_free( str
, FALSE
));
1235 string_list_to_string_list( const FMABoxed
*boxed
)
1237 return( fma_core_utils_slist_duplicate( boxed
->private->u
.string_list
));
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
));
1247 string_list_to_void( const FMABoxed
*boxed
)
1251 if( boxed
->private->u
.string_list
){
1252 value
= fma_core_utils_slist_duplicate( boxed
->private->u
.string_list
);
1259 locale_are_equal( const FMABoxed
*a
, const FMABoxed
*b
)
1261 if( !a
->private->u
.string
&& !b
->private->u
.string
){
1264 if( !a
->private->u
.string
|| !b
->private->u
.string
){
1267 return( fma_core_utils_str_collate( a
->private->u
.string
, b
->private->u
.string
) == 0 );
1271 uint_are_equal( const FMABoxed
*a
, const FMABoxed
*b
)
1273 return( a
->private->u
.uint
== b
->private->u
.uint
);
1277 uint_copy( FMABoxed
*dest
, const FMABoxed
*src
)
1279 dest
->private->u
.uint
= src
->private->u
.uint
;
1280 dest
->private->is_set
= TRUE
;
1284 uint_free( FMABoxed
*boxed
)
1286 boxed
->private->u
.uint
= 0;
1287 boxed
->private->is_set
= FALSE
;
1291 uint_from_string( FMABoxed
*boxed
, const gchar
*string
)
1293 boxed
->private->u
.uint
= string
? atoi( string
) : 0;
1297 uint_from_value( FMABoxed
*boxed
, const GValue
*value
)
1299 boxed
->private->u
.uint
= g_value_get_uint( value
);
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
));
1315 uint_to_string( const FMABoxed
*boxed
)
1317 return( g_strdup_printf( "%u", boxed
->private->u
.uint
));
1321 uint_to_uint( const FMABoxed
*boxed
)
1323 return( boxed
->private->u
.uint
);
1327 uint_to_value( const FMABoxed
*boxed
, GValue
*value
)
1329 g_value_set_uint( value
, boxed
->private->u
.uint
);
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
1344 uint_list_are_equal( const FMABoxed
*a
, const FMABoxed
*b
)
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
)){
1364 uint_list_copy( FMABoxed
*dest
, const FMABoxed
*src
)
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
);
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
;
1384 uint_list_from_string( FMABoxed
*boxed
, const gchar
*string
)
1389 array
= string_to_array( string
);
1392 i
= ( gchar
** ) array
;
1394 boxed
->private->u
.uint_list
= g_list_prepend( boxed
->private->u
.uint_list
, GINT_TO_POINTER( atoi( *i
)));
1397 boxed
->private->u
.uint_list
= g_list_reverse( boxed
->private->u
.uint_list
);
1399 boxed
->private->u
.uint_list
= NULL
;
1402 g_strfreev( array
);
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
));
1414 uint_list_from_void( FMABoxed
*boxed
, const void *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
);
1428 uint_list_to_string( const FMABoxed
*boxed
)
1431 GString
*str
= g_string_new( "" );
1435 for( is
= boxed
->private->u
.uint_list
; is
; is
= is
->next
){
1437 str
= g_string_append( str
, LIST_SEPARATOR
);
1439 g_string_append_printf( str
, "%u", GPOINTER_TO_UINT( is
->data
));
1443 return( g_string_free( str
, FALSE
));
1447 uint_list_to_uint_list( const FMABoxed
*boxed
)
1449 return( g_list_copy( boxed
->private->u
.uint_list
));
1453 uint_list_to_value( const FMABoxed
*boxed
, GValue
*value
)
1455 g_value_set_pointer( value
, g_list_copy( boxed
->private->u
.uint_list
));
1459 uint_list_to_void( const FMABoxed
*boxed
)
1463 if( boxed
->private->u
.uint_list
){
1464 value
= g_list_copy( boxed
->private->u
.uint_list
);