예제 #1
0
static GKeyFile *
preset_open_and_parse_header (GstPreset * preset, const gchar * preset_path,
    guint64 * preset_version)
{
  GKeyFile *in;
  GError *error = NULL;
  gboolean res;
  const gchar *element_name;
  gchar *name;

  in = g_key_file_new ();

  res = g_key_file_load_from_file (in, preset_path,
      G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error);
  if (!res || error != NULL)
    goto load_error;

  /* element type name and preset name must match or we are dealing with a wrong
   * preset file */
  element_name = G_OBJECT_TYPE_NAME (preset);
  name =
      g_key_file_get_value (in, PRESET_HEADER, PRESET_HEADER_ELEMENT_NAME,
      NULL);

  if (!name || strcmp (name, element_name))
    goto wrong_name;

  g_free (name);

  /* get the version now so that the caller can check it */
  if (preset_version) {
    gchar *str =
        g_key_file_get_value (in, PRESET_HEADER, PRESET_HEADER_VERSION, NULL);
    *preset_version = preset_parse_version (str);
    g_free (str);
  }

  return in;

  /* ERRORS */
load_error:
  {
    GST_WARNING_OBJECT (preset, "Unable to read preset file %s: %s",
        preset_path, error->message);
    g_error_free (error);
    g_key_file_free (in);
    return NULL;
  }
wrong_name:
  {
    GST_WARNING_OBJECT (preset,
        "Wrong element name in preset file %s. Expected %s, got %s",
        preset_path, element_name, GST_STR_NULL (name));
    g_free (name);
    g_key_file_free (in);
    return NULL;
  }
}
/* reads the user and system presets files and merges them together. This
 * function caches the GKeyFile on the element type. If there is no existing
 * preset file, a new in-memory GKeyFile will be created. */
static GKeyFile *
preset_get_keyfile (GstPreset * preset)
{
  GKeyFile *presets;
  GType type = G_TYPE_FROM_INSTANCE (preset);

  /* first see if the have a cached version for the type */
  if (!(presets = g_type_get_qdata (type, preset_quark))) {
    const gchar *preset_user_path, *preset_system_path;
    gchar *str_version_user = NULL, *str_version_system = NULL;
    gboolean updated_from_system = FALSE;
    GKeyFile *in_user, *in_system;

    preset_get_paths (preset, &preset_user_path, &preset_system_path);

    /* try to load the user and system presets, we do this to get the versions
     * of both files. */
    in_user = preset_open_and_parse_header (preset, preset_user_path,
        &str_version_user);
    in_system = preset_open_and_parse_header (preset, preset_system_path,
        &str_version_system);

    /* compare version to check for merge */
    if (in_system) {
      /* keep system presets if there is no user preset or when the system
       * version is higher than the user version. */
      if (!in_user) {
        presets = in_system;
      } else if (preset_parse_version (str_version_system) >
          preset_parse_version (str_version_user)) {
        presets = in_system;
        updated_from_system = TRUE;
      }
    }
    if (in_user) {
      if (updated_from_system) {
        /* merge user on top of system presets */
        preset_merge (presets, in_user);
        g_key_file_free (in_user);
      } else {
        /* keep user presets */
        presets = in_user;
      }
    }
    if (!in_user && !in_system) {
      /* we did not load a user or system presets file, create a new one */
      presets = g_key_file_new ();
      g_key_file_set_string (presets, PRESET_HEADER, PRESET_HEADER_ELEMENT_NAME,
          G_OBJECT_TYPE_NAME (preset));
    }

    g_free (str_version_user);
    g_free (str_version_system);

    /* attach the preset to the type */
    g_type_set_qdata (type, preset_quark, (gpointer) presets);

    if (updated_from_system) {
      gst_preset_default_save_presets_file (preset);
    }
  }
  return presets;
}