diff options
author | Richard Hughes <richard@hughsie.com> | 2016-11-16 21:15:02 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2016-11-21 15:19:55 +0000 |
commit | bd6ea9106e0539364e66c6dc6fb5f5f3b0878920 (patch) | |
tree | 1105f249751103a08b0cc72a7d539ca38de59602 | |
parent | 977f0cc2623dc89e68b4c0d41b0164c59ac9a1ca (diff) | |
download | appstream-glib-bd6ea9106e0539364e66c6dc6fb5f5f3b0878920.tar.gz |
Use refcounted strings in all objects
This drops the RSS by ~1Mb and has the potential to do much more drastic
things if this is used in GNOME Software.
-rw-r--r-- | libappstream-glib/as-app.c | 395 | ||||
-rw-r--r-- | libappstream-glib/as-bundle.c | 39 | ||||
-rw-r--r-- | libappstream-glib/as-checksum.c | 30 | ||||
-rw-r--r-- | libappstream-glib/as-content-rating.c | 20 | ||||
-rw-r--r-- | libappstream-glib/as-icon.c | 45 | ||||
-rw-r--r-- | libappstream-glib/as-image.c | 56 | ||||
-rw-r--r-- | libappstream-glib/as-node-private.h | 6 | ||||
-rw-r--r-- | libappstream-glib/as-node.c | 187 | ||||
-rw-r--r-- | libappstream-glib/as-provide.c | 12 | ||||
-rw-r--r-- | libappstream-glib/as-release.c | 35 | ||||
-rw-r--r-- | libappstream-glib/as-review.c | 85 | ||||
-rw-r--r-- | libappstream-glib/as-screenshot.c | 10 | ||||
-rw-r--r-- | libappstream-glib/as-self-test.c | 10 | ||||
-rw-r--r-- | libappstream-glib/as-store.c | 24 | ||||
-rw-r--r-- | libappstream-glib/as-suggest.c | 5 | ||||
-rw-r--r-- | libappstream-glib/as-translation.c | 16 |
16 files changed, 492 insertions, 483 deletions
diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index 23b50aa..7d6679b 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -45,6 +45,7 @@ #include "as-node-private.h" #include "as-provide-private.h" #include "as-release-private.h" +#include "as-ref-string.h" #include "as-review-private.h" #include "as-screenshot-private.h" #include "as-stemmer.h" @@ -60,23 +61,23 @@ typedef struct AsIconKind icon_kind; AsAppKind kind; AsStemmer *stemmer; - GHashTable *comments; /* of locale:string */ - GHashTable *developer_names; /* of locale:string */ - GHashTable *descriptions; /* of locale:string */ - GHashTable *keywords; /* of locale:GPtrArray */ - GHashTable *languages; /* of locale:string */ - GHashTable *metadata; /* of key:value */ - GHashTable *names; /* of locale:string */ - GHashTable *urls; /* of key:string */ + GHashTable *comments; /* of AsRefString:AsRefString */ + GHashTable *developer_names; /* of AsRefString:AsRefString */ + GHashTable *descriptions; /* of AsRefString:AsRefString */ + GHashTable *keywords; /* of AsRefString:GPtrArray */ + GHashTable *languages; /* of AsRefString:AsRefString */ + GHashTable *metadata; /* of AsRefString:AsRefString */ + GHashTable *names; /* of AsRefString:AsRefString */ + GHashTable *urls; /* of AsRefString:AsRefString */ GPtrArray *addons; /* of AsApp */ - GPtrArray *categories; /* of string */ - GPtrArray *compulsory_for_desktops; /* of string */ - GPtrArray *extends; /* of string */ - GPtrArray *kudos; /* of string */ - GPtrArray *permissions; /* of string */ - GPtrArray *mimetypes; /* of string */ - GPtrArray *pkgnames; /* of string */ - GPtrArray *architectures; /* of string */ + GPtrArray *categories; /* of AsRefString */ + GPtrArray *compulsory_for_desktops; /* of AsRefString */ + GPtrArray *extends; /* of AsRefString */ + GPtrArray *kudos; /* of AsRefString */ + GPtrArray *permissions; /* of AsRefString */ + GPtrArray *mimetypes; /* of AsRefString */ + GPtrArray *pkgnames; /* of AsRefString */ + GPtrArray *architectures; /* of AsRefString */ GPtrArray *releases; /* of AsRelease */ GPtrArray *provides; /* of AsProvide */ GPtrArray *screenshots; /* of AsScreenshot */ @@ -86,7 +87,7 @@ typedef struct GPtrArray *bundles; /* of AsBundle */ GPtrArray *translations; /* of AsTranslation */ GPtrArray *suggests; /* of AsSuggest */ - GPtrArray *vetos; /* of string */ + GPtrArray *vetos; /* of AsRefString */ AsAppSourceKind source_kind; AsAppScope scope; AsAppMergeKind merge_kind; @@ -94,19 +95,19 @@ typedef struct AsAppTrustFlags trust_flags; AsAppQuirk quirk; AsAppSearchMatch search_match; - gchar *icon_path; - gchar *id_filename; - gchar *id; - gchar *origin; - gchar *project_group; - gchar *project_license; - gchar *metadata_license; - gchar *source_pkgname; - gchar *update_contact; + AsRefString *icon_path; + AsRefString *id_filename; + AsRefString *id; + AsRefString *origin; + AsRefString *project_group; + AsRefString *project_license; + AsRefString *metadata_license; + AsRefString *source_pkgname; + AsRefString *update_contact; gchar *unique_id; gboolean unique_id_valid; - gchar *source_file; - gchar *branch; + AsRefString *source_file; + AsRefString *branch; gint priority; gsize token_cache_valid; GHashTable *token_cache; /* of string:AsAppTokenType* */ @@ -462,18 +463,29 @@ as_app_finalize (GObject *object) if (priv->search_blacklist != NULL) g_hash_table_unref (priv->search_blacklist); - g_free (priv->icon_path); - g_free (priv->id_filename); - g_free (priv->id); - g_free (priv->project_group); - g_free (priv->project_license); - g_free (priv->metadata_license); - g_free (priv->origin); - g_free (priv->source_pkgname); - g_free (priv->update_contact); + if (priv->icon_path != NULL) + as_ref_string_unref (priv->icon_path); + if (priv->id_filename != NULL) + as_ref_string_unref (priv->id_filename); + if (priv->id != NULL) + as_ref_string_unref (priv->id); + if (priv->project_group != NULL) + as_ref_string_unref (priv->project_group); + if (priv->project_license != NULL) + as_ref_string_unref (priv->project_license); + if (priv->metadata_license != NULL) + as_ref_string_unref (priv->metadata_license); + if (priv->origin != NULL) + as_ref_string_unref (priv->origin); + if (priv->source_pkgname != NULL) + as_ref_string_unref (priv->source_pkgname); + if (priv->update_contact != NULL) + as_ref_string_unref (priv->update_contact); g_free (priv->unique_id); - g_free (priv->source_file); - g_free (priv->branch); + if (priv->source_file != NULL) + as_ref_string_unref (priv->source_file); + if (priv->branch != NULL) + as_ref_string_unref (priv->branch); g_hash_table_unref (priv->comments); g_hash_table_unref (priv->developer_names); g_hash_table_unref (priv->descriptions); @@ -510,17 +522,18 @@ static void as_app_init (AsApp *app) { AsAppPrivate *priv = GET_PRIVATE (app); - priv->categories = g_ptr_array_new_with_free_func (g_free); - priv->compulsory_for_desktops = g_ptr_array_new_with_free_func (g_free); + priv->categories = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + priv->compulsory_for_desktops = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); priv->content_ratings = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - priv->extends = g_ptr_array_new_with_free_func (g_free); + priv->extends = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); priv->keywords = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_ptr_array_unref); - priv->kudos = g_ptr_array_new_with_free_func (g_free); - priv->permissions = g_ptr_array_new_with_free_func (g_free); - priv->mimetypes = g_ptr_array_new_with_free_func (g_free); - priv->pkgnames = g_ptr_array_new_with_free_func (g_free); - priv->architectures = g_ptr_array_new_with_free_func (g_free); + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) g_ptr_array_unref); + priv->kudos = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + priv->permissions = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + priv->mimetypes = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + priv->pkgnames = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + priv->architectures = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); priv->addons = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->provides = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); @@ -530,15 +543,29 @@ as_app_init (AsApp *app) priv->bundles = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->translations = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->suggests = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - priv->vetos = g_ptr_array_new_with_free_func (g_free); - - priv->comments = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->developer_names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->descriptions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->languages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->urls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->vetos = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + + priv->comments = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); + priv->developer_names = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); + priv->descriptions = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); + priv->languages = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, NULL); + priv->metadata = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); + priv->names = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); + priv->urls = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); priv->token_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->search_match = AS_APP_SEARCH_MATCH_LAST; } @@ -1987,12 +2014,12 @@ as_app_set_id (AsApp *app, const gchar *id) } /* save full ID */ - g_free (priv->id); - priv->id = g_strdup (id); + as_ref_string_assign_safe (&priv->id, id); /* save filename */ - g_free (priv->id_filename); - priv->id_filename = g_strdup (as_app_get_id_no_prefix (app)); + if (priv->id_filename != NULL) + as_ref_string_unref (priv->id_filename); + priv->id_filename = as_ref_string_new_copy (as_app_get_id_no_prefix (app)); g_strdelimit (priv->id_filename, "&<>", '-'); for (i = 0; suffixes[i] != NULL; i++) { tmp = g_strrstr_len (priv->id_filename, -1, suffixes[i]); @@ -2188,8 +2215,7 @@ as_app_set_project_group (AsApp *app, const gchar *project_group) } } - g_free (priv->project_group); - priv->project_group = g_strdup (project_group); + as_ref_string_assign_safe (&priv->project_group, project_group); } /** @@ -2213,8 +2239,7 @@ as_app_set_project_license (AsApp *app, const gchar *project_license) return; } - g_free (priv->project_license); - priv->project_license = g_strdup (project_license); + as_ref_string_assign_safe (&priv->project_license, project_license); } /** @@ -2230,6 +2255,7 @@ void as_app_set_metadata_license (AsApp *app, const gchar *metadata_license) { AsAppPrivate *priv = GET_PRIVATE (app); + g_autofree gchar *tmp = NULL; g_auto(GStrv) tokens = NULL; /* handle untrusted */ @@ -2240,9 +2266,9 @@ as_app_set_metadata_license (AsApp *app, const gchar *metadata_license) } /* automatically replace deprecated license names */ - g_free (priv->metadata_license); tokens = as_utils_spdx_license_tokenize (metadata_license); - priv->metadata_license = as_utils_spdx_license_detokenize (tokens); + tmp = as_utils_spdx_license_detokenize (tokens); + as_ref_string_assign_safe (&priv->metadata_license, tmp); } /** @@ -2266,8 +2292,7 @@ as_app_set_source_pkgname (AsApp *app, priv->problems |= AS_APP_PROBLEM_NOT_VALID_UTF8; return; } - g_free (priv->source_pkgname); - priv->source_pkgname = g_strdup (source_pkgname); + as_ref_string_assign_safe (&priv->source_pkgname, source_pkgname); } /** @@ -2283,8 +2308,7 @@ void as_app_set_source_file (AsApp *app, const gchar *source_file) { AsAppPrivate *priv = GET_PRIVATE (app); - g_free (priv->source_file); - priv->source_file = g_strdup (source_file); + as_ref_string_assign_safe (&priv->source_file, source_file); } /** @@ -2300,8 +2324,7 @@ void as_app_set_branch (AsApp *app, const gchar *branch) { AsAppPrivate *priv = GET_PRIVATE (app); - g_free (priv->branch); - priv->branch = g_strdup (branch); + as_ref_string_assign_safe (&priv->branch, branch); /* no longer valid */ priv->unique_id_valid = FALSE; @@ -2345,8 +2368,7 @@ as_app_set_update_contact (AsApp *app, const gchar *update_contact) } /* copy as-is */ - g_free (priv->update_contact); - priv->update_contact = g_strdup (update_contact); + as_ref_string_assign_safe (&priv->update_contact, update_contact); if (priv->update_contact == NULL) return; @@ -2381,10 +2403,7 @@ void as_app_set_origin (AsApp *app, const gchar *origin) { AsAppPrivate *priv = GET_PRIVATE (app); - g_free (priv->origin); - priv->origin = g_strdup (origin); - - /* no longer valid */ + as_ref_string_assign_safe (&priv->origin, origin); priv->unique_id_valid = FALSE; } @@ -2409,8 +2428,7 @@ as_app_set_icon_path (AsApp *app, const gchar *icon_path) return; } - g_free (priv->icon_path); - priv->icon_path = g_strdup (icon_path); + as_ref_string_assign_safe (&priv->icon_path, icon_path); } /** @@ -2429,7 +2447,7 @@ as_app_set_name (AsApp *app, const gchar *name) { AsAppPrivate *priv = GET_PRIVATE (app); - gchar *tmp_locale; + g_autoptr(AsRefString) locale_fixed = NULL; /* handle untrusted */ if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_VALID_UTF8) > 0 && @@ -2439,12 +2457,12 @@ as_app_set_name (AsApp *app, } /* get fixed locale */ - tmp_locale = as_node_fix_locale (locale); - if (tmp_locale == NULL) + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) return; g_hash_table_insert (priv->names, - tmp_locale, - g_strdup (name)); + as_ref_string_ref (locale_fixed), + as_ref_string_new (name)); } /** @@ -2463,7 +2481,7 @@ as_app_set_comment (AsApp *app, const gchar *comment) { AsAppPrivate *priv = GET_PRIVATE (app); - gchar *tmp_locale; + g_autoptr(AsRefString) locale_fixed = NULL; g_return_if_fail (comment != NULL); @@ -2475,12 +2493,12 @@ as_app_set_comment (AsApp *app, } /* get fixed locale */ - tmp_locale = as_node_fix_locale (locale); - if (tmp_locale == NULL) + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) return; g_hash_table_insert (priv->comments, - tmp_locale, - g_strdup (comment)); + as_ref_string_ref (locale_fixed), + as_ref_string_new (comment)); } /** @@ -2499,7 +2517,7 @@ as_app_set_developer_name (AsApp *app, const gchar *developer_name) { AsAppPrivate *priv = GET_PRIVATE (app); - gchar *tmp_locale; + g_autoptr(AsRefString) locale_fixed = NULL; g_return_if_fail (developer_name != NULL); @@ -2511,12 +2529,12 @@ as_app_set_developer_name (AsApp *app, } /* get fixed locale */ - tmp_locale = as_node_fix_locale (locale); - if (tmp_locale == NULL) + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) return; g_hash_table_insert (priv->developer_names, - tmp_locale, - g_strdup (developer_name)); + as_ref_string_ref (locale_fixed), + as_ref_string_new (developer_name)); } /** @@ -2535,7 +2553,7 @@ as_app_set_description (AsApp *app, const gchar *description) { AsAppPrivate *priv = GET_PRIVATE (app); - gchar *tmp_locale; + g_autoptr(AsRefString) locale_fixed = NULL; g_return_if_fail (description != NULL); @@ -2547,12 +2565,12 @@ as_app_set_description (AsApp *app, } /* get fixed locale */ - tmp_locale = as_node_fix_locale (locale); - if (tmp_locale == NULL) + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) return; g_hash_table_insert (priv->descriptions, - tmp_locale, - g_strdup (description)); + as_ref_string_ref (locale_fixed), + as_ref_string_new (description)); } /** @@ -2599,7 +2617,7 @@ as_app_add_category (AsApp *app, const gchar *category) return; } - g_ptr_array_add (priv->categories, g_strdup (category)); + g_ptr_array_add (priv->categories, as_ref_string_new (category)); } @@ -2632,7 +2650,7 @@ as_app_add_compulsory_for_desktop (AsApp *app, const gchar *compulsory_for_deskt } g_ptr_array_add (priv->compulsory_for_desktops, - g_strdup (compulsory_for_desktop)); + as_ref_string_new (compulsory_for_desktop)); } /** @@ -2652,7 +2670,7 @@ as_app_add_keyword (AsApp *app, { AsAppPrivate *priv = GET_PRIVATE (app); GPtrArray *tmp; - g_autofree gchar *tmp_locale = NULL; + g_autoptr(AsRefString) locale_fixed = NULL; g_return_if_fail (keyword != NULL); @@ -2663,20 +2681,20 @@ as_app_add_keyword (AsApp *app, } /* get fixed locale */ - tmp_locale = as_node_fix_locale (locale); - if (tmp_locale == NULL) + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) return; /* create an array if required */ - tmp = g_hash_table_lookup (priv->keywords, tmp_locale); + tmp = g_hash_table_lookup (priv->keywords, locale_fixed); if (tmp == NULL) { - tmp = g_ptr_array_new_with_free_func (g_free); - g_hash_table_insert (priv->keywords, g_strdup (tmp_locale), tmp); + tmp = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); + g_hash_table_insert (priv->keywords, as_ref_string_ref (locale_fixed), tmp); } else if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_DUPLICATES) > 0) { if (as_ptr_array_find_string (tmp, keyword)) return; } - g_ptr_array_add (tmp, g_strdup (keyword)); + g_ptr_array_add (tmp, as_ref_string_new (keyword)); } /** @@ -2704,7 +2722,7 @@ as_app_add_kudo (AsApp *app, const gchar *kudo) as_ptr_array_find_string (priv->kudos, kudo)) { return; } - g_ptr_array_add (priv->kudos, g_strdup (kudo)); + g_ptr_array_add (priv->kudos, as_ref_string_new (kudo)); } /** @@ -2732,7 +2750,7 @@ as_app_add_permission (AsApp *app, const gchar *permission) as_ptr_array_find_string (priv->permissions, permission)) { return; } - g_ptr_array_add (priv->permissions, g_strdup (permission)); + g_ptr_array_add (priv->permissions, as_ref_string_new (permission)); } /** @@ -2777,7 +2795,7 @@ as_app_add_mimetype (AsApp *app, const gchar *mimetype) return; } - g_ptr_array_add (priv->mimetypes, g_strdup (mimetype)); + g_ptr_array_add (priv->mimetypes, as_ref_string_new (mimetype)); } static void @@ -3187,7 +3205,7 @@ as_app_add_pkgname (AsApp *app, const gchar *pkgname) return; } - g_ptr_array_add (priv->pkgnames, g_strdup (pkgname)); + g_ptr_array_add (priv->pkgnames, as_ref_string_new (pkgname)); /* no longer valid */ priv->unique_id_valid = FALSE; @@ -3220,7 +3238,7 @@ as_app_add_arch (AsApp *app, const gchar *arch) return; } - g_ptr_array_add (priv->architectures, g_strdup (arch)); + g_ptr_array_add (priv->architectures, as_ref_string_new (arch)); } /** @@ -3250,7 +3268,7 @@ as_app_add_language (AsApp *app, if (locale == NULL) locale = "C"; g_hash_table_insert (priv->languages, - g_strdup (locale), + as_ref_string_new (locale), GINT_TO_POINTER (percentage)); } @@ -3277,10 +3295,13 @@ as_app_add_url (AsApp *app, priv->problems |= AS_APP_PROBLEM_NOT_VALID_UTF8; return; } - - g_hash_table_insert (priv->urls, - g_strdup (as_url_kind_to_string (url_kind)), - g_strdup (url)); + if (url == NULL) { + g_hash_table_remove (priv->urls, as_url_kind_to_string (url_kind)); + } else { + g_hash_table_insert (priv->urls, + as_ref_string_new (as_url_kind_to_string (url_kind)), + as_ref_string_new (url)); + } } /** @@ -3310,8 +3331,8 @@ as_app_add_metadata (AsApp *app, if (value == NULL) value = ""; g_hash_table_insert (priv->metadata, - g_strdup (key), - g_strdup (value)); + as_ref_string_new (key), + as_ref_string_new (value)); } /** @@ -3359,7 +3380,7 @@ as_app_add_extends (AsApp *app, const gchar *extends) if (g_strcmp0 (priv->id, extends) == 0) return; - g_ptr_array_add (priv->extends, g_strdup (extends)); + g_ptr_array_add (priv->extends, as_ref_string_new (extends)); } /** @@ -3401,7 +3422,7 @@ as_app_subsume_dict (GHashTable *dest, GHashTable *src, AsAppSubsumeFlags flags) continue; } value = g_hash_table_lookup (src, key); - g_hash_table_insert (dest, g_strdup (key), g_strdup (value)); + g_hash_table_insert (dest, as_ref_string_new (key), as_ref_string_new (value)); } } @@ -3892,13 +3913,13 @@ as_app_node_insert_keywords (AsApp *app, GNode *parent, AsNodeContext *ctx) /* don't add localized keywords that already exist in C, e.g. * there's no point adding "c++" in 14 different languages */ already_in_c = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + (GDestroyNotify) as_ref_string_unref, NULL); keywords = g_hash_table_lookup (priv->keywords, "C"); if (keywords != NULL) { for (i = 0; i < keywords->len; i++) { tmp = g_ptr_array_index (keywords, i); g_hash_table_insert (already_in_c, - g_strdup (tmp), + as_ref_string_new (tmp), GINT_TO_POINTER (1)); } } @@ -4223,7 +4244,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, AsAppPrivate *priv = GET_PRIVATE (app); GNode *c; const gchar *tmp; - gchar *taken; + g_autoptr(AsRefString) xml_lang = NULL; switch (as_node_get_tag (n)) { @@ -4249,7 +4270,9 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, /* <pkgname> */ case AS_TAG_PKGNAME: - g_ptr_array_add (priv->pkgnames, as_node_take_data (n)); + tmp = as_node_get_data (n); + if (tmp != NULL) + g_ptr_array_add (priv->pkgnames, as_ref_string_ref (tmp)); break; /* <bundle> */ @@ -4287,32 +4310,41 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, /* <name> */ case AS_TAG_NAME: - taken = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); - if (taken == NULL) + xml_lang = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); + if (xml_lang == NULL) break; - g_hash_table_insert (priv->names, - taken, - as_node_take_data (n)); + tmp = as_node_get_data (n); + if (tmp != NULL) { + g_hash_table_insert (priv->names, + as_ref_string_ref (xml_lang), + as_ref_string_ref (tmp)); + } break; /* <summary> */ case AS_TAG_SUMMARY: - taken = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); - if (taken == NULL) + xml_lang = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); + if (xml_lang == NULL) break; - g_hash_table_insert (priv->comments, - taken, - as_node_take_data (n)); + tmp = as_node_get_data (n); + if (tmp != NULL) { + g_hash_table_insert (priv->comments, + as_ref_string_ref (xml_lang), + as_ref_string_ref (tmp)); + } break; /* <developer_name> */ case AS_TAG_DEVELOPER_NAME: - taken = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); - if (taken == NULL) + xml_lang = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); + if (xml_lang == NULL) break; - g_hash_table_insert (priv->developer_names, - taken, - as_node_take_data (n)); + tmp = as_node_get_data (n); + if (tmp != NULL) { + g_hash_table_insert (priv->developer_names, + as_ref_string_ref (xml_lang), + as_ref_string_ref (tmp)); + } break; /* <description> */ @@ -4394,10 +4426,11 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, for (c = n->children; c != NULL; c = c->next) { if (as_node_get_tag (c) != AS_TAG_ARCH) continue; - taken = as_node_take_data (c); - if (taken == NULL) + tmp = as_node_get_data (c); + if (tmp == NULL) continue; - g_ptr_array_add (priv->architectures, taken); + g_ptr_array_add (priv->architectures, + as_ref_string_ref (tmp)); } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -4408,18 +4441,18 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, if (!(flags & AS_APP_PARSE_FLAG_APPEND_DATA)) g_hash_table_remove_all (priv->keywords); for (c = n->children; c != NULL; c = c->next) { + g_autoptr(AsRefString) xml_lang2 = NULL; if (as_node_get_tag (c) != AS_TAG_KEYWORD) continue; tmp = as_node_get_data (c); if (tmp == NULL) continue; - taken = as_node_fix_locale (as_node_get_attribute (c, "xml:lang")); - if (taken == NULL) + xml_lang2 = as_node_fix_locale (as_node_get_attribute (c, "xml:lang")); + if (xml_lang2 == NULL) continue; if (g_strstr_len (tmp, -1, ",") != NULL) priv->problems |= AS_APP_PROBLEM_INVALID_KEYWORDS; - as_app_add_keyword (app, taken, tmp); - g_free (taken); + as_app_add_keyword (app, xml_lang2, tmp); } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -4432,10 +4465,10 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, for (c = n->children; c != NULL; c = c->next) { if (as_node_get_tag (c) != AS_TAG_KUDO) continue; - taken = as_node_take_data (c); - if (taken == NULL) + tmp = as_node_get_data (c); + if (tmp == NULL) continue; - g_ptr_array_add (priv->kudos, taken); + g_ptr_array_add (priv->kudos, as_ref_string_ref (tmp)); } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -4448,10 +4481,10 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, for (c = n->children; c != NULL; c = c->next) { if (as_node_get_tag (c) != AS_TAG_PERMISSION) continue; - taken = as_node_take_data (c); - if (taken == NULL) + tmp = as_node_get_data (c); + if (tmp == NULL) continue; - g_ptr_array_add (priv->permissions, taken); + g_ptr_array_add (priv->permissions, as_ref_string_ref (tmp)); } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -4464,10 +4497,10 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, for (c = n->children; c != NULL; c = c->next) { if (as_node_get_tag (c) != AS_TAG_VETO) continue; - taken = as_node_take_data (c); - if (taken == NULL) + tmp = as_node_get_data (c); + if (tmp == NULL) continue; - g_ptr_array_add (priv->vetos, taken); + g_ptr_array_add (priv->vetos, as_ref_string_ref (tmp)); } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -4480,10 +4513,10 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, for (c = n->children; c != NULL; c = c->next) { if (as_node_get_tag (c) != AS_TAG_MIMETYPE) continue; - taken = as_node_take_data (c); - if (taken == NULL) + tmp = as_node_get_data (c); + if (tmp == NULL) continue; - g_ptr_array_add (priv->mimetypes, taken); + g_ptr_array_add (priv->mimetypes, as_ref_string_ref (tmp)); } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -4495,8 +4528,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, priv->problems |= AS_APP_PROBLEM_TRANSLATED_LICENSE; break; } - g_free (priv->project_license); - priv->project_license = as_node_take_data (n); + as_ref_string_assign (&priv->project_license, as_node_get_data (n)); break; /* <project_license> */ @@ -4542,13 +4574,19 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, /* <compulsory_for_desktop> */ case AS_TAG_COMPULSORY_FOR_DESKTOP: + tmp = as_node_get_data (n); + if (tmp == NULL) + break; g_ptr_array_add (priv->compulsory_for_desktops, - as_node_take_data (n)); + as_ref_string_ref (tmp)); break; /* <extends> */ case AS_TAG_EXTENDS: - g_ptr_array_add (priv->extends, as_node_take_data (n)); + tmp = as_node_get_data (n); + if (tmp == NULL) + break; + g_ptr_array_add (priv->extends, as_ref_string_ref (tmp)); break; /* <screenshots> */ @@ -4650,14 +4688,21 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, if (!(flags & AS_APP_PARSE_FLAG_APPEND_DATA)) g_hash_table_remove_all (priv->metadata); for (c = n->children; c != NULL; c = c->next) { - gchar *key; + AsRefString *key; + AsRefString *value; if (as_node_get_tag (c) != AS_TAG_VALUE) continue; - key = as_node_take_attribute (c, "key"); - taken = as_node_take_data (c); - if (taken == NULL) - taken = g_strdup (""); - g_hash_table_insert (priv->metadata, key, taken); + key = as_node_get_attribute (c, "key"); + value = as_node_get_data (c); + if (value == NULL) { + g_hash_table_insert (priv->metadata, + as_ref_string_ref (key), + as_ref_string_new ("")); + } else { + g_hash_table_insert (priv->metadata, + as_ref_string_ref (key), + as_ref_string_ref (value)); + } } if (n->children == NULL) priv->problems |= AS_APP_PROBLEM_EXPECTED_CHILDREN; @@ -5342,7 +5387,7 @@ as_app_get_search_tokens (AsApp *app) keys = g_hash_table_get_keys (priv->token_cache); array = g_ptr_array_new_with_free_func (g_free); for (l = keys; l != NULL; l = l->next) - g_ptr_array_add (array, g_strdup (l->data)); + g_ptr_array_add (array, as_ref_string_new (l->data)); return array; } @@ -5847,12 +5892,12 @@ void as_app_add_veto (AsApp *app, const gchar *fmt, ...) { AsAppPrivate *priv = GET_PRIVATE (app); - gchar *tmp; + g_autofree gchar *tmp = NULL; va_list args; va_start (args, fmt); tmp = g_strdup_vprintf (fmt, args); va_end (args); - g_ptr_array_add (priv->vetos, tmp); + g_ptr_array_add (priv->vetos, as_ref_string_new (tmp)); } /** diff --git a/libappstream-glib/as-bundle.c b/libappstream-glib/as-bundle.c index a793828..8d5f475 100644 --- a/libappstream-glib/as-bundle.c +++ b/libappstream-glib/as-bundle.c @@ -36,15 +36,16 @@ #include "as-bundle-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" typedef struct { AsBundleKind kind; - gchar *id; - gchar *runtime; - gchar *sdk; + AsRefString *id; + AsRefString *runtime; + AsRefString *sdk; } AsBundlePrivate; G_DEFINE_TYPE_WITH_PRIVATE (AsBundle, as_bundle, G_TYPE_OBJECT) @@ -57,9 +58,12 @@ as_bundle_finalize (GObject *object) AsBundle *bundle = AS_BUNDLE (object); AsBundlePrivate *priv = GET_PRIVATE (bundle); - g_free (priv->id); - g_free (priv->runtime); - g_free (priv->sdk); + if (priv->id != NULL) + as_ref_string_unref (priv->id); + if (priv->runtime != NULL) + as_ref_string_unref (priv->runtime); + if (priv->sdk != NULL) + as_ref_string_unref (priv->sdk); G_OBJECT_CLASS (as_bundle_parent_class)->finalize (object); } @@ -216,8 +220,7 @@ void as_bundle_set_id (AsBundle *bundle, const gchar *id) { AsBundlePrivate *priv = GET_PRIVATE (bundle); - g_free (priv->id); - priv->id = g_strdup (id); + as_ref_string_assign_safe (&priv->id, id); } /** @@ -233,8 +236,7 @@ void as_bundle_set_runtime (AsBundle *bundle, const gchar *runtime) { AsBundlePrivate *priv = GET_PRIVATE (bundle); - g_free (priv->runtime); - priv->runtime = g_strdup (runtime); + as_ref_string_assign_safe (&priv->runtime, runtime); } /** @@ -250,8 +252,7 @@ void as_bundle_set_sdk (AsBundle *bundle, const gchar *sdk) { AsBundlePrivate *priv = GET_PRIVATE (bundle); - g_free (priv->sdk); - priv->sdk = g_strdup (sdk); + as_ref_string_assign_safe (&priv->sdk, sdk); } /** @@ -319,21 +320,15 @@ as_bundle_node_parse (AsBundle *bundle, GNode *node, { AsBundlePrivate *priv = GET_PRIVATE (bundle); const gchar *tmp; - gchar *taken; tmp = as_node_get_attribute (node, "type"); as_bundle_set_kind (bundle, as_bundle_kind_from_string (tmp)); - taken = as_node_take_data (node); - if (taken != NULL) { - g_free (priv->id); - priv->id = taken; - } + + as_ref_string_assign (&priv->id, as_node_get_data (node)); /* optional */ - g_free (priv->runtime); - priv->runtime = as_node_take_attribute (node, "runtime"); - g_free (priv->sdk); - priv->sdk = as_node_take_attribute (node, "sdk"); + as_ref_string_assign (&priv->runtime, as_node_get_attribute (node, "runtime")); + as_ref_string_assign (&priv->sdk, as_node_get_attribute (node, "sdk")); return TRUE; } diff --git a/libappstream-glib/as-checksum.c b/libappstream-glib/as-checksum.c index cbdbedd..f5ac787 100644 --- a/libappstream-glib/as-checksum.c +++ b/libappstream-glib/as-checksum.c @@ -34,6 +34,7 @@ #include "as-checksum-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" @@ -41,8 +42,8 @@ typedef struct { AsChecksumTarget target; GChecksumType kind; - gchar *filename; - gchar *value; + AsRefString *filename; + AsRefString *value; } AsChecksumPrivate; G_DEFINE_TYPE_WITH_PRIVATE (AsChecksum, as_checksum, G_TYPE_OBJECT) @@ -57,8 +58,10 @@ as_checksum_finalize (GObject *object) AsChecksum *checksum = AS_CHECKSUM (object); AsChecksumPrivate *priv = GET_PRIVATE (checksum); - g_free (priv->filename); - g_free (priv->value); + if (priv->filename != NULL) + as_ref_string_unref (priv->filename); + if (priv->value != NULL) + as_ref_string_unref (priv->value); G_OBJECT_CLASS (as_checksum_parent_class)->finalize (object); } @@ -199,8 +202,7 @@ as_checksum_set_filename (AsChecksum *checksum, const gchar *filename) { AsChecksumPrivate *priv = GET_PRIVATE (checksum); - g_free (priv->filename); - priv->filename = g_strdup (filename); + as_ref_string_assign_safe (&priv->filename, filename); } /** @@ -216,8 +218,7 @@ void as_checksum_set_value (AsChecksum *checksum, const gchar *value) { AsChecksumPrivate *priv = GET_PRIVATE (checksum); - g_free (priv->value); - priv->value = g_strdup (value); + as_ref_string_assign_safe (&priv->value, value); } /** @@ -333,7 +334,6 @@ as_checksum_node_parse (AsChecksum *checksum, GNode *node, { AsChecksumPrivate *priv = GET_PRIVATE (checksum); const gchar *tmp; - gchar *taken; tmp = as_node_get_attribute (node, "type"); if (tmp != NULL) @@ -341,16 +341,8 @@ as_checksum_node_parse (AsChecksum *checksum, GNode *node, tmp = as_node_get_attribute (node, "target"); if (tmp != NULL) priv->target = as_checksum_target_from_string (tmp); - taken = as_node_take_attribute (node, "filename"); - if (taken != NULL) { - g_free (priv->filename); - priv->filename = taken; - } - taken = as_node_take_data (node); - if (taken != NULL) { - g_free (priv->value); - priv->value = taken; - } + as_ref_string_assign (&priv->filename, as_node_get_attribute (node, "filename")); + as_ref_string_assign (&priv->value, as_node_get_data (node)); return TRUE; } diff --git a/libappstream-glib/as-content-rating.c b/libappstream-glib/as-content-rating.c index 488fdc9..0b0a76d 100644 --- a/libappstream-glib/as-content-rating.c +++ b/libappstream-glib/as-content-rating.c @@ -34,16 +34,17 @@ #include "as-node-private.h" #include "as-content-rating-private.h" +#include "as-ref-string.h" #include "as-tag.h" typedef struct { - gchar *id; + AsRefString *id; AsContentRatingValue value; } AsContentRatingKey; typedef struct { - gchar *kind; + AsRefString *kind; GPtrArray *keys; /* of AsContentRatingKey */ } AsContentRatingPrivate; @@ -57,7 +58,8 @@ as_content_rating_finalize (GObject *object) AsContentRating *content_rating = AS_CONTENT_RATING (object); AsContentRatingPrivate *priv = GET_PRIVATE (content_rating); - g_free (priv->kind); + if (priv->kind != NULL) + as_ref_string_unref (priv->kind); g_ptr_array_unref (priv->keys); G_OBJECT_CLASS (as_content_rating_parent_class)->finalize (object); @@ -66,8 +68,9 @@ as_content_rating_finalize (GObject *object) static void as_content_rating_key_free (AsContentRatingKey *key) { - g_free (key->id); - g_free (key); + if (key->id != NULL) + as_ref_string_unref (key->id); + g_slice_free (AsContentRatingKey, key); } static void @@ -323,8 +326,7 @@ void as_content_rating_set_kind (AsContentRating *content_rating, const gchar *kind) { AsContentRatingPrivate *priv = GET_PRIVATE (content_rating); - g_free (priv->kind); - priv->kind = g_strdup (kind); + as_ref_string_assign_safe (&priv->kind, kind); } /** @@ -399,8 +401,8 @@ as_content_rating_node_parse (AsContentRating *content_rating, GNode *node, g_autoptr(AsImage) image = NULL; if (as_node_get_tag (c) != AS_TAG_CONTENT_ATTRIBUTE) continue; - key = g_new0 (AsContentRatingKey, 1); - key->id = as_node_take_attribute (c, "id"); + key = g_slice_new0 (AsContentRatingKey); + as_ref_string_assign (&key->id, as_node_get_attribute (c, "id")); key->value = as_content_rating_value_from_string (as_node_get_data (c)); g_ptr_array_add (priv->keys, key); } diff --git a/libappstream-glib/as-icon.c b/libappstream-glib/as-icon.c index e712433..4ba2ae9 100644 --- a/libappstream-glib/as-icon.c +++ b/libappstream-glib/as-icon.c @@ -36,17 +36,18 @@ #include "as-icon-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" typedef struct { AsIconKind kind; - gchar *name; - gchar *url; - gchar *filename; - gchar *prefix; - gchar *prefix_private; + AsRefString *name; + AsRefString *url; + AsRefString *filename; + AsRefString *prefix; + AsRefString *prefix_private; guint width; guint height; GdkPixbuf *pixbuf; @@ -76,11 +77,16 @@ as_icon_finalize (GObject *object) g_object_unref (priv->pixbuf); if (priv->data != NULL) g_bytes_unref (priv->data); - g_free (priv->name); - g_free (priv->url); - g_free (priv->filename); - g_free (priv->prefix); - g_free (priv->prefix_private); + if (priv->name != NULL) + as_ref_string_unref (priv->name); + if (priv->url != NULL) + as_ref_string_unref (priv->url); + if (priv->filename != NULL) + as_ref_string_unref (priv->filename); + if (priv->prefix != NULL) + as_ref_string_unref (priv->prefix); + if (priv->prefix_private != NULL) + as_ref_string_unref (priv->prefix_private); G_OBJECT_CLASS (as_icon_parent_class)->finalize (object); } @@ -320,8 +326,7 @@ void as_icon_set_name (AsIcon *icon, const gchar *name) { AsIconPrivate *priv = GET_PRIVATE (icon); - g_free (priv->name); - priv->name = g_strdup (name); + as_ref_string_assign_safe (&priv->name, name); } /** @@ -337,8 +342,7 @@ void as_icon_set_prefix (AsIcon *icon, const gchar *prefix) { AsIconPrivate *priv = GET_PRIVATE (icon); - g_free (priv->prefix); - priv->prefix = g_strdup (prefix); + as_ref_string_assign_safe (&priv->prefix, prefix); } /** @@ -354,8 +358,7 @@ void as_icon_set_url (AsIcon *icon, const gchar *url) { AsIconPrivate *priv = GET_PRIVATE (icon); - g_free (priv->url); - priv->url = g_strdup (url); + as_ref_string_assign_safe (&priv->url, url); } /** @@ -371,8 +374,7 @@ void as_icon_set_filename (AsIcon *icon, const gchar *filename) { AsIconPrivate *priv = GET_PRIVATE (icon); - g_free (priv->filename); - priv->filename = g_strdup (filename); + as_ref_string_assign_safe (&priv->filename, filename); } /** @@ -566,8 +568,7 @@ as_icon_node_parse_embedded (AsIcon *icon, GNode *n, GError **error) "embedded icons needs <name>"); return FALSE; } - g_free (priv->name); - priv->name = as_node_take_data (c); + as_ref_string_assign (&priv->name, as_node_get_data (c)); /* parse the Base64 data */ c = as_node_find (n, "filecontent"); @@ -675,11 +676,11 @@ as_icon_node_parse (AsIcon *icon, GNode *node, /* only use the size if the metadata has width and height */ if (prepend_size) { - g_free (priv->prefix_private); - priv->prefix_private = g_strdup_printf ("%s/%ux%u", + g_autofree gchar *sz = g_strdup_printf ("%s/%ux%u", priv->prefix, priv->width, priv->height); + as_ref_string_assign_safe (&priv->prefix_private, sz); } break; } diff --git a/libappstream-glib/as-image.c b/libappstream-glib/as-image.c index 3cf060f..2f48940 100644 --- a/libappstream-glib/as-image.c +++ b/libappstream-glib/as-image.c @@ -36,16 +36,17 @@ #include "as-image-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" typedef struct { AsImageKind kind; - gchar *locale; - gchar *url; - gchar *md5; - gchar *basename; + AsRefString *locale; + AsRefString *url; + AsRefString *md5; + AsRefString *basename; guint width; guint height; GdkPixbuf *pixbuf; @@ -63,10 +64,14 @@ as_image_finalize (GObject *object) if (priv->pixbuf != NULL) g_object_unref (priv->pixbuf); - g_free (priv->url); - g_free (priv->md5); - g_free (priv->basename); - g_free (priv->locale); + if (priv->url != NULL) + as_ref_string_unref (priv->url); + if (priv->md5 != NULL) + as_ref_string_unref (priv->md5); + if (priv->basename != NULL) + as_ref_string_unref (priv->basename); + if (priv->locale != NULL) + as_ref_string_unref (priv->locale); G_OBJECT_CLASS (as_image_parent_class)->finalize (object); } @@ -273,8 +278,7 @@ void as_image_set_url (AsImage *image, const gchar *url) { AsImagePrivate *priv = GET_PRIVATE (image); - g_free (priv->url); - priv->url = g_strdup (url); + as_ref_string_assign_safe (&priv->url, url); } /** @@ -290,8 +294,7 @@ void as_image_set_basename (AsImage *image, const gchar *basename) { AsImagePrivate *priv = GET_PRIVATE (image); - g_free (priv->basename); - priv->basename = g_strdup (basename); + as_ref_string_assign_safe (&priv->basename, basename); } /** @@ -307,8 +310,7 @@ void as_image_set_locale (AsImage *image, const gchar *locale) { AsImagePrivate *priv = GET_PRIVATE (image); - g_free (priv->locale); - priv->locale = g_strdup (locale); + as_ref_string_assign_safe (&priv->locale, locale); } /** @@ -379,9 +381,11 @@ as_image_set_pixbuf (AsImage *image, GdkPixbuf *pixbuf) if (pixbuf == NULL) return; if (priv->md5 == NULL) { + g_autofree gchar *md5_tmp = NULL; data = gdk_pixbuf_get_pixels_with_length (pixbuf, &len); - priv->md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5, - data, len); + md5_tmp = g_compute_checksum_for_data (G_CHECKSUM_MD5, + data, len); + as_ref_string_assign_safe (&priv->md5, md5_tmp); } priv->width = (guint) gdk_pixbuf_get_width (pixbuf); priv->height = (guint) gdk_pixbuf_get_height (pixbuf); @@ -437,7 +441,6 @@ as_image_node_parse (AsImage *image, GNode *node, { AsImagePrivate *priv = GET_PRIVATE (image); const gchar *tmp; - gchar *taken; guint size; size = as_node_get_attribute_as_uint (node, "width"); @@ -451,16 +454,8 @@ as_image_node_parse (AsImage *image, GNode *node, as_image_set_kind (image, AS_IMAGE_KIND_SOURCE); else as_image_set_kind (image, as_image_kind_from_string (tmp)); - taken = as_node_take_data (node); - if (taken != NULL) { - g_free (priv->url); - priv->url = taken; - } - taken = as_node_take_attribute (node, "xml:lang"); - if (taken != NULL) { - g_free (priv->locale); - priv->locale = taken; - } + as_ref_string_assign (&priv->url, as_node_get_data (node)); + as_ref_string_assign (&priv->locale, as_node_get_attribute (node, "xml:lang")); return TRUE; } @@ -570,14 +565,15 @@ as_image_load_filename_full (AsImage *image, if (flags & AS_IMAGE_LOAD_FLAG_SET_CHECKSUM) { gsize len; g_autofree gchar *data = NULL; + g_autofree gchar *md5_tmp = NULL; /* get the contents so we can hash the predictable file data, * rather than the unpredicatable (for JPEG) pixel data */ if (!g_file_get_contents (filename, &data, &len, error)) return FALSE; - g_free (priv->md5); - priv->md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5, - (guchar * )data, len); + md5_tmp = g_compute_checksum_for_data (G_CHECKSUM_MD5, + (guchar * )data, len); + as_ref_string_assign_safe (&priv->md5, md5_tmp); } /* load the image of the native size */ diff --git a/libappstream-glib/as-node-private.h b/libappstream-glib/as-node-private.h index 9d72633..56aca21 100644 --- a/libappstream-glib/as-node-private.h +++ b/libappstream-glib/as-node-private.h @@ -28,6 +28,7 @@ #include "as-app.h" #include "as-node.h" +#include "as-ref-string.h" G_BEGIN_DECLS @@ -50,10 +51,7 @@ const gchar *as_node_context_get_media_base_url (AsNodeContext *ctx); void as_node_context_set_media_base_url (AsNodeContext *ctx, const gchar *url); -gchar *as_node_take_data (const GNode *node); -gchar *as_node_take_attribute (const GNode *node, - const gchar *key); -gchar *as_node_reflow_text (const gchar *text, +AsRefString *as_node_reflow_text (const gchar *text, gssize text_len); gchar *as_node_fix_locale (const gchar *locale); diff --git a/libappstream-glib/as-node.c b/libappstream-glib/as-node.c index 39cba47..6231367 100644 --- a/libappstream-glib/as-node.c +++ b/libappstream-glib/as-node.c @@ -39,11 +39,12 @@ #include "as-markup.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" typedef struct { - GHashTable *intern_attr; - GHashTable *intern_name; + GHashTable *intern_attr; /* key=value of AsRefString */ + GHashTable *intern_name; /* key=value of AsRefString */ } AsNodeRoot; typedef struct @@ -52,12 +53,12 @@ typedef struct union { AsTag tag; const gchar *name_const; /* only if is_name_const = TRUE */ - gchar *name; /* only if is_tag_valid = FALSE */ + AsRefString *name; /* only if is_tag_valid = FALSE */ }; union { AsNodeRoot *root; /* only if is_root_node = TRUE */ const gchar *cdata_const; /* only if is_cdata_const = TRUE */ - gchar *cdata; + AsRefString *cdata; }; guint8 is_root_node:1; guint8 is_cdata_const:1; @@ -68,8 +69,8 @@ typedef struct } AsNodeData; typedef struct { - const gchar *key; - const gchar *value; + AsRefString *key; + AsRefString *value; } AsNodeAttr; /** @@ -92,11 +93,11 @@ as_node_new (void) data->root = g_new0 (AsNodeRoot, 1); data->root->intern_attr = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, + (GDestroyNotify) as_ref_string_unref, NULL); data->root->intern_name = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, + (GDestroyNotify) as_ref_string_unref, NULL); return g_node_new (data); } @@ -107,15 +108,15 @@ as_node_attr_free (AsNodeAttr *attr) g_slice_free (AsNodeAttr, attr); } -static const gchar * +static AsRefString * as_node_intern (GHashTable *hash, const gchar *key) { - gchar *value = g_hash_table_lookup (hash, key); - if (value == NULL) { - value = g_strdup (key); - g_hash_table_insert (hash, value, value); + AsRefString *rstr = g_hash_table_lookup (hash, key); + if (rstr == NULL) { + rstr = as_ref_string_new (key); + g_hash_table_insert (hash, rstr, rstr); } - return value; + return rstr; } static AsNodeAttr * @@ -164,15 +165,15 @@ as_node_destroy_node_cb (AsNode *node, gpointer user_data) AsNodeData *data = node->data; if (data == NULL) return FALSE; - if (!data->is_tag_valid && !data->is_name_const) - g_free (data->name); + if (!data->is_tag_valid && !data->is_name_const && data->name != NULL) + as_ref_string_unref (data->name); if (data->is_root_node) { g_hash_table_unref (data->root->intern_attr); g_hash_table_unref (data->root->intern_name); g_free (data->root); } else { - if (!data->is_cdata_const) - g_free (data->cdata); + if (!data->is_cdata_const && data->cdata != NULL) + as_ref_string_unref (data->cdata); } g_list_free_full (data->attrs, (GDestroyNotify) as_node_attr_free); g_slice_free (AsNodeData, data); @@ -235,7 +236,7 @@ as_node_cdata_to_heap (AsNodeData *data) { if (!data->is_cdata_const) return; - data->cdata = g_strdup (data->cdata); + data->cdata = as_ref_string_new (data->cdata); data->is_cdata_const = FALSE; } @@ -243,11 +244,11 @@ static void as_node_cdata_to_intern (AsNode *root, AsNodeData *data) { AsNodeRoot *root_data = ((AsNodeData *)root->data)->root; - const gchar *tmp; + AsRefString *tmp; if (data->is_cdata_const) return; tmp = as_node_intern (root_data->intern_attr, data->cdata); - g_free (data->cdata); + as_ref_string_unref (data->cdata); data->cdata_const = tmp; data->is_cdata_const = TRUE; } @@ -271,16 +272,22 @@ static void as_node_cdata_to_escaped (AsNodeData *data) { GString *str; + g_autofree gchar *tmp = NULL; + if (data->is_root_node) return; if (data->is_cdata_escaped) return; - str = g_string_new (data->cdata); - g_free (data->cdata); - as_utils_string_replace (str, "&", "&"); - as_utils_string_replace (str, "<", "<"); - as_utils_string_replace (str, ">", ">"); - data->cdata = g_string_free (str, FALSE); + if (g_strstr_len (data->cdata, -1, "&") != NULL || + g_strstr_len (data->cdata, -1, "<") != NULL || + g_strstr_len (data->cdata, -1, ">") != NULL) { + str = g_string_new (data->cdata); + as_ref_string_unref (data->cdata); + as_utils_string_replace (str, "&", "&"); + as_utils_string_replace (str, "<", "<"); + as_utils_string_replace (str, ">", ">"); + data->cdata = as_ref_string_new_copy_with_length (str->str, str->len); + } data->is_cdata_escaped = TRUE; } @@ -352,12 +359,14 @@ as_node_data_set_name (AsNode *root, data->is_name_const = TRUE; data->is_tag_valid = FALSE; } else { + data->name = NULL; data->tag = tag; data->is_tag_valid = TRUE; } } else { /* always store the translated tag */ - data->name = g_strdup_printf ("_%s", name); + g_autofree gchar *name_tmp = g_strdup_printf ("_%s", name); + data->name = as_ref_string_new (name_tmp); data->is_tag_valid = FALSE; } } @@ -489,13 +498,13 @@ as_node_to_xml_string (GString *xml, * * Since: 0.1.4 **/ -gchar * +AsRefString * as_node_reflow_text (const gchar *text, gssize text_len) { - GString *tmp; guint i; guint newline_count = 0; g_auto(GStrv) split = NULL; + g_autoptr(GString) tmp = NULL; /* split the text into lines */ tmp = g_string_sized_new ((gsize) text_len + 1); @@ -529,7 +538,7 @@ as_node_reflow_text (const gchar *text, gssize text_len) /* this last section was paragraph */ newline_count = 1; } - return g_string_free (tmp, FALSE); + return as_ref_string_new_copy_with_length (tmp->str, tmp->len); } typedef struct { @@ -583,7 +592,7 @@ as_node_start_element_cb (GMarkupParseContext *context, AsNodeData *data; AsNodeData *data_parent; AsNode *current; - gchar *tmp; + AsRefString *tmp; guint i; /* check if we should ignore the locale */ @@ -624,10 +633,10 @@ as_node_start_element_cb (GMarkupParseContext *context, current = g_node_append_data (helper->current, data); /* transfer the ownership of the comment to the new child */ - tmp = as_node_take_attribute (helper->current, "@comment-tmp"); + tmp = as_node_get_attribute (helper->current, "@comment-tmp"); if (tmp != NULL) { as_node_add_attribute (current, "@comment", tmp); - g_free (tmp); + as_node_remove_attribute (helper->current, "@comment-tmp"); } /* the child is now the node to be processed */ @@ -683,7 +692,7 @@ as_node_text_cb (GMarkupParseContext *context, return; } if ((helper->flags & AS_NODE_FROM_XML_FLAG_LITERAL_TEXT) > 0) { - data->cdata = g_strndup (text, text_len); + data->cdata = as_ref_string_new_with_length (text, text_len + 1); } else { data->cdata = as_node_reflow_text (text, (gssize) text_len); } @@ -1053,7 +1062,7 @@ as_node_set_name (AsNode *node, const gchar *name) /* overwrite */ if (!data->is_tag_valid) { if (!data->is_name_const) - g_free (data->name); + as_ref_string_unref (data->name); data->name = NULL; } as_node_data_set_name (root, data, name, AS_NODE_INSERT_FLAG_NONE); @@ -1157,8 +1166,7 @@ as_node_set_data (AsNode *node, data = (AsNodeData *) node->data; if (data->is_root_node) return; - g_free (data->cdata); - data->cdata = g_strdup (cdata); + as_ref_string_assign_safe (&data->cdata, cdata); data->is_cdata_escaped = insert_flags & AS_NODE_INSERT_FLAG_PRE_ESCAPED; } @@ -1178,39 +1186,6 @@ as_node_set_comment (AsNode *node, const gchar *comment) } /** - * as_node_take_data: - * @node: a #AsNode - * - * Gets the node data, e.g. "paragraph text" - * - * Return value: string value - * - * Since: 0.1.0 - **/ -gchar * -as_node_take_data (const AsNode *node) -{ - AsNodeData *data; - gchar *tmp; - - if (node->data == NULL) - return NULL; - data = (AsNodeData *) node->data; - if (data->is_root_node) - return NULL; - if (data->cdata == NULL || data->cdata[0] == '\0') - return NULL; - as_node_cdata_to_raw (data); - if (data->is_cdata_const) { - tmp = g_strdup (data->cdata); - } else { - tmp = data->cdata; - data->cdata = NULL; - } - return tmp; -} - -/** * as_node_get_attribute_as_int: * @node: a #AsNode * @key: the attribute key @@ -1294,36 +1269,6 @@ as_node_get_attribute (const AsNode *node, const gchar *key) } /** - * as_node_take_attribute: (skip) - * @node: a #AsNode - * @key: the attribute key - * - * Gets a node attribute, e.g. "false" - * - * Return value: string value - * - * Since: 0.1.2 - **/ -gchar * -as_node_take_attribute (const AsNode *node, const gchar *key) -{ - AsNodeAttr *attr; - AsNodeData *data; - gchar *tmp; - - g_return_val_if_fail (node != NULL, NULL); - g_return_val_if_fail (key != NULL, NULL); - - if (node->data == NULL) - return NULL; - data = (AsNodeData *) node->data; - attr = as_node_attr_find (data, key); - if (attr == NULL) - return NULL; - return g_strdup (attr->value); -} - -/** * as_node_remove_attribute: (skip) * @node: a #AsNode * @key: the attribute key @@ -1484,9 +1429,9 @@ as_node_find_with_attribute (AsNode *root, const gchar *path, static gchar * as_node_insert_line_breaks (const gchar *text, guint break_len) { - GString *str; guint i; gssize new_len; + g_autoptr(GString) str = NULL; /* allocate long enough for the string, plus the extra newlines */ new_len = (gssize) (strlen (text) * (break_len + 1) / break_len); @@ -1498,7 +1443,7 @@ as_node_insert_line_breaks (const gchar *text, guint break_len) for (i = break_len + 1; i < str->len; i += break_len + 1) g_string_insert (str, (gssize) i, "\n"); g_string_append (str, "\n"); - return g_string_free (str, FALSE); + return as_ref_string_new_copy_with_length (str->str, str->len);; } /** @@ -1537,7 +1482,7 @@ as_node_insert (AsNode *parent, if (insert_flags & AS_NODE_INSERT_FLAG_BASE64_ENCODED) data->cdata = as_node_insert_line_breaks (cdata, 76); else - data->cdata = g_strdup (cdata); + data->cdata = as_ref_string_new (cdata); } data->is_cdata_escaped = insert_flags & AS_NODE_INSERT_FLAG_PRE_ESCAPED; @@ -1597,10 +1542,11 @@ as_node_insert_localized (AsNode *parent, data = g_slice_new0 (AsNodeData); as_node_data_set_name (root, data, name, insert_flags); if (insert_flags & AS_NODE_INSERT_FLAG_NO_MARKUP) { - data->cdata = as_markup_convert_simple (value_c, NULL); + g_autofree gchar *tmp = as_markup_convert_simple (value_c, NULL); + data->cdata = as_ref_string_new_copy (tmp); data->is_cdata_escaped = FALSE; } else { - data->cdata = g_strdup (value_c); + data->cdata = as_ref_string_new (value_c); data->is_cdata_escaped = insert_flags & AS_NODE_INSERT_FLAG_PRE_ESCAPED; } g_node_insert_data (parent, -1, data); @@ -1622,10 +1568,11 @@ as_node_insert_localized (AsNode *parent, as_node_attr_insert (root, data, "xml:lang", key); as_node_data_set_name (root, data, name, insert_flags); if (insert_flags & AS_NODE_INSERT_FLAG_NO_MARKUP) { - data->cdata = as_markup_convert_simple (value, NULL); + g_autofree gchar *tmp = as_markup_convert_simple (value, NULL); + data->cdata = as_ref_string_new_copy (tmp); data->is_cdata_escaped = FALSE; } else { - data->cdata = g_strdup (value); + data->cdata = as_ref_string_new (value); data->is_cdata_escaped = insert_flags & AS_NODE_INSERT_FLAG_PRE_ESCAPED; } g_node_insert_data (parent, -1, data); @@ -1668,7 +1615,7 @@ as_node_insert_hash (AsNode *parent, value = g_hash_table_lookup (hash, key); data = g_slice_new0 (AsNodeData); as_node_data_set_name (root, data, name, insert_flags); - data->cdata = g_strdup (!swapped ? value : key); + data->cdata = as_ref_string_new (!swapped ? value : key); data->is_cdata_escaped = insert_flags & AS_NODE_INSERT_FLAG_PRE_ESCAPED; if (!swapped) { if (key != NULL && key[0] != '\0') @@ -1977,16 +1924,16 @@ as_node_get_localized_unwrap_type_ul (const AsNode *node, gchar * as_node_fix_locale (const gchar *locale) { - gchar *tmp; + AsRefString *tmp; if (locale == NULL) - return g_strdup ("C"); + return as_ref_string_new ("C"); if (g_strcmp0 (locale, "xx") == 0) return NULL; if (g_strcmp0 (locale, "x-test") == 0) return NULL; - tmp = g_strdup (locale); - g_strdelimit (tmp, "-", '_'); + tmp = as_ref_string_new (locale); + g_strdelimit (tmp, "-", '_'); // FIXME: might be evil return tmp; } @@ -2068,7 +2015,9 @@ as_node_get_localized_unwrap (const AsNode *node, GError **error) } /* copy into a hash table of the correct size */ - results = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + results = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); keys = g_hash_table_get_keys (hash); for (l = keys; l != NULL; l = l->next) { gchar *locale_fixed; @@ -2079,7 +2028,7 @@ as_node_get_localized_unwrap (const AsNode *node, GError **error) str = g_hash_table_lookup (hash, xml_lang); g_hash_table_insert (results, locale_fixed, - g_strdup (str->str)); + as_ref_string_new (str->str)); } return results; } @@ -2090,7 +2039,7 @@ struct _AsNodeContext { AsAppSourceKind output; gdouble version; gboolean output_trusted; - gchar *media_base_url; + AsRefString *media_base_url; }; /** @@ -2126,7 +2075,8 @@ as_node_context_free (AsNodeContext *ctx) { if (ctx == NULL) return; - g_free (ctx->media_base_url); + if (ctx->media_base_url != NULL) + as_ref_string_unref (ctx->media_base_url); g_free (ctx); } @@ -2280,6 +2230,5 @@ as_node_context_get_media_base_url (AsNodeContext *ctx) void as_node_context_set_media_base_url (AsNodeContext *ctx, const gchar *url) { - g_free (ctx->media_base_url); - ctx->media_base_url = g_strdup (url); + as_ref_string_assign_safe (&ctx->media_base_url, url); } diff --git a/libappstream-glib/as-provide.c b/libappstream-glib/as-provide.c index fc1f43c..ea43a05 100644 --- a/libappstream-glib/as-provide.c +++ b/libappstream-glib/as-provide.c @@ -35,13 +35,14 @@ #include "as-node-private.h" #include "as-provide-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" typedef struct { AsProvideKind kind; - gchar *value; + AsRefString *value; } AsProvidePrivate; G_DEFINE_TYPE_WITH_PRIVATE (AsProvide, as_provide, G_TYPE_OBJECT) @@ -54,7 +55,8 @@ as_provide_finalize (GObject *object) AsProvide *provide = AS_PROVIDE (object); AsProvidePrivate *priv = GET_PRIVATE (provide); - g_free (priv->value); + if (priv->value != NULL) + as_ref_string_unref (priv->value); G_OBJECT_CLASS (as_provide_parent_class)->finalize (object); } @@ -191,8 +193,7 @@ void as_provide_set_value (AsProvide *provide, const gchar *value) { AsProvidePrivate *priv = GET_PRIVATE (provide); - g_free (priv->value); - priv->value = g_strdup (value); + as_ref_string_assign_safe (&priv->value, value); } /** @@ -325,8 +326,7 @@ as_provide_node_parse (AsProvide *provide, GNode *node, } else { priv->kind = as_provide_kind_from_string (as_node_get_name (node)); } - g_free (priv->value); - priv->value = as_node_take_data (node); + as_ref_string_assign (&priv->value, as_node_get_data (node)); return TRUE; } diff --git a/libappstream-glib/as-release.c b/libappstream-glib/as-release.c index a0fda4a..2e4f355 100644 --- a/libappstream-glib/as-release.c +++ b/libappstream-glib/as-release.c @@ -41,6 +41,7 @@ #include "as-checksum-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-release-private.h" #include "as-tag.h" #include "as-utils-private.h" @@ -51,11 +52,11 @@ typedef struct AsUrgencyKind urgency; AsReleaseState state; guint64 size[AS_SIZE_KIND_LAST]; - gchar *version; + AsRefString *version; GHashTable *blobs; /* of gchar*:GBytes */ GHashTable *descriptions; guint64 timestamp; - GPtrArray *locations; + GPtrArray *locations; /* of AsRefString */ GPtrArray *checksums; } AsReleasePrivate; @@ -69,7 +70,8 @@ as_release_finalize (GObject *object) AsRelease *release = AS_RELEASE (object); AsReleasePrivate *priv = GET_PRIVATE (release); - g_free (priv->version); + if (priv->version != NULL) + as_ref_string_unref (priv->version); g_hash_table_unref (priv->blobs); g_ptr_array_unref (priv->checksums); g_ptr_array_unref (priv->locations); @@ -87,10 +89,11 @@ as_release_init (AsRelease *release) priv->urgency = AS_URGENCY_KIND_UNKNOWN; priv->state = AS_RELEASE_STATE_UNKNOWN; - priv->locations = g_ptr_array_new_with_free_func (g_free); + priv->locations = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); priv->checksums = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_bytes_unref); + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) g_bytes_unref); for (i = 0; i < AS_SIZE_KIND_LAST; i++) priv->size[i] = 0; } @@ -397,8 +400,7 @@ void as_release_set_version (AsRelease *release, const gchar *version) { AsReleasePrivate *priv = GET_PRIVATE (release); - g_free (priv->version); - priv->version = g_strdup (version); + as_ref_string_assign_safe (&priv->version, version); } /** @@ -419,7 +421,9 @@ as_release_set_blob (AsRelease *release, const gchar *filename, GBytes *blob) AsReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (filename != NULL); g_return_if_fail (blob != NULL); - g_hash_table_insert (priv->blobs, g_strdup (filename), g_bytes_ref (blob)); + g_hash_table_insert (priv->blobs, + as_ref_string_new (filename), + g_bytes_ref (blob)); } /** @@ -472,7 +476,7 @@ as_release_add_location (AsRelease *release, const gchar *location) if (as_ptr_array_find_string (priv->locations, location)) return; - g_ptr_array_add (priv->locations, g_strdup (location)); + g_ptr_array_add (priv->locations, as_ref_string_new (location)); } /** @@ -528,12 +532,12 @@ as_release_set_description (AsRelease *release, if (priv->descriptions == NULL) { priv->descriptions = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, - g_free); + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); } g_hash_table_insert (priv->descriptions, - g_strdup (locale), - g_strdup (description)); + as_ref_string_new (locale), + as_ref_string_new (description)); } /** @@ -646,7 +650,10 @@ as_release_node_parse (AsRelease *release, GNode *node, for (n = node->children; n != NULL; n = n->next) { if (as_node_get_tag (n) != AS_TAG_LOCATION) continue; - g_ptr_array_add (priv->locations, as_node_take_data (n)); + tmp = as_node_get_data (n); + if (tmp == NULL) + continue; + g_ptr_array_add (priv->locations, as_ref_string_ref (tmp)); } /* get optional checksums */ diff --git a/libappstream-glib/as-review.c b/libappstream-glib/as-review.c index 34a07db..4a1c5c9 100644 --- a/libappstream-glib/as-review.c +++ b/libappstream-glib/as-review.c @@ -36,23 +36,24 @@ #include "as-review-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" typedef struct { AsReviewFlags flags; - gchar *id; - gchar *summary; - gchar *description; - gchar *locale; + AsRefString *id; + AsRefString *summary; + AsRefString *description; + AsRefString *locale; gint priority; gint rating; - gchar *version; - gchar *reviewer_id; - gchar *reviewer_name; + AsRefString *version; + AsRefString *reviewer_id; + AsRefString *reviewer_name; GDateTime *date; - GHashTable *metadata; + GHashTable *metadata; /* AsRefString : AsRefString */ } AsReviewPrivate; enum { @@ -80,13 +81,20 @@ as_review_finalize (GObject *object) AsReview *review = AS_REVIEW (object); AsReviewPrivate *priv = GET_PRIVATE (review); - g_free (priv->id); - g_free (priv->summary); - g_free (priv->description); - g_free (priv->locale); - g_free (priv->version); - g_free (priv->reviewer_id); - g_free (priv->reviewer_name); + if (priv->id != NULL) + as_ref_string_unref (priv->id); + if (priv->summary != NULL) + as_ref_string_unref (priv->summary); + if (priv->description != NULL) + as_ref_string_unref (priv->description); + if (priv->locale != NULL) + as_ref_string_unref (priv->locale); + if (priv->version != NULL) + as_ref_string_unref (priv->version); + if (priv->reviewer_id != NULL) + as_ref_string_unref (priv->reviewer_id); + if (priv->reviewer_name != NULL) + as_ref_string_unref (priv->reviewer_name); g_hash_table_unref (priv->metadata); if (priv->date != NULL) g_date_time_unref (priv->date); @@ -298,7 +306,8 @@ as_review_init (AsReview *review) { AsReviewPrivate *priv = GET_PRIVATE (review); priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); } /** @@ -388,8 +397,7 @@ as_review_set_id (AsReview *review, const gchar *id) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->id); - priv->id = g_strdup (id); + as_ref_string_assign_safe (&priv->id, id); } /** @@ -406,8 +414,7 @@ as_review_set_summary (AsReview *review, const gchar *summary) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->summary); - priv->summary = g_strdup (summary); + as_ref_string_assign_safe (&priv->summary, summary); } /** @@ -442,8 +449,7 @@ as_review_set_description (AsReview *review, const gchar *description) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->description); - priv->description = g_strdup (description); + as_ref_string_assign_safe (&priv->description, description); } /** @@ -478,8 +484,7 @@ as_review_set_locale (AsReview *review, const gchar *locale) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->locale); - priv->locale = g_strdup (locale); + as_ref_string_assign_safe (&priv->locale, locale); } /** @@ -621,8 +626,7 @@ as_review_set_reviewer_id (AsReview *review, const gchar *reviewer_id) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->reviewer_id); - priv->reviewer_id = g_strdup (reviewer_id); + as_ref_string_assign_safe (&priv->reviewer_id, reviewer_id); } /** @@ -639,8 +643,7 @@ as_review_set_reviewer_name (AsReview *review, const gchar *reviewer_name) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->reviewer_name); - priv->reviewer_name = g_strdup (reviewer_name); + as_ref_string_assign_safe (&priv->reviewer_name, reviewer_name); } /** @@ -657,8 +660,7 @@ as_review_set_version (AsReview *review, const gchar *version) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_free (priv->version); - priv->version = g_strdup (version); + as_ref_string_assign_safe (&priv->version, version); } /** @@ -755,7 +757,9 @@ as_review_add_metadata (AsReview *review, const gchar *key, const gchar *value) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value)); + g_hash_table_insert (priv->metadata, + as_ref_string_new (key), + as_ref_string_new (value)); } /** @@ -950,14 +954,21 @@ as_review_node_parse (AsReview *review, GNode *node, AsNode *c2; gchar *taken; for (c2 = c->children; c2 != NULL; c2 = c2->next) { - gchar *key; + AsRefString *key; + AsRefString *value; if (as_node_get_tag (c2) != AS_TAG_VALUE) continue; - key = as_node_take_attribute (c2, "key"); - taken = as_node_take_data (c2); - if (taken == NULL) - taken = g_strdup (""); - g_hash_table_insert (priv->metadata, key, taken); + key = as_node_get_attribute (c2, "key"); + value = as_node_get_data (c2); + if (value == NULL) { + g_hash_table_insert (priv->metadata, + as_ref_string_ref (key), + as_ref_string_new ("")); + } else { + g_hash_table_insert (priv->metadata, + as_ref_string_ref (key), + as_ref_string_ref (value)); + } } continue; } diff --git a/libappstream-glib/as-screenshot.c b/libappstream-glib/as-screenshot.c index cc64f52..3a03d3c 100644 --- a/libappstream-glib/as-screenshot.c +++ b/libappstream-glib/as-screenshot.c @@ -35,6 +35,7 @@ #include "as-image-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-screenshot-private.h" #include "as-tag.h" #include "as-utils-private.h" @@ -70,7 +71,10 @@ as_screenshot_init (AsScreenshot *screenshot) AsScreenshotPrivate *priv = GET_PRIVATE (screenshot); priv->kind = AS_SCREENSHOT_KIND_NORMAL; priv->images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - priv->captions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->captions = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); } static void @@ -383,8 +387,8 @@ as_screenshot_set_caption (AsScreenshot *screenshot, if (locale == NULL) locale = "C"; g_hash_table_insert (priv->captions, - g_strdup (locale), - g_strdup (caption)); + as_ref_string_new (locale), + as_ref_string_new (caption)); } /** diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index 457a4c5..09c9619 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -2233,22 +2233,22 @@ as_test_app_no_markup_func (void) static void as_test_node_reflow_text_func (void) { - gchar *tmp; + AsRefString *tmp; /* plain text */ tmp = as_node_reflow_text ("Dave", -1); g_assert_cmpstr (tmp, ==, "Dave"); - g_free (tmp); + as_ref_string_unref (tmp); /* stripping */ tmp = as_node_reflow_text (" Dave ", -1); g_assert_cmpstr (tmp, ==, "Dave"); - g_free (tmp); + as_ref_string_unref (tmp); /* paragraph */ tmp = as_node_reflow_text ("Dave\n\nSoftware", -1); g_assert_cmpstr (tmp, ==, "Dave\n\nSoftware"); - g_free (tmp); + as_ref_string_unref (tmp); /* pathological */ tmp = as_node_reflow_text ( @@ -2258,7 +2258,7 @@ as_test_node_reflow_text_func (void) " awesome.\n\n\n" " Okay!\n", -1); g_assert_cmpstr (tmp, ==, "Dave: Software is awesome.\n\nOkay!"); - g_free (tmp); + as_ref_string_unref (tmp); } static void diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c index be50647..b46e481 100644 --- a/libappstream-glib/as-store.c +++ b/libappstream-glib/as-store.c @@ -41,6 +41,7 @@ #include "as-problem.h" #include "as-profile.h" #include "as-monitor.h" +#include "as-ref-string.h" #include "as-stemmer.h" #include "as-store.h" #include "as-utils-private.h" @@ -1327,6 +1328,9 @@ as_store_from_root (AsStore *store, g_autofree gchar *origin_app_icons = NULL; _cleanup_uninhibit_ guint32 *tok = NULL; g_autoptr(AsProfileTask) ptask = NULL; + g_autoptr(AsRefString) icon_path_str = NULL; + g_autoptr(AsRefString) origin_str = NULL; + g_autoptr(AsRefString) source_filename_str = NULL; g_return_val_if_fail (AS_IS_STORE (store), FALSE); @@ -1444,6 +1448,14 @@ as_store_from_root (AsStore *store, if (tmp != NULL) as_store_set_builder_id (store, tmp); + /* create refcounted versions */ + if (source_filename != NULL) + source_filename_str = as_ref_string_new (source_filename); + if (origin_app != NULL) + origin_str = as_ref_string_new (origin_app); + if (icon_path != NULL) + icon_path_str = as_ref_string_new (icon_path); + ctx = as_node_context_new (); for (n = apps->children; n != NULL; n = n->next) { g_autoptr(GError) error_local = NULL; @@ -1463,8 +1475,8 @@ as_store_from_root (AsStore *store, } app = as_app_new (); - if (icon_path != NULL) - as_app_set_icon_path (app, icon_path); + if (icon_path_str != NULL) + as_app_set_icon_path (app, icon_path_str); if (arch != NULL) as_app_add_arch (app, arch); as_app_set_scope (app, scope); @@ -1490,10 +1502,10 @@ as_store_from_root (AsStore *store, if ((priv->add_flags & AS_STORE_ADD_FLAG_USE_UNIQUE_ID) == 0) as_store_fixup_id_prefix (app, id_prefix_app); - if (origin_app != NULL) - as_app_set_origin (app, origin_app); - if (source_filename != NULL) - as_app_set_source_file (app, source_filename); + if (origin_str != NULL) + as_app_set_origin (app, origin_str); + if (source_filename_str != NULL) + as_app_set_source_file (app, source_filename_str); as_store_add_app (store, app); } diff --git a/libappstream-glib/as-suggest.c b/libappstream-glib/as-suggest.c index d45f7aa..174d745 100644 --- a/libappstream-glib/as-suggest.c +++ b/libappstream-glib/as-suggest.c @@ -36,6 +36,7 @@ #include "as-suggest-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" typedef struct @@ -63,7 +64,7 @@ static void as_suggest_init (AsSuggest *suggest) { AsSuggestPrivate *priv = GET_PRIVATE (suggest); - priv->ids = g_ptr_array_new_with_free_func (g_free); + priv->ids = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); } static void @@ -177,7 +178,7 @@ void as_suggest_add_id (AsSuggest *suggest, const gchar *id) { AsSuggestPrivate *priv = GET_PRIVATE (suggest); - g_ptr_array_add (priv->ids, g_strdup (id)); + g_ptr_array_add (priv->ids, as_ref_string_new (id)); } /** diff --git a/libappstream-glib/as-translation.c b/libappstream-glib/as-translation.c index a50c486..b362442 100644 --- a/libappstream-glib/as-translation.c +++ b/libappstream-glib/as-translation.c @@ -37,13 +37,14 @@ #include "as-translation-private.h" #include "as-node-private.h" +#include "as-ref-string.h" #include "as-utils-private.h" #include "as-yaml.h" typedef struct { AsTranslationKind kind; - gchar *id; + AsRefString *id; } AsTranslationPrivate; G_DEFINE_TYPE_WITH_PRIVATE (AsTranslation, as_translation, G_TYPE_OBJECT) @@ -56,7 +57,8 @@ as_translation_finalize (GObject *object) AsTranslation *translation = AS_TRANSLATION (object); AsTranslationPrivate *priv = GET_PRIVATE (translation); - g_free (priv->id); + if (priv->id != NULL) + as_ref_string_unref (priv->id); G_OBJECT_CLASS (as_translation_parent_class)->finalize (object); } @@ -161,8 +163,7 @@ void as_translation_set_id (AsTranslation *translation, const gchar *id) { AsTranslationPrivate *priv = GET_PRIVATE (translation); - g_free (priv->id); - priv->id = g_strdup (id); + as_ref_string_assign_safe (&priv->id, id); } /** @@ -229,15 +230,10 @@ as_translation_node_parse (AsTranslation *translation, GNode *node, { AsTranslationPrivate *priv = GET_PRIVATE (translation); const gchar *tmp; - gchar *taken; tmp = as_node_get_attribute (node, "type"); as_translation_set_kind (translation, as_translation_kind_from_string (tmp)); - taken = as_node_take_data (node); - if (taken != NULL) { - g_free (priv->id); - priv->id = taken; - } + as_ref_string_assign (&priv->id, as_node_get_data (node)); return TRUE; } |