diff --git a/BUILD b/BUILD
index 86d1f77cd4e..b7186c7479f 100644
--- a/BUILD
+++ b/BUILD
@@ -1490,6 +1490,7 @@ grpc_cc_library(
"src/core/lib/slice/slice_api.cc",
"src/core/lib/slice/slice_buffer.cc",
"src/core/lib/slice/slice_intern.cc",
+ "src/core/lib/slice/slice_split.cc",
"src/core/lib/surface/api_trace.cc",
"src/core/lib/surface/byte_buffer.cc",
"src/core/lib/surface/byte_buffer_reader.cc",
@@ -1541,6 +1542,7 @@ grpc_cc_library(
"src/core/lib/channel/context.h",
"src/core/lib/channel/handshaker.h",
"src/core/lib/channel/status_util.h",
+ "src/core/lib/slice/slice_split.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f0a505081e5..a452071d466 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -681,6 +681,8 @@ if(gRPC_BUILD_TESTS)
endif()
add_dependencies(buildtests_c server_test)
add_dependencies(buildtests_c slice_buffer_test)
+ add_dependencies(buildtests_c slice_intern_test)
+ add_dependencies(buildtests_c slice_split_test)
add_dependencies(buildtests_c slice_string_helpers_test)
add_dependencies(buildtests_c sockaddr_resolver_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -2043,6 +2045,7 @@ add_library(grpc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_refcount.cc
+ src/core/lib/slice/slice_split.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/slice/static_slice.cc
src/core/lib/surface/api_trace.cc
@@ -2626,6 +2629,7 @@ add_library(grpc_unsecure
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_refcount.cc
+ src/core/lib/slice/slice_split.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/slice/static_slice.cc
src/core/lib/surface/api_trace.cc
@@ -6860,10 +6864,69 @@ target_link_libraries(slice_buffer_test
)
+endif()
+if(gRPC_BUILD_TESTS)
+
+add_executable(slice_intern_test
+ test/core/slice/slice_intern_test.cc
+)
+
+target_include_directories(slice_intern_test
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ ${_gRPC_RE2_INCLUDE_DIR}
+ ${_gRPC_SSL_INCLUDE_DIR}
+ ${_gRPC_UPB_GENERATED_DIR}
+ ${_gRPC_UPB_GRPC_GENERATED_DIR}
+ ${_gRPC_UPB_INCLUDE_DIR}
+ ${_gRPC_XXHASH_INCLUDE_DIR}
+ ${_gRPC_ZLIB_INCLUDE_DIR}
+)
+
+target_link_libraries(slice_intern_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
+add_executable(slice_split_test
+ test/core/slice/slice_split_test.cc
+)
+
+target_include_directories(slice_split_test
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ ${_gRPC_RE2_INCLUDE_DIR}
+ ${_gRPC_SSL_INCLUDE_DIR}
+ ${_gRPC_UPB_GENERATED_DIR}
+ ${_gRPC_UPB_GRPC_GENERATED_DIR}
+ ${_gRPC_UPB_INCLUDE_DIR}
+ ${_gRPC_XXHASH_INCLUDE_DIR}
+ ${_gRPC_ZLIB_INCLUDE_DIR}
+)
+
+target_link_libraries(slice_split_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+)
+
+
endif()
if(gRPC_BUILD_TESTS)
add_executable(slice_string_helpers_test
+ src/core/lib/debug/trace.cc
+ src/core/lib/slice/slice.cc
+ src/core/lib/slice/slice_refcount.cc
+ src/core/lib/slice/slice_string_helpers.cc
+ src/core/lib/slice/static_slice.cc
test/core/slice/slice_string_helpers_test.cc
)
@@ -6883,7 +6946,7 @@ target_include_directories(slice_string_helpers_test
target_link_libraries(slice_string_helpers_test
${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
+ gpr
)
@@ -7335,6 +7398,11 @@ endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_slice_slice_test
+ src/core/lib/debug/trace.cc
+ src/core/lib/slice/slice.cc
+ src/core/lib/slice/slice_refcount.cc
+ src/core/lib/slice/slice_string_helpers.cc
+ src/core/lib/slice/static_slice.cc
test/core/slice/slice_test.cc
)
@@ -7354,7 +7422,7 @@ target_include_directories(test_core_slice_slice_test
target_link_libraries(test_core_slice_slice_test
${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
+ gpr
)
diff --git a/Makefile b/Makefile
index 2545806bdf7..b3462ac66cb 100644
--- a/Makefile
+++ b/Makefile
@@ -1547,6 +1547,7 @@ LIBGRPC_SRC = \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_refcount.cc \
+ src/core/lib/slice/slice_split.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/static_slice.cc \
src/core/lib/surface/api_trace.cc \
@@ -1978,6 +1979,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_refcount.cc \
+ src/core/lib/slice/slice_split.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/static_slice.cc \
src/core/lib/surface/api_trace.cc \
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index a05885d1ff8..7f8344833fb 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -897,6 +897,7 @@ libs:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
+ - src/core/lib/slice/slice_split.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/slice/slice_utils.h
- src/core/lib/slice/static_slice.h
@@ -1460,6 +1461,7 @@ libs:
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_intern.cc
- src/core/lib/slice/slice_refcount.cc
+ - src/core/lib/slice/slice_split.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/slice/static_slice.cc
- src/core/lib/surface/api_trace.cc
@@ -1899,6 +1901,7 @@ libs:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
+ - src/core/lib/slice/slice_split.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/slice/slice_utils.h
- src/core/lib/slice/static_slice.h
@@ -2180,6 +2183,7 @@ libs:
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_intern.cc
- src/core/lib/slice/slice_refcount.cc
+ - src/core/lib/slice/slice_split.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/slice/static_slice.cc
- src/core/lib/surface/api_trace.cc
@@ -3925,15 +3929,48 @@ targets:
deps:
- grpc_test_util
uses_polling: false
-- name: slice_string_helpers_test
+- name: slice_intern_test
build: test
language: c
headers: []
src:
- - test/core/slice/slice_string_helpers_test.cc
+ - test/core/slice/slice_intern_test.cc
deps:
- grpc_test_util
uses_polling: false
+- name: slice_split_test
+ build: test
+ language: c
+ headers: []
+ src:
+ - test/core/slice/slice_split_test.cc
+ deps:
+ - grpc_test_util
+ uses_polling: false
+- name: slice_string_helpers_test
+ build: test
+ language: c
+ headers:
+ - src/core/lib/debug/trace.h
+ - src/core/lib/gprpp/atomic_utils.h
+ - src/core/lib/gprpp/ref_counted.h
+ - src/core/lib/gprpp/ref_counted_ptr.h
+ - src/core/lib/slice/slice_internal.h
+ - src/core/lib/slice/slice_refcount.h
+ - src/core/lib/slice/slice_refcount_base.h
+ - src/core/lib/slice/slice_string_helpers.h
+ - src/core/lib/slice/slice_utils.h
+ - src/core/lib/slice/static_slice.h
+ src:
+ - src/core/lib/debug/trace.cc
+ - src/core/lib/slice/slice.cc
+ - src/core/lib/slice/slice_refcount.cc
+ - src/core/lib/slice/slice_string_helpers.cc
+ - src/core/lib/slice/static_slice.cc
+ - test/core/slice/slice_string_helpers_test.cc
+ deps:
+ - gpr
+ uses_polling: false
- name: sockaddr_resolver_test
build: test
language: c
@@ -4095,11 +4132,26 @@ targets:
- name: test_core_slice_slice_test
build: test
language: c
- headers: []
+ headers:
+ - src/core/lib/debug/trace.h
+ - src/core/lib/gprpp/atomic_utils.h
+ - src/core/lib/gprpp/ref_counted.h
+ - src/core/lib/gprpp/ref_counted_ptr.h
+ - src/core/lib/slice/slice_internal.h
+ - src/core/lib/slice/slice_refcount.h
+ - src/core/lib/slice/slice_refcount_base.h
+ - src/core/lib/slice/slice_string_helpers.h
+ - src/core/lib/slice/slice_utils.h
+ - src/core/lib/slice/static_slice.h
src:
+ - src/core/lib/debug/trace.cc
+ - src/core/lib/slice/slice.cc
+ - src/core/lib/slice/slice_refcount.cc
+ - src/core/lib/slice/slice_string_helpers.cc
+ - src/core/lib/slice/static_slice.cc
- test/core/slice/slice_test.cc
deps:
- - grpc_test_util
+ - gpr
uses_polling: false
- name: thd_test
build: test
diff --git a/config.m4 b/config.m4
index 62f688844c5..4db0a4815ff 100644
--- a/config.m4
+++ b/config.m4
@@ -600,6 +600,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_refcount.cc \
+ src/core/lib/slice/slice_split.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/static_slice.cc \
src/core/lib/surface/api_trace.cc \
diff --git a/config.w32 b/config.w32
index ed1fed2a096..3a00547195e 100644
--- a/config.w32
+++ b/config.w32
@@ -566,6 +566,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\slice\\slice_buffer.cc " +
"src\\core\\lib\\slice\\slice_intern.cc " +
"src\\core\\lib\\slice\\slice_refcount.cc " +
+ "src\\core\\lib\\slice\\slice_split.cc " +
"src\\core\\lib\\slice\\slice_string_helpers.cc " +
"src\\core\\lib\\slice\\static_slice.cc " +
"src\\core\\lib\\surface\\api_trace.cc " +
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 61ee87c41f8..a075ee96537 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -709,6 +709,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_refcount.h',
'src/core/lib/slice/slice_refcount_base.h',
+ 'src/core/lib/slice/slice_split.h',
'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/slice/slice_utils.h',
'src/core/lib/slice/static_slice.h',
@@ -1379,6 +1380,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_refcount.h',
'src/core/lib/slice/slice_refcount_base.h',
+ 'src/core/lib/slice/slice_split.h',
'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/slice/slice_utils.h',
'src/core/lib/slice/static_slice.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 477b1860ed2..ba9680f9b0a 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -1260,6 +1260,8 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_refcount.cc',
'src/core/lib/slice/slice_refcount.h',
'src/core/lib/slice/slice_refcount_base.h',
+ 'src/core/lib/slice/slice_split.cc',
+ 'src/core/lib/slice/slice_split.h',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/slice/slice_utils.h',
@@ -1965,6 +1967,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_refcount.h',
'src/core/lib/slice/slice_refcount_base.h',
+ 'src/core/lib/slice/slice_split.h',
'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/slice/slice_utils.h',
'src/core/lib/slice/static_slice.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 26351af43dc..e3ca3b6a9f8 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -1173,6 +1173,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/slice_refcount.cc )
s.files += %w( src/core/lib/slice/slice_refcount.h )
s.files += %w( src/core/lib/slice/slice_refcount_base.h )
+ s.files += %w( src/core/lib/slice/slice_split.cc )
+ s.files += %w( src/core/lib/slice/slice_split.h )
s.files += %w( src/core/lib/slice/slice_string_helpers.cc )
s.files += %w( src/core/lib/slice/slice_string_helpers.h )
s.files += %w( src/core/lib/slice/slice_utils.h )
diff --git a/grpc.gyp b/grpc.gyp
index bcbd1f40cf5..3bd0fe6071c 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -988,6 +988,7 @@
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_refcount.cc',
+ 'src/core/lib/slice/slice_split.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/slice/static_slice.cc',
'src/core/lib/surface/api_trace.cc',
@@ -1394,6 +1395,7 @@
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_refcount.cc',
+ 'src/core/lib/slice/slice_split.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/slice/static_slice.cc',
'src/core/lib/surface/api_trace.cc',
diff --git a/package.xml b/package.xml
index 6bde677fd31..3e972674ae9 100644
--- a/package.xml
+++ b/package.xml
@@ -1153,6 +1153,8 @@
+
+
diff --git a/src/core/lib/slice/slice_split.cc b/src/core/lib/slice/slice_split.cc
new file mode 100644
index 00000000000..d2a951cb54d
--- /dev/null
+++ b/src/core/lib/slice/slice_split.cc
@@ -0,0 +1,100 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include
+
+#include "src/core/lib/slice/slice_split.h"
+
+#include
+
+#include
+
+/** Finds the initial (\a begin) and final (\a end) offsets of the next
+ * substring from \a str + \a read_offset until the next \a sep or the end of \a
+ * str.
+ *
+ * Returns 1 and updates \a begin and \a end. Returns 0 otherwise. */
+static int slice_find_separator_offset(const grpc_slice str, const char* sep,
+ const size_t read_offset, size_t* begin,
+ size_t* end) {
+ size_t i;
+ const uint8_t* str_ptr = GRPC_SLICE_START_PTR(str) + read_offset;
+ const size_t str_len = GRPC_SLICE_LENGTH(str) - read_offset;
+ const size_t sep_len = strlen(sep);
+ if (str_len < sep_len) {
+ return 0;
+ }
+
+ for (i = 0; i <= str_len - sep_len; i++) {
+ if (memcmp(str_ptr + i, sep, sep_len) == 0) {
+ *begin = read_offset;
+ *end = read_offset + i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+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, 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, begin, end));
+ } else { /* no sep found, add whole input */
+ 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);
+}
diff --git a/src/core/lib/slice/slice_split.h b/src/core/lib/slice/slice_split.h
new file mode 100644
index 00000000000..835b16a85d2
--- /dev/null
+++ b/src/core/lib/slice/slice_split.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SLICE_SLICE_SPLIT_H
+#define GRPC_CORE_LIB_SLICE_SLICE_SPLIT_H
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+/** Split \a str by the separator \a sep. Results are stored in \a dst, which
+ * 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);
+
+#endif /* GRPC_CORE_LIB_SLICE_SLICE_SPLIT_H */
diff --git a/src/core/lib/slice/slice_string_helpers.cc b/src/core/lib/slice/slice_string_helpers.cc
index 7887e0305fb..35744d0aa01 100644
--- a/src/core/lib/slice/slice_string_helpers.cc
+++ b/src/core/lib/slice/slice_string_helpers.cc
@@ -20,10 +20,6 @@
#include "src/core/lib/slice/slice_string_helpers.h"
-#include
-
-#include
-
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -41,85 +37,6 @@ grpc_slice grpc_dump_slice_to_slice(const grpc_slice& s, uint32_t flags) {
return grpc_slice_from_moved_buffer(std::move(ptr), len);
}
-/** Finds the initial (\a begin) and final (\a end) offsets of the next
- * substring from \a str + \a read_offset until the next \a sep or the end of \a
- * str.
- *
- * Returns 1 and updates \a begin and \a end. Returns 0 otherwise. */
-static int slice_find_separator_offset(const grpc_slice str, const char* sep,
- const size_t read_offset, size_t* begin,
- size_t* end) {
- size_t i;
- const uint8_t* str_ptr = GRPC_SLICE_START_PTR(str) + read_offset;
- const size_t str_len = GRPC_SLICE_LENGTH(str) - read_offset;
- const size_t sep_len = strlen(sep);
- if (str_len < sep_len) {
- return 0;
- }
-
- for (i = 0; i <= str_len - sep_len; i++) {
- if (memcmp(str_ptr + i, sep, sep_len) == 0) {
- *begin = read_offset;
- *end = read_offset + i;
- return 1;
- }
- }
- return 0;
-}
-
-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, 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, begin, end));
- } else { /* no sep found, add whole input */
- 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(
reinterpret_cast GRPC_SLICE_START_PTR(str),
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index 6551a6df75d..df9cadd5a81 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -25,7 +25,6 @@
#include
#include
-#include
#include "src/core/lib/gpr/string.h"
@@ -34,16 +33,6 @@ char* grpc_dump_slice(const grpc_slice& slice, uint32_t flags);
/* Calls gpr_dump on a slice and returns the result as a slice. */
grpc_slice grpc_dump_slice_to_slice(const grpc_slice& slice, uint32_t flags);
-/** Split \a str by the separator \a sep. Results are stored in \a dst, which
- * 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);
#endif /* GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H */
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index bc9cf54d93c..268ec985cf5 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -50,6 +50,7 @@
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_split.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/slice/slice_utils.h"
#include "src/core/lib/surface/api_trace.h"
diff --git a/src/core/lib/transport/status_metadata.cc b/src/core/lib/transport/status_metadata.cc
index 1b19307e7c6..fb7064641d8 100644
--- a/src/core/lib/transport/status_metadata.cc
+++ b/src/core/lib/transport/status_metadata.cc
@@ -20,6 +20,7 @@
#include "src/core/lib/transport/status_metadata.h"
+#include "src/core/lib/gpr/string.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index e5aa570c2d4..767a9adfa13 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -575,6 +575,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_refcount.cc',
+ 'src/core/lib/slice/slice_split.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/slice/static_slice.cc',
'src/core/lib/surface/api_trace.cc',
diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD
index 9be57ab7b5e..22994202fcc 100644
--- a/test/core/slice/BUILD
+++ b/test/core/slice/BUILD
@@ -85,6 +85,18 @@ grpc_cc_test(
srcs = ["slice_test.cc"],
language = "C++",
uses_polling = False,
+ deps = [
+ "//:gpr",
+ "//:slice",
+ "//test/core/util:grpc_suppressions",
+ ],
+)
+
+grpc_cc_test(
+ name = "slice_intern_test",
+ srcs = ["slice_intern_test.cc"],
+ language = "C++",
+ uses_polling = False,
deps = [
"//:gpr",
"//:grpc",
@@ -97,6 +109,18 @@ grpc_cc_test(
srcs = ["slice_string_helpers_test.cc"],
language = "C++",
uses_polling = False,
+ deps = [
+ "//:gpr",
+ "//:slice",
+ "//test/core/util:grpc_suppressions",
+ ],
+)
+
+grpc_cc_test(
+ name = "slice_split_test",
+ srcs = ["slice_split_test.cc"],
+ language = "C++",
+ uses_polling = False,
deps = [
"//:gpr",
"//:grpc",
diff --git a/test/core/slice/slice_intern_test.cc b/test/core/slice/slice_intern_test.cc
new file mode 100644
index 00000000000..277351cd816
--- /dev/null
+++ b/test/core/slice/slice_intern_test.cc
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/transport/static_metadata.h"
+#include "test/core/util/test_config.h"
+
+#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x);
+
+static void test_slice_interning(void) {
+ LOG_TEST_NAME("test_slice_interning");
+
+ grpc_init();
+ grpc_slice src1 = grpc_slice_from_copied_string("hello123456789123456789");
+ grpc_slice src2 = grpc_slice_from_copied_string("hello123456789123456789");
+
+ // Explicitly checking that the slices are at different addresses prevents
+ // failure with windows opt 64bit build.
+ // See https://github.com/grpc/grpc/issues/20519
+ GPR_ASSERT(&src1 != &src2);
+ GPR_ASSERT(GRPC_SLICE_START_PTR(src1) != GRPC_SLICE_START_PTR(src2));
+
+ grpc_slice interned1 = grpc_slice_intern(src1);
+ grpc_slice interned2 = grpc_slice_intern(src2);
+ GPR_ASSERT(GRPC_SLICE_START_PTR(interned1) ==
+ GRPC_SLICE_START_PTR(interned2));
+ GPR_ASSERT(GRPC_SLICE_START_PTR(interned1) != GRPC_SLICE_START_PTR(src1));
+ GPR_ASSERT(GRPC_SLICE_START_PTR(interned2) != GRPC_SLICE_START_PTR(src2));
+ grpc_slice_unref(src1);
+ grpc_slice_unref(src2);
+ grpc_slice_unref(interned1);
+ grpc_slice_unref(interned2);
+ grpc_shutdown();
+}
+
+static void test_static_slice_interning(void) {
+ LOG_TEST_NAME("test_static_slice_interning");
+
+ // grpc_init/grpc_shutdown deliberately omitted: they should not be necessary
+ // to intern a static slice
+
+ for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
+ GPR_ASSERT(grpc_slice_is_equivalent(
+ grpc_core::g_static_metadata_slice_table[i],
+ grpc_slice_intern(grpc_core::g_static_metadata_slice_table[i])));
+ }
+}
+
+static void test_static_slice_copy_interning(void) {
+ LOG_TEST_NAME("test_static_slice_copy_interning");
+
+ grpc_init();
+
+ for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
+ grpc_slice copy =
+ grpc_slice_dup(grpc_core::g_static_metadata_slice_table[i]);
+ GPR_ASSERT(grpc_core::g_static_metadata_slice_table[i].refcount !=
+ copy.refcount);
+ GPR_ASSERT(grpc_core::g_static_metadata_slice_table[i].refcount ==
+ grpc_slice_intern(copy).refcount);
+ grpc_slice_unref(copy);
+ }
+
+ grpc_shutdown();
+}
+
+int main(int argc, char** argv) {
+ grpc::testing::TestEnvironment env(argc, argv);
+ grpc_init();
+ test_slice_interning();
+ test_static_slice_interning();
+ test_static_slice_copy_interning();
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/slice/slice_split_test.cc b/test/core/slice/slice_split_test.cc
new file mode 100644
index 00000000000..6e349ac333d
--- /dev/null
+++ b/test/core/slice/slice_split_test.cc
@@ -0,0 +1,174 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/slice/slice_split.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "src/core/lib/gpr/string.h"
+#include "test/core/util/test_config.h"
+
+#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
+
+static void test_strsplit(void) {
+ grpc_slice_buffer* parts;
+ grpc_slice str;
+
+ LOG_TEST_NAME("test_strsplit");
+
+ parts =
+ static_cast(gpr_malloc(sizeof(grpc_slice_buffer)));
+ grpc_slice_buffer_init(parts);
+
+ str = grpc_slice_from_copied_string("one, two, three, four");
+ grpc_slice_split(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(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(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(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(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(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);
+}
+
+static void test_strsplit_nospace(void) {
+ grpc_slice_buffer* parts;
+ grpc_slice str;
+
+ LOG_TEST_NAME("test_strsplit_nospace");
+
+ parts =
+ static_cast(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::testing::TestEnvironment env(argc, argv);
+ test_strsplit();
+ test_strsplit_nospace();
+ return 0;
+}
diff --git a/test/core/slice/slice_string_helpers_test.cc b/test/core/slice/slice_string_helpers_test.cc
index 1bbc0947bc6..53b229c0d4f 100644
--- a/test/core/slice/slice_string_helpers_test.cc
+++ b/test/core/slice/slice_string_helpers_test.cc
@@ -28,7 +28,7 @@
#include
#include "src/core/lib/gpr/string.h"
-#include "test/core/util/test_config.h"
+#include "src/core/lib/slice/slice_internal.h"
#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
@@ -37,7 +37,7 @@ static void expect_slice_dump(grpc_slice slice, uint32_t flags,
char* got = grpc_dump_slice(slice, flags);
GPR_ASSERT(0 == strcmp(got, result));
gpr_free(got);
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
static void test_dump_slice(void) {
@@ -60,144 +60,7 @@ static void test_dump_slice(void) {
GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'");
}
-static void test_strsplit(void) {
- grpc_slice_buffer* parts;
- grpc_slice str;
-
- LOG_TEST_NAME("test_strsplit");
-
- parts =
- static_cast(gpr_malloc(sizeof(grpc_slice_buffer)));
- grpc_slice_buffer_init(parts);
-
- str = grpc_slice_from_copied_string("one, two, three, four");
- grpc_slice_split(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(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(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(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(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(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);
-}
-
-static void test_strsplit_nospace(void) {
- grpc_slice_buffer* parts;
- grpc_slice str;
-
- LOG_TEST_NAME("test_strsplit_nospace");
-
- parts =
- static_cast(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::testing::TestEnvironment env(argc, argv);
+int main(int, char**) {
test_dump_slice();
- test_strsplit();
- test_strsplit_nospace();
return 0;
}
diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc
index 52b85de9615..3da56f16eb8 100644
--- a/test/core/slice/slice_test.cc
+++ b/test/core/slice/slice_test.cc
@@ -28,8 +28,6 @@
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/transport/static_metadata.h"
-#include "test/core/util/test_config.h"
#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x);
@@ -56,7 +54,7 @@ static void test_slice_malloc_returns_something_sensible(void) {
GRPC_SLICE_START_PTR(slice)[i] = static_cast(i);
}
/* And finally we must succeed in destroying the slice */
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
}
@@ -69,7 +67,7 @@ static void test_slice_new_returns_something_sensible(void) {
GPR_ASSERT(slice.refcount);
GPR_ASSERT(slice.data.refcounted.bytes == &x);
GPR_ASSERT(slice.data.refcounted.length == 1);
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
/* destroy function that sets a mark to indicate it was called. */
@@ -89,7 +87,7 @@ static void test_slice_new_with_user_data(void) {
GPR_ASSERT(GRPC_SLICE_START_PTR(slice)[1] == 1);
/* unref should cause destroy function to run. */
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
GPR_ASSERT(marker == 1);
}
@@ -115,15 +113,15 @@ static void test_slice_new_with_len_returns_something_sensible(void) {
make sure that that the destroy callback (i.e do_nothing_with_len_1()) is
not called until the last unref operation */
for (i = 0; i < num_refs; i++) {
- grpc_slice_ref(slice);
+ grpc_slice_ref_internal(slice);
}
for (i = 0; i < num_refs; i++) {
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
GPR_ASSERT(do_nothing_with_len_1_calls == 0); /* Shouldn't be called yet */
/* last unref */
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
GPR_ASSERT(do_nothing_with_len_1_calls == 1);
}
@@ -151,10 +149,10 @@ static void test_slice_sub_works(unsigned length) {
for (k = 0; k < j - i; k++) {
GPR_ASSERT(GRPC_SLICE_START_PTR(sub)[k] == (uint8_t)(i + k));
}
- grpc_slice_unref(sub);
+ grpc_slice_unref_internal(sub);
}
}
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
static void check_head_tail(grpc_slice slice, grpc_slice head,
@@ -185,14 +183,14 @@ static void test_slice_split_head_works(size_t length) {
/* Ensure that for all subsets length is correct and that we start on the
correct byte. Additionally check that no copies were made. */
for (i = 0; i < length; i++) {
- tail = grpc_slice_ref(slice);
+ tail = grpc_slice_ref_internal(slice);
head = grpc_slice_split_head(&tail, i);
check_head_tail(slice, head, tail);
- grpc_slice_unref(tail);
- grpc_slice_unref(head);
+ grpc_slice_unref_internal(tail);
+ grpc_slice_unref_internal(head);
}
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
static void test_slice_split_tail_works(size_t length) {
@@ -213,14 +211,14 @@ static void test_slice_split_tail_works(size_t length) {
/* Ensure that for all subsets length is correct and that we start on the
correct byte. Additionally check that no copies were made. */
for (i = 0; i < length; i++) {
- head = grpc_slice_ref(slice);
+ head = grpc_slice_ref_internal(slice);
tail = grpc_slice_split_tail(&head, i);
check_head_tail(slice, head, tail);
- grpc_slice_unref(tail);
- grpc_slice_unref(head);
+ grpc_slice_unref_internal(tail);
+ grpc_slice_unref_internal(head);
}
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
}
static void test_slice_from_copied_string_works(void) {
@@ -233,71 +231,12 @@ static void test_slice_from_copied_string_works(void) {
GPR_ASSERT(strlen(text) == GRPC_SLICE_LENGTH(slice));
GPR_ASSERT(
0 == memcmp(text, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice)));
- grpc_slice_unref(slice);
-}
-
-static void test_slice_interning(void) {
- LOG_TEST_NAME("test_slice_interning");
-
- grpc_init();
- grpc_slice src1 = grpc_slice_from_copied_string("hello123456789123456789");
- grpc_slice src2 = grpc_slice_from_copied_string("hello123456789123456789");
-
- // Explicitly checking that the slices are at different addresses prevents
- // failure with windows opt 64bit build.
- // See https://github.com/grpc/grpc/issues/20519
- GPR_ASSERT(&src1 != &src2);
- GPR_ASSERT(GRPC_SLICE_START_PTR(src1) != GRPC_SLICE_START_PTR(src2));
-
- grpc_slice interned1 = grpc_slice_intern(src1);
- grpc_slice interned2 = grpc_slice_intern(src2);
- GPR_ASSERT(GRPC_SLICE_START_PTR(interned1) ==
- GRPC_SLICE_START_PTR(interned2));
- GPR_ASSERT(GRPC_SLICE_START_PTR(interned1) != GRPC_SLICE_START_PTR(src1));
- GPR_ASSERT(GRPC_SLICE_START_PTR(interned2) != GRPC_SLICE_START_PTR(src2));
- grpc_slice_unref(src1);
- grpc_slice_unref(src2);
- grpc_slice_unref(interned1);
- grpc_slice_unref(interned2);
- grpc_shutdown();
-}
-
-static void test_static_slice_interning(void) {
- LOG_TEST_NAME("test_static_slice_interning");
-
- // grpc_init/grpc_shutdown deliberately omitted: they should not be necessary
- // to intern a static slice
-
- for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
- GPR_ASSERT(grpc_slice_is_equivalent(
- grpc_core::g_static_metadata_slice_table[i],
- grpc_slice_intern(grpc_core::g_static_metadata_slice_table[i])));
- }
-}
-
-static void test_static_slice_copy_interning(void) {
- LOG_TEST_NAME("test_static_slice_copy_interning");
-
- grpc_init();
-
- for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
- grpc_slice copy =
- grpc_slice_dup(grpc_core::g_static_metadata_slice_table[i]);
- GPR_ASSERT(grpc_core::g_static_metadata_slice_table[i].refcount !=
- copy.refcount);
- GPR_ASSERT(grpc_core::g_static_metadata_slice_table[i].refcount ==
- grpc_slice_intern(copy).refcount);
- grpc_slice_unref(copy);
- }
-
- grpc_shutdown();
+ grpc_slice_unref_internal(slice);
}
static void test_moved_string_slice(void) {
LOG_TEST_NAME("test_moved_string_slice");
- grpc_init();
-
// Small string should be inlined.
constexpr char kSmallStr[] = "hello12345";
char* small_ptr = strdup(kSmallStr);
@@ -306,7 +245,7 @@ static void test_moved_string_slice(void) {
GPR_ASSERT(GRPC_SLICE_LENGTH(small) == strlen(kSmallStr));
GPR_ASSERT(GRPC_SLICE_START_PTR(small) !=
reinterpret_cast(small_ptr));
- grpc_slice_unref(small);
+ grpc_slice_unref_internal(small);
// Large string should be move the reference.
constexpr char kSLargeStr[] = "hello123456789123456789123456789";
@@ -316,7 +255,7 @@ static void test_moved_string_slice(void) {
GPR_ASSERT(GRPC_SLICE_LENGTH(large) == strlen(kSLargeStr));
GPR_ASSERT(GRPC_SLICE_START_PTR(large) ==
reinterpret_cast(large_ptr));
- grpc_slice_unref(large);
+ grpc_slice_unref_internal(large);
// Moved buffer must respect the provided length not the actual length of the
// string.
@@ -326,9 +265,7 @@ static void test_moved_string_slice(void) {
GPR_ASSERT(GRPC_SLICE_LENGTH(small) == strlen(kSmallStr));
GPR_ASSERT(GRPC_SLICE_START_PTR(small) !=
reinterpret_cast(large_ptr));
- grpc_slice_unref(small);
-
- grpc_shutdown();
+ grpc_slice_unref_internal(small);
}
void test_string_view_from_slice() {
@@ -338,10 +275,8 @@ void test_string_view_from_slice() {
GPR_ASSERT(std::string(sv) == kStr);
}
-int main(int argc, char** argv) {
+int main(int, char**) {
unsigned length;
- grpc::testing::TestEnvironment env(argc, argv);
- grpc_init();
test_slice_malloc_returns_something_sensible();
test_slice_new_returns_something_sensible();
test_slice_new_with_user_data();
@@ -352,11 +287,7 @@ int main(int argc, char** argv) {
test_slice_split_tail_works(length);
}
test_slice_from_copied_string_works();
- test_slice_interning();
- test_static_slice_interning();
- test_static_slice_copy_interning();
test_moved_string_slice();
test_string_view_from_slice();
- grpc_shutdown();
return 0;
}
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 71260cd3b72..ee9d1290472 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -2106,6 +2106,8 @@ src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_refcount.cc \
src/core/lib/slice/slice_refcount.h \
src/core/lib/slice/slice_refcount_base.h \
+src/core/lib/slice/slice_split.cc \
+src/core/lib/slice/slice_split.h \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/slice_string_helpers.h \
src/core/lib/slice/slice_utils.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 6c05ee3ed40..ed1e199a887 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1946,6 +1946,8 @@ src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_refcount.cc \
src/core/lib/slice/slice_refcount.h \
src/core/lib/slice/slice_refcount_base.h \
+src/core/lib/slice/slice_split.cc \
+src/core/lib/slice/slice_split.h \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/slice_string_helpers.h \
src/core/lib/slice/slice_utils.h \
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 04f4633ac49..d72d3623073 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -2375,6 +2375,54 @@
],
"uses_polling": false
},
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": false,
+ "language": "c",
+ "name": "slice_intern_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": false,
+ "language": "c",
+ "name": "slice_split_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
{
"args": [],
"benchmark": false,