libgimpconfig: add gimp_config_deserialize_stream()

and gimp_scanner_new_stream().
This commit is contained in:
Michael Natterer 2014-07-04 03:29:09 +02:00
parent e7d9e01d63
commit d7812173f4
5 changed files with 163 additions and 77 deletions

View File

@ -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.

View File

@ -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,

View File

@ -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

View File

@ -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:

View File

@ -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__ */