Define new 'pivot-prop-loadable' property
[nautilus-actions.git] / src / core / na-boxed.c
blob635570c62e40c9e1f9cb28465931397ba7bca9bf
1 /*
2 * Nautilus-Actions
3 * A Nautilus extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
9 * This Program 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 * This Program 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
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this Library; see the file COPYING. If not,
21 * write to the Free Software Foundation, Inc., 59 Temple Place,
22 * Suite 330, Boston, MA 02111-1307, USA.
24 * Authors:
25 * Frederic Ruaudel <grumz@grumz.net>
26 * Rodrigo Moya <rodrigo@gnome-db.org>
27 * Pierre Wieser <pwieser@trychlos.org>
28 * ... and many others (see AUTHORS)
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include <stdlib.h>
36 #include <string.h>
38 #include <api/na-boxed.h>
39 #include <api/na-data-types.h>
40 #include <api/na-core-utils.h>
42 /* private class data
44 struct _NABoxedClassPrivate {
45 void *empty; /* so that gcc -pedantic is happy */
48 /* BoxedDef:
49 * This is the structure which fully defines the behavior of this data type.
51 typedef struct {
52 guint type;
53 const gchar *label;
54 gboolean ( *are_equal ) ( const NABoxed *, const NABoxed * );
55 void ( *copy ) ( NABoxed *, const NABoxed * );
56 void ( *free ) ( NABoxed * );
57 void ( *from_string ) ( NABoxed *, const gchar * );
58 void ( *from_value ) ( NABoxed *, const GValue * );
59 void ( *from_void ) ( NABoxed *, const void * );
60 gboolean ( *to_bool ) ( const NABoxed * );
61 gconstpointer ( *to_pointer ) ( const NABoxed * );
62 gchar * ( *to_string ) ( const NABoxed * );
63 GSList * ( *to_string_list )( const NABoxed * );
64 guint ( *to_uint ) ( const NABoxed * );
65 GList * ( *to_uint_list ) ( const NABoxed * );
66 void ( *to_value ) ( const NABoxed *, GValue * );
67 void * ( *to_void ) ( const NABoxed * );
69 BoxedDef;
71 /* private instance data
73 struct _NABoxedPrivate {
74 gboolean dispose_has_run;
75 const BoxedDef *def;
76 gboolean is_set;
77 union {
78 gboolean boolean;
79 void *pointer;
80 gchar *string;
81 GSList *string_list;
82 guint uint;
83 GList *uint_list;
84 } u;
87 #define LIST_SEPARATOR ";"
89 static GObjectClass *st_parent_class = NULL;
91 static GType register_type( void );
92 static void class_init( NABoxedClass *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 NABoxed *boxed_new( const BoxedDef *def );
98 static const BoxedDef *get_boxed_def( guint type );
99 static gchar **string_to_array( const gchar *string );
101 static gboolean bool_are_equal( const NABoxed *a, const NABoxed *b );
102 static void bool_copy( NABoxed *dest, const NABoxed *src );
103 static void bool_free( NABoxed *boxed );
104 static void bool_from_string( NABoxed *boxed, const gchar *string );
105 static void bool_from_value( NABoxed *boxed, const GValue *value );
106 static void bool_from_void( NABoxed *boxed, const void *value );
107 static gchar *bool_to_string( const NABoxed *boxed );
108 static gboolean bool_to_bool( const NABoxed *boxed );
109 static gconstpointer bool_to_pointer( const NABoxed *boxed );
110 static gchar *bool_to_string( const NABoxed *boxed );
111 static void bool_to_value( const NABoxed *boxed, GValue *value );
112 static void *bool_to_void( const NABoxed *boxed );
114 static gboolean pointer_are_equal( const NABoxed *a, const NABoxed *b );
115 static void pointer_copy( NABoxed *dest, const NABoxed *src );
116 static void pointer_free( NABoxed *boxed );
117 static void pointer_from_string( NABoxed *boxed, const gchar *string );
118 static void pointer_from_value( NABoxed *boxed, const GValue *value );
119 static void pointer_from_void( NABoxed *boxed, const void *value );
120 static gconstpointer pointer_to_pointer( const NABoxed *boxed );
121 static gchar *pointer_to_string( const NABoxed *boxed );
122 static void pointer_to_value( const NABoxed *boxed, GValue *value );
123 static void *pointer_to_void( const NABoxed *boxed );
125 static gboolean string_are_equal( const NABoxed *a, const NABoxed *b );
126 static void string_copy( NABoxed *dest, const NABoxed *src );
127 static void string_free( NABoxed *boxed );
128 static void string_from_string( NABoxed *boxed, const gchar *string );
129 static void string_from_value( NABoxed *boxed, const GValue *value );
130 static void string_from_void( NABoxed *boxed, const void *value );
131 static gconstpointer string_to_pointer( const NABoxed *boxed );
132 static gchar *string_to_string( const NABoxed *boxed );
133 static void string_to_value( const NABoxed *boxed, GValue *value );
134 static void *string_to_void( const NABoxed *boxed );
136 static gboolean string_list_are_equal( const NABoxed *a, const NABoxed *b );
137 static void string_list_copy( NABoxed *dest, const NABoxed *src );
138 static void string_list_free( NABoxed *boxed );
139 static void string_list_from_string( NABoxed *boxed, const gchar *string );
140 static void string_list_from_value( NABoxed *boxed, const GValue *value );
141 static void string_list_from_void( NABoxed *boxed, const void *value );
142 static gconstpointer string_list_to_pointer( const NABoxed *boxed );
143 static gchar *string_list_to_string( const NABoxed *boxed );
144 static GSList *string_list_to_string_list( const NABoxed *boxed );
145 static void string_list_to_value( const NABoxed *boxed, GValue *value );
146 static void *string_list_to_void( const NABoxed *boxed );
148 static gboolean locale_are_equal( const NABoxed *a, const NABoxed *b );
150 static gboolean uint_are_equal( const NABoxed *a, const NABoxed *b );
151 static void uint_copy( NABoxed *dest, const NABoxed *src );
152 static void uint_free( NABoxed *boxed );
153 static void uint_from_string( NABoxed *boxed, const gchar *string );
154 static void uint_from_value( NABoxed *boxed, const GValue *value );
155 static void uint_from_void( NABoxed *boxed, const void *value );
156 static gconstpointer uint_to_pointer( const NABoxed *boxed );
157 static gchar *uint_to_string( const NABoxed *boxed );
158 static guint uint_to_uint( const NABoxed *boxed );
159 static void uint_to_value( const NABoxed *boxed, GValue *value );
160 static void *uint_to_void( const NABoxed *boxed );
162 static gboolean uint_list_are_equal( const NABoxed *a, const NABoxed *b );
163 static void uint_list_copy( NABoxed *dest, const NABoxed *src );
164 static void uint_list_free( NABoxed *boxed );
165 static void uint_list_from_string( NABoxed *boxed, const gchar *string );
166 static void uint_list_from_value( NABoxed *boxed, const GValue *value );
167 static void uint_list_from_void( NABoxed *boxed, const void *value );
168 static gconstpointer uint_list_to_pointer( const NABoxed *boxed );
169 static gchar *uint_list_to_string( const NABoxed *boxed );
170 static GList *uint_list_to_uint_list( const NABoxed *boxed );
171 static void uint_list_to_value( const NABoxed *boxed, GValue *value );
172 static void *uint_list_to_void( const NABoxed *boxed );
174 static BoxedDef st_boxed_def[] = {
175 { NA_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 { NA_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 { NA_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 { NA_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 { NA_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 { NA_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 { NA_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 na_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 = "na_boxed_register_type";
313 GType type;
315 static GTypeInfo info = {
316 sizeof( NABoxedClass ),
317 NULL,
318 NULL,
319 ( GClassInitFunc ) class_init,
320 NULL,
321 NULL,
322 sizeof( NABoxed ),
324 ( GInstanceInitFunc ) instance_init
327 g_debug( "%s", thisfn );
329 type = g_type_register_static( G_TYPE_OBJECT, "NABoxed", &info, 0 );
331 return( type );
334 static void
335 class_init( NABoxedClass *klass )
337 static const gchar *thisfn = "na_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( NABoxedClassPrivate, 1 );
351 static void
352 instance_init( GTypeInstance *instance, gpointer klass )
354 static const gchar *thisfn = "na_boxed_instance_init";
355 NABoxed *self;
357 g_return_if_fail( NA_IS_BOXED( instance ));
359 g_debug( "%s: instance=%p (%s), klass=%p",
360 thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
362 self = NA_BOXED( instance );
364 self->private = g_new0( NABoxedPrivate, 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 NABoxed *self;
376 g_return_if_fail( NA_IS_BOXED( object ));
378 self = NA_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 = "na_boxed_instance_finalize";
395 NABoxed *self;
397 g_return_if_fail( NA_IS_BOXED( object ));
399 g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
401 self = NA_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 NABoxed *
418 boxed_new( const BoxedDef *def )
420 NABoxed *boxed;
422 boxed = g_object_new( NA_BOXED_TYPE, NULL );
423 boxed->private->def = def;
425 return( boxed );
428 static const BoxedDef *
429 get_boxed_def( guint type )
431 static const gchar *thisfn = "na_boxed_get_boxed_def";
432 BoxedDef *def;
434 for( def = st_boxed_def ; def->type ; ++def ){
435 if( def->type == type ){
436 return(( const BoxedDef * ) def );
440 g_warning( "%s: unmanaged data type: %d", thisfn, type );
441 return( NULL );
445 * converts a string to an array of string
446 * the last separator, if any, is not counted
448 static gchar **
449 string_to_array( const gchar *string )
451 gchar *sdup;
452 gchar **array;
454 array = NULL;
456 if( string && strlen( string )){
457 sdup = g_strdup( string );
458 if( g_str_has_suffix( string, LIST_SEPARATOR )){
459 sdup[strlen(sdup)-1] = '\0';
460 sdup = g_strstrip( sdup );
462 array = g_strsplit( sdup, LIST_SEPARATOR, -1 );
463 g_free( sdup );
466 return( array );
470 * na_boxed_set_type:
471 * @boxed: this #NABoxed object.
472 * @type: the required type as defined in na-data-types.h
474 * Set the type of the just-allocated @boxed object.
476 * Since: 3.1.0
478 void
479 na_boxed_set_type( NABoxed *boxed, guint type )
481 g_return_if_fail( NA_IS_BOXED( boxed ));
482 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
483 g_return_if_fail( boxed->private->def == NULL );
485 boxed->private->def = get_boxed_def( type );
489 * na_boxed_are_equal:
490 * @a: the first #NABoxed object.
491 * @b: the second #NABoxed object.
493 * Returns: %TRUE if @a and @b are equal, %FALSE else.
495 * Since: 3.1.0
497 gboolean
498 na_boxed_are_equal( const NABoxed *a, const NABoxed *b )
500 gboolean are_equal;
502 g_return_val_if_fail( NA_IS_BOXED( a ), FALSE );
503 g_return_val_if_fail( a->private->dispose_has_run == FALSE, FALSE );
504 g_return_val_if_fail( NA_IS_BOXED( b ), FALSE );
505 g_return_val_if_fail( b->private->dispose_has_run == FALSE, FALSE );
506 g_return_val_if_fail( a->private->def, FALSE );
507 g_return_val_if_fail( a->private->def == b->private->def, FALSE );
508 g_return_val_if_fail( a->private->def->are_equal, FALSE );
510 are_equal = FALSE;
512 if( a->private->is_set == b->private->is_set ){
513 are_equal = TRUE;
514 if( a->private->is_set ){
515 are_equal = ( *a->private->def->are_equal )( a, b );
519 return( are_equal );
523 * na_boxed_copy:
524 * @boxed: the source #NABoxed box.
526 * Returns: a copy of @boxed, as a newly allocated #NABoxed which should
527 * be g_object_unref() by the caller.
529 * Since: 3.1.0
531 NABoxed *
532 na_boxed_copy( const NABoxed *boxed )
534 NABoxed *dest;
536 g_return_val_if_fail( NA_IS_BOXED( boxed ), NULL );
537 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
538 g_return_val_if_fail( boxed->private->def, NULL );
539 g_return_val_if_fail( boxed->private->def->copy, NULL );
541 dest = boxed_new( boxed->private->def );
542 if( boxed->private->is_set ){
543 ( *boxed->private->def->copy )( dest, boxed );
544 dest->private->is_set = TRUE;
547 return( dest );
551 * na_boxed_dump:
552 * @boxed: the #NABoxed box to be dumped.
554 * Dumps the @boxed box.
556 * Since: 3.1.0
558 void
559 na_boxed_dump( const NABoxed *boxed )
561 static const gchar *thisfn = "na_boxed_dump";
562 gchar *str;
564 g_return_if_fail( NA_IS_BOXED( boxed ));
565 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
566 g_return_if_fail( boxed->private->def );
567 g_return_if_fail( boxed->private->def->to_string );
569 str = ( boxed->private->is_set ) ? ( *boxed->private->def->to_string )( boxed ) : NULL;
570 g_debug( "%s: boxed=%p, type=%u, is_set=%s, value=%s",
571 thisfn, ( void * ) boxed, boxed->private->def->type,
572 boxed->private->is_set ? "True":"False", str );
573 g_free( str );
577 * na_boxed_new_from_string:
578 * @type: the type of the #NABoxed to be allocated.
579 * @string: the initial value of the #NABoxed as a string.
581 * Allocates a new #NABoxed of the specified @type, and initializes it
582 * with @string.
584 * If the type is a list, then the last separator is automatically stripped.
586 * Returns: a newly allocated #NABoxed, which should be g_object_unref()
587 * by the caller, or %NULL if the type is unknowned, or does not provide
588 * the 'from_string' function.
590 * Since: 3.1.0
592 NABoxed *
593 na_boxed_new_from_string( guint type, const gchar *string )
595 const BoxedDef *def;
596 NABoxed *boxed;
598 def = get_boxed_def( type );
600 g_return_val_if_fail( def, NULL );
601 g_return_val_if_fail( def->from_string, NULL );
603 boxed = boxed_new( def );
604 ( *def->from_string )( boxed, string );
605 boxed->private->is_set = TRUE;
607 return( boxed );
611 * na_boxed_get_boolean:
612 * @boxed: the #NABoxed structure.
614 * Returns: the boolean value if @boxed is of %NA_DATA_TYPE_BOOLEAN type,
615 * %FALSE else.
617 * Since: 3.1.0
619 gboolean
620 na_boxed_get_boolean( const NABoxed *boxed )
622 gboolean value;
624 g_return_val_if_fail( NA_IS_BOXED( boxed ), FALSE );
625 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, FALSE );
626 g_return_val_if_fail( boxed->private->def, FALSE );
627 g_return_val_if_fail( boxed->private->def->type == NA_DATA_TYPE_BOOLEAN, FALSE );
628 g_return_val_if_fail( boxed->private->def->to_bool, FALSE );
630 value = ( *boxed->private->def->to_bool )( boxed );
632 return( value );
636 * na_boxed_get_pointer:
637 * @boxed: the #NABoxed structure.
639 * Returns: a const pointer to the data if @boxed is of %NA_DATA_TYPE_POINTER
640 * type, %NULL else.
642 * Since: 3.1.0
644 gconstpointer
645 na_boxed_get_pointer( const NABoxed *boxed )
647 gconstpointer value;
649 g_return_val_if_fail( NA_IS_BOXED( boxed ), NULL );
650 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
651 g_return_val_if_fail( boxed->private->def, NULL );
652 g_return_val_if_fail( boxed->private->def->to_pointer, NULL );
654 value = ( *boxed->private->def->to_pointer )( boxed );
656 return( value );
660 * na_boxed_get_string:
661 * @boxed: the #NABoxed structure.
663 * Returns: a newly allocated string if @boxed is of %NA_DATA_TYPE_STRING
664 * type, which should be g_free() by the caller, %NULL else.
666 * Since: 3.1.0
668 gchar *
669 na_boxed_get_string( const NABoxed *boxed )
671 gchar *value;
673 g_return_val_if_fail( NA_IS_BOXED( boxed ), NULL );
674 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
675 g_return_val_if_fail( boxed->private->def, NULL );
676 g_return_val_if_fail( boxed->private->def->to_string, NULL );
678 value = ( *boxed->private->def->to_string )( boxed );
680 return( value );
684 * na_boxed_get_string_list:
685 * @boxed: the #NABoxed structure.
687 * Returns: a newly allocated string list if @boxed is of %NA_DATA_TYPE_STRING_LIST
688 * type, which should be na_core_utils_slist_free() by the caller, %NULL else.
690 * Since: 3.1.0
692 GSList *
693 na_boxed_get_string_list( const NABoxed *boxed )
695 GSList *value;
697 g_return_val_if_fail( NA_IS_BOXED( boxed ), NULL );
698 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
699 g_return_val_if_fail( boxed->private->def, NULL );
700 g_return_val_if_fail( boxed->private->def->type == NA_DATA_TYPE_STRING_LIST, NULL );
701 g_return_val_if_fail( boxed->private->def->to_string_list, NULL );
703 value = ( *boxed->private->def->to_string_list )( boxed );
705 return( value );
709 * na_boxed_get_uint:
710 * @boxed: the #NABoxed structure.
712 * Returns: an unsigned integer if @boxed is of %NA_DATA_TYPE_UINT type,
713 * zero else.
715 * Since: 3.1.0
717 guint
718 na_boxed_get_uint( const NABoxed *boxed )
720 guint value;
722 g_return_val_if_fail( NA_IS_BOXED( boxed ), 0 );
723 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, 0 );
724 g_return_val_if_fail( boxed->private->def, 0 );
725 g_return_val_if_fail( boxed->private->def->type == NA_DATA_TYPE_UINT, 0 );
726 g_return_val_if_fail( boxed->private->def->to_uint, 0 );
728 value = ( *boxed->private->def->to_uint )( boxed );
730 return( value );
734 * na_boxed_get_uint_list:
735 * @boxed: the #NABoxed structure.
737 * Returns: a newly allocated list if @boxed is of %NA_DATA_TYPE_UINT_LIST
738 * type, which should be g_list_free() by the caller, %FALSE else.
740 * Since: 3.1.0
742 GList *
743 na_boxed_get_uint_list( const NABoxed *boxed )
745 GList *value;
747 g_return_val_if_fail( NA_IS_BOXED( boxed ), NULL );
748 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
749 g_return_val_if_fail( boxed->private->def, NULL );
750 g_return_val_if_fail( boxed->private->def->type == NA_DATA_TYPE_UINT_LIST, NULL );
751 g_return_val_if_fail( boxed->private->def->to_uint_list, NULL );
753 value = ( *boxed->private->def->to_uint_list )( boxed );
755 return( value );
759 * na_boxed_get_as_value:
760 * @boxed: the #NABoxed whose value is to be got.
761 * @value: the #GValue which holds the string to be set.
763 * Setup @value with the content of the @boxed.
765 * Since: 3.1.0
767 void
768 na_boxed_get_as_value( const NABoxed *boxed, GValue *value )
770 g_return_if_fail( NA_IS_BOXED( boxed ));
771 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
772 g_return_if_fail( boxed->private->def );
773 g_return_if_fail( boxed->private->def->to_value );
775 ( *boxed->private->def->to_value )( boxed, value );
779 * na_boxed_get_as_void:
780 * @boxed: the #NABoxed whose value is to be got.
782 * Returns: the content of the @boxed.
784 * If of type NA_DATA_TYPE_STRING (resp. NA_DATA_TYPE_LOCALE_STRING,
785 * NA_DATA_TYPE_STRING_LIST or NA_DATA_TYPE_UINT_LIST), then the content
786 * is returned in a newly allocated value, which should be g_free() (resp.
787 * g_free(), na_core_utils_slist_free(), g_list_free()) by the caller.
789 * Since: 3.1.0
791 void *
792 na_boxed_get_as_void( const NABoxed *boxed )
794 g_return_val_if_fail( NA_IS_BOXED( boxed ), NULL );
795 g_return_val_if_fail( boxed->private->dispose_has_run == FALSE, NULL );
796 g_return_val_if_fail( boxed->private->def, NULL );
797 g_return_val_if_fail( boxed->private->def->to_void, NULL );
799 return(( *boxed->private->def->to_void )( boxed ));
803 * na_boxed_set_from_boxed:
804 * @boxed: the #NABoxed whose value is to be set.
805 * @value: the source #NABoxed.
807 * Copy value from @value to @boxed.
809 * Since: 3.1.0
811 void
812 na_boxed_set_from_boxed( NABoxed *boxed, const NABoxed *value )
814 g_return_if_fail( NA_IS_BOXED( boxed ));
815 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
816 g_return_if_fail( NA_IS_BOXED( value ));
817 g_return_if_fail( value->private->dispose_has_run == FALSE );
818 g_return_if_fail( boxed->private->def );
819 g_return_if_fail( boxed->private->def == value->private->def );
820 g_return_if_fail( boxed->private->def->copy );
821 g_return_if_fail( boxed->private->def->free );
823 ( *boxed->private->def->free )( boxed );
824 ( *boxed->private->def->copy )( boxed, value );
825 boxed->private->is_set = TRUE;
829 * na_boxed_set_from_string:
830 * @boxed: the #NABoxed whose value is to be set.
831 * @value: the string to be set.
833 * Evaluates the @value and set it to the @boxed.
835 * Since: 3.1.0
837 void
838 na_boxed_set_from_string( NABoxed *boxed, const gchar *value )
840 g_return_if_fail( NA_IS_BOXED( boxed ));
841 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
842 g_return_if_fail( boxed->private->def );
843 g_return_if_fail( boxed->private->def->free );
844 g_return_if_fail( boxed->private->def->from_string );
846 ( *boxed->private->def->free )( boxed );
847 ( *boxed->private->def->from_string )( boxed, value );
848 boxed->private->is_set = TRUE;
852 * na_boxed_set_from_value:
853 * @boxed: the #NABoxed whose value is to be set.
854 * @value: the value whose content is to be got.
856 * Evaluates the @value and set it to the @boxed.
858 * Since: 3.1.0
860 void
861 na_boxed_set_from_value( NABoxed *boxed, const GValue *value )
863 g_return_if_fail( NA_IS_BOXED( boxed ));
864 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
865 g_return_if_fail( boxed->private->def );
866 g_return_if_fail( boxed->private->def->free );
867 g_return_if_fail( boxed->private->def->from_value );
869 ( *boxed->private->def->free )( boxed );
870 ( *boxed->private->def->from_value )( boxed, value );
871 boxed->private->is_set = TRUE;
875 * na_boxed_set_from_void:
876 * @boxed: the #NABoxed whose value is to be set.
877 * @value: the value whose content is to be got.
879 * Evaluates the @value and set it to the @boxed.
881 * Since: 3.1.0
883 void
884 na_boxed_set_from_void( NABoxed *boxed, const void *value )
886 g_return_if_fail( NA_IS_BOXED( boxed ));
887 g_return_if_fail( boxed->private->dispose_has_run == FALSE );
888 g_return_if_fail( boxed->private->def );
889 g_return_if_fail( boxed->private->def->free );
890 g_return_if_fail( boxed->private->def->from_void );
892 ( *boxed->private->def->free )( boxed );
893 ( *boxed->private->def->from_void )( boxed, value );
894 boxed->private->is_set = TRUE;
897 static gboolean
898 bool_are_equal( const NABoxed *a, const NABoxed *b )
900 return( a->private->u.boolean == b->private->u.boolean );
903 static void
904 bool_copy( NABoxed *dest, const NABoxed *src )
906 dest->private->u.boolean = src->private->u.boolean;
909 static void
910 bool_free( NABoxed *boxed )
912 boxed->private->u.boolean = FALSE;
913 boxed->private->is_set = FALSE;
916 static void
917 bool_from_string( NABoxed *boxed, const gchar *string )
919 boxed->private->u.boolean = na_core_utils_boolean_from_string( string );
922 static void
923 bool_from_value( NABoxed *boxed, const GValue *value )
925 boxed->private->u.boolean = g_value_get_boolean( value );
928 static void
929 bool_from_void( NABoxed *boxed, const void *value )
931 boxed->private->u.boolean = GPOINTER_TO_UINT( value );
934 static gboolean
935 bool_to_bool( const NABoxed *boxed )
937 return( boxed->private->u.boolean );
940 static gconstpointer
941 bool_to_pointer( const NABoxed *boxed )
943 return(( gconstpointer ) GUINT_TO_POINTER( boxed->private->u.boolean ));
946 static gchar *
947 bool_to_string( const NABoxed *boxed )
949 return( g_strdup_printf( "%s", boxed->private->u.boolean ? "true":"false" ));
952 static void
953 bool_to_value( const NABoxed *boxed, GValue *value )
955 g_value_set_boolean( value, boxed->private->u.boolean );
958 static void *
959 bool_to_void( const NABoxed *boxed )
961 return( GUINT_TO_POINTER( boxed->private->u.boolean ));
964 static gboolean
965 pointer_are_equal( const NABoxed *a, const NABoxed *b )
967 return( a->private->u.pointer == b->private->u.pointer );
971 * note that copying a pointer is not safe
973 static void
974 pointer_copy( NABoxed *dest, const NABoxed *src )
976 dest->private->u.pointer = src->private->u.pointer;
979 static void
980 pointer_free( NABoxed *boxed )
982 boxed->private->u.pointer = NULL;
983 boxed->private->is_set = FALSE;
986 static void
987 pointer_from_string( NABoxed *boxed, const gchar *pointer )
989 g_warning( "na_boxed_pointer_from_string: unrelevant function call" );
992 static void
993 pointer_from_value( NABoxed *boxed, const GValue *value )
995 boxed->private->u.pointer = g_value_get_pointer( value );
998 static void
999 pointer_from_void( NABoxed *boxed, const void *value )
1001 boxed->private->u.pointer = ( void * ) value;
1004 static gconstpointer
1005 pointer_to_pointer( const NABoxed *boxed )
1007 return( boxed->private->u.pointer );
1010 static gchar *
1011 pointer_to_string( const NABoxed *boxed )
1013 return( g_strdup_printf( "%p", boxed->private->u.pointer ));
1016 static void
1017 pointer_to_value( const NABoxed *boxed, GValue *value )
1019 g_value_set_pointer( value, boxed->private->u.pointer );
1022 static void *
1023 pointer_to_void( const NABoxed *boxed )
1025 return( boxed->private->u.pointer );
1028 static gboolean
1029 string_are_equal( const NABoxed *a, const NABoxed *b )
1031 if( a->private->u.string && b->private->u.string ){
1032 return( strcmp( a->private->u.string, b->private->u.string ) == 0 );
1034 if( !a->private->u.string && !b->private->u.string ){
1035 return( TRUE );
1037 return( FALSE );
1040 static void
1041 string_copy( NABoxed *dest, const NABoxed *src )
1043 dest->private->u.string = g_strdup( src->private->u.string );
1046 static void
1047 string_free( NABoxed *boxed )
1049 g_free( boxed->private->u.string );
1050 boxed->private->u.string = NULL;
1051 boxed->private->is_set = FALSE;
1054 static void
1055 string_from_string( NABoxed *boxed, const gchar *string )
1057 boxed->private->u.string = g_strdup( string ? string : "" );
1060 static void
1061 string_from_value( NABoxed *boxed, const GValue *value )
1063 if( g_value_get_string( value )){
1064 boxed->private->u.string = g_value_dup_string( value );
1065 } else {
1066 boxed->private->u.string = g_strdup( "" );
1070 static void
1071 string_from_void( NABoxed *boxed, const void *value )
1073 boxed->private->u.string = g_strdup( value ? ( const gchar * ) value : "" );
1076 static gconstpointer
1077 string_to_pointer( const NABoxed *boxed )
1079 return(( gconstpointer ) boxed->private->u.string );
1082 static gchar *
1083 string_to_string( const NABoxed *boxed )
1085 return( g_strdup( boxed->private->u.string ));
1088 static void
1089 string_to_value( const NABoxed *boxed, GValue *value )
1091 gchar *str;
1093 str = string_to_string( boxed );
1094 g_value_set_string( value, str );
1095 g_free( str );
1098 static void *
1099 string_to_void( const NABoxed *boxed )
1101 return(( void * ) string_to_string( boxed ));
1104 /* the two string lists are equal if they have the same elements in the
1105 * same order
1107 static gboolean
1108 string_list_are_equal( const NABoxed *a, const NABoxed *b )
1110 GSList *ia, *ib;
1111 gboolean diff = FALSE;
1113 guint na = g_slist_length( a->private->u.string_list );
1114 guint nb = g_slist_length( b->private->u.string_list );
1116 if( na != nb ) return( FALSE );
1118 for( ia=a->private->u.string_list, ib=b->private->u.string_list ; ia && ib && !diff ; ia=ia->next, ib=ib->next ){
1119 if( strcmp( ia->data, ib->data ) != 0 ){
1120 diff = TRUE;
1124 return( !diff );
1127 static void
1128 string_list_copy( NABoxed *dest, const NABoxed *src )
1130 if( dest->private->is_set ){
1131 string_list_free( dest );
1133 dest->private->u.string_list = na_core_utils_slist_duplicate( src->private->u.string_list );
1134 dest->private->is_set = TRUE;
1137 static void
1138 string_list_free( NABoxed *boxed )
1140 na_core_utils_slist_free( boxed->private->u.string_list );
1141 boxed->private->u.string_list = NULL;
1142 boxed->private->is_set = FALSE;
1145 static void
1146 string_list_from_string( NABoxed *boxed, const gchar *string )
1148 gchar **array;
1149 gchar **i;
1151 array = string_to_array( string );
1153 if( array ){
1154 i = ( gchar ** ) array;
1155 while( *i ){
1156 boxed->private->u.string_list = g_slist_prepend( boxed->private->u.string_list, g_strdup( *i ));
1157 i++;
1159 boxed->private->u.string_list = g_slist_reverse( boxed->private->u.string_list );
1160 } else {
1161 boxed->private->u.string_list = NULL;
1164 g_strfreev( array );
1167 static void
1168 string_list_from_value( NABoxed *boxed, const GValue *value )
1170 if( g_value_get_pointer( value )){
1171 boxed->private->u.string_list = na_core_utils_slist_duplicate( g_value_get_pointer( value ));
1175 static void
1176 string_list_from_void( NABoxed *boxed, const void *value )
1178 if( value ){
1179 boxed->private->u.string_list = na_core_utils_slist_duplicate(( GSList * ) value );
1183 static gconstpointer
1184 string_list_to_pointer( const NABoxed *boxed )
1186 return(( gconstpointer ) boxed->private->u.string_list );
1189 static gchar *
1190 string_list_to_string( const NABoxed *boxed )
1192 GSList *is;
1193 GString *str = g_string_new( "" );
1194 gboolean first;
1196 first = TRUE;
1197 for( is = boxed->private->u.string_list ; is ; is = is->next ){
1198 if( !first ){
1199 str = g_string_append( str, LIST_SEPARATOR );
1201 str = g_string_append( str, ( const gchar * ) is->data );
1202 first = FALSE;
1205 return( g_string_free( str, FALSE ));
1208 static GSList *
1209 string_list_to_string_list( const NABoxed *boxed )
1211 return( na_core_utils_slist_duplicate( boxed->private->u.string_list ));
1214 static void
1215 string_list_to_value( const NABoxed *boxed, GValue *value )
1217 g_value_set_pointer( value, na_core_utils_slist_duplicate( boxed->private->u.string_list ));
1220 static void *
1221 string_list_to_void( const NABoxed *boxed )
1223 void *value = NULL;
1225 if( boxed->private->u.string_list ){
1226 value = na_core_utils_slist_duplicate( boxed->private->u.string_list );
1229 return( value );
1232 static gboolean
1233 locale_are_equal( const NABoxed *a, const NABoxed *b )
1235 if( !a->private->u.string && !b->private->u.string ){
1236 return( TRUE );
1238 if( !a->private->u.string || !b->private->u.string ){
1239 return( FALSE );
1241 return( na_core_utils_str_collate( a->private->u.string, b->private->u.string ) == 0 );
1244 static gboolean
1245 uint_are_equal( const NABoxed *a, const NABoxed *b )
1247 return( a->private->u.uint == b->private->u.uint );
1250 static void
1251 uint_copy( NABoxed *dest, const NABoxed *src )
1253 dest->private->u.uint = src->private->u.uint;
1254 dest->private->is_set = TRUE;
1257 static void
1258 uint_free( NABoxed *boxed )
1260 boxed->private->u.uint = 0;
1261 boxed->private->is_set = FALSE;
1264 static void
1265 uint_from_string( NABoxed *boxed, const gchar *string )
1267 boxed->private->u.uint = string ? atoi( string ) : 0;
1270 static void
1271 uint_from_value( NABoxed *boxed, const GValue *value )
1273 boxed->private->u.uint = g_value_get_uint( value );
1276 static void
1277 uint_from_void( NABoxed *boxed, const void *value )
1279 boxed->private->u.uint = GPOINTER_TO_UINT( value );
1282 static gconstpointer
1283 uint_to_pointer( const NABoxed *boxed )
1285 return(( gconstpointer ) GUINT_TO_POINTER( boxed->private->u.uint ));
1288 static gchar *
1289 uint_to_string( const NABoxed *boxed )
1291 return( g_strdup_printf( "%u", boxed->private->u.uint ));
1294 static guint
1295 uint_to_uint( const NABoxed *boxed )
1297 return( boxed->private->u.uint );
1300 static void
1301 uint_to_value( const NABoxed *boxed, GValue *value )
1303 g_value_set_uint( value, boxed->private->u.uint );
1306 static void *
1307 uint_to_void( const NABoxed *boxed )
1309 return( GUINT_TO_POINTER( boxed->private->u.uint ));
1312 /* compare uint list as string list:
1313 * if the two list do not have the same count, then one is lesser than the other
1314 * if they have same count and same elements in same order, they are equal
1315 * else just arbitrarily return -1
1317 static gboolean
1318 uint_list_are_equal( const NABoxed *a, const NABoxed *b )
1320 GList *ia, *ib;
1321 gboolean diff = FALSE;
1323 guint na = g_list_length( a->private->u.uint_list );
1324 guint nb = g_list_length( b->private->u.uint_list );
1326 if( na != nb ) return( FALSE );
1328 for( ia=a->private->u.uint_list, ib=b->private->u.uint_list ; ia && ib && !diff ; ia=ia->next, ib=ib->next ){
1329 if( GPOINTER_TO_UINT( ia->data ) != GPOINTER_TO_UINT( ib->data )){
1330 diff = TRUE;
1334 return( !diff );
1337 static void
1338 uint_list_copy( NABoxed *dest, const NABoxed *src )
1340 GList *isrc;
1342 dest->private->u.uint_list = NULL;
1343 for( isrc = src->private->u.uint_list ; isrc ; isrc = isrc->next ){
1344 dest->private->u.uint_list = g_list_prepend( dest->private->u.uint_list, isrc->data );
1346 dest->private->u.uint_list = g_list_reverse( dest->private->u.uint_list );
1349 static void
1350 uint_list_free( NABoxed *boxed )
1352 g_list_free( boxed->private->u.uint_list );
1353 boxed->private->u.uint_list = NULL;
1354 boxed->private->is_set = FALSE;
1357 static void
1358 uint_list_from_string( NABoxed *boxed, const gchar *string )
1360 gchar **array;
1361 gchar **i;
1363 array = string_to_array( string );
1365 if( array ){
1366 i = ( gchar ** ) array;
1367 while( *i ){
1368 boxed->private->u.uint_list = g_list_prepend( boxed->private->u.uint_list, GINT_TO_POINTER( atoi( *i )));
1369 i++;
1371 boxed->private->u.uint_list = g_list_reverse( boxed->private->u.uint_list );
1372 } else {
1373 boxed->private->u.uint_list = NULL;
1376 g_strfreev( array );
1379 static void
1380 uint_list_from_value( NABoxed *boxed, const GValue *value )
1382 if( g_value_get_pointer( value )){
1383 boxed->private->u.uint_list = g_list_copy( g_value_get_pointer( value ));
1387 static void
1388 uint_list_from_void( NABoxed *boxed, const void *value )
1390 if( value ){
1391 boxed->private->u.uint_list = g_list_copy(( GList * ) value );
1395 static gconstpointer
1396 uint_list_to_pointer( const NABoxed *boxed )
1398 return(( gconstpointer ) boxed->private->u.uint_list );
1401 static gchar *
1402 uint_list_to_string( const NABoxed *boxed )
1404 GList *is;
1405 GString *str = g_string_new( "" );
1406 gboolean first;
1408 first = TRUE;
1409 for( is = boxed->private->u.uint_list ; is ; is = is->next ){
1410 if( !first ){
1411 str = g_string_append( str, LIST_SEPARATOR );
1413 g_string_append_printf( str, "%u", GPOINTER_TO_UINT( is->data ));
1414 first = FALSE;
1417 return( g_string_free( str, FALSE ));
1420 static GList *
1421 uint_list_to_uint_list( const NABoxed *boxed )
1423 return( g_list_copy( boxed->private->u.uint_list ));
1426 static void
1427 uint_list_to_value( const NABoxed *boxed, GValue *value )
1429 g_value_set_pointer( value, g_list_copy( boxed->private->u.uint_list ));
1432 static void *
1433 uint_list_to_void( const NABoxed *boxed )
1435 void *value = NULL;
1437 if( boxed->private->u.uint_list ){
1438 value = g_list_copy( boxed->private->u.uint_list );
1441 return( value );