static GTokenType gimp_config_deserialize_object (GValue *value, GimpConfig *config, GParamSpec *prop_spec, GScanner *scanner, gint nest_level) { GimpConfigInterface *config_iface; GimpConfig *prop_object; g_object_get_property (G_OBJECT (config), prop_spec->name, value); prop_object = g_value_get_object (value); if (! prop_object) { /* if the object property is not GIMP_CONFIG_PARAM_AGGREGATE, read * the type of the object and create it */ if (! (prop_spec->flags & GIMP_CONFIG_PARAM_AGGREGATE)) { gchar *type_name; GType type; if (! gimp_scanner_parse_string (scanner, &type_name)) return G_TOKEN_STRING; type = g_type_from_name (type_name); g_free (type_name); if (! g_type_is_a (type, prop_spec->value_type)) return G_TOKEN_STRING; prop_object = g_object_new (type, NULL); g_value_take_object (value, prop_object); } else { return G_TOKEN_RIGHT_PAREN; } } config_iface = GIMP_CONFIG_GET_INTERFACE (prop_object); if (! config_iface) return gimp_config_deserialize_any (value, prop_spec, scanner); if (! config_iface->deserialize (prop_object, scanner, nest_level + 1, NULL)) return G_TOKEN_NONE; return G_TOKEN_RIGHT_PAREN; }
static GTokenType gimp_config_deserialize_value (GValue *value, GimpConfig *config, GParamSpec *prop_spec, GScanner *scanner) { if (G_TYPE_FUNDAMENTAL (prop_spec->value_type) == G_TYPE_ENUM) { return gimp_config_deserialize_enum (value, prop_spec, scanner); } else if (G_TYPE_IS_FUNDAMENTAL (prop_spec->value_type)) { return gimp_config_deserialize_fundamental (value, prop_spec, scanner); } else if (prop_spec->value_type == GIMP_TYPE_MEMSIZE) { return gimp_config_deserialize_memsize (value, prop_spec, scanner); } else if (prop_spec->value_type == GIMP_TYPE_CONFIG_PATH) { return gimp_config_deserialize_path (value, prop_spec, scanner); } else if (prop_spec->value_type == GIMP_TYPE_RGB) { return gimp_config_deserialize_rgb (value, prop_spec, scanner); } else if (prop_spec->value_type == GIMP_TYPE_MATRIX2) { return gimp_config_deserialize_matrix2 (value, prop_spec, scanner); } else if (prop_spec->value_type == GIMP_TYPE_VALUE_ARRAY) { return gimp_config_deserialize_value_array (value, config, prop_spec, scanner); } else if (prop_spec->value_type == GIMP_TYPE_UNIT) { return gimp_config_deserialize_unit (value, prop_spec, scanner); } else if (prop_spec->value_type == G_TYPE_FILE) { return gimp_config_deserialize_file_value (value, prop_spec, scanner); } /* This fallback will only work for value_types that * can be transformed from a string value. */ return gimp_config_deserialize_any (value, prop_spec, scanner); }
/* This function is entirely sick, so is our method of serializing * units, which we write out as (unit foo bar) instead of * (unit "foo bar"). The assumption that caused this shit was that a * unit's "identifier" is really an identifier in the C-ish sense, * when in fact it's just a random user entered string. * * Here, we try to parse at least the default units shipped with gimp, * and we add code to parse (unit "foo bar") in order to be compatible * with future correct unit serializing. */ static GTokenType gimp_config_deserialize_unit (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { gchar *old_cset_skip_characters; gchar *old_cset_identifier_first; gchar *old_cset_identifier_nth; GString *buffer; GValue src = G_VALUE_INIT; GTokenType token; /* parse the next token *before* reconfiguring the scanner, so it * skips whitespace first */ token = g_scanner_peek_next_token (scanner); if (token == G_TOKEN_STRING) return gimp_config_deserialize_any (value, prop_spec, scanner); old_cset_skip_characters = scanner->config->cset_skip_characters; old_cset_identifier_first = scanner->config->cset_identifier_first; old_cset_identifier_nth = scanner->config->cset_identifier_nth; scanner->config->cset_skip_characters = ""; scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z "." ); scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_." ); buffer = g_string_new (""); while (g_scanner_peek_next_token (scanner) != G_TOKEN_RIGHT_PAREN) { token = g_scanner_peek_next_token (scanner); if (token == G_TOKEN_IDENTIFIER) { g_scanner_get_next_token (scanner); g_string_append (buffer, scanner->value.v_identifier); } else if (token == G_TOKEN_CHAR) { g_scanner_get_next_token (scanner); g_string_append_c (buffer, scanner->value.v_char); } else if (token == ' ') { g_scanner_get_next_token (scanner); g_string_append_c (buffer, token); } else { token = G_TOKEN_IDENTIFIER; goto cleanup; } } g_value_init (&src, G_TYPE_STRING); g_value_set_static_string (&src, buffer->str); g_value_transform (&src, value); g_value_unset (&src); token = G_TOKEN_RIGHT_PAREN; cleanup: g_string_free (buffer, TRUE); scanner->config->cset_skip_characters = old_cset_skip_characters; scanner->config->cset_identifier_first = old_cset_identifier_first; scanner->config->cset_identifier_nth = old_cset_identifier_nth; return token; }