From b42aa969dc10493fd1989398ee5ac14f5216d71d Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 5 Jan 2024 22:37:11 +0100 Subject: [PATCH] unicode: Write directly into std::string buffer This removes extra memory allocation. Signed-off-by: Simon Rozman --- include/stdex/unicode.hpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/include/stdex/unicode.hpp b/include/stdex/unicode.hpp index fcb3c2521..538898b2c 100644 --- a/include/stdex/unicode.hpp +++ b/include/stdex/unicode.hpp @@ -207,9 +207,10 @@ namespace stdex if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Query the required output size. Allocate buffer. Then convert again. cch = MultiByteToWideChar(static_cast(m_from_wincp), dwFlagsMBWC, reinterpret_cast(src), static_cast(count_src), NULL, 0); - std::unique_ptr szBuffer(new WCHAR[cch]); - cch = MultiByteToWideChar(static_cast(m_from_wincp), dwFlagsMBWC, reinterpret_cast(src), static_cast(count_src), szBuffer.get(), cch); - dst.append(reinterpret_cast(szBuffer.get()), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : static_cast(cch) - 1); + size_t offset = dst.size(); + dst.resize(offset + static_cast(cch)); + cch = MultiByteToWideChar(static_cast(m_from_wincp), dwFlagsMBWC, reinterpret_cast(src), static_cast(count_src), &dst[offset], cch); + dst.resize(offset + (count_src != SIZE_MAX ? wcsnlen(&dst[offset], cch) : static_cast(cch) - 1)); return; } throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed"); @@ -231,9 +232,10 @@ namespace stdex if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Query the required output size. Allocate buffer. Then convert again. cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, reinterpret_cast(src), static_cast(count_src), NULL, 0, lpDefaultChar, NULL); - std::unique_ptr szBuffer(new CHAR[cch]); - cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, reinterpret_cast(src), static_cast(count_src), szBuffer.get(), cch, lpDefaultChar, NULL); - dst.append(reinterpret_cast(szBuffer.get()), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : static_cast(cch) - 1); + size_t offset = dst.size(); + dst.resize(offset + static_cast(cch)); + cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, reinterpret_cast(src), static_cast(count_src), &dst[offset], cch, lpDefaultChar, NULL); + dst.resize(offset + (count_src != SIZE_MAX ? strnlen(&dst[offset], cch) : static_cast(cch) - 1)); return; } throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed"); @@ -264,9 +266,10 @@ namespace stdex if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Query the required output size. Allocate buffer. Then convert again. cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast(count_inter), NULL, 0, lpDefaultChar, NULL); - std::unique_ptr szBufferWCMB(new CHAR[cch]); - cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast(count_inter), szBufferWCMB.get(), cch, lpDefaultChar, NULL); - dst.append(reinterpret_cast(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch)); + size_t offset = dst.size(); + dst.resize(offset + cch); + cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast(count_inter), &dst[offset], cch, lpDefaultChar, NULL); + dst.resize(offset + strnlen(&dst[offset], cch)); return; } throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed"); @@ -280,9 +283,10 @@ namespace stdex // Query the required output size. Allocate buffer. Then convert again. cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast(count_inter), NULL, 0, lpDefaultChar, NULL); - std::unique_ptr szBufferWCMB(new CHAR[cch]); - cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast(count_inter), szBufferWCMB.get(), cch, lpDefaultChar, NULL); - dst.append(reinterpret_cast(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch)); + size_t offset = dst.size(); + dst.resize(offset + cch); + cch = WideCharToMultiByte(static_cast(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast(count_inter), &dst[offset], cch, lpDefaultChar, NULL); + dst.resize(offset + strnlen(&dst[offset], cch)); return; } throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");