gimpconfig-iface.c 25.8 KB
Newer Older
1 2
/* LIBGIMP - The GIMP Library
 * 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 9
 * modify it under the terms of the GNU Lesser General Public
 * 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 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 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 23
 */

#include "config.h"

24
#include <string.h>
25

26
#include <gio/gio.h>
27

28
#include "libgimpbase/gimpbase.h"
29

30 31
#include "gimpconfigtypes.h"

32 33
#include "gimpconfigwriter.h"
#include "gimpconfig-iface.h"
34
#include "gimpconfig-deserialize.h"
35 36
#include "gimpconfig-serialize.h"
#include "gimpconfig-params.h"
37
#include "gimpconfig-utils.h"
38
#include "gimpscanner.h"
39

40
#include "libgimp/libgimp-intl.h"
41

42

43 44 45 46 47 48 49 50 51
/**
 * SECTION: gimpconfig-iface
 * @title: GimpConfig-iface
 * @short_description: High-level API for libgimpconfig.
 *
 * High-level API for libgimpconfig.
 **/


52
/*
Sven Neumann's avatar
Sven Neumann committed
53 54
 * The GimpConfig serialization and deserialization interface.
 */
55

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

/*  local function prototypes  */

static void         gimp_config_iface_default_init (GimpConfigInterface *iface);
static void         gimp_config_iface_base_init    (GimpConfigInterface *iface);

static gboolean     gimp_config_iface_serialize    (GimpConfig          *config,
                                                    GimpConfigWriter    *writer,
                                                    gpointer             data);
static gboolean     gimp_config_iface_deserialize  (GimpConfig          *config,
                                                    GScanner            *scanner,
                                                    gint                 nest_level,
                                                    gpointer             data);
static GimpConfig * gimp_config_iface_duplicate    (GimpConfig          *config);
static gboolean     gimp_config_iface_equal        (GimpConfig          *a,
                                                    GimpConfig          *b);
static void         gimp_config_iface_reset        (GimpConfig          *config);
static gboolean     gimp_config_iface_copy         (GimpConfig          *src,
                                                    GimpConfig          *dest,
                                                    GParamFlags          flags);


/*  private functions  */
79 80 81


GType
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 92 93 94
        (GBaseInitFunc)      gimp_config_iface_base_init,
        (GBaseFinalizeFunc)  NULL,
        (GClassInitFunc)     gimp_config_iface_default_init,
        (GClassFinalizeFunc) NULL,
95 96
      };

97 98 99
      config_iface_type = g_type_register_static (G_TYPE_INTERFACE,
                                                  "GimpConfigInterface",
                                                  &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
}

static void
109
gimp_config_iface_default_init (GimpConfigInterface *iface)
110
{
111 112 113 114 115 116 117
  iface->serialize   = gimp_config_iface_serialize;
  iface->deserialize = gimp_config_iface_deserialize;
  iface->duplicate   = gimp_config_iface_duplicate;
  iface->equal       = gimp_config_iface_equal;
  iface->reset       = gimp_config_iface_reset;
  iface->copy        = gimp_config_iface_copy;
}
118

119 120 121
static void
gimp_config_iface_base_init (GimpConfigInterface *iface)
{
122 123 124
  /*  always set these to NULL since we don't want to inherit them
   *  from parent classes
   */
125 126
  iface->serialize_property   = NULL;
  iface->deserialize_property = NULL;
127 128
}

129
static gboolean
130
gimp_config_iface_serialize (GimpConfig       *config,
Sven Neumann's avatar
Sven Neumann committed
131
                             GimpConfigWriter *writer,
132
                             gpointer          data)
133
{
134
  return gimp_config_serialize_properties (config, writer);
135
}
136

137
static gboolean
138 139 140 141
gimp_config_iface_deserialize (GimpConfig *config,
                               GScanner   *scanner,
                               gint        nest_level,
                               gpointer    data)
142
{
143
  return gimp_config_deserialize_properties (config, scanner, nest_level);
144 145
}

146 147
static GimpConfig *
gimp_config_iface_duplicate (GimpConfig *config)
148
{
149 150
  GObject       *object = G_OBJECT (config);
  GObjectClass  *klass  = G_OBJECT_GET_CLASS (object);
151 152
  GParamSpec   **property_specs;
  guint          n_property_specs;
153 154 155
  gint           n_construct_properties = 0;
  const gchar  **construct_names        = NULL;
  GValue        *construct_values       = NULL;
156
  guint          i;
157
  GObject       *dup;
158 159 160

  property_specs = g_object_class_list_properties (klass, &n_property_specs);

161 162
  construct_names  = g_new0 (const gchar *, n_property_specs);
  construct_values = g_new0 (GValue,        n_property_specs);
163 164 165 166 167 168 169 170 171

  for (i = 0; i < n_property_specs; i++)
    {
      GParamSpec *prop_spec = property_specs[i];

      if ((prop_spec->flags & G_PARAM_READABLE) &&
          (prop_spec->flags & G_PARAM_WRITABLE) &&
          (prop_spec->flags & G_PARAM_CONSTRUCT_ONLY))
        {
172
          construct_names[n_construct_properties] = prop_spec->name;
173

174 175 176 177
          g_value_init (&construct_values[n_construct_properties],
                        prop_spec->value_type);
          g_object_get_property (object, prop_spec->name,
                                 &construct_values[n_construct_properties]);
178

179
          n_construct_properties++;
180 181 182 183 184
        }
    }

  g_free (property_specs);

185 186 187 188
  dup = g_object_new_with_properties (G_TYPE_FROM_INSTANCE (object),
                                      n_construct_properties,
                                      (const gchar **) construct_names,
                                      (const GValue *) construct_values);
189

190 191
  for (i = 0; i < n_construct_properties; i++)
    g_value_unset (&construct_values[i]);
192

193 194
  g_free (construct_names);
  g_free (construct_values);
195

196
  gimp_config_copy (config, GIMP_CONFIG (dup), 0);
197

198
  return GIMP_CONFIG (dup);
199 200 201
}

static gboolean
202 203
gimp_config_iface_equal (GimpConfig *a,
                         GimpConfig *b)
204 205 206 207 208 209 210 211 212 213
{
  GObjectClass  *klass;
  GParamSpec   **property_specs;
  guint          n_property_specs;
  guint          i;
  gboolean       equal = TRUE;

  klass = G_OBJECT_GET_CLASS (a);

  property_specs = g_object_class_list_properties (klass, &n_property_specs);
214

215 216 217
  for (i = 0; equal && i < n_property_specs; i++)
    {
      GParamSpec  *prop_spec;
218 219
      GValue       a_value = G_VALUE_INIT;
      GValue       b_value = G_VALUE_INIT;
220 221 222 223 224 225 226 227

      prop_spec = property_specs[i];

      if (! (prop_spec->flags & G_PARAM_READABLE))
        continue;

      g_value_init (&a_value, prop_spec->value_type);
      g_value_init (&b_value, prop_spec->value_type);
228 229
      g_object_get_property (G_OBJECT (a), prop_spec->name, &a_value);
      g_object_get_property (G_OBJECT (b), prop_spec->name, &b_value);
230

231 232
      if (g_param_values_cmp (prop_spec, &a_value, &b_value))
        {
233
          if ((prop_spec->flags & GIMP_CONFIG_PARAM_AGGREGATE) &&
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
              G_IS_PARAM_SPEC_OBJECT (prop_spec)        &&
              g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
                                     GIMP_TYPE_CONFIG))
            {
              if (! gimp_config_is_equal_to (g_value_get_object (&a_value),
                                             g_value_get_object (&b_value)))
                {
                  equal = FALSE;
                }
            }
          else
            {
              equal = FALSE;
            }
        }
249 250 251 252 253 254 255 256 257 258

      g_value_unset (&a_value);
      g_value_unset (&b_value);
    }

  g_free (property_specs);

  return equal;
}

259
static void
260
gimp_config_iface_reset (GimpConfig *config)
261
{
262
  gimp_config_reset_properties (G_OBJECT (config));
263 264
}

265 266 267 268 269 270 271 272
static gboolean
gimp_config_iface_copy (GimpConfig  *src,
                        GimpConfig  *dest,
                        GParamFlags  flags)
{
  return gimp_config_sync (G_OBJECT (src), G_OBJECT (dest), flags);
}

273 274 275 276

/*  public functions  */


277
/**
278
 * gimp_config_serialize_to_file:
279
 * @config: a #GObject that implements the #GimpConfigInterface.
280
 * @filename: the name of the file to write the configuration to.
281 282
 * @header: optional file header (must be ASCII only)
 * @footer: optional file footer (must be ASCII only)
283
 * @data: user data passed to the serialize implementation.
284
 * @error: return location for a possible error
285
 *
286
 * Serializes the object properties of @config to the file specified
287
 * by @filename. If a file with that name already exists, it is
288
 * overwritten. Basically this function opens @filename for you and
289
 * calls the serialize function of the @config's #GimpConfigInterface.
290 291
 *
 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
292
 *
293
 * Since: 2.4
294
 **/
295
gboolean
296
gimp_config_serialize_to_file (GimpConfig   *config,
Sven Neumann's avatar
Sven Neumann committed
297 298 299 300 301
                               const gchar  *filename,
                               const gchar  *header,
                               const gchar  *footer,
                               gpointer      data,
                               GError      **error)
302
{
303
  GimpConfigWriter *writer;
304

305
  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
306
  g_return_val_if_fail (filename != NULL, FALSE);
307
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
308

309
  writer = gimp_config_writer_new_file (filename, TRUE, header, error);
310 311
  if (!writer)
    return FALSE;
312

313
  GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
314

315
  return gimp_config_writer_finish (writer, footer, error);
316 317
}

318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
/**
 * gimp_config_serialize_to_gfile:
 * @config: a #GObject that implements the #GimpConfigInterface.
 * @file:   the #GFile to write the configuration to.
 * @header: optional file header (must be ASCII only)
 * @footer: optional file footer (must be ASCII only)
 * @data: user data passed to the serialize implementation.
 * @error: return location for a possible error
 *
 * Serializes the object properties of @config to the file specified
 * by @file. If a file with that name already exists, it is
 * overwritten. Basically this function opens @file for you and calls
 * the serialize function of the @config's #GimpConfigInterface.
 *
 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
 *
334
 * Since: 2.10
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
 **/
gboolean
gimp_config_serialize_to_gfile (GimpConfig   *config,
                                GFile        *file,
                                const gchar  *header,
                                const gchar  *footer,
                                gpointer      data,
                                GError      **error)
{
  GimpConfigWriter *writer;

  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  writer = gimp_config_writer_new_gfile (file, TRUE, header, error);
  if (!writer)
    return FALSE;

  GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);

  return gimp_config_writer_finish (writer, footer, error);
}

359 360 361
/**
 * gimp_config_serialize_to_stream:
 * @config: a #GObject that implements the #GimpConfigInterface.
362
 * @output: the #GOutputStream to write the configuration to.
363 364 365 366 367 368
 * @header: optional file header (must be ASCII only)
 * @footer: optional file footer (must be ASCII only)
 * @data: user data passed to the serialize implementation.
 * @error: return location for a possible error
 *
 * Serializes the object properties of @config to the stream specified
369
 * by @output.
370 371 372
 *
 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
 *
373
 * Since: 2.10
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
 **/
gboolean
gimp_config_serialize_to_stream (GimpConfig     *config,
                                 GOutputStream  *output,
                                 const gchar    *header,
                                 const gchar    *footer,
                                 gpointer        data,
                                 GError        **error)
{
  GimpConfigWriter *writer;

  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (output), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  writer = gimp_config_writer_new_stream (output, header, error);
  if (!writer)
    return FALSE;

  GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);

  return gimp_config_writer_finish (writer, footer, error);
}

398 399 400 401 402 403 404 405 406 407 408
/**
 * gimp_config_serialize_to_fd:
 * @config: a #GObject that implements the #GimpConfigInterface.
 * @fd: a file descriptor, opened for writing
 * @data: user data passed to the serialize implementation.
 *
 * Serializes the object properties of @config to the given file
 * descriptor.
 *
 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
 *
409
 * Since: 2.4
410
 **/
411
gboolean
412 413 414
gimp_config_serialize_to_fd (GimpConfig *config,
                             gint        fd,
                             gpointer    data)
415
{
416
  GimpConfigWriter *writer;
417

418
  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
419 420 421 422 423 424
  g_return_val_if_fail (fd > 0, FALSE);

  writer = gimp_config_writer_new_fd (fd);
  if (!writer)
    return FALSE;

425
  GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
426 427 428 429

  return gimp_config_writer_finish (writer, NULL, NULL);
}

430 431
/**
 * gimp_config_serialize_to_string:
432
 * @config: a #GObject that implements the #GimpConfigInterface.
433
 * @data: user data passed to the serialize implementation.
434
 *
435
 * Serializes the object properties of @config to a string.
436
 *
437
 * Return value: a newly allocated NUL-terminated string.
438
 *
439
 * Since: 2.4
440 441
 **/
gchar *
442
gimp_config_serialize_to_string (GimpConfig *config,
Sven Neumann's avatar
Sven Neumann committed
443
                                 gpointer    data)
444
{
445 446
  GimpConfigWriter *writer;
  GString          *str;
447

448
  g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
449 450 451 452

  str = g_string_new (NULL);
  writer = gimp_config_writer_new_string (str);

453
  GIMP_CONFIG_GET_INTERFACE (config)->serialize (config, writer, data);
454 455 456 457 458 459

  gimp_config_writer_finish (writer, NULL, NULL);

  return g_string_free (str, FALSE);
}

460
/**
461
 * gimp_config_deserialize_file:
462
 * @config: a #GObject that implements the #GimpConfigInterface.
463
 * @filename: the name of the file to read configuration from.
Sven Neumann's avatar
Sven Neumann committed
464
 * @data: user data passed to the deserialize implementation.
465
 * @error: return location for a possible error
466
 *
467
 * Opens the file specified by @filename, reads configuration data
468
 * from it and configures @config accordingly. Basically this function
469
 * creates a properly configured #GScanner for you and calls the
470
 * deserialize function of the @config's #GimpConfigInterface.
471 472
 *
 * Return value: %TRUE if deserialization succeeded, %FALSE otherwise.
473
 *
474
 * Since: 2.4
475
 **/
476
gboolean
477
gimp_config_deserialize_file (GimpConfig   *config,
Sven Neumann's avatar
Sven Neumann committed
478 479 480
                              const gchar  *filename,
                              gpointer      data,
                              GError      **error)
481
{
482 483
  GScanner *scanner;
  gboolean  success;
484

485
  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
486
  g_return_val_if_fail (filename != NULL, FALSE);
487
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
488

489
  scanner = gimp_scanner_new_file (filename, error);
490 491
  if (! scanner)
    return FALSE;
492

493 494
  g_object_freeze_notify (G_OBJECT (config));

495 496
  success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
                                                             scanner, 0, data);
497

498 499
  g_object_thaw_notify (G_OBJECT (config));

500
  gimp_scanner_destroy (scanner);
501

502 503 504
  if (! success)
    g_assert (error == NULL || *error != NULL);

505 506
  return success;
}
507

508 509 510 511 512 513 514 515 516 517 518 519 520 521
/**
 * gimp_config_deserialize_gfile:
 * @config: a #GObject that implements the #GimpConfigInterface.
 * @file: the #GFile to read configuration from.
 * @data: user data passed to the deserialize implementation.
 * @error: return location for a possible error
 *
 * Opens the file specified by @file, reads configuration data from it
 * and configures @config accordingly. Basically this function creates
 * a properly configured #GScanner for you and calls the deserialize
 * function of the @config's #GimpConfigInterface.
 *
 * Return value: %TRUE if deserialization succeeded, %FALSE otherwise.
 *
522
 * Since: 2.10
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
 **/
gboolean
gimp_config_deserialize_gfile (GimpConfig  *config,
                               GFile       *file,
                               gpointer     data,
                               GError     **error)
{
  GScanner *scanner;
  gboolean  success;

  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  scanner = gimp_scanner_new_gfile (file, error);
  if (! scanner)
    return FALSE;

  g_object_freeze_notify (G_OBJECT (config));

  success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
                                                             scanner, 0, data);

  g_object_thaw_notify (G_OBJECT (config));

  gimp_scanner_destroy (scanner);

  if (! success)
    g_assert (error == NULL || *error != NULL);

  return success;
}

556 557 558 559 560 561 562 563 564 565 566 567 568 569
/**
 * gimp_config_deserialize_stream:
 * @config: a #GObject that implements the #GimpConfigInterface.
 * @input: the #GInputStream to read configuration from.
 * @data: user data passed to the deserialize implementation.
 * @error: return location for a possible error
 *
 * Reads configuration data from @input and configures @config
 * accordingly. Basically this function creates a properly configured
 * #GScanner for you and calls the deserialize function of the
 * @config's #GimpConfigInterface.
 *
 * Return value: %TRUE if deserialization succeeded, %FALSE otherwise.
 *
570
 * Since: 2.10
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
 **/
gboolean
gimp_config_deserialize_stream (GimpConfig    *config,
                                GInputStream  *input,
                                gpointer       data,
                                GError       **error)
{
  GScanner *scanner;
  gboolean  success;

  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  scanner = gimp_scanner_new_stream (input, error);
  if (! scanner)
    return FALSE;

  g_object_freeze_notify (G_OBJECT (config));

  success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
                                                             scanner, 0, data);

  g_object_thaw_notify (G_OBJECT (config));

  gimp_scanner_destroy (scanner);

  if (! success)
    g_assert (error == NULL || *error != NULL);

  return success;
}

604 605
/**
 * gimp_config_deserialize_string:
606 607
 * @config:   a #GObject that implements the #GimpConfigInterface.
 * @text:     string to deserialize (in UTF-8 encoding)
608
 * @text_len: length of @text in bytes or -1
609 610
 * @data:     client data
 * @error:    return location for a possible error
611
 *
612
 * Configures @config from @text. Basically this function creates a
613
 * properly configured #GScanner for you and calls the deserialize
614
 * function of the @config's #GimpConfigInterface.
615
 *
616
 * Returns: %TRUE if deserialization succeeded, %FALSE otherwise.
617
 *
618
 * Since: 2.4
619 620
 **/
gboolean
621
gimp_config_deserialize_string (GimpConfig      *config,
622 623
                                const gchar  *text,
                                gint          text_len,
Sven Neumann's avatar
Sven Neumann committed
624
                                gpointer      data,
625 626
                                GError      **error)
{
627 628
  GScanner *scanner;
  gboolean  success;
629

630
  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
631 632 633 634 635
  g_return_val_if_fail (text != NULL || text_len == 0, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  scanner = gimp_scanner_new_string (text, text_len, error);

636 637
  g_object_freeze_notify (G_OBJECT (config));

638 639
  success = GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
                                                             scanner, 0, data);
640

641 642
  g_object_thaw_notify (G_OBJECT (config));

643 644 645 646 647 648 649 650
  gimp_scanner_destroy (scanner);

  if (! success)
    g_assert (error == NULL || *error != NULL);

  return success;
}

651 652
/**
 * gimp_config_deserialize_return:
653 654
 * @scanner:        a #GScanner
 * @expected_token: the expected token
655
 * @nest_level:     the nest level
656 657 658
 *
 * Returns:
 *
659
 * Since: 2.4
660
 **/
661 662 663
gboolean
gimp_config_deserialize_return (GScanner     *scanner,
                                GTokenType    expected_token,
664
                                gint          nest_level)
665 666 667 668 669 670 671 672 673 674
{
  GTokenType next_token;

  g_return_val_if_fail (scanner != NULL, FALSE);

  next_token = g_scanner_peek_next_token (scanner);

  if (expected_token != G_TOKEN_LEFT_PAREN)
    {
      g_scanner_get_next_token (scanner);
675
      g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL,
676 677 678 679 680 681 682 683 684 685 686 687
                             _("fatal parse error"), TRUE);
      return FALSE;
    }
  else
    {
      if (nest_level > 0 && next_token == G_TOKEN_RIGHT_PAREN)
        {
          return TRUE;
        }
      else if (next_token != G_TOKEN_EOF)
        {
          g_scanner_get_next_token (scanner);
688
          g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL,
689 690 691 692 693 694 695 696
                                 _("fatal parse error"), TRUE);
          return FALSE;
        }
    }

  return TRUE;
}

697

698 699 700 701 702 703 704 705 706 707
/**
 * gimp_config_serialize:
 * @config: a #GObject that implements the #GimpConfigInterface.
 * @writer: the #GimpConfigWriter to use.
 * @data: client data
 *
 * Serialize the #GimpConfig object.
 *
 * Returns: %TRUE if serialization succeeded, %FALSE otherwise.
 *
708
 * Since: 2.8
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
 **/
gboolean
gimp_config_serialize (GimpConfig       *config,
                       GimpConfigWriter *writer,
                       gpointer          data)
{
  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);

  return GIMP_CONFIG_GET_INTERFACE (config)->serialize (config,
                                                        writer,
                                                        data);
}

/**
 * gimp_config_deserialize:
 * @config: a #GObject that implements the #GimpConfigInterface.
 * @scanner: the #GScanner to use.
 * @nest_level: the nest level.
 * @data: client data.
 *
 * Deserialize the #GimpConfig object.
 *
 * Returns: %TRUE if deserialization succeeded, %FALSE otherwise.
 *
733
 * Since: 2.8
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
 **/
gboolean
gimp_config_deserialize (GimpConfig *config,
                         GScanner   *scanner,
                         gint        nest_level,
                         gpointer    data)
{
  g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);

  return GIMP_CONFIG_GET_INTERFACE (config)->deserialize (config,
                                                          scanner,
                                                          nest_level,
                                                          data);
}

749 750
/**
 * gimp_config_duplicate:
751
 * @config: a #GObject that implements the #GimpConfigInterface.
752
 *
753 754 755 756
 * Creates a copy of the passed object by copying all object
 * properties. The default implementation of the #GimpConfigInterface
 * only works for objects that are completely defined by their
 * properties.
757
 *
758
 * Return value: the duplicated #GimpConfig object
759
 *
760
 * Since: 2.4
761
 **/
762
gpointer
763
gimp_config_duplicate (GimpConfig *config)
764
{
765
  g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
766

767
  return GIMP_CONFIG_GET_INTERFACE (config)->duplicate (config);
768 769 770 771 772 773
}

/**
 * gimp_config_is_equal_to:
 * @a: a #GObject that implements the #GimpConfigInterface.
 * @b: another #GObject of the same type as @a.
774
 *
775 776 777 778
 * Compares the two objects. The default implementation of the
 * #GimpConfigInterface compares the object properties and thus only
 * works for objects that are completely defined by their
 * properties.
779
 *
780
 * Return value: %TRUE if the two objects are equal.
781
 *
782
 * Since: 2.4
783 784
 **/
gboolean
785 786
gimp_config_is_equal_to (GimpConfig *a,
                         GimpConfig *b)
787
{
788 789
  g_return_val_if_fail (GIMP_IS_CONFIG (a), FALSE);
  g_return_val_if_fail (GIMP_IS_CONFIG (b), FALSE);
790
  g_return_val_if_fail (G_TYPE_FROM_INSTANCE (a) == G_TYPE_FROM_INSTANCE (b),
791 792
                        FALSE);

793
  return GIMP_CONFIG_GET_INTERFACE (a)->equal (a, b);
794 795
}

796 797
/**
 * gimp_config_reset:
798
 * @config: a #GObject that implements the #GimpConfigInterface.
799
 *
800 801 802
 * Resets the object to its default state. The default implementation of the
 * #GimpConfigInterface only works for objects that are completely defined by
 * their properties.
803
 *
804
 * Since: 2.4
805 806
 **/
void
807
gimp_config_reset (GimpConfig *config)
808
{
809
  g_return_if_fail (GIMP_IS_CONFIG (config));
810

811 812
  g_object_freeze_notify (G_OBJECT (config));

813
  GIMP_CONFIG_GET_INTERFACE (config)->reset (config);
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831

  g_object_thaw_notify (G_OBJECT (config));
}

/**
 * gimp_config_copy:
 * @src: a #GObject that implements the #GimpConfigInterface.
 * @dest: another #GObject of the same type as @a.
 * @flags: a mask of GParamFlags
 *
 * Compares all read- and write-able properties from @src and @dest
 * that have all @flags set. Differing values are then copied from
 * @src to @dest. If @flags is 0, all differing read/write properties.
 *
 * Properties marked as "construct-only" are not touched.
 *
 * Return value: %TRUE if @dest was modified, %FALSE otherwise
 *
832
 * Since: 2.6
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
 **/
gboolean
gimp_config_copy (GimpConfig  *src,
                  GimpConfig  *dest,
                  GParamFlags  flags)
{
  gboolean changed;

  g_return_val_if_fail (GIMP_IS_CONFIG (src), FALSE);
  g_return_val_if_fail (GIMP_IS_CONFIG (dest), FALSE);
  g_return_val_if_fail (G_TYPE_FROM_INSTANCE (src) == G_TYPE_FROM_INSTANCE (dest),
                        FALSE);

  g_object_freeze_notify (G_OBJECT (dest));

  changed = GIMP_CONFIG_GET_INTERFACE (src)->copy (src, dest, flags);

  g_object_thaw_notify (G_OBJECT (dest));

  return changed;
853
}