mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-06 09:26:17 +01:00
Merge branch 'wip/chergert/gdatainputstream-memchr' into 'main'
gio/gdatainputstream: use memchr() when possible See merge request GNOME/glib!4327
This commit is contained in:
commit
c94cbf2368
@ -870,13 +870,26 @@ scan_for_chars (GDataInputStream *stream,
|
||||
end = available;
|
||||
peeked = end - start;
|
||||
|
||||
for (i = 0; checked < available && i < peeked; i++)
|
||||
/* For single-char case such as \0, defer to memchr which can
|
||||
* take advantage of simd/etc.
|
||||
*/
|
||||
if (stop_chars_len == 1)
|
||||
{
|
||||
for (stop_char = stop_chars; stop_char != stop_end; stop_char++)
|
||||
{
|
||||
if (buffer[i] == *stop_char)
|
||||
return (start + i);
|
||||
}
|
||||
const char *p = memchr (buffer, stop_chars[0], peeked);
|
||||
|
||||
if (p != NULL)
|
||||
return start + (p - buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; checked < available && i < peeked; i++)
|
||||
{
|
||||
for (stop_char = stop_chars; stop_char != stop_end; stop_char++)
|
||||
{
|
||||
if (buffer[i] == *stop_char)
|
||||
return (start + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checked = end;
|
||||
|
@ -274,61 +274,99 @@ test_read_until (void)
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static char *
|
||||
escape_data_string (const char *str,
|
||||
size_t len)
|
||||
{
|
||||
char *escaped = g_memdup2 (str, len + 1);
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (escaped[i] == '\0')
|
||||
escaped[i] = '?';
|
||||
}
|
||||
|
||||
return escaped;
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_upto (void)
|
||||
{
|
||||
GInputStream *stream;
|
||||
GInputStream *base_stream;
|
||||
GError *error = NULL;
|
||||
char *data;
|
||||
int line;
|
||||
int i;
|
||||
guchar stop_char;
|
||||
const struct {
|
||||
int n_repeats;
|
||||
const char *data_string;
|
||||
size_t data_string_len;
|
||||
size_t data_part_len;
|
||||
const char *data_sep;
|
||||
size_t data_sep_len;
|
||||
} vectors[] = {
|
||||
{ 10, " part1 # part2 $ part3 \0 part4 ", 32, 7, "#$\0^", 4 },
|
||||
{ 20, "{\"key\": \"value\"}\0", 17, 16, "\0", 1 },
|
||||
};
|
||||
|
||||
#undef REPEATS
|
||||
#undef DATA_STRING
|
||||
#undef DATA_PART_LEN
|
||||
#undef DATA_SEP
|
||||
#undef DATA_SEP_LEN
|
||||
#define REPEATS 10 /* number of rounds */
|
||||
#define DATA_STRING " part1 # part2 $ part3 \0 part4 ^"
|
||||
#define DATA_PART_LEN 7 /* number of characters between separators */
|
||||
#define DATA_SEP "#$\0^"
|
||||
#define DATA_SEP_LEN 4
|
||||
const int DATA_PARTS_NUM = DATA_SEP_LEN * REPEATS;
|
||||
#define REPEATS vectors[n].n_repeats
|
||||
#define DATA_STRING vectors[n].data_string
|
||||
#define DATA_STRING_LEN vectors[n].data_string_len
|
||||
#define DATA_PART_LEN vectors[n].data_part_len
|
||||
#define DATA_SEP vectors[n].data_sep
|
||||
#define DATA_SEP_LEN vectors[n].data_sep_len
|
||||
|
||||
base_stream = g_memory_input_stream_new ();
|
||||
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
|
||||
|
||||
for (i = 0; i < REPEATS; i++)
|
||||
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, 32, NULL);
|
||||
|
||||
/* Test stop characters */
|
||||
error = NULL;
|
||||
data = (char*)1;
|
||||
line = 0;
|
||||
while (data)
|
||||
for (guint n = 0; n < G_N_ELEMENTS (vectors); n++)
|
||||
{
|
||||
gsize length = -1;
|
||||
data = g_data_input_stream_read_upto (G_DATA_INPUT_STREAM (stream), DATA_SEP, DATA_SEP_LEN, &length, NULL, &error);
|
||||
if (data)
|
||||
const int DATA_PARTS_NUM = DATA_SEP_LEN * REPEATS;
|
||||
GInputStream *stream;
|
||||
GInputStream *base_stream;
|
||||
GError *error = NULL;
|
||||
char *data;
|
||||
int line;
|
||||
int i;
|
||||
guchar stop_char;
|
||||
|
||||
char *escaped_data = escape_data_string (DATA_STRING, DATA_STRING_LEN);
|
||||
char *escaped_sep = escape_data_string (DATA_SEP, DATA_SEP_LEN);
|
||||
g_test_message ("Test vector %u: %s and %s", n, escaped_data, escaped_sep);
|
||||
g_free (escaped_data);
|
||||
g_free (escaped_sep);
|
||||
|
||||
base_stream = g_memory_input_stream_new ();
|
||||
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
|
||||
|
||||
for (i = 0; i < REPEATS; i++)
|
||||
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, DATA_STRING_LEN, NULL);
|
||||
|
||||
/* Test stop characters */
|
||||
error = NULL;
|
||||
data = (char*)1;
|
||||
line = 0;
|
||||
while (data)
|
||||
{
|
||||
g_assert_cmpint (strlen (data), ==, DATA_PART_LEN);
|
||||
g_assert_no_error (error);
|
||||
line++;
|
||||
gsize length = -1;
|
||||
data = g_data_input_stream_read_upto (G_DATA_INPUT_STREAM (stream), DATA_SEP, DATA_SEP_LEN, &length, NULL, &error);
|
||||
if (data)
|
||||
{
|
||||
g_assert_cmpint (strlen (data), ==, DATA_PART_LEN);
|
||||
g_assert_no_error (error);
|
||||
line++;
|
||||
|
||||
stop_char = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error);
|
||||
g_assert (memchr (DATA_SEP, stop_char, DATA_SEP_LEN) != NULL);
|
||||
g_assert_no_error (error);
|
||||
stop_char = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error);
|
||||
g_assert (memchr (DATA_SEP, stop_char, DATA_SEP_LEN) != NULL);
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
g_free (data);
|
||||
}
|
||||
g_free (data);
|
||||
}
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (line, ==, DATA_PARTS_NUM);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (line, ==, DATA_PARTS_NUM);
|
||||
|
||||
g_object_unref (base_stream);
|
||||
g_object_unref (stream);
|
||||
g_object_unref (base_stream);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
}
|
||||
|
||||
enum TestDataType {
|
||||
TEST_DATA_BYTE = 0,
|
||||
TEST_DATA_INT16,
|
||||
|
Loading…
Reference in New Issue
Block a user