diff --git a/kiwano-network/src/HttpClient.cpp b/kiwano-network/src/HttpClient.cpp index 43cdf686..b14cac9d 100644 --- a/kiwano-network/src/HttpClient.cpp +++ b/kiwano-network/src/HttpClient.cpp @@ -32,7 +32,7 @@ namespace size_t write_data(void* buffer, size_t size, size_t nmemb, void* userp) { - std::string* recv_buffer = (std::string*)userp; + kiwano::string* recv_buffer = (kiwano::string*)userp; size_t total = size * nmemb; // add data to the end of recv_buffer @@ -42,10 +42,10 @@ namespace return total; } - std::string convert_to_utf8(String const& str) + kiwano::string convert_to_utf8(kiwano::wstring const& str) { std::wstring_convert> utf8_conv; - std::string result; + kiwano::string result; try { @@ -54,15 +54,15 @@ namespace catch (std::range_error&) { // bad conversion - result = str.to_string(); + result = wide_to_string(str); } return result; } - String convert_from_utf8(std::string const& str) + kiwano::wstring convert_from_utf8(kiwano::string const& str) { - std::wstring_convert> utf8_conv; - String result; + kiwano::string_convert> utf8_conv; + kiwano::wstring result; try { @@ -71,7 +71,7 @@ namespace catch (std::range_error&) { // bad conversion - result = str; + result = string_to_wide(str); } return result; } @@ -100,7 +100,7 @@ namespace } } - bool Init(HttpClient* client, Array const& headers, std::string const& url, std::string* response_data, std::string* response_header, char* error_buffer) + bool Init(HttpClient* client, Array const& headers, kiwano::string const& url, kiwano::string* response_data, kiwano::string* response_header, char* error_buffer) { if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) return false; @@ -109,7 +109,7 @@ namespace if (!SetOption(CURLOPT_CONNECTTIMEOUT, client->GetTimeoutForConnect())) return false; - const auto ssl_ca_file = client->GetSSLVerification().to_string(); + const auto ssl_ca_file = wide_to_string(client->GetSSLVerification()); if (ssl_ca_file.empty()) { if (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L)) return false; @@ -166,11 +166,11 @@ namespace public: static inline bool GetRequest( HttpClient* client, - Array const& headers, - std::string const& url, + Array const& headers, + kiwano::string const& url, long* response_code, - std::string* response_data, - std::string* response_header, + kiwano::string* response_data, + kiwano::string* response_header, char* error_buffer) { Curl curl; @@ -181,12 +181,12 @@ namespace static inline bool PostRequest( HttpClient* client, - Array const& headers, - std::string const& url, - std::string const& request_data, + Array const& headers, + kiwano::string const& url, + kiwano::string const& request_data, long* response_code, - std::string* response_data, - std::string* response_header, + kiwano::string* response_data, + kiwano::string* response_header, char* error_buffer) { Curl curl; @@ -199,12 +199,12 @@ namespace static inline bool PutRequest( HttpClient* client, - Array const& headers, - std::string const& url, - std::string const& request_data, + Array const& headers, + kiwano::string const& url, + kiwano::string const& request_data, long* response_code, - std::string* response_data, - std::string* response_header, + kiwano::string* response_data, + kiwano::string* response_header, char* error_buffer) { Curl curl; @@ -217,11 +217,11 @@ namespace static inline bool DeleteRequest( HttpClient* client, - Array const& headers, - std::string const& url, + Array const& headers, + kiwano::string const& url, long* response_code, - std::string* response_data, - std::string* response_header, + kiwano::string* response_data, + kiwano::string* response_header, char* error_buffer) { Curl curl; @@ -303,17 +303,17 @@ namespace kiwano bool ok = false; long response_code = 0; char error_message[256] = { 0 }; - std::string response_header; - std::string response_data; + kiwano::string response_header; + kiwano::string response_data; - std::string url = convert_to_utf8(request->GetUrl()); - std::string data = convert_to_utf8(request->GetData()); + kiwano::string url = convert_to_utf8(request->GetUrl()); + kiwano::string data = convert_to_utf8(request->GetData()); - Array headers; + Array headers; headers.reserve(request->GetHeaders().size()); for (const auto& pair : request->GetHeaders()) { - headers.push_back(pair.first.to_string() + ":" + pair.second.to_string()); + headers.push_back(wide_to_string(pair.first) + ":" + wide_to_string(pair.second)); } switch (request->GetType()) @@ -336,12 +336,12 @@ namespace kiwano } response->SetResponseCode(response_code); - response->SetHeader(response_header); + response->SetHeader(string_to_wide(response_header)); response->SetData(convert_from_utf8(response_data)); if (!ok) { response->SetSucceed(false); - response->SetError(error_message); + response->SetError(string_to_wide(error_message)); } else { diff --git a/kiwano/common/String.h b/kiwano/common/String.h index 10b53297..bb1d42ca 100644 --- a/kiwano/common/String.h +++ b/kiwano/common/String.h @@ -109,8 +109,8 @@ namespace kiwano using const_iterator = iterator_impl; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - using char_traits = std::char_traits; - using allocator = std::allocator; + using traits_type = std::char_traits; + using allocator_type = std::allocator; basic_string(); basic_string(const char_type* cstr, bool const_str = true); @@ -144,31 +144,31 @@ namespace kiwano basic_string& append(size_type count, char_type ch); basic_string& append(const char_type* cstr, size_type count); basic_string& append(basic_string const& other, size_type pos, size_type count = npos); - inline basic_string& append(const char_type* cstr) { return append(cstr, char_traits::length(cstr)); } + inline basic_string& append(const char_type* cstr) { return append(cstr, traits_type::length(cstr)); } inline basic_string& append(basic_string const& other) { return append(other.const_str_, 0, npos); } inline basic_string& append(std::basic_string const& other) { return append(other.c_str()); } size_type find(const char_type ch, size_type offset = 0) const; size_type find(const char_type* const str, size_type offset, size_type count) const; inline size_type find(basic_string const& str, size_type offset = 0) const { return find(str.c_str(), offset, str.size()); } - inline size_type find(const char_type* const str, size_type offset = 0) const { return find(str, offset, char_traits::length(str)); } + inline size_type find(const char_type* const str, size_type offset = 0) const { return find(str, offset, traits_type::length(str)); } size_type find_first_of(const char_type* const str, size_type offset, size_type count) const; inline size_type find_first_of(const char_type ch, size_type offset = 0) const { return find(ch, offset); } inline size_type find_first_of(basic_string const& str, size_type offset = 0) const { return find_first_of(str.c_str(), offset, str.size()); } - inline size_type find_first_of(const char_type* const str, size_type offset = 0) const { return find_first_of(str, offset, char_traits::length(str)); } + inline size_type find_first_of(const char_type* const str, size_type offset = 0) const { return find_first_of(str, offset, traits_type::length(str)); } size_type find_last_of(const char_type ch, size_type pos = npos) const; size_type find_last_of(const char_type* const str, size_type pos, size_type count) const; inline size_type find_last_of(basic_string const& str, size_type pos = npos) const { return find_first_of(str.c_str(), pos, str.size()); } - inline size_type find_last_of(const char_type* const str, size_type pos = npos) const { return find_first_of(str, pos, char_traits::length(str)); } + inline size_type find_last_of(const char_type* const str, size_type pos = npos) const { return find_first_of(str, pos, traits_type::length(str)); } basic_string& replace(size_type pos, size_type count, const char_type* cstr, size_type count2); basic_string& replace(size_type pos, size_type count, size_type count2, const char_type ch); inline basic_string& replace(size_type pos, size_type count, const basic_string& str) { return replace(pos, count, str.c_str(), str.size()); } - inline basic_string& replace(size_type pos, size_type count, const char_type* cstr) { return replace(pos, count, cstr, char_traits::length(cstr)); } + inline basic_string& replace(size_type pos, size_type count, const char_type* cstr) { return replace(pos, count, cstr, traits_type::length(cstr)); } inline basic_string& replace(const_iterator first, const_iterator last, const basic_string& str) { return replace(first, last, str.c_str(), str.size()); } - inline basic_string& replace(const_iterator first, const_iterator last, const char_type* cstr) { return replace(first, last, cstr, char_traits::length(cstr)); } + inline basic_string& replace(const_iterator first, const_iterator last, const char_type* cstr) { return replace(first, last, cstr, traits_type::length(cstr)); } inline basic_string& replace(const_iterator first, const_iterator last, const char_type* cstr, size_type count) { return replace(first - cbegin(), last - first, cstr, count); } inline basic_string& replace(const_iterator first, const_iterator last, size_type count2, const char_type ch) { return replace(first - cbegin(), last - first, count2, ch); } @@ -191,7 +191,7 @@ namespace kiwano basic_string& insert(size_type index, size_type count, char_type ch); basic_string& insert(size_type index, const char_type* s, size_type count); basic_string& insert(size_type index, const basic_string& str, size_type off, size_type count = npos); - inline basic_string& insert(size_type index, const char_type* s) { return insert(index, s, char_traits::length(s)); } + inline basic_string& insert(size_type index, const char_type* s) { return insert(index, s, traits_type::length(s)); } inline basic_string& insert(size_type index, const basic_string& str) { return insert(index, str, 0, str.size()); } inline iterator insert(const_iterator pos, size_type count, char_type ch) { size_type off = pos - cbegin(); insert(off, count, ch); return begin().base() + off; } inline iterator insert(const_iterator pos, char_type ch) { return insert(pos, 1, ch); } @@ -259,9 +259,9 @@ namespace kiwano static const size_type npos; static const char_type empty_cstr[1]; - static inline allocator& get_allocator() + static inline allocator_type& get_allocator() { - static allocator allocator_; + static allocator_type allocator_; return allocator_; } @@ -294,9 +294,9 @@ namespace kiwano for (size_type index = 0; first != last; ++first, ++index) { - char_traits::assign(str_[index], char_traits::to_char_type(*first)); + traits_type::assign(str_[index], traits_type::to_char_type(*first)); } - char_traits::assign(str_[size_], value_type()); + traits_type::assign(str_[size_], value_type()); } private: @@ -330,7 +330,7 @@ namespace kiwano // template - inline bool operator==(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) == 0; } + inline bool operator==(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) == 0; } template inline bool operator==(const typename basic_string<_CharTy>::char_type* lhs, basic_string<_CharTy> const& rhs) { return rhs.compare(lhs) == 0; } @@ -343,7 +343,7 @@ namespace kiwano // template - inline bool operator!=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) != 0; } + inline bool operator!=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) != 0; } template inline bool operator!=(const typename basic_string<_CharTy>::char_type* lhs, basic_string<_CharTy> const& rhs) { return rhs.compare(lhs) != 0; } @@ -356,7 +356,7 @@ namespace kiwano // template - inline basic_string<_CharTy> operator+(const typename basic_string<_CharTy>::char_type* lhs, basic_string<_CharTy> const& rhs) { return basic_string{ lhs } + rhs; } + inline basic_string<_CharTy> operator+(const typename basic_string<_CharTy>::char_type* lhs, basic_string<_CharTy> const& rhs) { return basic_string<_CharTy>{ lhs } + rhs; } // // operator<> for basic_string @@ -369,10 +369,10 @@ namespace kiwano inline bool operator>(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) > 0; } template - inline bool operator<=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) <= 0; } + inline bool operator<=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) <= 0; } template - inline bool operator>=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) >= 0; } + inline bool operator>=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> const& rhs) { return lhs.compare(rhs) >= 0; } // // operator<<>> for basic_string @@ -509,12 +509,12 @@ namespace kiwano if (operable_) { - assign(cstr, char_traits::length(cstr)); + assign(cstr, traits_type::length(cstr)); } else { const_str_ = cstr; - size_ = char_traits::length(cstr); + size_ = traits_type::length(cstr); capacity_ = size_; } } @@ -548,7 +548,7 @@ namespace kiwano template inline basic_string<_CharTy>::basic_string(std::basic_string const& str) - : String(str.c_str(), false) + : basic_string(str.c_str(), false) { } @@ -584,8 +584,8 @@ namespace kiwano } size_ = count; - char_traits::assign(str_, size_, ch); - char_traits::assign(str_[size_], value_type()); + traits_type::assign(str_, size_, ch); + traits_type::assign(str_[size_], value_type()); } else { @@ -609,8 +609,8 @@ namespace kiwano } size_ = count; - char_traits::move(str_, cstr, size_); - char_traits::assign(str_[size_], value_type()); + traits_type::move(str_, cstr, size_); + traits_type::assign(str_[size_], value_type()); } else { @@ -640,8 +640,8 @@ namespace kiwano } size_ = count; - char_traits::move(str_, rhs.begin().base() + pos, size_); - char_traits::assign(str_[size_], value_type()); + traits_type::move(str_, rhs.begin().base() + pos, size_); + traits_type::assign(str_[size_], value_type()); return (*this); } @@ -664,7 +664,7 @@ namespace kiwano size_type new_size = size_ - count; iterator erase_at = begin().base() + offset; - char_traits::move(erase_at.base(), erase_at.base() + count, new_size - offset + 1); + traits_type::move(erase_at.base(), erase_at.base() + count, new_size - offset + 1); return (*this); } @@ -692,9 +692,9 @@ namespace kiwano char_type* new_ptr = allocate(capacity_ + 1); char_type* const insert_at = new_ptr + index; - char_traits::move(new_ptr, old_ptr, index); // (0) - (index) - char_traits::assign(insert_at, count, ch); // (index) - (index + count) - char_traits::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) + traits_type::move(new_ptr, old_ptr, index); // (0) - (index) + traits_type::assign(insert_at, count, ch); // (index) - (index + count) + traits_type::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) deallocate(str_, old_capacity + 1); str_ = new_ptr; @@ -702,8 +702,8 @@ namespace kiwano else { char_type* const insert_at = old_ptr + index; - char_traits::move(insert_at + count, old_ptr + index, suffix_size); - char_traits::assign(insert_at, count, ch); + traits_type::move(insert_at + count, old_ptr + index, suffix_size); + traits_type::assign(insert_at, count, ch); } return (*this); @@ -733,9 +733,9 @@ namespace kiwano char_type* new_ptr = allocate(capacity_ + 1); char_type* const insert_at = new_ptr + index; - char_traits::move(new_ptr, old_ptr, index); // (0) - (index) - char_traits::move(insert_at, cstr, count); // (index) - (index + count) - char_traits::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) + traits_type::move(new_ptr, old_ptr, index); // (0) - (index) + traits_type::move(insert_at, cstr, count); // (index) - (index + count) + traits_type::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) deallocate(str_, old_capacity + 1); str_ = new_ptr; @@ -743,8 +743,8 @@ namespace kiwano else { char_type* const insert_at = old_ptr + index; - char_traits::move(insert_at + count, old_ptr + index, suffix_size); - char_traits::move(insert_at, cstr, count); + traits_type::move(insert_at + count, old_ptr + index, suffix_size); + traits_type::move(insert_at, cstr, count); } return (*this); @@ -776,9 +776,9 @@ namespace kiwano char_type* new_ptr = allocate(capacity_ + 1); char_type* const insert_at = new_ptr + index; - char_traits::move(new_ptr, old_ptr, index); // (0) - (index) - char_traits::move(insert_at, str.begin().base() + off, count); // (index) - (index + count) - char_traits::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) + traits_type::move(new_ptr, old_ptr, index); // (0) - (index) + traits_type::move(insert_at, str.begin().base() + off, count); // (index) - (index + count) + traits_type::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) deallocate(str_, old_capacity + 1); str_ = new_ptr; @@ -786,8 +786,8 @@ namespace kiwano else { char_type* const insert_at = old_ptr + index; - char_traits::move(insert_at + count, old_ptr + index, suffix_size); - char_traits::move(insert_at, str.begin().base() + off, count); + traits_type::move(insert_at + count, old_ptr + index, suffix_size); + traits_type::move(insert_at, str.begin().base() + off, count); } return (*this); @@ -802,9 +802,9 @@ namespace kiwano size_t new_cap = new_size + 1; char_type* new_str = allocate(new_cap); - char_traits::move(new_str, str_, size_); - char_traits::assign(new_str + size_, count, ch); - char_traits::assign(new_str[new_size], value_type()); + traits_type::move(new_str, str_, size_); + traits_type::assign(new_str + size_, count, ch); + traits_type::assign(new_str[new_size], value_type()); destroy(); @@ -823,9 +823,9 @@ namespace kiwano size_t new_cap = new_size + 1; char_type* new_str = allocate(new_cap); - char_traits::move(new_str, str_, size_); - char_traits::move(new_str + size_, cstr, count); - char_traits::assign(new_str[new_size], value_type()); + traits_type::move(new_str, str_, size_); + traits_type::move(new_str + size_, cstr, count); + traits_type::assign(new_str[new_size], value_type()); destroy(); @@ -849,9 +849,9 @@ namespace kiwano size_t new_cap = new_size + 1; char_type* new_str = allocate(new_cap); - char_traits::move(new_str, str_, size_); - char_traits::move(new_str + size_, other.begin().base() + pos, count); - char_traits::assign(new_str[new_size], value_type()); + traits_type::move(new_str, str_, size_); + traits_type::move(new_str + size_, other.begin().base() + pos, count); + traits_type::assign(new_str[new_size], value_type()); destroy(); @@ -870,7 +870,7 @@ namespace kiwano check_operability(); char_type* new_str = allocate(new_cap); - char_traits::move(new_str, str_, capacity_); + traits_type::move(new_str, str_, capacity_); destroy(); @@ -896,10 +896,10 @@ namespace kiwano inline int basic_string<_CharTy>::compare(const char_type * const str) const { size_type count1 = size(); - size_type count2 = char_traits::length(str); + size_type count2 = traits_type::length(str); size_type rlen = std::min(count1, count2); - int ret = char_traits::compare(const_str_, str, rlen); + int ret = traits_type::compare(const_str_, str, rlen); if (ret != 0) return ret; @@ -918,7 +918,7 @@ namespace kiwano if (offset >= size_) return basic_string<_CharTy>::npos; - const_iterator citer = char_traits::find(cbegin().base() + offset, size_, ch); + const_iterator citer = traits_type::find(cbegin().base() + offset, size_, ch); return citer ? (citer - cbegin()) : basic_string<_CharTy>::npos; } @@ -927,7 +927,7 @@ namespace kiwano { if (offset >= size_) return basic_string<_CharTy>::npos; - return __string_details::TraitsFind::char_traits>(const_str_, size_, offset, str, count); + return __string_details::TraitsFind::traits_type>(const_str_, size_, offset, str, count); } template @@ -956,7 +956,7 @@ namespace kiwano if (pos == 0 || pos > size_ || pos == npos) return npos; - return __string_details::TraitsFindLastOf::char_traits>(const_str_, size_, pos, str, count); + return __string_details::TraitsFindLastOf::traits_type>(const_str_, size_, pos, str, count); } template @@ -968,7 +968,7 @@ namespace kiwano count = clamp_suffix_size(pos, count); if (count == count2) { - char_traits::move(str_ + pos, cstr, count2); + traits_type::move(str_ + pos, cstr, count2); return (*this); } @@ -985,7 +985,7 @@ namespace kiwano capacity_ = size_; new_ptr = allocate(capacity_ + 1); - char_traits::move(new_ptr, old_ptr, pos); + traits_type::move(new_ptr, old_ptr, pos); } else { @@ -993,8 +993,8 @@ namespace kiwano } char_type* const insert_at = (new_ptr ? new_ptr : old_ptr) + pos; - char_traits::move(insert_at, cstr, count2); - char_traits::move(insert_at + count2, old_ptr + count, suffix_size); + traits_type::move(insert_at, cstr, count2); + traits_type::move(insert_at + count2, old_ptr + count, suffix_size); if (new_ptr) { @@ -1014,7 +1014,7 @@ namespace kiwano count = clamp_suffix_size(pos, count); if (count == count2) { - char_traits::assign(str_ + pos, count2, ch); + traits_type::assign(str_ + pos, count2, ch); return (*this); } @@ -1031,7 +1031,7 @@ namespace kiwano capacity_ = size_; new_ptr = allocate(capacity_ + 1); - char_traits::move(new_ptr, old_ptr, pos); + traits_type::move(new_ptr, old_ptr, pos); } else { @@ -1039,8 +1039,8 @@ namespace kiwano } char_type* const insert_at = (new_ptr ? new_ptr : old_ptr) + pos; - char_traits::assign(insert_at, count2, ch); - char_traits::move(insert_at + count2, old_ptr + count, suffix_size); + traits_type::assign(insert_at, count2, ch); + traits_type::move(insert_at + count2, old_ptr + count, suffix_size); if (new_ptr) { @@ -1060,7 +1060,7 @@ namespace kiwano check_offset(pos); count = clamp_suffix_size(pos, count); - char_traits::move(cstr, cbegin().base() + pos, count); + traits_type::move(cstr, cbegin().base() + pos, count); return count; } @@ -1173,9 +1173,9 @@ namespace kiwano template inline std::basic_ostream::char_type>& operator<<(std::basic_ostream::char_type>& os, const basic_string<_CharTy>& str) { - using ostream = std::basic_ostream::char_type, typename basic_string<_CharTy>::char_traits>; + using ostream = std::basic_ostream::char_type, typename basic_string<_CharTy>::traits_type>; using size_type = typename basic_string<_CharTy>::size_type; - using traits = typename basic_string<_CharTy>::char_traits; + using traits = typename basic_string<_CharTy>::traits_type; const ostream::sentry ok(os); std::ios_base::iostate state = std::ios_base::goodbit; @@ -1235,9 +1235,9 @@ namespace kiwano inline std::basic_istream::char_type>& operator>>(std::basic_istream::char_type>& is, basic_string<_CharTy>& str) { using ctype = std::ctype::char_type>; - using istream = std::basic_istream::char_type, typename basic_string<_CharTy>::char_traits>; + using istream = std::basic_istream::char_type, typename basic_string<_CharTy>::traits_type>; using size_type = typename basic_string<_CharTy>::size_type; - using traits = typename basic_string<_CharTy>::char_traits; + using traits = typename basic_string<_CharTy>::traits_type; bool changed = false; const istream::sentry ok(is); @@ -1419,7 +1419,7 @@ namespace kiwano { static_assert(std::is_integral<_Ty>::value, "_Ty must be integral"); - using _Elem = typename basic_string::char_traits::char_type; + using _Elem = typename basic_string::traits_type::char_type; _Elem buffer[21]; _Elem* const buffer_end = std::end(buffer); @@ -1437,7 +1437,7 @@ namespace kiwano { static_assert(std::is_integral<_Ty>::value, "_Ty must be integral"); - using _Elem = typename basic_string::char_traits::char_type; + using _Elem = typename basic_string::traits_type::char_type; _Elem buffer[21]; _Elem* const buffer_end = std::end(buffer); @@ -1489,36 +1489,208 @@ namespace kiwano namespace kiwano { - namespace __string_details + template + class string_convert { - class chs_codecvt - : public std::codecvt_byname + enum { BUFFER_INCREASE = 8, BUFFER_MAX = 16 }; + + public: + using byte_string = kiwano::basic_string; + using wide_string = kiwano::basic_string<_Elem>; + using codecvt_type = _Codecvt; + using state_type = typename codecvt_type::state_type; + using int_type = typename wide_string::traits_type::int_type; + + string_convert() + : string_convert(new codecvt_type) { - public: - chs_codecvt() : codecvt_byname("chs") {} + } - static inline std::wstring string_to_wide(std::string const& str) - { - std::wstring_convert conv; - return conv.from_bytes(str); - } + explicit string_convert(const codecvt_type* cvt) + : state_{} + , cvt_(cvt) + , loc_() + , conv_num_(0) + { + loc_ = std::locale(loc_, cvt_); + } - static inline std::string wide_to_string(std::wstring const& str) + virtual ~string_convert() { } + + size_t converted() const noexcept { return conv_num_; } + + state_type state() const { return state_; } + + wide_string from_bytes(char _Byte) + { + return from_bytes(&_Byte, &_Byte + 1); + } + + wide_string from_bytes(const char* ptr) + { + return from_bytes(ptr, ptr + std::strlen(ptr)); + } + + wide_string from_bytes(const byte_string& byte_str) + { + const char* ptr = byte_str.c_str(); + return from_bytes(ptr, ptr + byte_str.size()); + } + + wide_string from_bytes(const char* first, const char* last) + { + wide_string wbuf, wstr; + const char* first_save = first; + + state_ = state_type{}; + + wbuf.append((std::size_t) BUFFER_INCREASE, (_Elem) '\0'); + for (conv_num_ = 0; first != last; conv_num_ = static_cast(first - first_save)) { - std::wstring_convert conv; - return conv.to_bytes(str); + _Elem* dest = &*wbuf.begin(); + _Elem* dnext; + + switch (cvt_->in(state_, first, last, first, dest, dest + wbuf.size(), dnext)) + { + case codecvt_type::partial: + case codecvt_type::ok: + { + if (dest < dnext) + { + wstr.append(dest, static_cast(dnext - dest)); + } + else if (wbuf.size() < BUFFER_MAX) + { + wbuf.append(static_cast(BUFFER_INCREASE), '\0'); + } + else + { + throw (std::range_error("bad conversion")); + } + break; + } + + case codecvt_type::noconv: + { + // no conversion, just copy code values + for (; first != last; ++first) { + wstr.push_back((_Elem)(unsigned char)* first); + } + break; + } + + default: + throw (std::range_error("bad conversion")); + } } - }; + return wstr; + } + + byte_string to_bytes(_Elem _Char) + { + return to_bytes(&_Char, &_Char + 1); + } + + byte_string to_bytes(const _Elem* _Wptr) + { + const _Elem* _Next = _Wptr; + while ((int_type)* _Next != 0) { ++_Next; } + + return to_bytes(_Wptr, _Next); + } + + byte_string to_bytes(const wide_string& _Wstr) + { + const _Elem* _Wptr = _Wstr.c_str(); + return to_bytes(_Wptr, _Wptr + _Wstr.size()); + } + + byte_string to_bytes(const _Elem* first, const _Elem* last) + { + byte_string bbuf, bstr; + const _Elem* first_save = first; + + state_ = state_type{}; + + bbuf.append((std::size_t) BUFFER_INCREASE, '\0'); + for (conv_num_ = 0; first != last; conv_num_ = static_cast(first - first_save)) + { + char* dest = &*bbuf.begin(); + char* dnext; + + switch (cvt_->out(state_, first, last, first, dest, dest + bbuf.size(), dnext)) + { + case codecvt_type::partial: + case codecvt_type::ok: + { + if (dest < dnext) + { + bstr.append(dest, (std::size_t)(dnext - dest)); + } + else if (bbuf.size() < BUFFER_MAX) + { + bbuf.append((std::size_t) BUFFER_INCREASE, '\0'); + } + else + { + throw (std::range_error("bad conversion")); + } + break; + } + + case codecvt_type::noconv: + { + // no conversion, just copy code values + for (; first != last; ++first) { + bstr.push_back((char)(int_type)* first); + } + break; + } + + default: + throw (std::range_error("bad conversion")); + } + } + return bstr; + } + + string_convert(const string_convert&) = delete; + string_convert& operator=(const string_convert&) = delete; + + private: + const codecvt_type* cvt_; + std::locale loc_; + state_type state_; + size_t conv_num_; + }; + + class chs_codecvt + : public std::codecvt_byname + { + public: + chs_codecvt() : codecvt_byname("chs") {} + + static inline kiwano::wstring string_to_wide(kiwano::string const& str) + { + string_convert conv; + return conv.from_bytes(str); + } + + static inline kiwano::string wide_to_string(kiwano::wstring const& str) + { + string_convert conv; + return conv.to_bytes(str); + } + }; + + inline kiwano::wstring string_to_wide(kiwano::string const& str) + { + return kiwano::chs_codecvt::string_to_wide(str); } - inline ::kiwano::wstring string_to_wide(::kiwano::string const& str) + inline kiwano::string wide_to_string(kiwano::wstring const& str) { - return __string_details::chs_codecvt::string_to_wide(str.c_str()).c_str(); - } - - inline ::kiwano::string wide_to_string(::kiwano::wstring const& str) - { - return __string_details::chs_codecvt::wide_to_string(str.c_str()).c_str(); + return kiwano::chs_codecvt::wide_to_string(str); } } diff --git a/kiwano/utils/ResLoader.cpp b/kiwano/utils/ResLoader.cpp index 405dc0e0..2961f152 100644 --- a/kiwano/utils/ResLoader.cpp +++ b/kiwano/utils/ResLoader.cpp @@ -208,7 +208,7 @@ namespace kiwano return false; } - bool ResLoader::AddFrames(String const& id, Array const& images) + size_t ResLoader::AddFrames(String const& id, Array const& images) { if (images.empty()) return 0; diff --git a/kiwano/utils/ResLoader.h b/kiwano/utils/ResLoader.h index 557b990e..c96b3754 100644 --- a/kiwano/utils/ResLoader.h +++ b/kiwano/utils/ResLoader.h @@ -50,7 +50,7 @@ namespace kiwano bool AddGifImage(String const& id, GifImagePtr image); // 添加帧集合 - bool AddFrames(String const& id, Array const& images); + size_t AddFrames(String const& id, Array const& images); // 添加帧集合 size_t AddFrames(String const& id, Array const& images); diff --git a/samples/Samples/Demo5.h b/samples/Samples/Demo5.h index 63b5cddd..2fbd918e 100644 --- a/samples/Samples/Demo5.h +++ b/samples/Samples/Demo5.h @@ -87,12 +87,12 @@ public: // 创建 JSON 格式的 POST 数据 Json request_data = { - { "string", "test中文" }, - { "boolean", true }, - { "integer", 12 }, - { "float", 3.125 }, - { "array", { 1, 2, 3, 4, 4.5 } }, - { "object", { "key", "value" } }, + { L"string", L"test中文" }, + { L"boolean", true }, + { L"integer", 12 }, + { L"float", 3.125 }, + { L"array", { 1, 2, 3, 4, 4.5 } }, + { L"object", { L"key", L"value" } }, }; HttpRequestPtr request = new HttpRequest; diff --git a/samples/Samples/main.cpp b/samples/Samples/main.cpp index b8796125..c88b701d 100644 --- a/samples/Samples/main.cpp +++ b/samples/Samples/main.cpp @@ -75,7 +75,7 @@ public: scene->AddListener(Event::KeyUp, MakeClosure(this, &DemoApp::KeyPressed)); // 显示提示文字 - String intro_str = format_wstring(L"按键 1~%d 可切换示例\n", s_DemoNum); + String intro_str = String::format(L"按键 1~%d 可切换示例\n", s_DemoNum); TextPtr intro = new Text(intro_str + title); intro->SetFontSize(16.f); intro->SetPosition(10, 10);