diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/Utilities/Containers.h | 30 | ||||
| -rw-r--r-- | src/common/Utilities/Util.cpp | 24 |
2 files changed, 37 insertions, 17 deletions
diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h index c43012e6d73..212dc3994f2 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 d42997d522e..baa5e867fcf 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -18,6 +18,7 @@ #include "Util.h" #include "Common.h" +#include "Containers.h" #include "IpAddress.h" #include <utf8.h> #include <algorithm> @@ -252,18 +253,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) { @@ -278,13 +271,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) { |
