BLI_string_ref: add copy_bytes_truncated method
Needed to copy non UTF8 bytes into a null terminated string. Ref !144052
This commit is contained in:
@@ -77,6 +77,17 @@ class StringRefBase {
|
||||
void copy_utf8_truncated(char *dst, int64_t dst_size) const;
|
||||
template<size_t N> void copy_utf8_truncated(char (&dst)[N]) const;
|
||||
|
||||
/**
|
||||
* Copy the string into a char array. The copied string will be null-terminated. If it does not
|
||||
* fit, it will be truncated.
|
||||
*
|
||||
* \note #copy_utf8_truncated should be used UTF8 strings,
|
||||
* this should be used for strings which are allowed to contain arbitrary
|
||||
* byte sequences without a known encoding such as file-paths.
|
||||
*/
|
||||
void copy_bytes_truncated(char *dst, int64_t dst_size) const;
|
||||
template<size_t N> void copy_bytes_truncated(char (&dst)[N]) const;
|
||||
|
||||
/**
|
||||
* Copy the string into a buffer. The buffer has to be one byte larger than the size of the
|
||||
* string, because the copied string will be null-terminated. Only use this when you are
|
||||
@@ -231,6 +242,11 @@ template<size_t N> inline void StringRefBase::copy_utf8_truncated(char (&dst)[N]
|
||||
this->copy_utf8_truncated(dst, N);
|
||||
}
|
||||
|
||||
template<size_t N> inline void StringRefBase::copy_bytes_truncated(char (&dst)[N]) const
|
||||
{
|
||||
this->copy_bytes_truncated(dst, N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true when the string starts with the given prefix.
|
||||
*/
|
||||
|
||||
@@ -44,4 +44,20 @@ void StringRefBase::copy_utf8_truncated(char *dst, const int64_t dst_size) const
|
||||
dst[new_len] = '\0';
|
||||
}
|
||||
|
||||
void StringRefBase::copy_bytes_truncated(char *dst, const int64_t dst_size) const
|
||||
{
|
||||
/* Destination must at least hold the null terminator. */
|
||||
BLI_assert(dst_size >= 1);
|
||||
|
||||
/* Common case when the string can just be copied over entirely. */
|
||||
if (size_ < dst_size) {
|
||||
this->copy_unsafe(dst);
|
||||
return;
|
||||
}
|
||||
|
||||
const int64_t new_len = std::min(size_, dst_size - 1);
|
||||
memcpy(dst, data_, new_len);
|
||||
dst[new_len] = '\0';
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
|
||||
@@ -464,6 +464,58 @@ TEST(string_ref, CopyUtf8Truncated)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(string_ref, CopyBytesTruncated)
|
||||
{
|
||||
{
|
||||
StringRef ref("hello");
|
||||
char dst[10];
|
||||
memset(dst, 0xFF, 10);
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(dst[5], '\0');
|
||||
EXPECT_EQ(dst[6], 0xFF);
|
||||
EXPECT_EQ(ref, dst);
|
||||
}
|
||||
{
|
||||
StringRef ref("0123456789");
|
||||
char dst[4];
|
||||
memset(dst, 0xFF, 4);
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(dst[0], '0');
|
||||
EXPECT_EQ(dst[1], '1');
|
||||
EXPECT_EQ(dst[2], '2');
|
||||
EXPECT_EQ(dst[3], '\0');
|
||||
}
|
||||
{
|
||||
/* Simple 4 byte string. */
|
||||
StringRef ref("01234");
|
||||
{
|
||||
char dst[1];
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(dst[0], '\0');
|
||||
}
|
||||
{
|
||||
char dst[2];
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(dst[0], '0');
|
||||
}
|
||||
{
|
||||
char dst[3];
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(StringRef(dst), "01");
|
||||
}
|
||||
{
|
||||
char dst[4];
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(StringRef(dst), "012");
|
||||
}
|
||||
{
|
||||
char dst[5];
|
||||
ref.copy_bytes_truncated(dst);
|
||||
EXPECT_EQ(StringRef(dst), "0123");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(string_ref, FromStringView)
|
||||
{
|
||||
std::string_view view = "hello";
|
||||
|
||||
Reference in New Issue
Block a user