summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2016-11-16 21:15:02 +0000
committerRichard Hughes <richard@hughsie.com>2016-11-21 15:19:55 +0000
commitbd6ea9106e0539364e66c6dc6fb5f5f3b0878920 (patch)
tree1105f249751103a08b0cc72a7d539ca38de59602
parent977f0cc2623dc89e68b4c0d41b0164c59ac9a1ca (diff)
downloadappstream-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.c395
-rw-r--r--libappstream-glib/as-bundle.c39
-rw-r--r--libappstream-glib/as-checksum.c30
-rw-r--r--libappstream-glib/as-content-rating.c20
-rw-r--r--libappstream-glib/as-icon.c45
-rw-r--r--libappstream-glib/as-image.c56
-rw-r--r--libappstream-glib/as-node-private.h6
-rw-r--r--libappstream-glib/as-node.c187
-rw-r--r--libappstream-glib/as-provide.c12
-rw-r--r--libappstream-glib/as-release.c35
-rw-r--r--libappstream-glib/as-review.c85
-rw-r--r--libappstream-glib/as-screenshot.c10
-rw-r--r--libappstream-glib/as-self-test.c10
-rw-r--r--libappstream-glib/as-store.c24
-rw-r--r--libappstream-glib/as-suggest.c5
-rw-r--r--libappstream-glib/as-translation.c16
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, "&", "&amp;");
- as_utils_string_replace (str, "<", "&lt;");
- as_utils_string_replace (str, ">", "&gt;");
- 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, "&", "&amp;");
+ as_utils_string_replace (str, "<", "&lt;");
+ as_utils_string_replace (str, ">", "&gt;");
+ 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;
}