/* 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_app_path, *preset_system_path; guint64 version_system = G_GUINT64_CONSTANT (0); guint64 version_app = G_GUINT64_CONSTANT (0); guint64 version_user = G_GUINT64_CONSTANT (0); guint64 version = G_GUINT64_CONSTANT (0); gboolean merged = FALSE; GKeyFile *in_user, *in_app = NULL, *in_system; preset_get_paths (preset, &preset_user_path, &preset_app_path, &preset_system_path); /* try to load the user, app and system presets, we do this to get the * versions of all files. */ in_user = preset_open_and_parse_header (preset, preset_user_path, &version_user); if (preset_app_path) { in_app = preset_open_and_parse_header (preset, preset_app_path, &version_app); } in_system = preset_open_and_parse_header (preset, preset_system_path, &version_system); /* compare version to check for merge */ if (in_system) { presets = in_system; version = version_system; } if (in_app) { /* if system version is higher, merge */ if (version > version_app) { preset_merge (presets, in_app); g_key_file_free (in_app); } else { if (presets) g_key_file_free (presets); presets = in_app; version = version_system; } } if (in_user) { /* if system or app version is higher, merge */ if (version > version_user) { preset_merge (presets, in_user); g_key_file_free (in_user); merged = TRUE; } else { if (presets) g_key_file_free (presets); presets = in_user; } } if (!presets) { /* we did not load a user, app 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)); } /* attach the preset to the type */ g_type_set_qdata (type, preset_quark, (gpointer) presets); if (merged) { gst_preset_default_save_presets_file (preset); } } return presets; }
/* save the presets file. A copy of the existing presets file is stored in a * .bak file */ static gboolean gst_preset_default_save_presets_file (GstPreset * preset) { GKeyFile *presets; const gchar *preset_path; GError *error = NULL; gchar *bak_file_name; gboolean backup = TRUE; gchar *data; gsize data_size; preset_get_paths (preset, &preset_path, NULL, NULL); /* get the presets from the type */ if (!(presets = preset_get_keyfile (preset))) goto no_presets; GST_DEBUG_OBJECT (preset, "saving preset file: '%s'", preset_path); /* create backup if possible */ bak_file_name = g_strdup_printf ("%s.bak", preset_path); if (g_file_test (bak_file_name, G_FILE_TEST_EXISTS)) { if (g_unlink (bak_file_name)) { backup = FALSE; GST_INFO_OBJECT (preset, "cannot remove old backup file : %s", bak_file_name); } } if (backup) { if (g_rename (preset_path, bak_file_name)) { GST_INFO_OBJECT (preset, "cannot backup file : %s -> %s", preset_path, bak_file_name); } } g_free (bak_file_name); /* update gstreamer version */ g_key_file_set_string (presets, PRESET_HEADER, PRESET_HEADER_VERSION, PACKAGE_VERSION); /* get new contents, wee need this to save it */ if (!(data = g_key_file_to_data (presets, &data_size, &error))) goto convert_failed; /* write presets */ if (!g_file_set_contents (preset_path, data, data_size, &error)) goto write_failed; g_free (data); return TRUE; /* ERRORS */ no_presets: { GST_WARNING_OBJECT (preset, "no presets, trying to unlink possibly existing preset file: '%s'", preset_path); g_unlink (preset_path); return FALSE; } convert_failed: { GST_WARNING_OBJECT (preset, "can not get the keyfile contents: %s", error->message); g_error_free (error); g_free (data); return FALSE; } write_failed: { GST_WARNING_OBJECT (preset, "Unable to store preset file %s: %s", preset_path, error->message); g_error_free (error); g_free (data); return FALSE; } }
/* 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; }