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,