mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 10:42:11 +01:00
Add a g_ref_string_new_len() to allow creating from non-NUL byte arrays
A lot of GLib APIs provide a string length and explicitly say that the strings are not NUL terminated. For instance, parsing XML using GMarkupParser or reading packed binary strings from mmapped data files.
This commit is contained in:
parent
2585099a5d
commit
dad58d7392
@ -3497,6 +3497,7 @@ g_arc_box_get_size
|
||||
<FILE>refstring</FILE>
|
||||
g_ref_string_new
|
||||
g_ref_string_new_intern
|
||||
g_ref_string_new_len
|
||||
g_ref_string_acquire
|
||||
g_ref_string_release
|
||||
g_ref_string_length
|
||||
|
@ -130,6 +130,39 @@ g_ref_string_new (const char *str)
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_ref_string_new_len:
|
||||
* @str: (not nullable): a string
|
||||
* @len: length of @str to use, or -1 if @str is nul-terminated
|
||||
*
|
||||
* Creates a new reference counted string and copies the contents of @str
|
||||
* into it, up to @len bytes.
|
||||
*
|
||||
* Since this function does not stop at nul bytes, it is the caller's
|
||||
* responsibility to ensure that @str has at least @len addressable bytes.
|
||||
*
|
||||
* Returns: (transfer full) (not nullable): the newly created reference counted string
|
||||
*
|
||||
* Since: 2.58
|
||||
*/
|
||||
char *
|
||||
g_ref_string_new_len (const char *str, gssize len)
|
||||
{
|
||||
char *res;
|
||||
|
||||
g_return_val_if_fail (str != NULL, NULL);
|
||||
|
||||
if (len < 0)
|
||||
return g_ref_string_new (str);
|
||||
|
||||
/* allocate then copy as str[len] may not be readable */
|
||||
res = (char *) g_atomic_rc_box_alloc ((gsize) len + 1);
|
||||
memcpy (res, str, len);
|
||||
res[len] = '\0';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* interned_str_equal: variant of g_str_equal() that compares
|
||||
* pointers as well as contents; this avoids running strcmp()
|
||||
* on arbitrarily long strings, as it's more likely to have
|
||||
|
@ -26,6 +26,9 @@ G_BEGIN_DECLS
|
||||
GLIB_AVAILABLE_IN_2_58
|
||||
char * g_ref_string_new (const char *str);
|
||||
GLIB_AVAILABLE_IN_2_58
|
||||
char * g_ref_string_new_len (const char *str,
|
||||
gssize len);
|
||||
GLIB_AVAILABLE_IN_2_58
|
||||
char * g_ref_string_new_intern (const char *str);
|
||||
|
||||
GLIB_AVAILABLE_IN_2_58
|
||||
|
@ -36,6 +36,42 @@ test_refstring_base (void)
|
||||
g_ref_string_release (s);
|
||||
}
|
||||
|
||||
/* test_refstring_length: Test the _len variant */
|
||||
static void
|
||||
test_refstring_length (void)
|
||||
{
|
||||
char buf[] = {'h', 'e', 'l', 'l', 'o'}; /* no NUL */
|
||||
char *s = g_ref_string_new_len (buf, 5);
|
||||
|
||||
g_assert_cmpstr (s, ==, "hello");
|
||||
g_assert_cmpint (strlen (s), ==, strlen ("hello"));
|
||||
g_assert_cmpuint (g_ref_string_length (s), ==, strlen ("hello"));
|
||||
g_ref_string_release (s);
|
||||
}
|
||||
|
||||
/* test_refstring_length: Test the _len variant with no size set */
|
||||
static void
|
||||
test_refstring_length_auto (void)
|
||||
{
|
||||
char *s = g_ref_string_new_len ("hello", -1);
|
||||
g_assert_cmpstr (s, ==, "hello");
|
||||
g_assert_cmpuint (g_ref_string_length (s), ==, strlen ("hello"));
|
||||
g_ref_string_release (s);
|
||||
}
|
||||
|
||||
/* test_refstring_length_nuls: Test the _len variant */
|
||||
static void
|
||||
test_refstring_length_nuls (void)
|
||||
{
|
||||
char buf[] = {'h', 'e', '\0', 'l', 'o'}; /* no NUL */
|
||||
char *s = g_ref_string_new_len (buf, 5);
|
||||
|
||||
g_assert_cmpstr (s, ==, "he");
|
||||
g_assert_cmpint (memcmp (s, "he\0lo", 5), ==, 0);
|
||||
g_assert_cmpuint (g_ref_string_length (s), ==, 5);
|
||||
g_ref_string_release (s);
|
||||
}
|
||||
|
||||
/* test_refstring_intern: Test the interning API of GRefString */
|
||||
static void
|
||||
test_refstring_intern (void)
|
||||
@ -76,6 +112,9 @@ main (int argc,
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/refstring/base", test_refstring_base);
|
||||
g_test_add_func ("/refstring/length", test_refstring_length);
|
||||
g_test_add_func ("/refstring/length-auto", test_refstring_length_auto);
|
||||
g_test_add_func ("/refstring/length-nuls", test_refstring_length_nuls);
|
||||
g_test_add_func ("/refstring/intern", test_refstring_intern);
|
||||
|
||||
return g_test_run ();
|
||||
|
Loading…
x
Reference in New Issue
Block a user