1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3 *
4 * Config file serialization and deserialization interface
5 * Copyright (C) 2001-2002 Sven Neumann <sven@gimp.org>
6 *
7 * This library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <string.h>
25
26 #include <gio/gio.h>
27
28 #include "libgimpbase/gimpbase.h"
29
30 #include "gimpconfigtypes.h"
31
32 #include "gimpconfigwriter.h"
33 #include "gimpconfig-iface.h"
34 #include "gimpconfig-deserialize.h"
35 #include "gimpconfig-serialize.h"
36 #include "gimpconfig-params.h"
37 #include "gimpconfig-utils.h"
38 #include "gimpscanner.h"
39
40 #include "libgimp/libgimp-intl.h"
41
42
43 /**
44 * SECTION: gimpconfig-iface
45 * @title: GimpConfig-iface
46 * @short_description: High-level API for libgimpconfig.
47 *
48 * High-level API for libgimpconfig.
49 **/
50
51
52 /*
53 * The GimpConfig serialization and deserialization interface.
54 */
55
56
57 /* local function prototypes */
58
59 static void gimp_config_iface_default_init (GimpConfigInterface *iface);
60 static void gimp_config_iface_base_init (GimpConfigInterface *iface);
61
62 static gboolean gimp_config_iface_serialize (GimpConfig *config,
63 GimpConfigWriter *writer,
64 gpointer data);
65 static gboolean gimp_config_iface_deserialize (GimpConfig *config,
66 GScanner *scanner,
67 gint nest_level,
68 gpointer data);
69 static GimpConfig * gimp_config_iface_duplicate (GimpConfig *config);
70 static gboolean gimp_config_iface_equal (GimpConfig *a,
71 GimpConfig *b);
72 static void gimp_config_iface_reset (GimpConfig *config);
73 static gboolean gimp_config_iface_copy (GimpConfig *src,
74 GimpConfig *dest,
75 GParamFlags flags);
76
77
78 /* private functions */
79
80
81 GType
gimp_config_get_type(void)82 gimp_config_get_type (void)
83 {
84 static GType config_iface_type = 0;
85
86 if (! config_iface_type)
87 {
88 const GTypeInfo config_iface_info =
89 {
90 sizeof (GimpConfigInterface),
91 (GBaseInitFunc) gimp_config_iface_base_init,
92 (GBaseFinalizeFunc) NULL,
93 (GClassInitFunc) gimp_config_iface_default_init,
94 (GClassFinalizeFunc) NULL,
95 };
96
97 config_iface_type = g_type_register_static (G_TYPE_INTERFACE,
98 "GimpConfigInterface",
99 &config_iface_info,
100 0);
101
102 g_type_interface_add_prerequisite (config_iface_type, G_TYPE_OBJECT);
103 }
104
105 return config_iface_type;
106 }
107
108 GType
gimp_config_interface_get_type(void)109 gimp_config_interface_get_type (void)
110 {
111 return gimp_config_get_type ();
112 }
113
114 static void
gimp_config_iface_default_init(GimpConfigInterface * iface)115 gimp_config_iface_default_init (GimpConfigInterface *iface)
116 {
117 iface->serialize = gimp_config_iface_serialize;
118 iface->deserialize = gimp_config_iface_deserialize;
119 iface->duplicate = gimp_config_iface_duplicate;
120 iface->equal = gimp_config_iface_equal;
121 iface->reset = gimp_config_iface_reset;
122 iface->copy = gimp_config_iface_copy;
123 }
124
125 static void
gimp_config_iface_base_init(GimpConfigInterface * iface)126 gimp_config_iface_base_init (GimpConfigInterface *iface)
127 {
128 /* always set these to NULL since we don't want to inherit them
129 * from parent classes
130 */
131 iface->serialize_property = NULL;
132 iface->deserialize_property = NULL;
133 }
134
135 static gboolean
gimp_config_iface_serialize(GimpConfig * config,GimpConfigWriter * writer,gpointer data)136 gimp_config_iface_serialize (GimpConfig *config,
137 GimpConfigWriter *writer,
138 gpointer data)
139 {
140 return gimp_config_serialize_properties (config, writer);
141 }
142
143 static gboolean
gimp_config_iface_deserialize(GimpConfig * config,GScanner * scanner,gint nest_level,gpointer data)144 gimp_config_iface_deserialize (GimpConfig *config,
145 GScanner *scanner,
146 gint nest_level,
147 gpointer data)
148 {
149 return gimp_config_deserialize_properties (config, scanner, nest_level);
150 }
151
152 static GimpConfig *
gimp_config_iface_duplicate(GimpConfig * config)153 gimp_config_iface_duplicate (GimpConfig *config)
154 {
155 GObject *object = G_OBJECT (config);
156 GObjectClass *klass = G_OBJECT_GET_CLASS (object);
157 GParamSpec **property_specs;
158 guint n_property_specs;
159 gint n_construct_properties = 0;
160 const gchar **construct_names = NULL;
161 GValue *construct_values = NULL;
162 guint i;
163 GObject *dup;
164
165 property_specs = g_object_class_list_properties (klass, &n_property_specs);
166
167 construct_names = g_new0 (const gchar *, n_property_specs);
168 construct_values = g_new0 (GValue, n_property_specs);
169
170 for (i = 0; i < n_property_specs; i++)
171 {
172 GParamSpec *prop_spec = property_specs[i];
173
174 if ((prop_spec->flags & G_PARAM_READABLE) &&
175 (prop_spec->flags & G_PARAM_WRITABLE) &&
176 (prop_spec->flags & G_PARAM_CONSTRUCT_ONLY))
177 {
178 construct_names[n_construct_properties] = prop_spec->name;
179
180 g_value_init (&construct_values[n_construct_properties],
181 prop_spec->value_type);
182 g_object_get_property (object, prop_spec->name,
183 &construct_values[n_construct_properties]);
184
185 n_construct_properties++;
186 }
187 }
188
189 g_free (property_specs);
190
191 dup = g_object_new_with_properties (G_TYPE_FROM_INSTANCE (object),
192 n_construct_properties,
193 (const gchar **) construct_names,
194 (const GValue *) construct_values);
195
196 for (i = 0; i < n_construct_properties; i++)
197 g_value_unset (&construct_values[i]);
198
199 g_free (construct_names);
200 g_free (construct_values);
201
202 gimp_config_copy (config, GIMP_CONFIG (dup), 0);
203
204 return GIMP_CONFIG (dup);
205 }
206
207 static gboolean
gimp_config_iface_equal(GimpConfig * a,GimpConfig * b)208 gimp_config_iface_equal (GimpConfig *a,
209 GimpConfig *b)
210 {
211 GObjectClass *klass;
212 GParamSpec **property_specs;
213 guint n_property_specs;
214 guint i;
215 gboolean equal = TRUE;
216
217 klass = G_OBJECT_GET_CLASS (a);
218
219 property_specs = g_object_class_list_properties (klass, &n_property_specs);
220
221 for (i = 0; equal && i < n_property_specs; i++)
222 {
223 GParamSpec *prop_spec;
224 GValue a_value = G_VALUE_INIT;
225 GValue b_value = G_VALUE_INIT;
226
227 prop_spec = property_specs[i];
228
229 if (! (prop_spec->flags & G_PARAM_READABLE))
230 continue;
231
232 g_value_init (&a_value, prop_spec->value_type);
233 g_value_init (&b_value, prop_spec->value_type);
234 g_object_get_property (G_OBJECT (a), prop_spec->name, &a_value);
235 g_object_get_property (G_OBJECT (b), prop_spec->name, &b_value);
236
237 if (g_param_values_cmp (prop_spec, &a_value, &b_value))
238 {
239 if ((prop_spec->flags & GIMP_CONFIG_PARAM_AGGREGATE) &&
240 G_IS_PARAM_SPEC_OBJECT (prop_spec) &&
241 g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
242 GIMP_TYPE_CONFIG))
243 {
244 if (! gimp_config_is_equal_to (g_value_get_object (&a_value),
245 g_value_get_object (&b_value)))
246 {
247 equal = FALSE;
248 }
249 }
250 else
251 {
252 equal = FALSE;
253 }
254 }
255
256 g_value_unset (&a_value);
257 g_value_unset (&b_value);
258 }
259
260 g_free (property_specs);
261
262 return equal;
263 }
264
265 static void
gimp_config_iface_reset(GimpConfig * config)266 gimp_config_iface_reset (GimpConfig *config)
267 {
268 gimp_config_reset_properties (G_OBJECT (config));
269 }
270
271 static gboolean
gimp_config_iface_copy(GimpConfig * src,GimpConfig * dest,GParamFlags flags)272 gimp_config_iface_copy (GimpConfig *src,
273 GimpConfig *dest,
274 GParamFlags flags)
275 {
276 return gimp_config_sync (G_OBJECT (src), G_OBJECT (dest), flags);
277 }
278
279
280 /* public functions */
281
282
283 /**
284 * gimp_config_serialize_to_file:
285 * @config: a #GObject that implements the #GimpConfigInterface.
286 * @filename: the name of the file to write the configuration to.
287 * @header: optional file header (must be ASCII only)
288 * @footer: optional file footer (must be ASCII only)
289 * @data: user data passed to the serialize implementation.
290 * @error: return location for a possible error
291 *
292 * Serializes the object properties of @config to the file specified
293 * by @filename. If a file with that name already exists, it is
294 * overwritten. Basically this function opens @filename for you and
295 * calls the serialize function of the @config's #GimpConfigInterface.
296 *
297 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
298 *
299 * Since: 2.4
300 **/
301 gboolean
gimp_config_serialize_to_file(GimpConfig * config,const gchar * filename,const gchar * header,const gchar * footer,gpointer data,GError ** error)302 gimp_config_serialize_to_file (GimpConfig *config,
303 const gchar *filename,
304 const gchar *header,
305 const gchar *footer,
306 gpointer data,
307 GError **error)
308 {
309 GimpConfigWriter *writer;
310
311 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
312 g_return_val_if_fail (filename != NULL, FALSE);
313 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
314
315 writer = gimp_config_writer_new_file (filename, TRUE, header, error);
316 if (!writer)
317 return FALSE;
318
319 GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
320
321 return gimp_config_writer_finish (writer, footer, error);
322 }
323
324 /**
325 * gimp_config_serialize_to_gfile:
326 * @config: a #GObject that implements the #GimpConfigInterface.
327 * @file: the #GFile to write the configuration to.
328 * @header: optional file header (must be ASCII only)
329 * @footer: optional file footer (must be ASCII only)
330 * @data: user data passed to the serialize implementation.
331 * @error: return location for a possible error
332 *
333 * Serializes the object properties of @config to the file specified
334 * by @file. If a file with that name already exists, it is
335 * overwritten. Basically this function opens @file for you and calls
336 * the serialize function of the @config's #GimpConfigInterface.
337 *
338 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
339 *
340 * Since: 2.10
341 **/
342 gboolean
gimp_config_serialize_to_gfile(GimpConfig * config,GFile * file,const gchar * header,const gchar * footer,gpointer data,GError ** error)343 gimp_config_serialize_to_gfile (GimpConfig *config,
344 GFile *file,
345 const gchar *header,
346 const gchar *footer,
347 gpointer data,
348 GError **error)
349 {
350 GimpConfigWriter *writer;
351
352 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
353 g_return_val_if_fail (G_IS_FILE (file), FALSE);
354 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
355
356 writer = gimp_config_writer_new_gfile (file, TRUE, header, error);
357 if (!writer)
358 return FALSE;
359
360 GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
361
362 return gimp_config_writer_finish (writer, footer, error);
363 }
364
365 /**
366 * gimp_config_serialize_to_stream:
367 * @config: a #GObject that implements the #GimpConfigInterface.
368 * @output: the #GOutputStream to write the configuration to.
369 * @header: optional file header (must be ASCII only)
370 * @footer: optional file footer (must be ASCII only)
371 * @data: user data passed to the serialize implementation.
372 * @error: return location for a possible error
373 *
374 * Serializes the object properties of @config to the stream specified
375 * by @output.
376 *
377 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
378 *
379 * Since: 2.10
380 **/
381 gboolean
gimp_config_serialize_to_stream(GimpConfig * config,GOutputStream * output,const gchar * header,const gchar * footer,gpointer data,GError ** error)382 gimp_config_serialize_to_stream (GimpConfig *config,
383 GOutputStream *output,
384 const gchar *header,
385 const gchar *footer,
386 gpointer data,
387 GError **error)
388 {
389 GimpConfigWriter *writer;
390
391 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
392 g_return_val_if_fail (G_IS_OUTPUT_STREAM (output), FALSE);
393 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
394
395 writer = gimp_config_writer_new_stream (output, header, error);
396 if (!writer)
397 return FALSE;
398
399 GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
400
401 return gimp_config_writer_finish (writer, footer, error);
402 }
403
404 /**
405 * gimp_config_serialize_to_fd:
406 * @config: a #GObject that implements the #GimpConfigInterface.
407 * @fd: a file descriptor, opened for writing
408 * @data: user data passed to the serialize implementation.
409 *
410 * Serializes the object properties of @config to the given file
411 * descriptor.
412 *
413 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
414 *
415 * Since: 2.4
416 **/
417 gboolean
gimp_config_serialize_to_fd(GimpConfig * config,gint fd,gpointer data)418 gimp_config_serialize_to_fd (GimpConfig *config,
419 gint fd,
420 gpointer data)
421 {
422 GimpConfigWriter *writer;
423
424 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
425 g_return_val_if_fail (fd > 0, FALSE);
426
427 writer = gimp_config_writer_new_fd (fd);
428 if (!writer)
429 return FALSE;
430
431 GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
432
433 return gimp_config_writer_finish (writer, NULL, NULL);
434 }
435
436 /**
437 * gimp_config_serialize_to_string:
438 * @config: a #GObject that implements the #GimpConfigInterface.
439 * @data: user data passed to the serialize implementation.
440 *
441 * Serializes the object properties of @config to a string.
442 *
443 * Return value: a newly allocated NUL-terminated string.
444 *
445 * Since: 2.4
446 **/
447 gchar *
gimp_config_serialize_to_string(GimpConfig * config,gpointer data)448 gimp_config_serialize_to_string (GimpConfig *config,
449 gpointer data)
450 {
451 GimpConfigWriter *writer;
452 GString *str;
453
454 g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
455
456 str = g_string_new (NULL);
457 writer = gimp_config_writer_new_string (str);
458
459 GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
460
461 gimp_config_writer_finish (writer, NULL, NULL);
462
463 return g_string_free (str, FALSE);
464 }
465
466 /**
467 * gimp_config_deserialize_file:
468 * @config: a #GObject that implements the #GimpConfigInterface.
469 * @filename: the name of the file to read configuration from.
470 * @data: user data passed to the deserialize implementation.
471 * @error: return location for a possible error
472 *
473 * Opens the file specified by @filename, reads configuration data
474 * from it and configures @config accordingly. Basically this function
475 * creates a properly configured #GScanner for you and calls the
476 * deserialize function of the @config's #GimpConfigInterface.
477 *
478 * Return value: %TRUE if deserialization succeeded, %FALSE otherwise.
479 *
480 * Since: 2.4
481 **/
482 gboolean
gimp_config_deserialize_file(GimpConfig * config,const gchar * filename,gpointer data,GError ** error)483 gimp_config_deserialize_file (GimpConfig *config,
484 const gchar *filename,
485 gpointer data,
486 GError **error)
487 {
488 GScanner *scanner;
489 gboolean success;
490
491 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
492 g_return_val_if_fail (filename != NULL, FALSE);
493 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
494
495 scanner = gimp_scanner_new_file (filename, error);
496 if (! scanner)
497 return FALSE;
498
499 g_object_freeze_notify (G_OBJECT (config));
500
501 success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
502 scanner, 0, data);
503
504 g_object_thaw_notify (G_OBJECT (config));
505
506 gimp_scanner_destroy (scanner);
507
508 if (! success)
509 g_assert (error == NULL || *error != NULL);
510
511 return success;
512 }
513
514 /**
515 * gimp_config_deserialize_gfile:
516 * @config: a #GObject that implements the #GimpConfigInterface.
517 * @file: the #GFile to read configuration from.
518 * @data: user data passed to the deserialize implementation.
519 * @error: return location for a possible error
520 *
521 * Opens the file specified by @file, reads configuration data from it
522 * and configures @config accordingly. Basically this function creates
523 * a properly configured #GScanner for you and calls the deserialize
524 * function of the @config's #GimpConfigInterface.
525 *
526 * Return value: %TRUE if deserialization succeeded, %FALSE otherwise.
527 *
528 * Since: 2.10
529 **/
530 gboolean
gimp_config_deserialize_gfile(GimpConfig * config,GFile * file,gpointer data,GError ** error)531 gimp_config_deserialize_gfile (GimpConfig *config,
532 GFile *file,
533 gpointer data,
534 GError **error)
535 {
536 GScanner *scanner;
537 gboolean success;
538
539 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
540 g_return_val_if_fail (G_IS_FILE (file), FALSE);
541 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
542
543 scanner = gimp_scanner_new_gfile (file, error);
544 if (! scanner)
545 return FALSE;
546
547 g_object_freeze_notify (G_OBJECT (config));
548
549 success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
550 scanner, 0, data);
551
552 g_object_thaw_notify (G_OBJECT (config));
553
554 gimp_scanner_destroy (scanner);
555
556 if (! success)
557 g_assert (error == NULL || *error != NULL);
558
559 return success;
560 }
561
562 /**
563 * gimp_config_deserialize_stream:
564 * @config: a #GObject that implements the #GimpConfigInterface.
565 * @input: the #GInputStream to read configuration from.
566 * @data: user data passed to the deserialize implementation.
567 * @error: return location for a possible error
568 *
569 * Reads configuration data from @input and configures @config
570 * accordingly. Basically this function creates a properly configured
571 * #GScanner for you and calls the deserialize function of the
572 * @config's #GimpConfigInterface.
573 *
574 * Return value: %TRUE if deserialization succeeded, %FALSE otherwise.
575 *
576 * Since: 2.10
577 **/
578 gboolean
gimp_config_deserialize_stream(GimpConfig * config,GInputStream * input,gpointer data,GError ** error)579 gimp_config_deserialize_stream (GimpConfig *config,
580 GInputStream *input,
581 gpointer data,
582 GError **error)
583 {
584 GScanner *scanner;
585 gboolean success;
586
587 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
588 g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
589 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
590
591 scanner = gimp_scanner_new_stream (input, error);
592 if (! scanner)
593 return FALSE;
594
595 g_object_freeze_notify (G_OBJECT (config));
596
597 success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
598 scanner, 0, data);
599
600 g_object_thaw_notify (G_OBJECT (config));
601
602 gimp_scanner_destroy (scanner);
603
604 if (! success)
605 g_assert (error == NULL || *error != NULL);
606
607 return success;
608 }
609
610 /**
611 * gimp_config_deserialize_string:
612 * @config: a #GObject that implements the #GimpConfigInterface.
613 * @text: string to deserialize (in UTF-8 encoding)
614 * @text_len: length of @text in bytes or -1
615 * @data: client data
616 * @error: return location for a possible error
617 *
618 * Configures @config from @text. Basically this function creates a
619 * properly configured #GScanner for you and calls the deserialize
620 * function of the @config's #GimpConfigInterface.
621 *
622 * Returns: %TRUE if deserialization succeeded, %FALSE otherwise.
623 *
624 * Since: 2.4
625 **/
626 gboolean
gimp_config_deserialize_string(GimpConfig * config,const gchar * text,gint text_len,gpointer data,GError ** error)627 gimp_config_deserialize_string (GimpConfig *config,
628 const gchar *text,
629 gint text_len,
630 gpointer data,
631 GError **error)
632 {
633 GScanner *scanner;
634 gboolean success;
635
636 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
637 g_return_val_if_fail (text != NULL || text_len == 0, FALSE);
638 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
639
640 scanner = gimp_scanner_new_string (text, text_len, error);
641
642 g_object_freeze_notify (G_OBJECT (config));
643
644 success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
645 scanner, 0, data);
646
647 g_object_thaw_notify (G_OBJECT (config));
648
649 gimp_scanner_destroy (scanner);
650
651 if (! success)
652 g_assert (error == NULL || *error != NULL);
653
654 return success;
655 }
656
657 /**
658 * gimp_config_deserialize_return:
659 * @scanner: a #GScanner
660 * @expected_token: the expected token
661 * @nest_level: the nest level
662 *
663 * Returns:
664 *
665 * Since: 2.4
666 **/
667 gboolean
gimp_config_deserialize_return(GScanner * scanner,GTokenType expected_token,gint nest_level)668 gimp_config_deserialize_return (GScanner *scanner,
669 GTokenType expected_token,
670 gint nest_level)
671 {
672 GTokenType next_token;
673
674 g_return_val_if_fail (scanner != NULL, FALSE);
675
676 next_token = g_scanner_peek_next_token (scanner);
677
678 if (expected_token != G_TOKEN_LEFT_PAREN)
679 {
680 g_scanner_get_next_token (scanner);
681 g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL,
682 _("fatal parse error"), TRUE);
683 return FALSE;
684 }
685 else
686 {
687 if (nest_level > 0 && next_token == G_TOKEN_RIGHT_PAREN)
688 {
689 return TRUE;
690 }
691 else if (next_token != G_TOKEN_EOF)
692 {
693 g_scanner_get_next_token (scanner);
694 g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL,
695 _("fatal parse error"), TRUE);
696 return FALSE;
697 }
698 }
699
700 return TRUE;
701 }
702
703
704 /**
705 * gimp_config_serialize:
706 * @config: a #GObject that implements the #GimpConfigInterface.
707 * @writer: the #GimpConfigWriter to use.
708 * @data: client data
709 *
710 * Serialize the #GimpConfig object.
711 *
712 * Returns: %TRUE if serialization succeeded, %FALSE otherwise.
713 *
714 * Since: 2.8
715 **/
716 gboolean
gimp_config_serialize(GimpConfig * config,GimpConfigWriter * writer,gpointer data)717 gimp_config_serialize (GimpConfig *config,
718 GimpConfigWriter *writer,
719 gpointer data)
720 {
721 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
722
723 return GIMP_CONFIG_GET_INTERFACE (config)->serialize (config,
724 writer,
725 data);
726 }
727
728 /**
729 * gimp_config_deserialize:
730 * @config: a #GObject that implements the #GimpConfigInterface.
731 * @scanner: the #GScanner to use.
732 * @nest_level: the nest level.
733 * @data: client data.
734 *
735 * Deserialize the #GimpConfig object.
736 *
737 * Returns: %TRUE if deserialization succeeded, %FALSE otherwise.
738 *
739 * Since: 2.8
740 **/
741 gboolean
gimp_config_deserialize(GimpConfig * config,GScanner * scanner,gint nest_level,gpointer data)742 gimp_config_deserialize (GimpConfig *config,
743 GScanner *scanner,
744 gint nest_level,
745 gpointer data)
746 {
747 g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
748
749 return GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
750 scanner,
751 nest_level,
752 data);
753 }
754
755 /**
756 * gimp_config_duplicate:
757 * @config: a #GObject that implements the #GimpConfigInterface.
758 *
759 * Creates a copy of the passed object by copying all object
760 * properties. The default implementation of the #GimpConfigInterface
761 * only works for objects that are completely defined by their
762 * properties.
763 *
764 * Return value: the duplicated #GimpConfig object
765 *
766 * Since: 2.4
767 **/
768 gpointer
gimp_config_duplicate(GimpConfig * config)769 gimp_config_duplicate (GimpConfig *config)
770 {
771 g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
772
773 return GIMP_CONFIG_GET_INTERFACE (config)->duplicate (config);
774 }
775
776 /**
777 * gimp_config_is_equal_to:
778 * @a: a #GObject that implements the #GimpConfigInterface.
779 * @b: another #GObject of the same type as @a.
780 *
781 * Compares the two objects. The default implementation of the
782 * #GimpConfigInterface compares the object properties and thus only
783 * works for objects that are completely defined by their
784 * properties.
785 *
786 * Return value: %TRUE if the two objects are equal.
787 *
788 * Since: 2.4
789 **/
790 gboolean
gimp_config_is_equal_to(GimpConfig * a,GimpConfig * b)791 gimp_config_is_equal_to (GimpConfig *a,
792 GimpConfig *b)
793 {
794 g_return_val_if_fail (GIMP_IS_CONFIG (a), FALSE);
795 g_return_val_if_fail (GIMP_IS_CONFIG (b), FALSE);
796 g_return_val_if_fail (G_TYPE_FROM_INSTANCE (a) == G_TYPE_FROM_INSTANCE (b),
797 FALSE);
798
799 return GIMP_CONFIG_GET_INTERFACE (a)->equal (a, b);
800 }
801
802 /**
803 * gimp_config_reset:
804 * @config: a #GObject that implements the #GimpConfigInterface.
805 *
806 * Resets the object to its default state. The default implementation of the
807 * #GimpConfigInterface only works for objects that are completely defined by
808 * their properties.
809 *
810 * Since: 2.4
811 **/
812 void
gimp_config_reset(GimpConfig * config)813 gimp_config_reset (GimpConfig *config)
814 {
815 g_return_if_fail (GIMP_IS_CONFIG (config));
816
817 g_object_freeze_notify (G_OBJECT (config));
818
819 GIMP_CONFIG_GET_INTERFACE (config)->reset (config);
820
821 g_object_thaw_notify (G_OBJECT (config));
822 }
823
824 /**
825 * gimp_config_copy:
826 * @src: a #GObject that implements the #GimpConfigInterface.
827 * @dest: another #GObject of the same type as @a.
828 * @flags: a mask of GParamFlags
829 *
830 * Compares all read- and write-able properties from @src and @dest
831 * that have all @flags set. Differing values are then copied from
832 * @src to @dest. If @flags is 0, all differing read/write properties.
833 *
834 * Properties marked as "construct-only" are not touched.
835 *
836 * Return value: %TRUE if @dest was modified, %FALSE otherwise
837 *
838 * Since: 2.6
839 **/
840 gboolean
gimp_config_copy(GimpConfig * src,GimpConfig * dest,GParamFlags flags)841 gimp_config_copy (GimpConfig *src,
842 GimpConfig *dest,
843 GParamFlags flags)
844 {
845 gboolean changed;
846
847 g_return_val_if_fail (GIMP_IS_CONFIG (src), FALSE);
848 g_return_val_if_fail (GIMP_IS_CONFIG (dest), FALSE);
849 g_return_val_if_fail (G_TYPE_FROM_INSTANCE (src) == G_TYPE_FROM_INSTANCE (dest),
850 FALSE);
851
852 g_object_freeze_notify (G_OBJECT (dest));
853
854 changed = GIMP_CONFIG_GET_INTERFACE (src)->copy (src, dest, flags);
855
856 g_object_thaw_notify (G_OBJECT (dest));
857
858 return changed;
859 }
860