X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b0c4d5d79272961d6b3f4037454737ee055e94e7..a66bf817a6ba833ad47cefc9fa8948ef8045a59d:/src/common/unichar.cpp?ds=sidebyside diff --git a/src/common/unichar.cpp b/src/common/unichar.cpp index b83a0817a3..645435641f 100644 --- a/src/common/unichar.cpp +++ b/src/common/unichar.cpp @@ -21,10 +21,11 @@ #ifndef WX_PRECOMP #include "wx/strconv.h" // wxConvLibc + #include "wx/log.h" #endif #include "wx/unichar.h" -#include "wx/stringops.h" +#include "wx/string.h" // =========================================================================== // implementation @@ -35,42 +36,53 @@ // --------------------------------------------------------------------------- /* static */ -wxUniChar::value_type wxUniChar::From8bit(char c) +wxUniChar::value_type wxUniChar::FromHi8bit(char c) { - // all supported charsets have the first 128 characters same as ASCII: - if ( (unsigned char)c < 0x80 ) - return c; - #if wxUSE_UTF8_LOCALE_ONLY - wxFAIL_MSG( _T("invalid UTF-8 character") ); + wxFAIL_MSG( "invalid UTF-8 character" ); + wxUnusedVar(c); + return wxT('?'); // FIXME-UTF8: what to use as failure character? #else - wchar_t buf[2]; - if ( wxConvLibc.ToWChar(buf, 2, &c, 1) != 2 ) + char cbuf[2]; + cbuf[0] = c; + cbuf[1] = '\0'; + wchar_t wbuf[2]; + if ( wxConvLibc.ToWChar(wbuf, 2, cbuf, 2) != 2 ) + { + wxFAIL_MSG( "invalid multibyte character" ); return wxT('?'); // FIXME-UTF8: what to use as failure character? - return buf[0]; + } + return wbuf[0]; #endif } /* static */ -char wxUniChar::To8bit(wxUniChar::value_type c) +char wxUniChar::ToHi8bit(wxUniChar::value_type v) { - // all supported charsets have the first 128 characters same as ASCII: - if ( c < 0x80 ) - return c; + char c; + if ( !GetAsHi8bit(v, &c) ) + { + wxFAIL_MSG( "character cannot be converted to single byte" ); + c = '?'; // FIXME-UTF8: what to use as failure character? + } -#if wxUSE_UTF8_LOCALE_ONLY - wxFAIL_MSG( _T("character cannot be converted to single UTF-8 byte") ); - return '?'; // FIXME-UTF8: what to use as failure character? -#else - wchar_t in = c; - char buf[2]; - if ( wxConvLibc.FromWChar(buf, 2, &in, 1) != 2 ) - return '?'; // FIXME-UTF8: what to use as failure character? - return buf[0]; -#endif + return c; } +/* static */ +bool wxUniChar::GetAsHi8bit(value_type v, char *c) +{ + wchar_t wbuf[2]; + wbuf[0] = v; + wbuf[1] = L'\0'; + char cbuf[2]; + if ( wxConvLibc.FromWChar(cbuf, 2, wbuf, 2) != 2 ) + return false; + + *c = cbuf[0]; + return true; +} // --------------------------------------------------------------------------- // wxUniCharRef @@ -97,14 +109,13 @@ wxUniCharRef& wxUniCharRef::operator=(const wxUniChar& c) for ( size_t i = 0; i < lenNew; ++i, ++pos ) *pos = utf[i]; } - else + else // length of character encoding in UTF-8 changed { // the worse case is when the new value has either longer or shorter // code -- in that case, we have to use wxStringImpl::replace() and // this invalidates all iterators, so we have to update them too: - wxString& str = *wx_const_cast(wxString*, m_node.m_str); - wxStringImpl& strimpl = str.m_impl; + wxStringImpl& strimpl = m_str.m_impl; int iterDiff = lenNew - lenOld; size_t posIdx = m_pos - strimpl.begin(); @@ -118,13 +129,13 @@ wxUniCharRef& wxUniCharRef::operator=(const wxUniChar& c) size_t *indexes = indexes_a; size_t iterNum = 0; wxStringIteratorNode *it; - for ( it = str.m_iterators.ptr; it; it = it->m_next, ++iterNum ) + for ( it = m_str.m_iterators.ptr; it; it = it->m_next, ++iterNum ) { wxASSERT( it->m_iter || it->m_citer ); if ( iterNum == STATIC_SIZE ) { - wxLogTrace( _T("utf8"), _T("unexpectedly many iterators") ); + wxLogTrace( wxT("utf8"), wxT("unexpectedly many iterators") ); size_t total = iterNum + 1; for ( wxStringIteratorNode *it2 = it; it2; it2 = it2->m_next ) @@ -146,10 +157,14 @@ wxUniCharRef& wxUniCharRef::operator=(const wxUniChar& c) // update the string: strimpl.replace(m_pos, m_pos + lenOld, utf, lenNew); +#if wxUSE_STRING_POS_CACHE + m_str.InvalidateCache(); +#endif // wxUSE_STRING_POS_CACHE + // finally, set the iterators to valid values again (note that this // updates m_pos as well): size_t i; - for ( i = 0, it = str.m_iterators.ptr; it; it = it->m_next, ++i ) + for ( i = 0, it = m_str.m_iterators.ptr; it; it = it->m_next, ++i ) { wxASSERT( i < iterNum ); wxASSERT( it->m_iter || it->m_citer );