From d7812173f4499e69eb6e868f8ffd06bbbf9a6ef8 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 4 Jul 2014 03:29:09 +0200 Subject: [PATCH] libgimpconfig: add gimp_config_deserialize_stream() and gimp_scanner_new_stream(). --- libgimpconfig/gimpconfig-iface.c | 48 ++++++++++++ libgimpconfig/gimpconfig-iface.h | 4 + libgimpconfig/gimpconfig.def | 2 + libgimpconfig/gimpscanner.c | 122 +++++++++++++++++++------------ libgimpconfig/gimpscanner.h | 64 ++++++++-------- 5 files changed, 163 insertions(+), 77 deletions(-) diff --git a/libgimpconfig/gimpconfig-iface.c b/libgimpconfig/gimpconfig-iface.c index 1d48c3e6b1..9710de9fea 100644 --- a/libgimpconfig/gimpconfig-iface.c +++ b/libgimpconfig/gimpconfig-iface.c @@ -535,6 +535,54 @@ gimp_config_deserialize_gfile (GimpConfig *config, return success; } +/** + * 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. + * + * Since: GIMP 2.10 + **/ +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; +} + /** * gimp_config_deserialize_string: * @config: a #GObject that implements the #GimpConfigInterface. diff --git a/libgimpconfig/gimpconfig-iface.h b/libgimpconfig/gimpconfig-iface.h index e582b4d6e7..03cf12197e 100644 --- a/libgimpconfig/gimpconfig-iface.h +++ b/libgimpconfig/gimpconfig-iface.h @@ -104,6 +104,10 @@ gboolean gimp_config_deserialize_gfile (GimpConfig *config, GFile *file, gpointer data, GError **error); +gboolean gimp_config_deserialize_stream (GimpConfig *config, + GInputStream *input, + gpointer data, + GError **error); gboolean gimp_config_deserialize_string (GimpConfig *config, const gchar *text, gint text_len, diff --git a/libgimpconfig/gimpconfig.def b/libgimpconfig/gimpconfig.def index 57a38004a7..f3c558fe48 100644 --- a/libgimpconfig/gimpconfig.def +++ b/libgimpconfig/gimpconfig.def @@ -12,6 +12,7 @@ EXPORTS gimp_config_deserialize_properties gimp_config_deserialize_property gimp_config_deserialize_return + gimp_config_deserialize_stream gimp_config_deserialize_string gimp_config_diff gimp_config_duplicate @@ -59,6 +60,7 @@ EXPORTS gimp_scanner_destroy gimp_scanner_new_file gimp_scanner_new_gfile + gimp_scanner_new_stream gimp_scanner_new_string gimp_scanner_parse_boolean gimp_scanner_parse_color diff --git a/libgimpconfig/gimpscanner.c b/libgimpconfig/gimpscanner.c index bd3b2e7d76..756ee4e2e4 100644 --- a/libgimpconfig/gimpscanner.c +++ b/libgimpconfig/gimpscanner.c @@ -109,8 +109,8 @@ GScanner * gimp_scanner_new_gfile (GFile *file, GError **error) { - GScanner *scanner; - gchar *path; + GScanner *scanner; + gchar *path; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); @@ -148,9 +148,6 @@ gimp_scanner_new_gfile (GFile *file, else { GInputStream *input; - GString *string; - gchar buffer[4096]; - gsize bytes_read; input = G_INPUT_STREAM (g_file_read (file, NULL, error)); @@ -167,55 +164,88 @@ gimp_scanner_new_gfile (GFile *file, return NULL; } - string = g_string_new (NULL); + g_object_set_data (G_OBJECT (input), "gimp-data", file); - do - { - GError *my_error = NULL; - gboolean success; - - success = g_input_stream_read_all (input, buffer, sizeof (buffer), - &bytes_read, NULL, &my_error); - - if (bytes_read > 0) - g_string_append_len (string, buffer, bytes_read); - - if (! success) - { - if (string->len > 0) - { - g_printerr ("%s: read error in '%s', trying to scan " - "partial content: %s", - G_STRFUNC, gimp_file_get_utf8_name (file), - my_error->message); - g_clear_error (&my_error); - break; - } - - g_string_free (string, TRUE); - g_object_unref (input); - - g_propagate_error (error, my_error); - - return NULL; - } - } - while (bytes_read == sizeof (buffer)); + scanner = gimp_scanner_new_stream (input, error); g_object_unref (input); - - /* gimp_scanner_new() takes a "name" for the scanner, not a filename */ - scanner = gimp_scanner_new (gimp_file_get_utf8_name (file), - NULL, string->str, error); - - bytes_read = string->len; - - g_scanner_input_text (scanner, g_string_free (string, FALSE), bytes_read); } return scanner; } +/** + * gimp_scanner_new_stream: + * @input: a #GInputStream + * @error: return location for #GError, or %NULL + * + * Return value: The new #GScanner. + * + * Since: GIMP 2.10 + **/ +GScanner * +gimp_scanner_new_stream (GInputStream *input, + GError **error) +{ + GScanner *scanner; + GFile *file; + const gchar *path; + GString *string; + gchar buffer[4096]; + gsize bytes_read; + + g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + file = g_object_get_data (G_OBJECT (input), "gimp-file"); + if (file) + path = gimp_file_get_utf8_name (file); + else + path = "stream"; + + string = g_string_new (NULL); + + do + { + GError *my_error = NULL; + gboolean success; + + success = g_input_stream_read_all (input, buffer, sizeof (buffer), + &bytes_read, NULL, &my_error); + + if (bytes_read > 0) + g_string_append_len (string, buffer, bytes_read); + + if (! success) + { + if (string->len > 0) + { + g_printerr ("%s: read error in '%s', trying to scan " + "partial content: %s", + G_STRFUNC, path, my_error->message); + g_clear_error (&my_error); + break; + } + + g_string_free (string, TRUE); + + g_propagate_error (error, my_error); + + return NULL; + } + } + while (bytes_read == sizeof (buffer)); + + /* gimp_scanner_new() takes a "name" for the scanner, not a filename */ + scanner = gimp_scanner_new (path, NULL, string->str, error); + + bytes_read = string->len; + + g_scanner_input_text (scanner, g_string_free (string, FALSE), bytes_read); + + return scanner; +} + /** * gimp_scanner_new_string: * @text: diff --git a/libgimpconfig/gimpscanner.h b/libgimpconfig/gimpscanner.h index 6592dba09a..c53de80e6a 100644 --- a/libgimpconfig/gimpscanner.h +++ b/libgimpconfig/gimpscanner.h @@ -28,38 +28,40 @@ #define __GIMP_SCANNER_H__ -GScanner * gimp_scanner_new_file (const gchar *filename, - GError **error); -GScanner * gimp_scanner_new_gfile (GFile *file, - GError **error); -GScanner * gimp_scanner_new_string (const gchar *text, - gint text_len, - GError **error); -void gimp_scanner_destroy (GScanner *scanner); +GScanner * gimp_scanner_new_file (const gchar *filename, + GError **error); +GScanner * gimp_scanner_new_gfile (GFile *file, + GError **error); +GScanner * gimp_scanner_new_stream (GInputStream *input, + GError **error); +GScanner * gimp_scanner_new_string (const gchar *text, + gint text_len, + GError **error); +void gimp_scanner_destroy (GScanner *scanner); -gboolean gimp_scanner_parse_token (GScanner *scanner, - GTokenType token); -gboolean gimp_scanner_parse_identifier (GScanner *scanner, - const gchar *identifier); -gboolean gimp_scanner_parse_string (GScanner *scanner, - gchar **dest); -gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, - gchar **dest); -gboolean gimp_scanner_parse_data (GScanner *scanner, - gint length, - guint8 **dest); -gboolean gimp_scanner_parse_int (GScanner *scanner, - gint *dest); -gboolean gimp_scanner_parse_int64 (GScanner *scanner, - gint64 *dest); -gboolean gimp_scanner_parse_float (GScanner *scanner, - gdouble *dest); -gboolean gimp_scanner_parse_boolean (GScanner *scanner, - gboolean *dest); -gboolean gimp_scanner_parse_color (GScanner *scanner, - GimpRGB *dest); -gboolean gimp_scanner_parse_matrix2 (GScanner *scanner, - GimpMatrix2 *dest); +gboolean gimp_scanner_parse_token (GScanner *scanner, + GTokenType token); +gboolean gimp_scanner_parse_identifier (GScanner *scanner, + const gchar *identifier); +gboolean gimp_scanner_parse_string (GScanner *scanner, + gchar **dest); +gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, + gchar **dest); +gboolean gimp_scanner_parse_data (GScanner *scanner, + gint length, + guint8 **dest); +gboolean gimp_scanner_parse_int (GScanner *scanner, + gint *dest); +gboolean gimp_scanner_parse_int64 (GScanner *scanner, + gint64 *dest); +gboolean gimp_scanner_parse_float (GScanner *scanner, + gdouble *dest); +gboolean gimp_scanner_parse_boolean (GScanner *scanner, + gboolean *dest); +gboolean gimp_scanner_parse_color (GScanner *scanner, + GimpRGB *dest); +gboolean gimp_scanner_parse_matrix2 (GScanner *scanner, + GimpMatrix2 *dest); #endif /* __GIMP_SCANNER_H__ */