aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/lib/slice/slice_string_helpers.c41
-rw-r--r--src/core/lib/slice/slice_string_helpers.h5
-rw-r--r--src/core/lib/surface/call.c2
-rw-r--r--test/core/slice/slice_string_helpers_test.c67
4 files changed, 110 insertions, 5 deletions
diff --git a/src/core/lib/slice/slice_string_helpers.c b/src/core/lib/slice/slice_string_helpers.c
index d461c474d2..e2d8c662f3 100644
--- a/src/core/lib/slice/slice_string_helpers.c
+++ b/src/core/lib/slice/slice_string_helpers.c
@@ -56,24 +56,57 @@ static int slice_find_separator_offset(const grpc_slice str, const char *sep,
return 0;
}
-void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
+static void skip_leading_trailing_spaces(const uint8_t *str_buffer, size_t *begin, size_t *end) {
+ while (*begin < *end && str_buffer[*begin] == ' ') {
+ (*begin)++;
+ }
+ while (*begin < *end && str_buffer[*end - 1] == ' ') {
+ (*end)--;
+ }
+}
+
+static void grpc_slice_split_inner(grpc_slice str, const char *sep, grpc_slice_buffer *dst, bool no_space) {
const size_t sep_len = strlen(sep);
size_t begin, end;
+ const uint8_t *str_buffer = GRPC_SLICE_START_PTR(str);
+ size_t sep_pos;
GPR_ASSERT(sep_len > 0);
if (slice_find_separator_offset(str, sep, 0, &begin, &end) != 0) {
do {
+ sep_pos = end;
+ if (no_space) {
+ skip_leading_trailing_spaces(str_buffer, &begin, &end);
+ }
grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
- } while (slice_find_separator_offset(str, sep, end + sep_len, &begin,
+ } while (slice_find_separator_offset(str, sep, sep_pos + sep_len, &begin,
&end) != 0);
+ begin = sep_pos + sep_len;
+ end = GRPC_SLICE_LENGTH(str);
+ if (no_space) {
+ skip_leading_trailing_spaces(str_buffer, &begin, &end);
+ }
grpc_slice_buffer_add_indexed(
- dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str)));
+ dst, grpc_slice_sub(str, begin, end));
} else { /* no sep found, add whole input */
- grpc_slice_buffer_add_indexed(dst, grpc_slice_ref_internal(str));
+ begin = 0;
+ end = GRPC_SLICE_LENGTH(str);
+ if (no_space) {
+ skip_leading_trailing_spaces(str_buffer, &begin, &end);
+ }
+ grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
}
}
+void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
+ grpc_slice_split_inner(str, sep, dst, false);
+}
+
+void grpc_slice_split_without_space(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
+ grpc_slice_split_inner(str, sep, dst, true);
+}
+
bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result) {
return gpr_parse_bytes_to_uint32((const char *)GRPC_SLICE_START_PTR(str),
GRPC_SLICE_LENGTH(str), result) != 0;
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index bcfb33bfb3..86125abec3 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -39,6 +39,11 @@ char *grpc_dump_slice(grpc_slice slice, uint32_t flags);
* should be a properly initialized instance. */
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
+/** Split \a str by the separator \a sep and remove the leading and trailing
+ * spaces of each resulting token. Results are stored in \a dst, which should be
+ * a properly initialized instance. */
+void grpc_slice_split_without_space(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
+
bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result);
#ifdef __cplusplus
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 797c5cf914..d4c2568c51 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -875,7 +875,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
accept_encoding_slice = GRPC_MDVALUE(mdel);
grpc_slice_buffer_init(&accept_encoding_parts);
- grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
+ grpc_slice_split_without_space(accept_encoding_slice, ",", &accept_encoding_parts);
GPR_BITSET(encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
for (i = 0; i < accept_encoding_parts.count; i++) {
diff --git a/test/core/slice/slice_string_helpers_test.c b/test/core/slice/slice_string_helpers_test.c
index 504acf8f84..48f3701c0a 100644
--- a/test/core/slice/slice_string_helpers_test.c
+++ b/test/core/slice/slice_string_helpers_test.c
@@ -127,9 +127,76 @@ static void test_strsplit(void) {
gpr_free(parts);
}
+static void test_strsplit_nospace(void) {
+ grpc_slice_buffer *parts;
+ grpc_slice str;
+
+ LOG_TEST_NAME("test_strsplit_nospace");
+
+ parts = gpr_malloc(sizeof(grpc_slice_buffer));
+ grpc_slice_buffer_init(parts);
+
+ str = grpc_slice_from_copied_string("one ,two, three , four");
+ grpc_slice_split_without_space(str, ",", parts);
+ GPR_ASSERT(4 == parts->count);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "two"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[2], "three"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[3], "four"));
+ grpc_slice_buffer_reset_and_unref(parts);
+ grpc_slice_unref(str);
+
+ /* separator not present in string */
+ str = grpc_slice_from_copied_string("one two three four ");
+ grpc_slice_split_without_space(str, ",", parts);
+ GPR_ASSERT(1 == parts->count);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one two three four"));
+ grpc_slice_buffer_reset_and_unref(parts);
+ grpc_slice_unref(str);
+
+ /* separator at the end */
+ str = grpc_slice_from_copied_string("foo,");
+ grpc_slice_split_without_space(str, ",", parts);
+ GPR_ASSERT(2 == parts->count);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], ""));
+ grpc_slice_buffer_reset_and_unref(parts);
+ grpc_slice_unref(str);
+
+ /* separator at the beginning */
+ str = grpc_slice_from_copied_string(" , foo");
+ grpc_slice_split_without_space(str, ",", parts);
+ GPR_ASSERT(2 == parts->count);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "foo"));
+ grpc_slice_buffer_reset_and_unref(parts);
+ grpc_slice_unref(str);
+
+ /* standalone separator */
+ str = grpc_slice_from_copied_string(", ");
+ grpc_slice_split_without_space(str, ", ", parts);
+ GPR_ASSERT(2 == parts->count);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], ""));
+ grpc_slice_buffer_reset_and_unref(parts);
+ grpc_slice_unref(str);
+
+ /* empty input */
+ str = grpc_slice_from_copied_string("");
+ grpc_slice_split_without_space(str, ",", parts);
+ GPR_ASSERT(1 == parts->count);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
+ grpc_slice_buffer_reset_and_unref(parts);
+ grpc_slice_unref(str);
+
+ grpc_slice_buffer_destroy(parts);
+ gpr_free(parts);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_dump_slice();
test_strsplit();
+ test_strsplit_nospace();
return 0;
}