X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/574c939ef1c1b835a8bc65c0fe724548fa04ec49..f357c0d42c17bf5be30e65e68cd99c474678da71:/src/common/strconv.cpp diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index c8207ca44e..b15169ac54 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -42,6 +42,7 @@ #include #include +#include "wx/module.h" #include "wx/strconv.h" // ---------------------------------------------------------------------------- @@ -51,13 +52,36 @@ #if wxUSE_WCHAR_T WXDLLEXPORT_DATA(wxMBConv) wxConvLibc; WXDLLEXPORT_DATA(wxCSConv) wxConvLocal((const wxChar *)NULL); + WXDLLEXPORT_DATA(wxCSConv) wxConvISO8859_1(_T("iso-8859-1")); #else // stand-ins in absence of wchar_t - WXDLLEXPORT_DATA(wxMBConv) wxConvLibc, wxConvFile; + WXDLLEXPORT_DATA(wxMBConv) wxConvLibc, + wxConvFile, + wxConvISO8859_1, + wxConvLocal; #endif // wxUSE_WCHAR_T WXDLLEXPORT_DATA(wxMBConv *) wxConvCurrent = &wxConvLibc; +class wxStrConvModule: public wxModule +{ +public: + wxStrConvModule() : wxModule() { } + virtual bool OnInit() { return TRUE; } + virtual void OnExit() + { +#if wxUSE_WCHAR_T + wxConvLocal.Clear(); + wxConvISO8859_1.Clear(); +#endif + } + + DECLARE_DYNAMIC_CLASS(wxStrConvModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxStrConvModule, wxModule) + + // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- @@ -167,61 +191,87 @@ static size_t decode_utf16(const wchar_t* input, wxUint32& output) // wxMBConv // ---------------------------------------------------------------------------- -size_t wxMBConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - return wxMB2WC(buf, psz, n); -} +#define IGNORE_LIBC 0 -size_t wxMBConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const +wxMBConv::~wxMBConv() { - return wxWC2MB(buf, psz, n); + // nothing to do here } -const wxWCharBuffer wxMBConv::cMB2WC(const char *psz) const +size_t wxMBConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const { - if (psz) +#if IGNORE_LIBC + if (buf) { - size_t nLen = MB2WC((wchar_t *) NULL, psz, 0); - if (nLen == (size_t)-1) - return wxWCharBuffer((wchar_t *) NULL); - wxWCharBuffer buf(nLen); - MB2WC((wchar_t *)(const wchar_t *) buf, psz, nLen); - return buf; + for (size_t i = 0; i < strlen( psz )+1; i++) + buf[i] = (wchar_t) psz[i]; + return strlen( psz ); } else - return wxWCharBuffer((wchar_t *) NULL); + { + return strlen( psz ); + } +#else + return wxMB2WC(buf, psz, n); +#endif } -const wxCharBuffer wxMBConv::cWC2MB(const wchar_t *psz) const +size_t wxMBConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const { - if (psz) +#if IGNORE_LIBC + if (buf) { - size_t nLen = WC2MB((char *) NULL, psz, 0); - if (nLen == (size_t)-1) - return wxCharBuffer((char *) NULL); - wxCharBuffer buf(nLen); - WC2MB((char *)(const char *) buf, psz, nLen); - return buf; + for (size_t i = 0; i < wxStrlen( psz )+1; i++) + buf[i] = (char) psz[i]; + return wxStrlen( psz ); } else - return wxCharBuffer((char *) NULL); + { + return wxStrlen( psz ); + } +#else + return wxWC2MB(buf, psz, n); +#endif } -// ---------------------------------------------------------------------------- -// standard file conversion -// ---------------------------------------------------------------------------- +const wxWCharBuffer wxMBConv::cMB2WC(const char *psz) const +{ + if ( psz ) + { + // calculate the length of the buffer needed first + size_t nLen = MB2WC(NULL, psz, 0); + if ( nLen != (size_t)-1 ) + { + // now do the actual conversion + wxWCharBuffer buf(nLen); + MB2WC(buf.data(), psz, nLen + 1); // with the trailing NUL -WXDLLEXPORT_DATA(wxMBConvFile) wxConvFile; + return buf; + } + } -// just use the libc conversion for now -size_t wxMBConvFile::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - return wxMB2WC(buf, psz, n); + wxWCharBuffer buf((wchar_t *)NULL); + + return buf; } -size_t wxMBConvFile::WC2MB(char *buf, const wchar_t *psz, size_t n) const +const wxCharBuffer wxMBConv::cWC2MB(const wchar_t *pwz) const { - return wxWC2MB(buf, psz, n); + if ( pwz ) + { + size_t nLen = WC2MB(NULL, pwz, 0); + if ( nLen != (size_t)-1 ) + { + wxCharBuffer buf(nLen); + WC2MB(buf.data(), pwz, nLen + 1); + + return buf; + } + } + + wxCharBuffer buf((char *)NULL); + + return buf; } // ---------------------------------------------------------------------------- @@ -406,6 +456,7 @@ size_t wxMBConvUTF8::WC2MB(char *buf, const wchar_t *psz, size_t n) const } if (buf && (len 0x530) - size_t inbuf = std::wcslen(psz) * SIZEOF_WCHAR_T; -#else - size_t inbuf = ::wcslen(psz) * SIZEOF_WCHAR_T; -#endif + size_t inbuf = wxWcslen(psz) * SIZEOF_WCHAR_T; size_t outbuf = n; size_t res, cres; @@ -681,6 +739,12 @@ size_t IC_CharSet::WC2MB(char *buf, const wchar_t *psz, size_t n) cres = iconv( w2m, ICONV_CHAR_CAST(&psz), &inbuf, &buf, &outbuf ); res = n-outbuf; + + // NB: iconv was given only wcslen(psz) characters on input, and so + // it couldn't convert the trailing zero. Let's do it ourselves + // if there's some room left for it in the output buffer. + if (res < n) + buf[0] = 0; } else { @@ -718,7 +782,7 @@ size_t IC_CharSet::WC2MB(char *buf, const wchar_t *psz, size_t n) // Win32 conversion classes // ============================================================================ -#if defined(__WIN32__) && !defined(__WXMICROWIN__) +#if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXUNIVERSAL__) extern long wxCharsetToCodepage(const wxChar *charset); // from utils.cpp @@ -733,20 +797,37 @@ public: size_t MB2WC(wchar_t *buf, const char *psz, size_t n) { - size_t len = - MultiByteToWideChar(m_CodePage, 0, psz, -1, buf, buf ? n : 0); - //VS: returns # of written chars for buf!=NULL and *size* - // needed buffer for buf==NULL - return len ? (buf ? len : len-1) : (size_t)-1; + const size_t len = ::MultiByteToWideChar + ( + m_CodePage, // code page + 0, // flags (none) + psz, // input string + -1, // its length (NUL-terminated) + buf, // output string + buf ? n : 0 // size of output buffer + ); + + // note that it returns # of written chars for buf != NULL and *size* + // of the needed buffer for buf == NULL + return len ? (buf ? len : len - 1) : (size_t)-1; } size_t WC2MB(char *buf, const wchar_t *psz, size_t n) { - size_t len = WideCharToMultiByte(m_CodePage, 0, psz, -1, buf, - buf ? n : 0, NULL, NULL); - //VS: returns # of written chars for buf!=NULL and *size* - // needed buffer for buf==NULL - return len ? (buf ? len : len-1) : (size_t)-1; + const size_t len = ::WideCharToMultiByte + ( + m_CodePage, // code page + 0, // flags (none) + psz, // input string + -1, // it is (wide) NUL-terminated + buf, // output buffer + buf ? n : 0, // and its size + NULL, // default "replacement" char + NULL // [out] was it used? + ); + + // see the comment above! + return len ? (buf ? len : len - 1) : (size_t)-1; } bool usable() const @@ -755,7 +836,7 @@ public: public: long m_CodePage; }; -#endif // __WIN32__ +#endif // defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXUNIVERSAL__) // ============================================================================ // wxEncodingConverter based conversion classes @@ -772,7 +853,7 @@ public: enc(wxFONTENCODING_SYSTEM) { if (name) - enc = wxTheFontMapper->CharsetToEncoding(name, FALSE); + enc = wxFontMapper::Get()->CharsetToEncoding(name, FALSE); m_ok = m2w.Init(enc, wxFONTENCODING_UNICODE) && w2m.Init(wxFONTENCODING_UNICODE, enc); @@ -788,12 +869,7 @@ public: size_t WC2MB(char *buf, const wchar_t *psz, size_t WXUNUSED(n)) { -#if ( defined(__BORLANDC__) && (__BORLANDC__ > 0x530) ) \ - || ( defined(__MWERKS__) && defined(__WXMSW__) ) - size_t inbuf = std::wcslen(psz); -#else - size_t inbuf = ::wcslen(psz); -#endif + const size_t inbuf = wxWcslen(psz); if (buf) w2m.Convert(psz,buf); @@ -821,7 +897,7 @@ static wxCharacterSet *wxGetCharacterSet(const wxChar *name) { // check for the special case of ASCII charset #if wxUSE_FONTMAP - if ( wxTheFontMapper->CharsetToEncoding(name) == wxFONTENCODING_DEFAULT ) + if ( wxFontMapper::Get()->CharsetToEncoding(name) == wxFONTENCODING_DEFAULT ) #else // wxUSE_FONTMAP if ( !name ) #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP @@ -860,14 +936,14 @@ static wxCharacterSet *wxGetCharacterSet(const wxChar *name) cset = NULL; } -#if defined(__WIN32__) && !defined(__WXMICROWIN__) +#if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXUNIVERSAL__) cset = new CP_CharSet(name); if ( cset->usable() ) return cset; delete cset; cset = NULL; -#endif // __WIN32__ +#endif // defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXUNIVERSAL__) #if wxUSE_FONTMAP cset = new EC_CharSet(name); @@ -898,8 +974,31 @@ wxCSConv::wxCSConv(const wxChar *charset) wxCSConv::~wxCSConv() { - free(m_name); - delete m_cset; + Clear(); +} + +wxCSConv::wxCSConv(const wxCSConv& conv) + : wxMBConv() +{ + Clear(); + SetName(conv.m_name); +} + +wxCSConv& wxCSConv::operator=(const wxCSConv& conv) +{ + Clear(); + SetName(conv.m_name); + return *this; +} + +void wxCSConv::Clear() +{ + if (m_name) + free(m_name); + if (m_cset) + delete m_cset; + m_name = NULL; + m_cset = NULL; } void wxCSConv::SetName(const wxChar *charset) @@ -913,14 +1012,20 @@ void wxCSConv::SetName(const wxChar *charset) void wxCSConv::LoadNow() { - if (m_deferred) + if ( m_deferred ) { + // it would probably be better to make GetSystemEncodingName() always + // available (i.e. even when wxUSE_INTL == 0)? +#if wxUSE_INTL if ( !m_name ) { wxString name = wxLocale::GetSystemEncodingName(); if ( !name.empty() ) + { SetName(name); + } } +#endif // wxUSE_INTL // wxGetCharacterSet() complains about NULL name m_cset = m_name ? wxGetCharacterSet(m_name) : NULL; @@ -955,12 +1060,7 @@ size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const return m_cset->WC2MB(buf, psz, n); // latin-1 (direct) -#if ( defined(__BORLANDC__) && (__BORLANDC__ > 0x530) ) \ - || ( defined(__MWERKS__) && defined(__WXMSW__) ) - size_t len=std::wcslen(psz); -#else - size_t len=::wcslen(psz); -#endif + const size_t len = wxWcslen(psz); if (buf) { for (size_t c = 0; c <= len; c++)