gimpconfig-iface.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  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. #include "config.h"
  22. #include <string.h>
  23. #include <gio/gio.h>
  24. #include "libgimpbase/gimpbase.h"
  25. #include "gimpconfigtypes.h"
  26. #include "gimpconfigwriter.h"
  27. #include "gimpconfig-iface.h"
  28. #include "gimpconfig-deserialize.h"
  29. #include "gimpconfig-serialize.h"
  30. #include "gimpconfig-params.h"
  31. #include "gimpconfig-utils.h"
  32. #include "gimpscanner.h"
  33. #include "libgimp/libgimp-intl.h"
  34. /*
  35. * GimpConfigIface:
  36. *
  37. * The [struct@Config] serialization and deserialization interface.
  38. */
  39. /* local function prototypes */
  40. static void gimp_config_iface_default_init (GimpConfigInterface *iface);
  41. static void gimp_config_iface_base_init (GimpConfigInterface *iface);
  42. static gboolean gimp_config_iface_serialize (GimpConfig *config,
  43. GimpConfigWriter *writer,
  44. gpointer data);
  45. static gboolean gimp_config_iface_deserialize (GimpConfig *config,
  46. GScanner *scanner,
  47. gint nest_level,
  48. gpointer data);
  49. static GimpConfig * gimp_config_iface_duplicate (GimpConfig *config);
  50. static gboolean gimp_config_iface_equal (GimpConfig *a,
  51. GimpConfig *b);
  52. static void gimp_config_iface_reset (GimpConfig *config);
  53. static gboolean gimp_config_iface_copy (GimpConfig *src,
  54. GimpConfig *dest,
  55. GParamFlags flags);
  56. /* private functions */
  57. GType
  58. gimp_config_get_type (void)
  59. {
  60. static GType config_iface_type = 0;
  61. if (! config_iface_type)
  62. {
  63. const GTypeInfo config_iface_info =
  64. {
  65. sizeof (GimpConfigInterface),
  66. (GBaseInitFunc) gimp_config_iface_base_init,
  67. (GBaseFinalizeFunc) NULL,
  68. (GClassInitFunc) gimp_config_iface_default_init,
  69. (GClassFinalizeFunc) NULL,
  70. };
  71. config_iface_type = g_type_register_static (G_TYPE_INTERFACE,
  72. "GimpConfigInterface",
  73. &config_iface_info,
  74. 0);
  75. g_type_interface_add_prerequisite (config_iface_type, G_TYPE_OBJECT);
  76. }
  77. return config_iface_type;
  78. }
  79. static void
  80. gimp_config_iface_default_init (GimpConfigInterface *iface)
  81. {
  82. iface->serialize = gimp_config_iface_serialize;
  83. iface->deserialize = gimp_config_iface_deserialize;
  84. iface->duplicate = gimp_config_iface_duplicate;
  85. iface->equal = gimp_config_iface_equal;
  86. iface->reset = gimp_config_iface_reset;
  87. iface->copy = gimp_config_iface_copy;
  88. }
  89. static void
  90. gimp_config_iface_base_init (GimpConfigInterface *iface)
  91. {
  92. /* always set these to NULL since we don't want to inherit them
  93. * from parent classes
  94. */
  95. iface->serialize_property = NULL;
  96. iface->deserialize_property = NULL;
  97. }
  98. static gboolean
  99. gimp_config_iface_serialize (GimpConfig *config,
  100. GimpConfigWriter *writer,
  101. gpointer data)
  102. {
  103. return gimp_config_serialize_properties (config, writer);
  104. }
  105. static gboolean
  106. gimp_config_iface_deserialize (GimpConfig *config,
  107. GScanner *scanner,
  108. gint nest_level,
  109. gpointer data)
  110. {
  111. return gimp_config_deserialize_properties (config, scanner, nest_level);
  112. }
  113. static GimpConfig *
  114. gimp_config_iface_duplicate (GimpConfig *config)
  115. {
  116. GObject *object = G_OBJECT (config);
  117. GObjectClass *klass = G_OBJECT_GET_CLASS (object);
  118. GParamSpec **property_specs;
  119. guint n_property_specs;
  120. gint n_construct_properties = 0;
  121. const gchar **construct_names = NULL;
  122. GValue *construct_values = NULL;
  123. guint i;
  124. GObject *dup;
  125. property_specs = g_object_class_list_properties (klass, &n_property_specs);
  126. construct_names = g_new0 (const gchar *, n_property_specs);
  127. construct_values = g_new0 (GValue, n_property_specs);
  128. for (i = 0; i < n_property_specs; i++)
  129. {
  130. GParamSpec *prop_spec = property_specs[i];
  131. if ((prop_spec->flags & G_PARAM_READABLE) &&
  132. (prop_spec->flags & G_PARAM_WRITABLE) &&
  133. (prop_spec->flags & G_PARAM_CONSTRUCT_ONLY))
  134. {
  135. construct_names[n_construct_properties] = prop_spec->name;
  136. g_value_init (&construct_values[n_construct_properties],
  137. prop_spec->value_type);
  138. g_object_get_property (object, prop_spec->name,
  139. &construct_values[n_construct_properties]);
  140. n_construct_properties++;
  141. }
  142. }
  143. g_free (property_specs);
  144. dup = g_object_new_with_properties (G_TYPE_FROM_INSTANCE (object),
  145. n_construct_properties,
  146. (const gchar **) construct_names,
  147. (const GValue *) construct_values);
  148. for (i = 0; i < n_construct_properties; i++)
  149. g_value_unset (&construct_values[i]);
  150. g_free (construct_names);
  151. g_free (construct_values);
  152. gimp_config_copy (config, GIMP_CONFIG (dup), 0);
  153. return GIMP_CONFIG (dup);
  154. }
  155. static gboolean
  156. gimp_config_iface_equal (GimpConfig *a,
  157. GimpConfig *b)
  158. {
  159. GObjectClass *klass;
  160. GParamSpec **property_specs;
  161. guint n_property_specs;
  162. guint i;
  163. gboolean equal = TRUE;
  164. klass = G_OBJECT_GET_CLASS (a);
  165. property_specs = g_object_class_list_properties (klass, &n_property_specs);
  166. for (i = 0; equal && i < n_property_specs; i++)
  167. {
  168. GParamSpec *prop_spec;
  169. GValue a_value = G_VALUE_INIT;
  170. GValue b_value = G_VALUE_INIT;
  171. prop_spec = property_specs[i];
  172. if (! (prop_spec->flags & G_PARAM_READABLE) ||
  173. (prop_spec->flags & GIMP_CONFIG_PARAM_DONT_COMPARE))
  174. {
  175. continue;
  176. }
  177. g_value_init (&a_value, prop_spec->value_type);
  178. g_value_init (&b_value, prop_spec->value_type);
  179. g_object_get_property (G_OBJECT (a), prop_spec->name, &a_value);
  180. g_object_get_property (G_OBJECT (b), prop_spec->name, &b_value);
  181. if (g_param_values_cmp (prop_spec, &a_value, &b_value))
  182. {
  183. if ((prop_spec->flags & GIMP_CONFIG_PARAM_AGGREGATE) &&
  184. G_IS_PARAM_SPEC_OBJECT (prop_spec) &&
  185. g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
  186. GIMP_TYPE_CONFIG))
  187. {
  188. if (! gimp_config_is_equal_to (g_value_get_object (&a_value),
  189. g_value_get_object (&b_value)))
  190. {
  191. equal = FALSE;
  192. }
  193. }
  194. else
  195. {
  196. equal = FALSE;
  197. }
  198. }
  199. g_value_unset (&a_value);
  200. g_value_unset (&b_value);
  201. }
  202. g_free (property_specs);
  203. return equal;
  204. }
  205. static void
  206. gimp_config_iface_reset (GimpConfig *config)
  207. {
  208. gimp_config_reset_properties (G_OBJECT (config));
  209. }
  210. static gboolean
  211. gimp_config_iface_copy (GimpConfig *src,
  212. GimpConfig *dest,
  213. GParamFlags flags)
  214. {
  215. return gimp_config_sync (G_OBJECT (src), G_OBJECT (dest), flags);
  216. }
  217. /* public functions */
  218. /**
  219. * gimp_config_serialize_to_file:
  220. * @config: an object that implements [iface@ConfigInterface].
  221. * @file: the file to write the configuration to.
  222. * @header: (nullable): optional file header (must be ASCII only)
  223. * @footer: (nullable): optional file footer (must be ASCII only)
  224. * @data: user data passed to the serialize implementation.
  225. * @error: return location for a possible error
  226. *
  227. * Serializes the object properties of @config to the file specified
  228. * by @file. If a file with that name already exists, it is
  229. * overwritten. Basically this function opens @file for you and calls
  230. * the serialize function of the @config's [iface@ConfigInterface].
  231. *
  232. * Returns: %TRUE if serialization succeeded, %FALSE otherwise.
  233. *
  234. * Since: 2.10
  235. **/
  236. gboolean
  237. gimp_config_serialize_to_file (GimpConfig *config,
  238. GFile *file,
  239. const gchar *header,
  240. const gchar *footer,
  241. gpointer data,
  242. GError **error)
  243. {
  244. GimpConfigWriter *writer;
  245. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  246. g_return_val_if_fail (G_IS_FILE (file), FALSE);
  247. g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  248. writer = gimp_config_writer_new_from_file (file, TRUE, header, error);
  249. if (!writer)
  250. return FALSE;
  251. GIMP_CONFIG_GET_IFACE (config)->serialize (config, writer, data);
  252. return gimp_config_writer_finish (writer, footer, error);
  253. }
  254. /**
  255. * gimp_config_serialize_to_stream:
  256. * @config: an object that implements [iface@ConfigInterface].
  257. * @output: the #GOutputStream to write the configuration to.
  258. * @header: (nullable): optional file header (must be ASCII only)
  259. * @footer: (nullable): optional file footer (must be ASCII only)
  260. * @data: user data passed to the serialize implementation.
  261. * @error: return location for a possible error
  262. *
  263. * Serializes the object properties of @config to the stream specified
  264. * by @output.
  265. *
  266. * Returns: Whether serialization succeeded.
  267. *
  268. * Since: 2.10
  269. **/
  270. gboolean
  271. gimp_config_serialize_to_stream (GimpConfig *config,
  272. GOutputStream *output,
  273. const gchar *header,
  274. const gchar *footer,
  275. gpointer data,
  276. GError **error)
  277. {
  278. GimpConfigWriter *writer;
  279. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  280. g_return_val_if_fail (G_IS_OUTPUT_STREAM (output), FALSE);
  281. g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  282. writer = gimp_config_writer_new_from_stream (output, header, error);
  283. if (!writer)
  284. return FALSE;
  285. GIMP_CONFIG_GET_IFACE (config)->serialize (config, writer, data);
  286. return gimp_config_writer_finish (writer, footer, error);
  287. }
  288. /**
  289. * gimp_config_serialize_to_fd:
  290. * @config: an object that implements [iface@ConfigInterface].
  291. * @fd: a file descriptor, opened for writing
  292. * @data: user data passed to the serialize implementation.
  293. *
  294. * Serializes the object properties of @config to the given file
  295. * descriptor.
  296. *
  297. * Returns: %TRUE if serialization succeeded, %FALSE otherwise.
  298. *
  299. * Since: 2.4
  300. **/
  301. gboolean
  302. gimp_config_serialize_to_fd (GimpConfig *config,
  303. gint fd,
  304. gpointer data)
  305. {
  306. GimpConfigWriter *writer;
  307. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  308. g_return_val_if_fail (fd > 0, FALSE);
  309. writer = gimp_config_writer_new_from_fd (fd);
  310. if (!writer)
  311. return FALSE;
  312. GIMP_CONFIG_GET_IFACE (config)->serialize (config, writer, data);
  313. return gimp_config_writer_finish (writer, NULL, NULL);
  314. }
  315. /**
  316. * gimp_config_serialize_to_string:
  317. * @config: an object that implements the [iface@ConfigInterface].
  318. * @data: user data passed to the serialize implementation.
  319. *
  320. * Serializes the object properties of @config to a string.
  321. *
  322. * Returns: a newly allocated NUL-terminated string.
  323. *
  324. * Since: 2.4
  325. **/
  326. gchar *
  327. gimp_config_serialize_to_string (GimpConfig *config,
  328. gpointer data)
  329. {
  330. GimpConfigWriter *writer;
  331. GString *str;
  332. g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
  333. str = g_string_new (NULL);
  334. writer = gimp_config_writer_new_from_string (str);
  335. GIMP_CONFIG_GET_IFACE (config)->serialize (config, writer, data);
  336. gimp_config_writer_finish (writer, NULL, NULL);
  337. return g_string_free (str, FALSE);
  338. }
  339. /**
  340. * gimp_config_serialize_to_parasite:
  341. * @config: an object that implements the [iface@ConfigInterface].
  342. * @parasite_name: the new parasite's name
  343. * @parasite_flags: the new parasite's flags
  344. * @data: user data passed to the serialize implementation.
  345. *
  346. * Serializes the object properties of @config to a [struct@Parasite].
  347. *
  348. * Returns: (transfer full): the newly allocated parasite.
  349. *
  350. * Since: 3.0
  351. **/
  352. GimpParasite *
  353. gimp_config_serialize_to_parasite (GimpConfig *config,
  354. const gchar *parasite_name,
  355. guint parasite_flags,
  356. gpointer data)
  357. {
  358. GimpParasite *parasite;
  359. gchar *str;
  360. g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
  361. g_return_val_if_fail (parasite_name != NULL, NULL);
  362. str = gimp_config_serialize_to_string (config, data);
  363. if (! str)
  364. return NULL;
  365. parasite = gimp_parasite_new (parasite_name,
  366. parasite_flags,
  367. 0, NULL);
  368. parasite->size = strlen (str) + 1;
  369. parasite->data = str;
  370. return parasite;
  371. }
  372. /**
  373. * gimp_config_deserialize_file:
  374. * @config: an object that implements the #GimpConfigInterface.
  375. * @file: the file to read configuration from.
  376. * @data: user data passed to the deserialize implementation.
  377. * @error: return location for a possible error
  378. *
  379. * Opens the file specified by @file, reads configuration data from it
  380. * and configures @config accordingly. Basically this function creates
  381. * a properly configured [struct@GLib.Scanner] for you and calls the deserialize
  382. * function of the @config's [iface@ConfigInterface].
  383. *
  384. * Returns: Whether deserialization succeeded.
  385. *
  386. * Since: 2.10
  387. **/
  388. gboolean
  389. gimp_config_deserialize_file (GimpConfig *config,
  390. GFile *file,
  391. gpointer data,
  392. GError **error)
  393. {
  394. GScanner *scanner;
  395. gboolean success;
  396. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  397. g_return_val_if_fail (G_IS_FILE (file), FALSE);
  398. g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  399. scanner = gimp_scanner_new_file (file, error);
  400. if (! scanner)
  401. return FALSE;
  402. g_object_freeze_notify (G_OBJECT (config));
  403. success = GIMP_CONFIG_GET_IFACE (config)->deserialize (config,
  404. scanner, 0, data);
  405. g_object_thaw_notify (G_OBJECT (config));
  406. gimp_scanner_unref (scanner);
  407. if (! success)
  408. /* If we get this assert, it means we have a bug in one of the
  409. * deserialize() implementations. Any failure case should report the
  410. * error condition with g_scanner_error() which will populate the
  411. * error object passed in gimp_scanner_new*().
  412. */
  413. g_assert (error == NULL || *error != NULL);
  414. return success;
  415. }
  416. /**
  417. * gimp_config_deserialize_stream:
  418. * @config: an object that implements the #GimpConfigInterface.
  419. * @input: the input stream to read configuration from.
  420. * @data: user data passed to the deserialize implementation.
  421. * @error: return location for a possible error
  422. *
  423. * Reads configuration data from @input and configures @config
  424. * accordingly. Basically this function creates a properly configured
  425. * #GScanner for you and calls the deserialize function of the
  426. * @config's #GimpConfigInterface.
  427. *
  428. * Returns: Whether deserialization succeeded.
  429. *
  430. * Since: 2.10
  431. **/
  432. gboolean
  433. gimp_config_deserialize_stream (GimpConfig *config,
  434. GInputStream *input,
  435. gpointer data,
  436. GError **error)
  437. {
  438. GScanner *scanner;
  439. gboolean success;
  440. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  441. g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
  442. g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  443. scanner = gimp_scanner_new_stream (input, error);
  444. if (! scanner)
  445. return FALSE;
  446. g_object_freeze_notify (G_OBJECT (config));
  447. success = GIMP_CONFIG_GET_IFACE (config)->deserialize (config,
  448. scanner, 0, data);
  449. g_object_thaw_notify (G_OBJECT (config));
  450. gimp_scanner_unref (scanner);
  451. if (! success)
  452. g_assert (error == NULL || *error != NULL);
  453. return success;
  454. }
  455. /**
  456. * gimp_config_deserialize_string:
  457. * @config: a #GObject that implements the #GimpConfigInterface.
  458. * @text: (array length=text_len): string to deserialize (in UTF-8 encoding)
  459. * @text_len: length of @text in bytes or -1
  460. * @data: client data
  461. * @error: return location for a possible error
  462. *
  463. * Configures @config from @text. Basically this function creates a
  464. * properly configured #GScanner for you and calls the deserialize
  465. * function of the @config's #GimpConfigInterface.
  466. *
  467. * Returns: %TRUE if deserialization succeeded, %FALSE otherwise.
  468. *
  469. * Since: 2.4
  470. **/
  471. gboolean
  472. gimp_config_deserialize_string (GimpConfig *config,
  473. const gchar *text,
  474. gint text_len,
  475. gpointer data,
  476. GError **error)
  477. {
  478. GScanner *scanner;
  479. gboolean success;
  480. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  481. g_return_val_if_fail (text != NULL || text_len == 0, FALSE);
  482. g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  483. scanner = gimp_scanner_new_string (text, text_len, error);
  484. g_object_freeze_notify (G_OBJECT (config));
  485. success = GIMP_CONFIG_GET_IFACE (config)->deserialize (config,
  486. scanner, 0, data);
  487. g_object_thaw_notify (G_OBJECT (config));
  488. gimp_scanner_unref (scanner);
  489. if (! success)
  490. g_assert (error == NULL || *error != NULL);
  491. return success;
  492. }
  493. /**
  494. * gimp_config_deserialize_parasite:
  495. * @config: a #GObject that implements the #GimpConfigInterface.
  496. * @parasite: parasite containing a serialized config string
  497. * @data: client data
  498. * @error: return location for a possible error
  499. *
  500. * Configures @config from @parasite. Basically this function creates
  501. * a properly configured #GScanner for you and calls the deserialize
  502. * function of the @config's #GimpConfigInterface.
  503. *
  504. * Returns: %TRUE if deserialization succeeded, %FALSE otherwise.
  505. *
  506. * Since: 3.0
  507. **/
  508. gboolean
  509. gimp_config_deserialize_parasite (GimpConfig *config,
  510. const GimpParasite *parasite,
  511. gpointer data,
  512. GError **error)
  513. {
  514. const gchar *parasite_data;
  515. guint32 parasite_size;
  516. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  517. g_return_val_if_fail (parasite != NULL, FALSE);
  518. g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  519. parasite_data = gimp_parasite_get_data (parasite, &parasite_size);
  520. if (! parasite_data)
  521. return TRUE;
  522. return gimp_config_deserialize_string (config, parasite_data, parasite_size,
  523. data, error);
  524. }
  525. /**
  526. * gimp_config_deserialize_return:
  527. * @scanner: a #GScanner
  528. * @expected_token: the expected token
  529. * @nest_level: the nest level
  530. *
  531. * Returns:
  532. *
  533. * Since: 2.4
  534. **/
  535. gboolean
  536. gimp_config_deserialize_return (GScanner *scanner,
  537. GTokenType expected_token,
  538. gint nest_level)
  539. {
  540. GTokenType next_token;
  541. g_return_val_if_fail (scanner != NULL, FALSE);
  542. next_token = g_scanner_peek_next_token (scanner);
  543. if (expected_token != G_TOKEN_LEFT_PAREN)
  544. {
  545. g_scanner_get_next_token (scanner);
  546. g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL,
  547. _("fatal parse error"), TRUE);
  548. return FALSE;
  549. }
  550. else
  551. {
  552. if (nest_level > 0 && next_token == G_TOKEN_RIGHT_PAREN)
  553. {
  554. return TRUE;
  555. }
  556. else if (next_token != G_TOKEN_EOF)
  557. {
  558. g_scanner_get_next_token (scanner);
  559. g_scanner_unexp_token (scanner, expected_token, NULL, NULL, NULL,
  560. _("fatal parse error"), TRUE);
  561. return FALSE;
  562. }
  563. }
  564. return TRUE;
  565. }
  566. /**
  567. * gimp_config_serialize:
  568. * @config: an object that implements the #GimpConfigInterface.
  569. * @writer: the #GimpConfigWriter to use.
  570. * @data: client data
  571. *
  572. * Serialize the #GimpConfig object.
  573. *
  574. * Returns: Whether serialization succeeded.
  575. *
  576. * Since: 2.8
  577. **/
  578. gboolean
  579. gimp_config_serialize (GimpConfig *config,
  580. GimpConfigWriter *writer,
  581. gpointer data)
  582. {
  583. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  584. return GIMP_CONFIG_GET_IFACE (config)->serialize (config, writer, data);
  585. }
  586. /**
  587. * gimp_config_deserialize:
  588. * @config: a #GObject that implements the #GimpConfigInterface.
  589. * @scanner: the #GScanner to use.
  590. * @nest_level: the nest level.
  591. * @data: client data.
  592. *
  593. * Deserialize the #GimpConfig object.
  594. *
  595. * Returns: Whether serialization succeeded.
  596. *
  597. * Since: 2.8
  598. **/
  599. gboolean
  600. gimp_config_deserialize (GimpConfig *config,
  601. GScanner *scanner,
  602. gint nest_level,
  603. gpointer data)
  604. {
  605. g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
  606. return GIMP_CONFIG_GET_IFACE (config)->deserialize (config,
  607. scanner,
  608. nest_level,
  609. data);
  610. }
  611. /**
  612. * gimp_config_duplicate:
  613. * @config: a #GObject that implements the #GimpConfigInterface.
  614. *
  615. * Creates a copy of the passed object by copying all object
  616. * properties. The default implementation of the #GimpConfigInterface
  617. * only works for objects that are completely defined by their
  618. * properties.
  619. *
  620. * Returns: the duplicated #GimpConfig object
  621. *
  622. * Since: 2.4
  623. **/
  624. gpointer
  625. gimp_config_duplicate (GimpConfig *config)
  626. {
  627. g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
  628. return GIMP_CONFIG_GET_IFACE (config)->duplicate (config);
  629. }
  630. /**
  631. * gimp_config_is_equal_to:
  632. * @a: a #GObject that implements the #GimpConfigInterface.
  633. * @b: another #GObject of the same type as @a.
  634. *
  635. * Compares the two objects. The default implementation of the
  636. * #GimpConfigInterface compares the object properties and thus only
  637. * works for objects that are completely defined by their
  638. * properties.
  639. *
  640. * Returns: %TRUE if the two objects are equal.
  641. *
  642. * Since: 2.4
  643. **/
  644. gboolean
  645. gimp_config_is_equal_to (GimpConfig *a,
  646. GimpConfig *b)
  647. {
  648. g_return_val_if_fail (GIMP_IS_CONFIG (a), FALSE);
  649. g_return_val_if_fail (GIMP_IS_CONFIG (b), FALSE);
  650. g_return_val_if_fail (G_TYPE_FROM_INSTANCE (a) == G_TYPE_FROM_INSTANCE (b),
  651. FALSE);
  652. return GIMP_CONFIG_GET_IFACE (a)->equal (a, b);
  653. }
  654. /**
  655. * gimp_config_reset:
  656. * @config: a #GObject that implements the #GimpConfigInterface.
  657. *
  658. * Resets the object to its default state. The default implementation of the
  659. * #GimpConfigInterface only works for objects that are completely defined by
  660. * their properties.
  661. *
  662. * Since: 2.4
  663. **/
  664. void
  665. gimp_config_reset (GimpConfig *config)
  666. {
  667. g_return_if_fail (GIMP_IS_CONFIG (config));
  668. g_object_freeze_notify (G_OBJECT (config));
  669. GIMP_CONFIG_GET_IFACE (config)->reset (config);
  670. g_object_thaw_notify (G_OBJECT (config));
  671. }
  672. /**
  673. * gimp_config_copy:
  674. * @src: a #GObject that implements the #GimpConfigInterface.
  675. * @dest: another #GObject of the same type as @a.
  676. * @flags: a mask of GParamFlags
  677. *
  678. * Compares all read- and write-able properties from @src and @dest
  679. * that have all @flags set. Differing values are then copied from
  680. * @src to @dest. If @flags is 0, all differing read/write properties.
  681. *
  682. * Properties marked as "construct-only" are not touched.
  683. *
  684. * Returns: %TRUE if @dest was modified, %FALSE otherwise
  685. *
  686. * Since: 2.6
  687. **/
  688. gboolean
  689. gimp_config_copy (GimpConfig *src,
  690. GimpConfig *dest,
  691. GParamFlags flags)
  692. {
  693. gboolean changed;
  694. g_return_val_if_fail (GIMP_IS_CONFIG (src), FALSE);
  695. g_return_val_if_fail (GIMP_IS_CONFIG (dest), FALSE);
  696. g_return_val_if_fail (G_TYPE_FROM_INSTANCE (src) == G_TYPE_FROM_INSTANCE (dest),
  697. FALSE);
  698. g_object_freeze_notify (G_OBJECT (dest));
  699. changed = GIMP_CONFIG_GET_IFACE (src)->copy (src, dest, flags);
  700. g_object_thaw_notify (G_OBJECT (dest));
  701. return changed;
  702. }