Previously, there was a `StringRef.copy` method which would copy the string into the given buffer. However, it was not defined for the case when the buffer was too small. It moved the responsibility of making sure the buffer is large enough to the caller. Unfortunately, in practice that easily hides bugs in builds without asserts which don't come up in testing much. Now, the method is replaced with `StringRef.copy_utf8_truncated` which has much more well defined semantics and also makes sure that the string remains valid utf-8. This also renames `unsafe_copy` to `copy_unsafe` to make the naming more similar to `copy_utf8_truncated`. Pull Request: https://projects.blender.org/blender/blender/pulls/133677
44 lines
1.1 KiB
C++
44 lines
1.1 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#include "BLI_string_ref.hh"
|
|
#include "BLI_string_utf8.h"
|
|
|
|
#include <ostream>
|
|
|
|
namespace blender {
|
|
|
|
std::ostream &operator<<(std::ostream &stream, StringRef ref)
|
|
{
|
|
stream << std::string(ref);
|
|
return stream;
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &stream, StringRefNull ref)
|
|
{
|
|
stream << std::string(ref.data(), size_t(ref.size()));
|
|
return stream;
|
|
}
|
|
|
|
void StringRefBase::copy_utf8_truncated(char *dst, const int64_t dst_size) const
|
|
{
|
|
/* Destination must at least hold the null terminator. */
|
|
BLI_assert(dst_size >= 1);
|
|
/* The current #StringRef is assumed to contain valid UTF-8. */
|
|
BLI_assert(BLI_str_utf8_invalid_byte(data_, 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 max_copy_num_without_terminator = std::min(size_, dst_size - 1);
|
|
const size_t new_len = BLI_strncpy_utf8_rlen_unterminated(
|
|
dst, data_, max_copy_num_without_terminator);
|
|
dst[new_len] = '\0';
|
|
}
|
|
|
|
} // namespace blender
|