Remove wxMBConv_mac and wxMBConv_macUTF8D converters and use wxMBConv_cf(wxFONTENCODING_UTF8) for wxConvFileName on Darwin platform regardless of GUI toolkit.

Check for Mac encodings in wxMBConv_wxwin::Init and fail to provide conversion for them via wxEncodingConverter because that code is horribly broken for several encodings.
Remove definition of wxConvLibc for non-Darwin Mac platforms (we don't support these anymore).


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47225 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
David Elliott
2007-07-07 19:10:15 +00:00
parent 991dd5beb9
commit 6ac84a7872

View File

@@ -60,17 +60,6 @@
#include "wx/mac/corefoundation/private/strconv_cf.h" #include "wx/mac/corefoundation/private/strconv_cf.h"
#endif //def __DARWIN__ #endif //def __DARWIN__
#ifdef __WXMAC__
#ifndef __DARWIN__
#include <ATSUnicode.h>
#include <TextCommon.h>
#include <TextEncodingConverter.h>
#endif
// includes Mac headers
#include "wx/mac/private.h"
#endif
#define TRACE_STRCONV _T("strconv") #define TRACE_STRCONV _T("strconv")
@@ -2301,379 +2290,6 @@ private:
#endif // wxHAVE_WIN32_MB2WC #endif // wxHAVE_WIN32_MB2WC
// ============================================================================
// Mac conversion classes
// ============================================================================
/* Although we are in the base library we currently have this wxMac
* conditional. This is not generally good but fortunately does not affect
* the ABI of the base library, only what encodings might work.
* It does mean that a wxBase built as part of wxMac has slightly more support
* than one built for wxCocoa or even wxGtk.
*/
#if defined(__WXMAC__) && defined(TARGET_CARBON)
class wxMBConv_mac : public wxMBConv
{
public:
wxMBConv_mac()
{
Init(CFStringGetSystemEncoding()) ;
}
wxMBConv_mac(const wxMBConv_mac& conv)
{
Init(conv.m_char_encoding);
}
#if wxUSE_FONTMAP
wxMBConv_mac(const char* name)
{
Init( wxMacGetSystemEncFromFontEnc( wxFontMapperBase::Get()->CharsetToEncoding(name, false) ) );
}
#endif
wxMBConv_mac(wxFontEncoding encoding)
{
Init( wxMacGetSystemEncFromFontEnc(encoding) );
}
virtual ~wxMBConv_mac()
{
OSStatus status = noErr ;
if (m_MB2WC_converter)
status = TECDisposeConverter(m_MB2WC_converter);
if (m_WC2MB_converter)
status = TECDisposeConverter(m_WC2MB_converter);
}
void Init( TextEncodingBase encoding,TextEncodingVariant encodingVariant = kTextEncodingDefaultVariant ,
TextEncodingFormat encodingFormat = kTextEncodingDefaultFormat)
{
m_MB2WC_converter = NULL ;
m_WC2MB_converter = NULL ;
m_char_encoding = CreateTextEncoding(encoding, encodingVariant, encodingFormat) ;
m_unicode_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault, 0, kUnicode16BitFormat) ;
}
virtual void CreateIfNeeded() const
{
if ( m_MB2WC_converter == NULL && m_WC2MB_converter == NULL )
{
OSStatus status = noErr ;
status = TECCreateConverter(&m_MB2WC_converter,
m_char_encoding,
m_unicode_encoding);
wxASSERT_MSG( status == noErr , _("Unable to create TextEncodingConverter")) ;
status = TECCreateConverter(&m_WC2MB_converter,
m_unicode_encoding,
m_char_encoding);
wxASSERT_MSG( status == noErr , _("Unable to create TextEncodingConverter")) ;
}
}
size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const
{
CreateIfNeeded() ;
OSStatus status = noErr ;
ByteCount byteOutLen ;
ByteCount byteInLen = strlen(psz) + 1;
wchar_t *tbuf = NULL ;
UniChar* ubuf = NULL ;
size_t res = 0 ;
if (buf == NULL)
{
// Apple specs say at least 32
n = wxMax( 32, byteInLen ) ;
tbuf = (wchar_t*) malloc( n * SIZEOF_WCHAR_T ) ;
}
ByteCount byteBufferLen = n * sizeof( UniChar ) ;
#if SIZEOF_WCHAR_T == 4
ubuf = (UniChar*) malloc( byteBufferLen + 2 ) ;
#else
ubuf = (UniChar*) (buf ? buf : tbuf) ;
#endif
status = TECConvertText(
m_MB2WC_converter, (ConstTextPtr) psz, byteInLen, &byteInLen,
(TextPtr) ubuf, byteBufferLen, &byteOutLen);
#if SIZEOF_WCHAR_T == 4
// we have to terminate here, because n might be larger for the trailing zero, and if UniChar
// is not properly terminated we get random characters at the end
ubuf[byteOutLen / sizeof( UniChar ) ] = 0 ;
wxMBConvUTF16 converter ;
res = converter.MB2WC( (buf ? buf : tbuf), (const char*)ubuf, n ) ;
free( ubuf ) ;
#else
res = byteOutLen / sizeof( UniChar ) ;
#endif
if ( buf == NULL )
free(tbuf) ;
if ( buf && res < n)
buf[res] = 0;
return res ;
}
size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const
{
CreateIfNeeded() ;
OSStatus status = noErr ;
ByteCount byteOutLen ;
ByteCount byteInLen = wxWcslen(psz) * SIZEOF_WCHAR_T ;
char *tbuf = NULL ;
if (buf == NULL)
{
// Apple specs say at least 32
n = wxMax( 32, ((byteInLen / SIZEOF_WCHAR_T) * 8) + SIZEOF_WCHAR_T );
tbuf = (char*) malloc( n ) ;
}
ByteCount byteBufferLen = n ;
UniChar* ubuf = NULL ;
#if SIZEOF_WCHAR_T == 4
wxMBConvUTF16 converter ;
size_t unicharlen = converter.WC2MB( NULL, psz, 0 ) ;
byteInLen = unicharlen ;
ubuf = (UniChar*) malloc( byteInLen + 2 ) ;
converter.WC2MB( (char*) ubuf, psz, unicharlen + 2 ) ;
#else
ubuf = (UniChar*) psz ;
#endif
status = TECConvertText(
m_WC2MB_converter, (ConstTextPtr) ubuf, byteInLen, &byteInLen,
(TextPtr) (buf ? buf : tbuf), byteBufferLen, &byteOutLen);
#if SIZEOF_WCHAR_T == 4
free( ubuf ) ;
#endif
if ( buf == NULL )
free(tbuf) ;
size_t res = byteOutLen ;
if ( buf && res < n)
{
buf[res] = 0;
//we need to double-trip to verify it didn't insert any ? in place
//of bogus characters
wxWCharBuffer wcBuf(n);
size_t pszlen = wxWcslen(psz);
if ( MB2WC(wcBuf.data(), buf, n) == wxCONV_FAILED ||
wxWcslen(wcBuf) != pszlen ||
memcmp(wcBuf, psz, pszlen * sizeof(wchar_t)) != 0 )
{
// we didn't obtain the same thing we started from, hence
// the conversion was lossy and we consider that it failed
return wxCONV_FAILED;
}
}
return res ;
}
virtual wxMBConv *Clone() const { return new wxMBConv_mac(*this); }
bool IsOk() const
{
CreateIfNeeded() ;
return m_MB2WC_converter != NULL && m_WC2MB_converter != NULL;
}
protected :
mutable TECObjectRef m_MB2WC_converter;
mutable TECObjectRef m_WC2MB_converter;
TextEncodingBase m_char_encoding;
TextEncodingBase m_unicode_encoding;
};
// MB is decomposed (D) normalized UTF8
class wxMBConv_macUTF8D : public wxMBConv_mac
{
public :
wxMBConv_macUTF8D()
{
Init( kTextEncodingUnicodeDefault , kUnicodeNoSubset , kUnicodeUTF8Format ) ;
m_uni = NULL;
m_uniBack = NULL ;
}
virtual ~wxMBConv_macUTF8D()
{
if (m_uni!=NULL)
DisposeUnicodeToTextInfo(&m_uni);
if (m_uniBack!=NULL)
DisposeUnicodeToTextInfo(&m_uniBack);
}
size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const
{
CreateIfNeeded() ;
OSStatus status = noErr ;
ByteCount byteOutLen ;
ByteCount byteInLen = wxWcslen(psz) * SIZEOF_WCHAR_T ;
char *tbuf = NULL ;
if (buf == NULL)
{
// Apple specs say at least 32
n = wxMax( 32, ((byteInLen / SIZEOF_WCHAR_T) * 8) + SIZEOF_WCHAR_T );
tbuf = (char*) malloc( n ) ;
}
ByteCount byteBufferLen = n ;
UniChar* ubuf = NULL ;
#if SIZEOF_WCHAR_T == 4
wxMBConvUTF16 converter ;
size_t unicharlen = converter.WC2MB( NULL, psz, 0 ) ;
byteInLen = unicharlen ;
ubuf = (UniChar*) malloc( byteInLen + 2 ) ;
converter.WC2MB( (char*) ubuf, psz, unicharlen + 2 ) ;
#else
ubuf = (UniChar*) psz ;
#endif
// ubuf is a non-decomposed UniChar buffer
ByteCount dcubuflen = byteInLen * 2 + 2 ;
ByteCount dcubufread , dcubufwritten ;
UniChar *dcubuf = (UniChar*) malloc( dcubuflen ) ;
ConvertFromUnicodeToText( m_uni , byteInLen , ubuf ,
kUnicodeDefaultDirectionMask, 0, NULL, NULL, NULL, dcubuflen , &dcubufread , &dcubufwritten , dcubuf ) ;
// we now convert that decomposed buffer into UTF8
status = TECConvertText(
m_WC2MB_converter, (ConstTextPtr) dcubuf, dcubufwritten, &dcubufread,
(TextPtr) (buf ? buf : tbuf), byteBufferLen, &byteOutLen);
free( dcubuf );
#if SIZEOF_WCHAR_T == 4
free( ubuf ) ;
#endif
if ( buf == NULL )
free(tbuf) ;
size_t res = byteOutLen ;
if ( buf && res < n)
{
buf[res] = 0;
// don't test for round-trip fidelity yet, we cannot guarantee it yet
}
return res ;
}
size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const
{
CreateIfNeeded() ;
OSStatus status = noErr ;
ByteCount byteOutLen ;
ByteCount byteInLen = strlen(psz) + 1;
wchar_t *tbuf = NULL ;
UniChar* ubuf = NULL ;
size_t res = 0 ;
if (buf == NULL)
{
// Apple specs say at least 32
n = wxMax( 32, byteInLen ) ;
tbuf = (wchar_t*) malloc( n * SIZEOF_WCHAR_T ) ;
}
ByteCount byteBufferLen = n * sizeof( UniChar ) ;
#if SIZEOF_WCHAR_T == 4
ubuf = (UniChar*) malloc( byteBufferLen + 2 ) ;
#else
ubuf = (UniChar*) (buf ? buf : tbuf) ;
#endif
ByteCount dcubuflen = byteBufferLen * 2 + 2 ;
ByteCount dcubufread , dcubufwritten ;
UniChar *dcubuf = (UniChar*) malloc( dcubuflen ) ;
status = TECConvertText(
m_MB2WC_converter, (ConstTextPtr) psz, byteInLen, &byteInLen,
(TextPtr) dcubuf, dcubuflen, &byteOutLen);
// we have to terminate here, because n might be larger for the trailing zero, and if UniChar
// is not properly terminated we get random characters at the end
dcubuf[byteOutLen / sizeof( UniChar ) ] = 0 ;
// now from the decomposed UniChar to properly composed uniChar
ConvertFromUnicodeToText( m_uniBack , byteOutLen , dcubuf ,
kUnicodeDefaultDirectionMask, 0, NULL, NULL, NULL, dcubuflen , &dcubufread , &dcubufwritten , ubuf ) ;
free( dcubuf );
byteOutLen = dcubufwritten ;
ubuf[byteOutLen / sizeof( UniChar ) ] = 0 ;
#if SIZEOF_WCHAR_T == 4
wxMBConvUTF16 converter ;
res = converter.MB2WC( (buf ? buf : tbuf), (const char*)ubuf, n ) ;
free( ubuf ) ;
#else
res = byteOutLen / sizeof( UniChar ) ;
#endif
if ( buf == NULL )
free(tbuf) ;
if ( buf && res < n)
buf[res] = 0;
return res ;
}
virtual void CreateIfNeeded() const
{
wxMBConv_mac::CreateIfNeeded() ;
if ( m_uni == NULL )
{
m_map.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
kUnicodeNoSubset, kTextEncodingDefaultFormat);
m_map.otherEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
kUnicodeCanonicalDecompVariant, kTextEncodingDefaultFormat);
m_map.mappingVersion = kUnicodeUseLatestMapping;
OSStatus err = CreateUnicodeToTextInfo(&m_map, &m_uni);
wxASSERT_MSG( err == noErr , _(" Couldn't create the UnicodeConverter")) ;
m_map.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
kUnicodeNoSubset, kTextEncodingDefaultFormat);
m_map.otherEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
kUnicodeCanonicalCompVariant, kTextEncodingDefaultFormat);
m_map.mappingVersion = kUnicodeUseLatestMapping;
err = CreateUnicodeToTextInfo(&m_map, &m_uniBack);
wxASSERT_MSG( err == noErr , _(" Couldn't create the UnicodeConverter")) ;
}
}
protected :
mutable UnicodeToTextInfo m_uni;
mutable UnicodeToTextInfo m_uniBack;
mutable UnicodeMapping m_map;
};
#endif // defined(__WXMAC__) && defined(TARGET_CARBON)
// ============================================================================ // ============================================================================
// wxEncodingConverter based conversion classes // wxEncodingConverter based conversion classes
// ============================================================================ // ============================================================================
@@ -2685,7 +2301,10 @@ class wxMBConv_wxwin : public wxMBConv
private: private:
void Init() void Init()
{ {
m_ok = m2w.Init(m_enc, wxFONTENCODING_UNICODE) && // Refuse to use broken wxEncodingConverter code for Mac-specific encodings.
// The wxMBConv_cf class does a better job.
m_ok = (m_enc < wxFONTENCODING_MACMIN || m_enc > wxFONTENCODING_MACMAX) &&
m2w.Init(m_enc, wxFONTENCODING_UNICODE) &&
w2m.Init(wxFONTENCODING_UNICODE, m_enc); w2m.Init(wxFONTENCODING_UNICODE, m_enc);
} }
@@ -2980,26 +2599,6 @@ wxMBConv *wxCSConv::DoCreate() const
} }
#endif // wxHAVE_WIN32_MB2WC #endif // wxHAVE_WIN32_MB2WC
#if defined(__WXMAC__)
{
// leave UTF16 and UTF32 to the built-ins of wx
if ( m_name || ( m_encoding < wxFONTENCODING_UTF16BE ||
( m_encoding >= wxFONTENCODING_MACMIN && m_encoding <= wxFONTENCODING_MACMAX ) ) )
{
#if wxUSE_FONTMAP
wxMBConv_mac *conv = m_name ? new wxMBConv_mac(m_name)
: new wxMBConv_mac(m_encoding);
#else
wxMBConv_mac *conv = new wxMBConv_mac(m_encoding);
#endif
if ( conv->IsOk() )
return conv;
delete conv;
}
}
#endif
#ifdef __DARWIN__ #ifdef __DARWIN__
{ {
// leave UTF16 and UTF32 to the built-ins of wx // leave UTF16 and UTF32 to the built-ins of wx
@@ -3300,8 +2899,6 @@ wxCharBuffer wxSafeConvertWX2MB(const wchar_t *ws)
#ifdef __WINDOWS__ #ifdef __WINDOWS__
WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_win32, wxConvLibc, wxEMPTY_PARAMETER_VALUE); WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_win32, wxConvLibc, wxEMPTY_PARAMETER_VALUE);
#elif defined(__WXMAC__) && !defined(__MACH__)
WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_mac, wxConvLibc, wxEMPTY_PARAMETER_VALUE);
#else #else
WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConvLibc, wxConvLibc, wxEMPTY_PARAMETER_VALUE); WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConvLibc, wxConvLibc, wxEMPTY_PARAMETER_VALUE);
#endif #endif
@@ -3315,19 +2912,18 @@ WX_DEFINE_GLOBAL_CONV(wxCSConv, wxConvISO8859_1, (wxFONTENCODING_ISO8859_1));
WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent = wxGet_wxConvLibcPtr(); WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent = wxGet_wxConvLibcPtr();
WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvUI = wxGet_wxConvLocalPtr(); WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvUI = wxGet_wxConvLocalPtr();
#if defined(__WXMAC__) && defined(TARGET_CARBON) #ifdef __DARWIN__
static wxMBConv_macUTF8D wxConvMacUTF8DObj; // The xnu kernel always communicates file paths in decomposed UTF-8.
// WARNING: Are we sure that CFString's conversion will cause decomposition?
static wxMBConv_cf wxConvMacUTF8DObj(wxFONTENCODING_UTF8);
#endif #endif
WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvFileName = WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvFileName =
#ifdef __WXOSX__ #ifdef __DARWIN__
#if defined(__WXMAC__) && defined(TARGET_CARBON)
&wxConvMacUTF8DObj; &wxConvMacUTF8DObj;
#else #else // !__DARWIN__
wxGet_wxConvUTF8Ptr();
#endif
#else // !__WXOSX__
wxGet_wxConvLibcPtr(); wxGet_wxConvLibcPtr();
#endif // __WXOSX__/!__WXOSX__ #endif // __DARWIN__/!__DARWIN__
#else // !wxUSE_WCHAR_T #else // !wxUSE_WCHAR_T