+#endif // wxUSE_FONTMAP
+
+// ============================================================================
+// wxCSConv implementation
+// ============================================================================
+
+void wxCSConv::Init()
+{
+ m_name = NULL;
+ m_convReal = NULL;
+ m_deferred = true;
+}
+
+wxCSConv::wxCSConv(const wxChar *charset)
+{
+ Init();
+
+ if ( charset )
+ {
+ SetName(charset);
+ }
+
+ m_encoding = wxFONTENCODING_SYSTEM;
+}
+
+wxCSConv::wxCSConv(wxFontEncoding encoding)
+{
+ if ( encoding == wxFONTENCODING_MAX || encoding == wxFONTENCODING_DEFAULT )
+ {
+ wxFAIL_MSG( _T("invalid encoding value in wxCSConv ctor") );
+
+ encoding = wxFONTENCODING_SYSTEM;
+ }
+
+ Init();
+
+ m_encoding = encoding;
+}
+
+wxCSConv::~wxCSConv()
+{
+ Clear();
+}
+
+wxCSConv::wxCSConv(const wxCSConv& conv)
+ : wxMBConv()
+{
+ Init();
+
+ SetName(conv.m_name);
+ m_encoding = conv.m_encoding;
+}
+
+wxCSConv& wxCSConv::operator=(const wxCSConv& conv)
+{
+ Clear();
+
+ SetName(conv.m_name);
+ m_encoding = conv.m_encoding;
+
+ return *this;
+}
+
+void wxCSConv::Clear()
+{
+ free(m_name);
+ delete m_convReal;
+
+ m_name = NULL;
+ m_convReal = NULL;
+}
+
+void wxCSConv::SetName(const wxChar *charset)
+{
+ if (charset)
+ {
+ m_name = wxStrdup(charset);
+ m_deferred = true;
+ }
+}
+
+static inline bool DoesntNeedConv(wxFontEncoding enc)
+{
+ return enc == wxFONTENCODING_DEFAULT ||
+ enc == wxFONTENCODING_SYSTEM ||
+ enc == wxFONTENCODING_ISO8859_1;
+}
+
+wxMBConv *wxCSConv::DoCreate() const
+{
+#if wxUSE_FONTMAP
+ wxFontMapper * const fontMapper = wxFontMapper::Get();
+
+ wxFontEncoding encFromName = m_name ? fontMapper->CharsetToEncoding(m_name)
+ : wxFONTENCODING_SYSTEM;
+#endif // wxUSE_FONTMAP
+
+ // check for the special case of ASCII charset
+ if ( (!m_name && DoesntNeedConv(m_encoding))
+#if wxUSE_FONTMAP
+ || (m_name && DoesntNeedConv(encFromName))
+#endif // wxUSE_FONTMAP
+ )
+ {
+ // don't convert at all
+ return NULL;
+ }
+
+ // we trust OS to do conversion better than we can so try external
+ // conversion methods first
+ //
+ // the full order is:
+ // 1. OS conversion (iconv() under Unix or Win32 API)
+ // 2. hard coded conversions for UTF
+ // 3. wxEncodingConverter as fall back
+
+ // step (1)
+#ifdef HAVE_ICONV
+ if ( m_name )
+ {
+ wxMBConv_iconv *conv = new wxMBConv_iconv(m_name);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+#endif // HAVE_ICONV
+
+#ifdef wxHAVE_WIN32_MB2WC
+ {
+ wxMBConv_win32 *conv = m_name ? new wxMBConv_win32(m_name)
+ : new wxMBConv_win32(m_encoding);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+#endif // wxHAVE_WIN32_MB2WC
+
+ // step (2)
+ wxFontEncoding enc = m_encoding;
+#if wxUSE_FONTMAP
+ if ( enc == wxFONTENCODING_SYSTEM )
+ enc = encFromName;
+#endif // wxUSE_FONTMAP
+
+ switch ( enc )
+ {
+ case wxFONTENCODING_UTF7:
+ return new wxMBConvUTF7;
+
+ case wxFONTENCODING_UTF8:
+ return new wxMBConvUTF8;
+
+ case wxFONTENCODING_UTF16BE:
+ return new wxMBConvUTF16BE;
+
+ case wxFONTENCODING_UTF16LE:
+ return new wxMBConvUTF16LE;
+
+ case wxFONTENCODING_UTF32BE:
+ return new wxMBConvUTF32BE;
+
+ case wxFONTENCODING_UTF32LE:
+ return new wxMBConvUTF32LE;
+
+ default:
+ // nothing to do but put here to suppress gcc warnings
+ ;
+ }
+
+ // step (3)
+#if wxUSE_FONTMAP
+ {
+ wxMBConv_wxwin *conv = m_name ? new wxMBConv_wxwin(m_name)
+ : new wxMBConv_wxwin(m_encoding);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+#endif // wxUSE_FONTMAP
+
+ wxLogError(_("Cannot convert from the charset '%s'!"),
+ m_name ? m_name
+ :
+#if wxUSE_FONTMAP
+ wxFontMapper::GetEncodingDescription(m_encoding).c_str()
+#else // !wxUSE_FONTMAP
+ wxString::Format(_("encoding %s"), m_encoding).c_str()
+#endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
+ );
+
+ return NULL;
+}
+
+void wxCSConv::CreateConvIfNeeded() const
+{
+ if ( m_deferred )
+ {
+ wxCSConv *self = (wxCSConv *)this; // const_cast
+
+#if wxUSE_INTL
+ // if we don't have neither the name nor the encoding, use the default
+ // encoding for this system
+ if ( !m_name && m_encoding == wxFONTENCODING_SYSTEM )
+ {
+ self->m_encoding = wxLocale::GetSystemEncoding();
+ }
+#endif // wxUSE_INTL
+
+ self->m_convReal = DoCreate();
+ self->m_deferred = false;
+ }
+}
+
+size_t wxCSConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const
+{
+ CreateConvIfNeeded();
+
+ if (m_convReal)
+ return m_convReal->MB2WC(buf, psz, n);
+
+ // latin-1 (direct)
+ size_t len = strlen(psz);
+
+ if (buf)
+ {
+ for (size_t c = 0; c <= len; c++)
+ buf[c] = (unsigned char)(psz[c]);
+ }
+
+ return len;
+}
+
+size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const
+{
+ CreateConvIfNeeded();
+
+ if (m_convReal)
+ return m_convReal->WC2MB(buf, psz, n);
+
+ // latin-1 (direct)
+ const size_t len = wxWcslen(psz);
+ if (buf)
+ {
+ for (size_t c = 0; c <= len; c++)
+ buf[c] = (psz[c] > 0xff) ? '?' : psz[c];
+ }
+
+ return len;
+}