aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-12-25 01:47:24 +0100
committerShauren <shauren.trinity@gmail.com>2021-11-16 21:04:53 +0100
commit4f8fd5690355a4202e8f29eb175bb782d4417cef (patch)
tree05adf69d5aaff5438defd7550b635a3d1f98767e
parent4177030dcfae9d5a866e4d77d47d333172a3efd6 (diff)
Core/Utils: Fix Unicode handling
(cherry picked from commit 6d6077e36fe9c5cb8ea8e4f981d637e72ee87037)
-rw-r--r--src/common/Utilities/Containers.h30
-rw-r--r--src/common/Utilities/Util.cpp24
2 files changed, 37 insertions, 17 deletions
diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h
index ca4a00e4c29..cf4d31d4dc2 100644
--- a/src/common/Utilities/Containers.h
+++ b/src/common/Utilities/Containers.h
@@ -21,6 +21,8 @@
#include "Define.h"
#include "Random.h"
#include <algorithm>
+#include <exception>
+#include <iterator>
#include <utility>
#include <vector>
@@ -38,6 +40,34 @@ namespace Trinity
return std::addressof(not_ptr);
}
+ template <class T>
+ class BufferWriteGuard
+ {
+ public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = void;
+ using pointer = T*;
+ using reference = T&;
+ using difference_type = std::ptrdiff_t;
+
+ BufferWriteGuard(T* buf, size_t n) : _buf(buf), _n(n) {}
+
+ T& operator*() const { check(); return *_buf; }
+ BufferWriteGuard& operator++() { check(); ++_buf; --_n; return *this; }
+ T* operator++(int) { check(); T* b = _buf; ++_buf; --_n; return b; }
+
+ size_t size() const { return _n; }
+
+ private:
+ T* _buf;
+ size_t _n;
+ void check()
+ {
+ if (!_n)
+ throw std::out_of_range("index");
+ }
+ };
+
namespace Containers
{
// replace with std::size in C++17
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index 4a4daa33b25..36099263c03 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -17,6 +17,7 @@
#include "Util.h"
#include "Common.h"
+#include "Containers.h"
#include "IpAddress.h"
#include "StringFormat.h"
#include <utf8.h>
@@ -250,18 +251,10 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
{
try
{
- size_t len = utf8::distance(utf8str, utf8str+csize);
- if (len > wsize)
- {
- if (wsize > 0)
- wstr[0] = L'\0';
- wsize = 0;
- return false;
- }
-
- wsize = len;
- utf8::utf8to16(utf8str, utf8str+csize, wstr);
- wstr[len] = L'\0';
+ Trinity::BufferWriteGuard<wchar_t> guard(wstr, wsize);
+ guard = utf8::utf8to16(utf8str, utf8str+csize, guard);
+ wsize -= guard.size(); // remaining unused space
+ wstr[wsize] = L'\0';
}
catch (std::exception const&)
{
@@ -276,13 +269,10 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
{
+ wstr.clear();
try
{
- if (size_t len = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size()))
- {
- wstr.resize(len);
- utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]);
- }
+ utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), std::back_inserter(wstr));
}
catch (std::exception const&)
{