From d36c9347ea16171bc2f855076d8b9b11801ec622 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 5 Apr 2006 16:10:08 +0000 Subject: [PATCH] added wxMBConv::Clone() to be able to copy conversion objects polymorphically git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38576 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/convauto.h | 2 ++ include/wx/datstrm.h | 8 ++++---- include/wx/strconv.h | 37 +++++++++++++++++++++++++++------ include/wx/txtstrm.h | 4 ++-- src/common/datstrm.cpp | 22 ++++++++++++++++---- src/common/strconv.cpp | 46 ++++++++++++++++++++++++++++++++++++++---- src/common/txtstrm.cpp | 18 +++++++++++------ 7 files changed, 111 insertions(+), 26 deletions(-) diff --git a/include/wx/convauto.h b/include/wx/convauto.h index ec32b93c43..6dc550ab49 100644 --- a/include/wx/convauto.h +++ b/include/wx/convauto.h @@ -40,6 +40,8 @@ public: virtual size_t GetMBNulLen() const { return m_conv->GetMBNulLen(); } + virtual wxMBConv *Clone() const { return new wxConvAuto(*this); } + private: // all currently recognized BOM values enum BOMType diff --git a/include/wx/datstrm.h b/include/wx/datstrm.h index 80fa7e285e..2fb430cbf8 100644 --- a/include/wx/datstrm.h +++ b/include/wx/datstrm.h @@ -26,7 +26,7 @@ public: #else wxDataInputStream(wxInputStream& s); #endif - ~wxDataInputStream(){} + ~wxDataInputStream(); bool IsOk() { return m_input->IsOk(); } @@ -83,7 +83,7 @@ protected: wxInputStream *m_input; bool m_be_order; #if wxUSE_UNICODE - wxMBConv m_conv; + wxMBConv *m_conv; #endif DECLARE_NO_COPY_CLASS(wxDataInputStream) @@ -97,7 +97,7 @@ public: #else wxDataOutputStream(wxOutputStream& s); #endif - ~wxDataOutputStream(){} + ~wxDataOutputStream(); bool IsOk() { return m_output->IsOk(); } @@ -157,7 +157,7 @@ protected: wxOutputStream *m_output; bool m_be_order; #if wxUSE_UNICODE - wxMBConv m_conv; + wxMBConv *m_conv; #endif DECLARE_NO_COPY_CLASS(wxDataOutputStream) diff --git a/include/wx/strconv.h b/include/wx/strconv.h index 877c44d122..73620ad125 100644 --- a/include/wx/strconv.h +++ b/include/wx/strconv.h @@ -9,8 +9,8 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_WXSTRCONVH__ -#define _WX_WXSTRCONVH__ +#ifndef _WX_STRCONV_H_ +#define _WX_STRCONV_H_ #include "wx/defs.h" #include "wx/wxchar.h" @@ -40,6 +40,9 @@ // don't let the fact that the existing classes implement MB2WC/WC2MB() instead // confuse you. // +// You also have to implement Clone() to allow copying the conversions +// polymorphically. +// // And you might need to override GetMBNulLen() as well. class WXDLLIMPEXP_BASE wxMBConv { @@ -147,6 +150,9 @@ public: virtual size_t WC2MB(char *out, const wchar_t *in, size_t outLen) const; + // make a heap-allocated copy of this object + virtual wxMBConv *Clone() const = 0; + // virtual dtor for any base class virtual ~wxMBConv(); }; @@ -161,6 +167,8 @@ class WXDLLIMPEXP_BASE wxMBConvLibc : public wxMBConv public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + + virtual wxMBConv *Clone() const { return new wxMBConvLibc; } }; #ifdef __UNIX__ @@ -176,6 +184,10 @@ class WXDLLIMPEXP_BASE wxConvBrokenFileNames : public wxMBConv { public: wxConvBrokenFileNames(const wxChar *charset); + wxConvBrokenFileNames(const wxConvBrokenFileNames& conv) + : m_conv(conv.m_conv ? conv.m_conv->Clone() : NULL) + { + } virtual ~wxConvBrokenFileNames() { delete m_conv; } virtual size_t MB2WC(wchar_t *out, const char *in, size_t outLen) const @@ -194,9 +206,13 @@ public: return m_conv->GetMBNulLen(); } + virtual wxMBConv *Clone() const { return new wxConvBrokenFileNames(*this); } + private: // the conversion object we forward to wxMBConv *m_conv; + + DECLARE_NO_ASSIGN_CLASS(wxConvBrokenFileNames) }; #endif // __UNIX__ @@ -210,6 +226,8 @@ class WXDLLIMPEXP_BASE wxMBConvUTF7 : public wxMBConv public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + + virtual wxMBConv *Clone() const { return new wxMBConvUTF7; } }; // ---------------------------------------------------------------------------- @@ -219,7 +237,8 @@ public: class WXDLLIMPEXP_BASE wxMBConvUTF8 : public wxMBConv { public: - enum { + enum + { MAP_INVALID_UTF8_NOT = 0, MAP_INVALID_UTF8_TO_PUA = 1, MAP_INVALID_UTF8_TO_OCTAL = 2 @@ -229,6 +248,8 @@ public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + virtual wxMBConv *Clone() const { return new wxMBConvUTF8(m_options); } + private: int m_options; }; @@ -252,6 +273,7 @@ class WXDLLIMPEXP_BASE wxMBConvUTF16LE : public wxMBConvUTF16Base public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + virtual wxMBConv *Clone() const { return new wxMBConvUTF16LE; } }; // ---------------------------------------------------------------------------- @@ -263,6 +285,7 @@ class WXDLLIMPEXP_BASE wxMBConvUTF16BE : public wxMBConvUTF16Base public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + virtual wxMBConv *Clone() const { return new wxMBConvUTF16BE; } }; // ---------------------------------------------------------------------------- @@ -284,6 +307,7 @@ class WXDLLIMPEXP_BASE wxMBConvUTF32LE : public wxMBConvUTF32Base public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + virtual wxMBConv *Clone() const { return new wxMBConvUTF32LE; } }; // ---------------------------------------------------------------------------- @@ -295,6 +319,7 @@ class WXDLLIMPEXP_BASE wxMBConvUTF32BE : public wxMBConvUTF32Base public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; + virtual wxMBConv *Clone() const { return new wxMBConvUTF32BE; } }; // ---------------------------------------------------------------------------- @@ -319,8 +344,9 @@ public: virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const; virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const; virtual size_t GetMBNulLen() const; + virtual wxMBConv *Clone() const { return new wxCSConv(*this); } - void Clear() ; + void Clear(); private: // common part of all ctors @@ -456,6 +482,5 @@ extern WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent; #define wxConvertMB2WX(s) (s) #endif // Unicode/ANSI -#endif - // _WX_WXSTRCONVH__ +#endif // _WX_STRCONV_H_ diff --git a/include/wx/txtstrm.h b/include/wx/txtstrm.h index d8011a8e49..b5d94c749f 100644 --- a/include/wx/txtstrm.h +++ b/include/wx/txtstrm.h @@ -81,7 +81,7 @@ protected: char m_lastBytes[10]; // stores the bytes that were read for the last character #if wxUSE_UNICODE - wxMBConv m_conv; + wxMBConv *m_conv; #endif bool EatEOL(const wxChar &c); @@ -144,7 +144,7 @@ protected: wxEOL m_mode; #if wxUSE_UNICODE - wxMBConv m_conv; + wxMBConv *m_conv; #endif DECLARE_NO_COPY_CLASS(wxTextOutputStream) diff --git a/src/common/datstrm.cpp b/src/common/datstrm.cpp index 67a2e45805..b4a4816f45 100644 --- a/src/common/datstrm.cpp +++ b/src/common/datstrm.cpp @@ -27,7 +27,7 @@ #if wxUSE_UNICODE wxDataInputStream::wxDataInputStream(wxInputStream& s, const wxMBConv& conv) - : m_input(&s), m_be_order(false), m_conv(conv) + : m_input(&s), m_be_order(false), m_conv(conv.Clone()) #else wxDataInputStream::wxDataInputStream(wxInputStream& s) : m_input(&s), m_be_order(false) @@ -35,6 +35,13 @@ wxDataInputStream::wxDataInputStream(wxInputStream& s) { } +wxDataInputStream::~wxDataInputStream() +{ +#if wxUSE_UNICODE + delete m_conv; +#endif // wxUSE_UNICODE +} + #if wxHAS_INT64 wxUint64 wxDataInputStream::Read64() { @@ -100,7 +107,7 @@ wxString wxDataInputStream::ReadString() wxCharBuffer tmp(len + 1); m_input->Read(tmp.data(), len); tmp.data()[len] = '\0'; - wxString ret(m_conv.cMB2WX(tmp.data())); + wxString ret(m_conv->cMB2WX(tmp.data())); #else wxString ret; m_input->Read( wxStringBuffer(ret, len), len); @@ -446,7 +453,7 @@ wxDataInputStream& wxDataInputStream::operator>>(float& f) #if wxUSE_UNICODE wxDataOutputStream::wxDataOutputStream(wxOutputStream& s, const wxMBConv& conv) - : m_output(&s), m_be_order(false), m_conv(conv) + : m_output(&s), m_be_order(false), m_conv(conv.Clone()) #else wxDataOutputStream::wxDataOutputStream(wxOutputStream& s) : m_output(&s), m_be_order(false) @@ -454,6 +461,13 @@ wxDataOutputStream::wxDataOutputStream(wxOutputStream& s) { } +wxDataOutputStream::~wxDataOutputStream() +{ +#if wxUSE_UNICODE + delete m_conv; +#endif // wxUSE_UNICODE +} + #if wxHAS_INT64 void wxDataOutputStream::Write64(wxUint64 i) { @@ -497,7 +511,7 @@ void wxDataOutputStream::Write8(wxUint8 i) void wxDataOutputStream::WriteString(const wxString& string) { #if wxUSE_UNICODE - const wxWX2MBbuf buf = string.mb_str(m_conv); + const wxWX2MBbuf buf = string.mb_str(*m_conv); #else const wxWX2MBbuf buf = string.mb_str(); #endif diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 80a0248e97..ed3d444868 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -1417,10 +1417,16 @@ public: virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const; virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const; - // classify this encoding as explained in wxMBConv::GetMBNulLen() - // comment + // classify this encoding as explained in wxMBConv::GetMBNulLen() comment virtual size_t GetMBNulLen() const; + virtual wxMBConv *Clone() const + { + wxMBConv_iconv *p = new wxMBConv_iconv(m_name); + p->m_minMBCharWidth = m_minMBCharWidth; + return p; + } + bool IsOk() const { return (m2w != ICONV_T_INVALID) && (w2m != ICONV_T_INVALID); } @@ -1443,6 +1449,10 @@ private: // different endian-ness than the native one static bool ms_wcNeedsSwap; + + // name of the encoding handled by this conversion + wxString m_name; + // cached result of GetMBNulLen(); set to 0 meaning "unknown" // initially size_t m_minMBCharWidth; @@ -1464,6 +1474,7 @@ wxString wxMBConv_iconv::ms_wcCharsetName; bool wxMBConv_iconv::ms_wcNeedsSwap = false; wxMBConv_iconv::wxMBConv_iconv(const wxChar *name) + : m_name(name) { m_minMBCharWidth = 0; @@ -1800,6 +1811,12 @@ public: m_minMBCharWidth = 0; } + wxMBConv_win32(const wxMBConv_win32& conv) + { + m_CodePage = conv.m_CodePage; + m_minMBCharWidth = conv.m_minMBCharWidth; + } + #if wxUSE_FONTMAP wxMBConv_win32(const wxChar* name) { @@ -1814,7 +1831,7 @@ public: } #endif // wxUSE_FONTMAP - size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const + virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const { // note that we have to use MB_ERR_INVALID_CHARS flag as it without it // the behaviour is not compatible with the Unix version (using iconv) @@ -1890,7 +1907,7 @@ public: return len - 1; } - size_t WC2MB(char *buf, const wchar_t *pwz, size_t n) const + virtual size_t WC2MB(char *buf, const wchar_t *pwz, size_t n) const { /* we have a problem here: by default, WideCharToMultiByte() may @@ -2009,6 +2026,8 @@ public: return m_minMBCharWidth; } + virtual wxMBConv *Clone() const { return new wxMBConv_win32(*this); } + bool IsOk() const { return m_CodePage != -1; } private: @@ -2356,6 +2375,11 @@ public: Init(CFStringGetSystemEncoding()) ; } + wxMBConv_cocoa(const wxMBConv_cocoa& conv) + { + m_encoding = conv.m_encoding; + } + #if wxUSE_FONTMAP wxMBConv_cocoa(const wxChar* name) { @@ -2478,6 +2502,10 @@ public: return nRealOutSize - 1; } + virtual wxMBConv *Clone() const { return new wxMBConv_cocoa(*this); } + + bool IsOk() const + bool IsOk() const { return m_encoding != kCFStringEncodingInvalidId && @@ -2504,6 +2532,11 @@ public: Init(CFStringGetSystemEncoding()) ; } + wxMBConv_mac(const wxMBConv_mac& conv) + { + Init(conv.m_char_encoding); + } + #if wxUSE_FONTMAP wxMBConv_mac(const wxChar* name) { @@ -2636,6 +2669,9 @@ public: return res ; } + virtual wxMBConv *Clone() const { return wxMBConv_mac(*this); } + + bool IsOk() const bool IsOk() const { return m_MB2WC_converter != NULL && m_WC2MB_converter != NULL ; } @@ -2724,6 +2760,8 @@ public: } } + virtual wxMBConv *Clone() const { return new wxMBConv_wxwin(m_enc); } + bool IsOk() const { return m_ok; } public: diff --git a/src/common/txtstrm.cpp b/src/common/txtstrm.cpp index 884c4b84c0..1ac783c88f 100644 --- a/src/common/txtstrm.cpp +++ b/src/common/txtstrm.cpp @@ -38,7 +38,7 @@ wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep, const wxMBConv& conv) - : m_input(s), m_separators(sep), m_conv(conv) + : m_input(s), m_separators(sep), m_conv(conv.Clone()) { memset((void*)m_lastBytes, 0, 10); } @@ -52,6 +52,9 @@ wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep) wxTextInputStream::~wxTextInputStream() { +#if wxUSE_UNICODE + delete m_conv; +#endif // wxUSE_UNICODE } void wxTextInputStream::UngetLast() @@ -76,7 +79,7 @@ wxChar wxTextInputStream::NextChar() if(m_input.LastRead() <= 0) return wxEOT; - int retlen = (int) m_conv.MB2WC(wbuf, m_lastBytes, 2); // returns -1 for failure + int retlen = (int) m_conv->MB2WC(wbuf, m_lastBytes, 2); // returns -1 for failure if(retlen >= 0) // res == 0 could happen for '\0' char return wbuf[0]; } @@ -303,7 +306,7 @@ wxTextInputStream& wxTextInputStream::operator>>(float& f) wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode, const wxMBConv& conv) - : m_output(s), m_conv(conv) + : m_output(s), m_conv(conv.Clone()) #else wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode) : m_output(s) @@ -324,6 +327,9 @@ wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode) wxTextOutputStream::~wxTextOutputStream() { +#if wxUSE_UNICODE + delete m_conv; +#endif // wxUSE_UNICODE } void wxTextOutputStream::SetMode(wxEOL mode) @@ -410,7 +416,7 @@ void wxTextOutputStream::WriteString(const wxString& string) // We must not write the trailing NULL here #if wxUSE_UNICODE - wxCharBuffer buffer = m_conv.cWC2MB( out ); + wxCharBuffer buffer = m_conv->cWC2MB( out ); m_output.Write( (const char*) buffer, strlen( (const char*) buffer ) ); #else m_output.Write(out.c_str(), out.length() ); @@ -420,7 +426,7 @@ void wxTextOutputStream::WriteString(const wxString& string) wxTextOutputStream& wxTextOutputStream::PutChar(wxChar c) { #if wxUSE_UNICODE - WriteString( wxString(&c, m_conv, 1) ); + WriteString( wxString(&c, *m_conv, 1) ); #else WriteString( wxString(&c, wxConvLocal, 1) ); #endif @@ -450,7 +456,7 @@ wxTextOutputStream& wxTextOutputStream::operator<<(char c) wxTextOutputStream& wxTextOutputStream::operator<<(wchar_t wc) { - WriteString( wxString(&wc, m_conv, 1) ); + WriteString( wxString(&wc, *m_conv, 1) ); return *this; } -- 2.47.2