Skip to content

Commit b41e64b

Browse files
committed
Add null_safe_string_view(const char*, std::size_t)
[why] There are use cases for constructing a string_view with a specified size that is still protected against null pointers. This is different from safe_string_view(const char*, std::size_t) which terminates the string at a null byte. Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
1 parent 32041ec commit b41e64b

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

include/gul17/string_util.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,30 @@ std::string null_safe_string(const char* char_ptr);
265265
GUL_EXPORT
266266
std::string_view null_safe_string_view(const char* char_ptr);
267267

268+
/**
269+
* Safely construct a string_view from a char pointer and a length.
270+
*
271+
* If the pointer is null, an empty string_view is constructed. Otherwise, the function
272+
* constructs a std::string_view with the specified length from it. Zero bytes in the
273+
* input range do not terminate the string_view.
274+
*
275+
* \code
276+
* auto a = null_safe_string_view(nullptr, 10); // a == ""sv
277+
* auto b = null_safe_string_view("ABC", 4); // b == "ABC\0"sv
278+
* auto c = null_safe_string_view("AB\0CD", 4); // c == "AB\0C"sv
279+
* \endcode
280+
*
281+
* \param char_ptr Pointer to a string with at least \c length accessible bytes, or a
282+
* null pointer
283+
* \param length Length of the generated string_view (unless the pointer is null)
284+
*
285+
* \see safe_string_view(), null_safe_string()
286+
*
287+
* \since version UNRELEASED
288+
*/
289+
GUL_EXPORT
290+
std::string_view null_safe_string_view(const char* char_ptr, std::size_t length);
291+
268292
/**
269293
* Repeat a string N times.
270294
* \code

src/string_util.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ std::string_view null_safe_string_view(const char* char_ptr)
5050
return result;
5151
}
5252

53+
std::string_view null_safe_string_view(const char* char_ptr, std::size_t length)
54+
{
55+
std::string_view result;
56+
57+
if (char_ptr)
58+
result = std::string_view(char_ptr, length);
59+
60+
return result;
61+
}
62+
5363
std::string repeat(std::string_view str, std::size_t n)
5464
{
5565
std::string result;

tests/test_string_util.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,20 @@ TEST_CASE("null_safe_string_view(const char*)", "[string_util]")
134134
REQUIRE(null_safe_string_view("hi\0there") == "hi"sv);
135135
}
136136

137+
TEST_CASE("null_safe_string_view(const char*, std::size_t)", "[string_util]")
138+
{
139+
using gul17::null_safe_string_view;
140+
141+
REQUIRE(null_safe_string_view(nullptr, 0ull) == std::string_view{});
142+
REQUIRE(null_safe_string_view(nullptr, 10ull) == std::string_view{});
143+
REQUIRE(null_safe_string_view("", 0ull) == ""sv);
144+
REQUIRE(null_safe_string_view("", 1ull) == "\0"sv);
145+
REQUIRE(null_safe_string_view("hello", 5ull) == "hello"sv);
146+
REQUIRE(null_safe_string_view("hello", 2ull) == "he"sv);
147+
REQUIRE(null_safe_string_view("hi\0there", 2ull) == "hi"sv);
148+
REQUIRE(null_safe_string_view("hi\0there", 4ull) == "hi\0t"sv);
149+
}
150+
137151
TEST_CASE("repeat()", "[string_util]")
138152
{
139153
REQUIRE(repeat("du", 3) == "dududu");

0 commit comments

Comments
 (0)