resource: Small refactoring

Break out a helper function so we can reuse it in the next commit.
This commit is contained in:
Matthias Clasen 2024-09-06 00:24:39 -04:00 committed by Philip Withnall
parent 0134888d50
commit cb5209282b

View File

@ -923,6 +923,44 @@ g_resource_get_info (GResource *resource,
return do_lookup (resource, path, lookup_flags, size, flags, NULL, NULL, error);
}
static inline const char *
ensure_slash_suffix (const char *path,
char *local_str,
gsize len,
char **free_path)
{
gsize path_len;
path_len = strlen (path);
if G_UNLIKELY (path[path_len-1] != '/')
{
if (path_len < len - 2)
{
/*
* We got a path that does not have a trailing /. It is not the
* ideal use of this API as we require trailing / for our lookup
* into gvdb. Some degenerate application configurations can hit
* this code path quite a bit, so we try to avoid using the
* g_strconcat()/g_free().
*/
memcpy (local_str, path, path_len);
local_str[path_len] = '/';
local_str[path_len+1] = 0;
return local_str;
}
else
{
*free_path = g_strconcat (path, "/", NULL);
return *free_path;
}
}
else
{
return path;
}
}
/**
* g_resource_enumerate_children:
* @resource: A #GResource
@ -949,17 +987,14 @@ g_resource_enumerate_children (GResource *resource,
GResourceLookupFlags lookup_flags,
GError **error)
{
gchar local_str[256];
const gchar *path_with_slash;
gchar **children;
gchar *free_path = NULL;
gsize path_len;
/*
* Size of 256 is arbitrarily chosen based on being large enough
/* Size of 256 is arbitrarily chosen based on being large enough
* for pretty much everything we come across, but not cumbersome
* on the stack. It also matches common cacheline sizes.
*/
gchar local_str[256];
const char *path_with_slash;
char *free_path = NULL;
gchar **children;
if (*path == 0)
{
@ -970,35 +1005,10 @@ g_resource_enumerate_children (GResource *resource,
return NULL;
}
path_len = strlen (path);
if G_UNLIKELY (path[path_len-1] != '/')
{
if (path_len < sizeof (local_str) - 2)
{
/*
* We got a path that does not have a trailing /. It is not the
* ideal use of this API as we require trailing / for our lookup
* into gvdb. Some degenerate application configurations can hit
* this code path quite a bit, so we try to avoid using the
* g_strconcat()/g_free().
*/
memcpy (local_str, path, path_len);
local_str[path_len] = '/';
local_str[path_len+1] = 0;
path_with_slash = local_str;
}
else
{
path_with_slash = free_path = g_strconcat (path, "/", NULL);
}
}
else
{
path_with_slash = path;
}
path_with_slash = ensure_slash_suffix (path, local_str, sizeof (local_str), &free_path);
children = gvdb_table_list (resource->table, path_with_slash);
g_free (free_path);
if (children == NULL)