mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-26 02:06:01 +08:00
Add wxString::AssignFromUTF8() function
This can be used to optimize repeated conversions from UTF-8 by reusing the string buffer. See #25740.
This commit is contained in:
@@ -1745,6 +1745,20 @@ public:
|
||||
return FromImpl(std::move(utf8));
|
||||
}
|
||||
|
||||
void AssignFromUTF8Unchecked(const char *utf8, size_t len = npos)
|
||||
{
|
||||
m_impl.assign(utf8, len == npos ? strlen(utf8) : len);
|
||||
}
|
||||
void AssignFromUTF8(const char *utf8, size_t len = npos)
|
||||
{
|
||||
if ( !utf8 || !wxStringOperations::IsValidUtf8String(utf8) )
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
AssignFromUTF8Unchecked(utf8, len);
|
||||
}
|
||||
|
||||
std::string utf8_string() const { return m_impl; }
|
||||
|
||||
const wxScopedCharBuffer utf8_str() const
|
||||
@@ -1768,6 +1782,56 @@ public:
|
||||
static wxString FromUTF8Unchecked(const std::string& utf8)
|
||||
{ return FromUTF8Unchecked(utf8.c_str(), utf8.length()); }
|
||||
|
||||
void AssignFromUTF8Unchecked(const char *utf8, size_t len = npos)
|
||||
{
|
||||
if ( len == npos )
|
||||
len = strlen(utf8);
|
||||
|
||||
wxMBConvStrictUTF8 conv;
|
||||
if ( m_impl.size() > len )
|
||||
{
|
||||
// We can be sure that the conversion result fits into the
|
||||
// existing buffer, so use it directly.
|
||||
m_impl.resize(conv.ToWChar(ImplData(), m_impl.size(), utf8, len));
|
||||
}
|
||||
else
|
||||
{
|
||||
// We can't be sure that the conversion result fits into the
|
||||
// existing buffer, so compute the length we need.
|
||||
m_impl.resize(conv.ToWChar(nullptr, 0, utf8, len));
|
||||
conv.ToWChar(ImplData(), m_impl.size(), utf8, len);
|
||||
}
|
||||
}
|
||||
void AssignFromUTF8(const char *utf8, size_t len = npos)
|
||||
{
|
||||
if ( !utf8 )
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( len == npos )
|
||||
len = strlen(utf8);
|
||||
|
||||
wxMBConvStrictUTF8 conv;
|
||||
if ( m_impl.size() > len )
|
||||
{
|
||||
m_impl.resize(conv.ToWChar(ImplData(), m_impl.size(), utf8, len));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto needed = conv.ToWChar(nullptr, 0, utf8, len);
|
||||
if ( needed == wxCONV_FAILED )
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
m_impl.resize(needed);
|
||||
conv.ToWChar(ImplData(), m_impl.size(), utf8, len);
|
||||
}
|
||||
}
|
||||
|
||||
std::string utf8_string() const { return ToStdString(wxMBConvUTF8()); }
|
||||
const wxScopedCharBuffer utf8_str() const { return mb_str(wxMBConvUTF8()); }
|
||||
#endif // wxUSE_UNICODE_UTF8/wxUSE_UNICODE_WCHAR
|
||||
@@ -3656,6 +3720,14 @@ private:
|
||||
private:
|
||||
wxStringImpl m_impl;
|
||||
|
||||
// Get access to the string buffer: we assume that we can always rely on
|
||||
// C++17 semantics of data(), even when not using C++17, which seems
|
||||
// reasonable as C++17 mostly standardized existing practice.
|
||||
wxStringCharType* ImplData()
|
||||
{
|
||||
return const_cast<wxStringCharType*>(m_impl.data());
|
||||
}
|
||||
|
||||
// buffers for compatibility conversion from (char*)c_str() and
|
||||
// (wchar_t*)c_str(): the pointers returned by these functions should remain
|
||||
// valid until the string itself is modified for compatibility with the
|
||||
|
||||
@@ -527,6 +527,34 @@ public:
|
||||
*/
|
||||
wxString operator =(wxUniChar c);
|
||||
|
||||
/**
|
||||
Assignment from UTF-8 string.
|
||||
|
||||
Calling `s.AssignFromUTF8(utf8, len) is equivalent to doing
|
||||
`s = wxString::FromUTF8(utf8, len)` but may be more efficient as it can
|
||||
reuse the existing string buffer instead of always having to allocate a
|
||||
new one.
|
||||
|
||||
This function can be useful in performance-sensitive loops or with
|
||||
static variables (retaining their buffer between calls) in often called
|
||||
functions.
|
||||
|
||||
@since 3.3.2
|
||||
*/
|
||||
void AssignFromUTF8(const char *utf8, size_t len = npos);
|
||||
|
||||
/**
|
||||
Assignment from UTF-8 string.
|
||||
|
||||
This function is the same as AssignFromUTF8() but doesn't check that
|
||||
@a utf8 is a valid pointer to a valid UTF-8 string. It must not be
|
||||
called if @a utf8 is @NULL or its contents is not already known to be
|
||||
correct UTF-8.
|
||||
|
||||
@since 3.3.2
|
||||
*/
|
||||
void AssignFromUTF8Unchecked(const char *utf8, size_t len = npos);
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
@@ -2018,6 +2046,8 @@ public:
|
||||
The overload taking @c std::string_view is only available starting with
|
||||
wxWidgets 3.3.0 and requires the consumer application to use C++17.
|
||||
|
||||
@see AssignFromUTF8()
|
||||
|
||||
@since 2.8.4
|
||||
*/
|
||||
static wxString FromUTF8(const char* s);
|
||||
@@ -2046,6 +2076,8 @@ public:
|
||||
The overload taking @c std::string_view is only available starting with
|
||||
wxWidgets 3.3.0 and requires the consumer application to use C++17.
|
||||
|
||||
@see AssignFromUTF8Unchecked()
|
||||
|
||||
@since 2.8.9
|
||||
*/
|
||||
static wxString FromUTF8Unchecked(const char* s);
|
||||
|
||||
@@ -192,6 +192,22 @@ TEST_CASE("StringStaticConstructors", "[wxString]")
|
||||
//CHECK( wxString::FromUTF8("", 1).length() == 1 );
|
||||
}
|
||||
|
||||
TEST_CASE("StringAssignUTF8", "[wxString]")
|
||||
{
|
||||
wxString s;
|
||||
s.AssignFromUTF8("Oberfläche");
|
||||
CHECK( s == wxString::FromUTF8("Oberfläche") );
|
||||
|
||||
s.AssignFromUTF8("fläche");
|
||||
CHECK( s == wxString::FromUTF8("fläche") );
|
||||
|
||||
s.AssignFromUTF8("Even longer than Oberfläche");
|
||||
CHECK( s == wxString::FromUTF8("Even longer than Oberfläche") );
|
||||
|
||||
s.AssignFromUTF8(nullptr);
|
||||
CHECK( s == wxString() );
|
||||
}
|
||||
|
||||
TEST_CASE("StringExtraction", "[wxString]")
|
||||
{
|
||||
wxString s(wxT("Hello, world!"));
|
||||
|
||||
Reference in New Issue
Block a user