#include "wx/strconv.h"
-#if wxUSE_WCHAR_T
-
#ifndef __WXWINCE__
#include <errno.h>
#endif
#endif //def __DARWIN__
-#define TRACE_STRCONV _T("strconv")
+#define TRACE_STRCONV wxT("strconv")
// WC_UTF16 is defined only if sizeof(wchar_t) == 2, otherwise it's supposed to
// be 4 bytes
{
wxUint32 out;
const size_t
- n = decode_utf16(wx_reinterpret_cast(const wxUint16 *, *pSrc), out);
+ n = decode_utf16(reinterpret_cast<const wxUint16 *>(*pSrc), out);
if ( n == wxCONV_FAILED )
*pSrc = NULL;
else
// all the complication come from the fact that this function, for
// historical reasons, must behave in 2 subtly different ways when it's
// called with a fixed number of characters and when it's called for the
- // entire NUL-terminated string: in the former case (srcEnd == NULL) we
+ // entire NUL-terminated string: in the former case (srcEnd != NULL) we
// must count all characters we convert, NUL or not; but in the latter we
// do not count the trailing NUL -- but still count all the NULs inside the
// string
if ( !srcEnd )
{
// we convert just one chunk in this case as this is the entire
- // string anyhow
+ // string anyhow (and we don't count the trailing NUL in this case)
break;
}
- // advance the input pointer past the end of this chunk
+ // advance the input pointer past the end of this chunk: notice that we
+ // will always stop before srcEnd because we know that the chunk is
+ // always properly NUL-terminated
while ( NotAllNULs(src, nulLen) )
{
// notice that we must skip over multiple bytes here as we suppose
src += nulLen;
}
- src += nulLen; // skipping over its terminator as well
+ // if the buffer ends before this NUL, we shouldn't count it in our
+ // output so skip the code below
+ if ( src == srcEnd )
+ break;
+
+ // do count this terminator as it's inside the buffer we convert
+ dstWritten++;
+ if ( dst )
+ dst++;
+
+ src += nulLen; // skip the terminator itself
- // note that ">=" (and not just "==") is needed here as the terminator
- // we skipped just above could be inside or just after the buffer
- // delimited by srcEnd
if ( src >= srcEnd )
break;
-
- // if we got here then this wasn't the last chunk in this string and
- // hence we must count an extra char for L'\0' even when converting a
- // fixed number of characters
- if ( srcEnd )
- {
- dstWritten++;
- if ( dst )
- dst++;
- }
}
return dstWritten;
const size_t lenNul = GetMBNulLen();
for ( const wchar_t * const srcEnd = src + srcLen;
src < srcEnd;
- src += wxWcslen(src) + 1 /* skip L'\0' too */ )
+ src++ /* skip L'\0' too */ )
{
// try to convert the current chunk
size_t lenChunk = WC2MB(NULL, src, 0);
-
if ( lenChunk == wxCONV_FAILED )
return wxCONV_FAILED;
dstWritten += lenChunk;
- if ( isNulTerminated )
+
+ const wchar_t * const
+ chunkEnd = isNulTerminated ? srcEnd - 1 : src + wxWcslen(src);
+
+ // our return value accounts for the trailing NUL(s), unlike that of
+ // WC2MB(), however don't do it for the last NUL we artificially added
+ // ourselves above
+ if ( chunkEnd < srcEnd )
dstWritten += lenNul;
if ( dst )
if ( dstWritten > dstLen )
return wxCONV_FAILED;
- if ( WC2MB(dst, src, lenChunk + lenNul) == wxCONV_FAILED )
+ // if we know that there is enough space in the destination buffer
+ // (because we accounted for lenNul in dstWritten above), we can
+ // convert directly in place -- but otherwise we need another
+ // temporary buffer to ensure that we don't overwrite the output
+ wxCharBuffer dstBuf;
+ char *dstTmp;
+ if ( chunkEnd == srcEnd )
+ {
+ dstBuf = wxCharBuffer(lenChunk + lenNul - 1);
+ dstTmp = dstBuf.data();
+ }
+ else
+ {
+ dstTmp = dst;
+ }
+
+ if ( WC2MB(dstTmp, src, lenChunk + lenNul) == wxCONV_FAILED )
return wxCONV_FAILED;
+ if ( dstTmp != dst )
+ {
+ // copy everything up to but excluding the terminating NUL(s)
+ // into the real output buffer
+ memcpy(dst, dstTmp, lenChunk);
+
+ // micro-optimization: if dstTmp != dst it means that chunkEnd
+ // == srcEnd and so we're done, no need to update anything below
+ break;
+ }
+
dst += lenChunk;
- if ( isNulTerminated )
+ if ( chunkEnd < srcEnd )
dst += lenNul;
}
+
+ src = chunkEnd;
}
return dstWritten;
return wxCharBuffer();
}
+const wxWCharBuffer wxMBConv::cMB2WC(const wxScopedCharBuffer& buf) const
+{
+ const size_t srcLen = buf.length();
+ if ( srcLen )
+ {
+ const size_t dstLen = ToWChar(NULL, 0, buf, srcLen);
+ if ( dstLen != wxCONV_FAILED )
+ {
+ wxWCharBuffer wbuf(dstLen);
+ wbuf.data()[dstLen] = L'\0';
+ if ( ToWChar(wbuf.data(), dstLen, buf, srcLen) != wxCONV_FAILED )
+ return wbuf;
+ }
+ }
+
+ return wxScopedWCharBuffer::CreateNonOwned(L"", 0);
+}
+
+const wxCharBuffer wxMBConv::cWC2MB(const wxScopedWCharBuffer& wbuf) const
+{
+ const size_t srcLen = wbuf.length();
+ if ( srcLen )
+ {
+ const size_t dstLen = FromWChar(NULL, 0, wbuf, srcLen);
+ if ( dstLen != wxCONV_FAILED )
+ {
+ wxCharBuffer buf(dstLen);
+ buf.data()[dstLen] = '\0';
+ if ( FromWChar(buf.data(), dstLen, wbuf, srcLen) != wxCONV_FAILED )
+ return buf;
+ }
+ }
+
+ return wxScopedCharBuffer::CreateNonOwned("", 0);
+}
+
// ----------------------------------------------------------------------------
// wxMBConvLibc
// ----------------------------------------------------------------------------
wxConvBrokenFileNames::wxConvBrokenFileNames(const wxString& charset)
{
- if ( wxStricmp(charset, _T("UTF-8")) == 0 ||
- wxStricmp(charset, _T("UTF8")) == 0 )
+ if ( wxStricmp(charset, wxT("UTF-8")) == 0 ||
+ wxStricmp(charset, wxT("UTF8")) == 0 )
m_conv = new wxMBConvUTF8(wxMBConvUTF8::MAP_INVALID_UTF8_TO_PUA);
else
m_conv = new wxCSConv(charset);
}
else // when working with partial strings we do use the shift state
{
- statePtr = wx_const_cast(DecoderState *, &m_stateDecoder);
+ statePtr = const_cast<DecoderState *>(&m_stateDecoder);
// also save the old state to be able to rollback to it on error
stateOrig = m_stateDecoder;
else // do use the mode we left the output in previously
{
stateOrig = m_stateEncoder;
- statePtr = wx_const_cast(EncoderState *, &m_stateEncoder);
+ statePtr = const_cast<EncoderState *>(&m_stateEncoder);
}
EncoderState& state = *statePtr;
}
else
{
- wxFAIL_MSG( _T("trying to encode undefined Unicode character") );
+ wxFAIL_MSG( wxT("trying to encode undefined Unicode character") );
break;
}
if ( srcLen == wxNO_LEN )
{
// count the number of bytes in input, including the trailing NULs
- const wxUint16 *inBuff = wx_reinterpret_cast(const wxUint16 *, src);
+ const wxUint16 *inBuff = reinterpret_cast<const wxUint16 *>(src);
for ( srcLen = 1; *inBuff++; srcLen++ )
;
if ( dstLen < srcLen )
return wxCONV_FAILED;
- const wxUint16 *inBuff = wx_reinterpret_cast(const wxUint16 *, src);
+ const wxUint16 *inBuff = reinterpret_cast<const wxUint16 *>(src);
for ( size_t n = 0; n < srcLen; n++, inBuff++ )
{
*dst++ = wxUINT16_SWAP_ALWAYS(*inBuff);
if ( dstLen < srcLen )
return wxCONV_FAILED;
- wxUint16 *outBuff = wx_reinterpret_cast(wxUint16 *, dst);
+ wxUint16 *outBuff = reinterpret_cast<wxUint16 *>(dst);
for ( size_t n = 0; n < srcLen; n += BYTES_PER_CHAR, src++ )
{
*outBuff++ = wxUINT16_SWAP_ALWAYS(*src);
}
size_t outLen = 0;
- const wxUint16 *inBuff = wx_reinterpret_cast(const wxUint16 *, src);
+ const wxUint16 *inBuff = reinterpret_cast<const wxUint16 *>(src);
for ( const wxUint16 * const inEnd = inBuff + inLen; inBuff < inEnd; )
{
const wxUint32 ch = wxDecodeSurrogate(&inBuff);
srcLen = wxWcslen(src) + 1;
size_t outLen = 0;
- wxUint16 *outBuff = wx_reinterpret_cast(wxUint16 *, dst);
+ wxUint16 *outBuff = reinterpret_cast<wxUint16 *>(dst);
for ( size_t n = 0; n < srcLen; n++ )
{
wxUint16 cc[2];
}
size_t outLen = 0;
- const wxUint16 *inBuff = wx_reinterpret_cast(const wxUint16 *, src);
+ const wxUint16 *inBuff = reinterpret_cast<const wxUint16 *>(src);
for ( const wxUint16 * const inEnd = inBuff + inLen; inBuff < inEnd; )
{
wxUint32 ch;
srcLen = wxWcslen(src) + 1;
size_t outLen = 0;
- wxUint16 *outBuff = wx_reinterpret_cast(wxUint16 *, dst);
+ wxUint16 *outBuff = reinterpret_cast<wxUint16 *>(dst);
for ( const wchar_t *srcEnd = src + srcLen; src < srcEnd; src++ )
{
wxUint16 cc[2];
if ( srcLen == wxNO_LEN )
{
// count the number of bytes in input, including the trailing NULs
- const wxUint32 *inBuff = wx_reinterpret_cast(const wxUint32 *, src);
+ const wxUint32 *inBuff = reinterpret_cast<const wxUint32 *>(src);
for ( srcLen = 1; *inBuff++; srcLen++ )
;
if ( srcLen == wxNO_LEN )
return wxCONV_FAILED;
- const wxUint32 *inBuff = wx_reinterpret_cast(const wxUint32 *, src);
+ const wxUint32 *inBuff = reinterpret_cast<const wxUint32 *>(src);
const size_t inLen = srcLen / BYTES_PER_CHAR;
size_t outLen = 0;
for ( size_t n = 0; n < inLen; n++ )
return srcLen * BYTES_PER_CHAR;
}
- wxUint32 *outBuff = wx_reinterpret_cast(wxUint32 *, dst);
+ wxUint32 *outBuff = reinterpret_cast<wxUint32 *>(dst);
size_t outLen = 0;
for ( const wchar_t * const srcEnd = src + srcLen; src < srcEnd; )
{
if ( srcLen == wxNO_LEN )
return wxCONV_FAILED;
- const wxUint32 *inBuff = wx_reinterpret_cast(const wxUint32 *, src);
+ const wxUint32 *inBuff = reinterpret_cast<const wxUint32 *>(src);
const size_t inLen = srcLen / BYTES_PER_CHAR;
size_t outLen = 0;
for ( size_t n = 0; n < inLen; n++, inBuff++ )
return srcLen*BYTES_PER_CHAR;
}
- wxUint32 *outBuff = wx_reinterpret_cast(wxUint32 *, dst);
+ wxUint32 *outBuff = reinterpret_cast<wxUint32 *>(dst);
size_t outLen = 0;
for ( const wchar_t * const srcEnd = src + srcLen; src < srcEnd; )
{
if ( dstLen < srcLen )
return wxCONV_FAILED;
- const wxUint32 *inBuff = wx_reinterpret_cast(const wxUint32 *, src);
+ const wxUint32 *inBuff = reinterpret_cast<const wxUint32 *>(src);
for ( size_t n = 0; n < srcLen; n++, inBuff++ )
{
*dst++ = wxUINT32_SWAP_ALWAYS(*inBuff);
if ( dstLen < srcLen )
return wxCONV_FAILED;
- wxUint32 *outBuff = wx_reinterpret_cast(wxUint32 *, dst);
+ wxUint32 *outBuff = reinterpret_cast<wxUint32 *>(dst);
for ( size_t n = 0; n < srcLen; n += BYTES_PER_CHAR, src++ )
{
*outBuff++ = wxUINT32_SWAP_ALWAYS(*src);
virtual wxMBConv *Clone() const
{
- wxMBConv_iconv *p = new wxMBConv_iconv(m_name.ToAscii());
+ wxMBConv_iconv *p = new wxMBConv_iconv(m_name);
p->m_minMBCharWidth = m_minMBCharWidth;
return p;
}
// name of the encoding handled by this conversion
- wxString m_name;
+ const char *m_name;
// cached result of GetMBNulLen(); set to 0 meaning "unknown"
// initially
bool wxMBConv_iconv::ms_wcNeedsSwap = false;
wxMBConv_iconv::wxMBConv_iconv(const char *name)
- : m_name(name)
+ : m_name(wxStrdup(name))
{
m_minMBCharWidth = 0;
// check for charset that represents wchar_t:
if ( ms_wcCharsetName.empty() )
{
- wxLogTrace(TRACE_STRCONV, _T("Looking for wide char codeset:"));
+ wxLogTrace(TRACE_STRCONV, wxT("Looking for wide char codeset:"));
#if wxUSE_FONTMAP
- const wxChar **names = wxFontMapperBase::GetAllEncodingNames(WC_ENC);
+ const wxChar *const *names = wxFontMapperBase::GetAllEncodingNames(WC_ENC);
#else // !wxUSE_FONTMAP
- static const wxChar *names_static[] =
+ static const wxChar *const names_static[] =
{
#if SIZEOF_WCHAR_T == 4
- _T("UCS-4"),
+ wxT("UCS-4"),
#elif SIZEOF_WCHAR_T = 2
- _T("UCS-2"),
+ wxT("UCS-2"),
#endif
NULL
};
- const wxChar **names = names_static;
+ const wxChar *const *names = names_static;
#endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
for ( ; *names && ms_wcCharsetName.empty(); ++names )
wxString nameXE(nameCS);
#ifdef WORDS_BIGENDIAN
- nameXE += _T("BE");
+ nameXE += wxT("BE");
#else // little endian
- nameXE += _T("LE");
+ nameXE += wxT("LE");
#endif
- wxLogTrace(TRACE_STRCONV, _T(" trying charset \"%s\""),
+ wxLogTrace(TRACE_STRCONV, wxT(" trying charset \"%s\""),
nameXE.c_str());
m2w = iconv_open(nameXE.ToAscii(), name);
if ( m2w == ICONV_T_INVALID )
{
// try charset w/o bytesex info (e.g. "UCS4")
- wxLogTrace(TRACE_STRCONV, _T(" trying charset \"%s\""),
+ wxLogTrace(TRACE_STRCONV, wxT(" trying charset \"%s\""),
nameCS.c_str());
m2w = iconv_open(nameCS.ToAscii(), name);
wxT("iconv wchar_t charset is \"%s\"%s"),
ms_wcCharsetName.empty() ? wxString("<none>")
: ms_wcCharsetName,
- ms_wcNeedsSwap ? _T(" (needs swap)")
- : _T(""));
+ ms_wcNeedsSwap ? wxT(" (needs swap)")
+ : wxT(""));
}
else // we already have ms_wcCharsetName
{
wxMBConv_iconv::~wxMBConv_iconv()
{
+ free(const_cast<char *>(m_name));
+
if ( m2w != ICONV_T_INVALID )
iconv_close(m2w);
if ( w2m != ICONV_T_INVALID )
else // no destination buffer
{
// convert using temp buffer to calculate the size of the buffer needed
- wchar_t tbuf[8];
+ wchar_t tbuf[256];
res = 0;
do
else // no destination buffer
{
// convert using temp buffer to calculate the size of the buffer needed
- char tbuf[16];
+ char tbuf[256];
res = 0;
do
{
switch ( len )
{
default:
- wxLogDebug(_T("Unexpected NUL length %d"), len);
+ wxLogDebug(wxT("Unexpected NUL length %d"), len);
self->m_minMBCharWidth = (size_t)-1;
break;
break;
}
- wxASSERT_MSG( s_isWin98Or2k != -1, _T("should be set above") );
+ wxASSERT_MSG( s_isWin98Or2k != -1, wxT("should be set above") );
}
return s_isWin98Or2k == 1;
// were we initialized successfully?
bool m_ok;
- DECLARE_NO_COPY_CLASS(wxMBConv_wxwin)
+ wxDECLARE_NO_COPY_CLASS(wxMBConv_wxwin);
};
// make the constructors available for unit testing
{
if ( encoding == wxFONTENCODING_MAX || encoding == wxFONTENCODING_DEFAULT )
{
- wxFAIL_MSG( _T("invalid encoding value in wxCSConv ctor") );
+ wxFAIL_MSG( wxT("invalid encoding value in wxCSConv ctor") );
encoding = wxFONTENCODING_SYSTEM;
}
void wxCSConv::Clear()
{
free(m_name);
- delete m_convReal;
+ wxDELETE(m_convReal);
m_name = NULL;
- m_convReal = NULL;
}
void wxCSConv::SetName(const char *charset)
delete conv;
}
- const wxChar** names = wxFontMapperBase::GetAllEncodingNames(encoding);
+ const wxChar* const* names = wxFontMapperBase::GetAllEncodingNames(encoding);
// CS : in case this does not return valid names (eg for MacRoman)
// encoding got a 'failure' entry in the cache all the same,
// although it just has to be created using a different method, so
delete conv;
}
- gs_nameCache[encoding] = _T(""); // cache the failure
+ gs_nameCache[encoding] = wxT(""); // cache the failure
}
}
#endif // wxUSE_FONTMAP
delete conv;
}
-#endif // wxUSE_FONTMAP
-
- // NB: This is a hack to prevent deadlock. What could otherwise happen
- // in Unicode build: wxConvLocal creation ends up being here
- // because of some failure and logs the error. But wxLog will try to
- // attach a timestamp, for which it will need wxConvLocal (to convert
- // time to char* and then wchar_t*), but that fails, tries to log the
- // error, but wxLog has an (already locked) critical section that
- // guards the static buffer.
- static bool alreadyLoggingError = false;
- if (!alreadyLoggingError)
- {
- alreadyLoggingError = true;
- wxLogError(_("Cannot convert from the charset '%s'!"),
- m_name ? m_name
- :
-#if wxUSE_FONTMAP
- (const char*)wxFontMapperBase::GetEncodingDescription(m_encoding).ToAscii()
-#else // !wxUSE_FONTMAP
- (const char*)wxString::Format(_("encoding %i"), m_encoding).ToAscii()
-#endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
- );
- alreadyLoggingError = false;
- }
+ wxLogTrace(TRACE_STRCONV,
+ wxT("encoding \"%s\" is not supported by this system"),
+ (m_name ? wxString(m_name)
+ : wxFontMapperBase::GetEncodingName(m_encoding)));
+#endif // wxUSE_FONTMAP
return NULL;
}
{
if ( m_deferred )
{
- wxCSConv *self = (wxCSConv *)this; // const_cast
+ wxCSConv *self = const_cast<wxCSConv *>(this);
// if we don't have neither the name nor the encoding, use the default
// encoding for this system
#define WX_DEFINE_GLOBAL_CONV(klass, name, ctor_args) \
WX_DEFINE_GLOBAL_CONV2(klass, klass, name, ctor_args)
+#ifdef __INTELC__
+ // disable warning "variable 'xxx' was declared but never referenced"
+ #pragma warning(disable: 177)
+#endif // Intel C++
+
#ifdef __WINDOWS__
WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_win32, wxConvLibc, wxEMPTY_PARAMETER_VALUE);
+#elif 0 // defined(__WXOSX__)
+ WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_cf, wxConvLibc, (wxFONTENCODING_UTF8));
#else
WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConvLibc, wxConvLibc, wxEMPTY_PARAMETER_VALUE);
#endif
#else // !__DARWIN__
wxGet_wxConvLibcPtr();
#endif // __DARWIN__/!__DARWIN__
-
-#else // !wxUSE_WCHAR_T
-
-// FIXME-UTF8: remove this, wxUSE_WCHAR_T is required now
-// stand-ins in absence of wchar_t
-WXDLLIMPEXP_DATA_BASE(wxMBConv) wxConvLibc,
- wxConvISO8859_1,
- wxConvLocal,
- wxConvUTF8;
-
-#endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T