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;
}
示例#2
0
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;
}