Refactor wxLog and wxMessageOutput classes to avoid duplication
Add wxMessageOutputWithConv mix-in class to avoid duplicating the same code in wxLogStream and wxMessageOutputStderr. Also derive wxLogStderr from wxMessageOutputStderr to reuse its code without having to create a temporary object of this type (which will be more expensive now that doing it involves creating a heap-allocated conversion object copy).
This commit is contained in:
@@ -61,6 +61,7 @@ class WXDLLIMPEXP_FWD_BASE wxObject;
|
|||||||
|
|
||||||
#include "wx/dynarray.h"
|
#include "wx/dynarray.h"
|
||||||
#include "wx/hashmap.h"
|
#include "wx/hashmap.h"
|
||||||
|
#include "wx/msgout.h"
|
||||||
|
|
||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
@@ -716,34 +717,31 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
// log everything to a "FILE *", stderr by default
|
// log everything to a "FILE *", stderr by default
|
||||||
class WXDLLIMPEXP_BASE wxLogStderr : public wxLog
|
class WXDLLIMPEXP_BASE wxLogStderr : public wxLog,
|
||||||
|
private wxMessageOutputStderr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// redirect log output to a FILE
|
// redirect log output to a FILE
|
||||||
wxLogStderr(FILE *fp = NULL,
|
wxLogStderr(FILE *fp = NULL,
|
||||||
const wxMBConv &conv = wxConvWhateverWorks);
|
const wxMBConv &conv = wxConvWhateverWorks);
|
||||||
virtual ~wxLogStderr();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// implement sink function
|
// implement sink function
|
||||||
virtual void DoLogText(const wxString& msg) wxOVERRIDE;
|
virtual void DoLogText(const wxString& msg) wxOVERRIDE;
|
||||||
|
|
||||||
FILE *m_fp;
|
|
||||||
const wxMBConv *m_conv;
|
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(wxLogStderr);
|
wxDECLARE_NO_COPY_CLASS(wxLogStderr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if wxUSE_STD_IOSTREAM
|
#if wxUSE_STD_IOSTREAM
|
||||||
|
|
||||||
// log everything to an "ostream", cerr by default
|
// log everything to an "ostream", cerr by default
|
||||||
class WXDLLIMPEXP_BASE wxLogStream : public wxLog
|
class WXDLLIMPEXP_BASE wxLogStream : public wxLog,
|
||||||
|
private wxMessageOutputWithConv
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// redirect log output to an ostream
|
// redirect log output to an ostream
|
||||||
wxLogStream(wxSTD ostream *ostr = (wxSTD ostream *) NULL,
|
wxLogStream(wxSTD ostream *ostr = (wxSTD ostream *) NULL,
|
||||||
const wxMBConv &conv = wxConvWhateverWorks);
|
const wxMBConv& conv = wxConvWhateverWorks);
|
||||||
virtual ~wxLogStream();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// implement sink function
|
// implement sink function
|
||||||
@@ -751,7 +749,8 @@ protected:
|
|||||||
|
|
||||||
// using ptr here to avoid including <iostream.h> from this file
|
// using ptr here to avoid including <iostream.h> from this file
|
||||||
wxSTD ostream *m_ostr;
|
wxSTD ostream *m_ostr;
|
||||||
const wxMBConv *m_conv;
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxLogStream);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_STD_IOSTREAM
|
#endif // wxUSE_STD_IOSTREAM
|
||||||
|
@@ -58,25 +58,51 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// implementation which sends output to stderr or specified file
|
// helper mix-in for output targets that can use difference encodings
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class WXDLLIMPEXP_BASE wxMessageOutputStderr : public wxMessageOutput
|
class WXDLLIMPEXP_BASE wxMessageOutputWithConv
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
wxMessageOutputStderr(FILE *fp = stderr,
|
|
||||||
const wxMBConv &conv = wxConvWhateverWorks);
|
|
||||||
virtual ~wxMessageOutputStderr();
|
|
||||||
|
|
||||||
virtual void Output(const wxString& str) wxOVERRIDE;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
explicit wxMessageOutputWithConv(const wxMBConv& conv)
|
||||||
|
: m_conv(conv.Clone())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~wxMessageOutputWithConv()
|
||||||
|
{
|
||||||
|
delete m_conv;
|
||||||
|
}
|
||||||
|
|
||||||
// return the string with "\n" appended if it doesn't already terminate
|
// return the string with "\n" appended if it doesn't already terminate
|
||||||
// with it (in which case it's returned unchanged)
|
// with it (in which case it's returned unchanged)
|
||||||
wxString AppendLineFeedIfNeeded(const wxString& str);
|
wxString AppendLineFeedIfNeeded(const wxString& str);
|
||||||
|
|
||||||
|
// Prepare the given string for output by appending a new line to it, if
|
||||||
|
// necessary, and converting it to a narrow string using our conversion
|
||||||
|
// object.
|
||||||
|
wxCharBuffer PrepareForOutput(const wxString& str);
|
||||||
|
|
||||||
|
const wxMBConv* const m_conv;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// implementation which sends output to stderr or specified file
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_BASE wxMessageOutputStderr : public wxMessageOutput,
|
||||||
|
protected wxMessageOutputWithConv
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxMessageOutputStderr(FILE *fp = stderr,
|
||||||
|
const wxMBConv &conv = wxConvWhateverWorks);
|
||||||
|
|
||||||
|
virtual void Output(const wxString& str) wxOVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
FILE *m_fp;
|
FILE *m_fp;
|
||||||
const wxMBConv *m_conv;
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxMessageOutputStderr);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -839,18 +839,9 @@ void wxLogBuffer::DoLogTextAtLevel(wxLogLevel level, const wxString& msg)
|
|||||||
// wxLogStderr class implementation
|
// wxLogStderr class implementation
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxLogStderr::wxLogStderr(FILE *fp, const wxMBConv &conv):
|
wxLogStderr::wxLogStderr(FILE *fp, const wxMBConv& conv)
|
||||||
m_conv(conv.Clone())
|
: wxMessageOutputStderr(fp ? fp : stderr, conv)
|
||||||
{
|
{
|
||||||
if ( fp == NULL )
|
|
||||||
m_fp = stderr;
|
|
||||||
else
|
|
||||||
m_fp = fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxLogStderr::~wxLogStderr()
|
|
||||||
{
|
|
||||||
delete m_conv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxLogStderr::DoLogText(const wxString& msg)
|
void wxLogStderr::DoLogText(const wxString& msg)
|
||||||
@@ -858,7 +849,7 @@ void wxLogStderr::DoLogText(const wxString& msg)
|
|||||||
// First send it to stderr, even if we don't have it (e.g. in a Windows GUI
|
// First send it to stderr, even if we don't have it (e.g. in a Windows GUI
|
||||||
// application under) it's not a problem to try to use it and it's easier
|
// application under) it's not a problem to try to use it and it's easier
|
||||||
// than determining whether we do have it or not.
|
// than determining whether we do have it or not.
|
||||||
wxMessageOutputStderr(m_fp, *m_conv).Output(msg);
|
wxMessageOutputStderr::Output(msg);
|
||||||
|
|
||||||
// under GUI systems such as Windows or Mac, programs usually don't have
|
// under GUI systems such as Windows or Mac, programs usually don't have
|
||||||
// stderr at all, so show the messages also somewhere else, typically in
|
// stderr at all, so show the messages also somewhere else, typically in
|
||||||
@@ -880,8 +871,8 @@ void wxLogStderr::DoLogText(const wxString& msg)
|
|||||||
|
|
||||||
#if wxUSE_STD_IOSTREAM
|
#if wxUSE_STD_IOSTREAM
|
||||||
#include "wx/ioswrap.h"
|
#include "wx/ioswrap.h"
|
||||||
wxLogStream::wxLogStream(wxSTD ostream *ostr, const wxMBConv &conv):
|
wxLogStream::wxLogStream(wxSTD ostream *ostr, const wxMBConv& conv)
|
||||||
m_conv(conv.Clone())
|
: wxMessageOutputWithConv(conv)
|
||||||
{
|
{
|
||||||
if ( ostr == NULL )
|
if ( ostr == NULL )
|
||||||
m_ostr = &wxSTD cerr;
|
m_ostr = &wxSTD cerr;
|
||||||
@@ -889,29 +880,9 @@ m_conv(conv.Clone())
|
|||||||
m_ostr = ostr;
|
m_ostr = ostr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogStream::~wxLogStream()
|
|
||||||
{
|
|
||||||
delete m_conv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxLogStream::DoLogText(const wxString& msg)
|
void wxLogStream::DoLogText(const wxString& msg)
|
||||||
{
|
{
|
||||||
wxString msgLF(msg);
|
const wxCharBuffer& buf = PrepareForOutput(msg);
|
||||||
if ( msgLF.empty() || *msgLF.rbegin() != '\n' )
|
|
||||||
msgLF += '\n';
|
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
|
||||||
// Determine whether the encoding is UTF-16. In that case, the file
|
|
||||||
// should have been opened in "wb" mode, and EOL-style must be handled
|
|
||||||
// here.
|
|
||||||
|
|
||||||
if (m_conv->GetMBNulLen() == 2)
|
|
||||||
{
|
|
||||||
msgLF.Replace("\n", "\r\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const wxCharBuffer buf = m_conv->cWX2MB(msgLF.c_str());
|
|
||||||
m_ostr->write(buf, buf.length());
|
m_ostr->write(buf, buf.length());
|
||||||
}
|
}
|
||||||
#endif // wxUSE_STD_IOSTREAM
|
#endif // wxUSE_STD_IOSTREAM
|
||||||
|
@@ -133,21 +133,10 @@ void wxMessageOutputBest::Output(const wxString& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxMessageOutputStderr
|
// wxMessageOutputWithConv
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxMessageOutputStderr::wxMessageOutputStderr(FILE *fp,
|
wxString wxMessageOutputWithConv::AppendLineFeedIfNeeded(const wxString& str)
|
||||||
const wxMBConv &conv):
|
|
||||||
m_fp(fp), m_conv(conv.Clone())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMessageOutputStderr::~wxMessageOutputStderr()
|
|
||||||
{
|
|
||||||
delete m_conv;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMessageOutputStderr::AppendLineFeedIfNeeded(const wxString& str)
|
|
||||||
{
|
{
|
||||||
wxString strLF(str);
|
wxString strLF(str);
|
||||||
if ( strLF.empty() || *strLF.rbegin() != '\n' )
|
if ( strLF.empty() || *strLF.rbegin() != '\n' )
|
||||||
@@ -156,23 +145,36 @@ wxString wxMessageOutputStderr::AppendLineFeedIfNeeded(const wxString& str)
|
|||||||
return strLF;
|
return strLF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMessageOutputStderr::Output(const wxString& str)
|
wxCharBuffer wxMessageOutputWithConv::PrepareForOutput(const wxString& str)
|
||||||
{
|
{
|
||||||
wxString strWithLF = AppendLineFeedIfNeeded(str);
|
wxString strWithLF = AppendLineFeedIfNeeded(str);
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
// Determine whether the encoding is UTF-16. In that case, the file
|
// Determine whether the encoding is UTF-16. In that case, the file
|
||||||
// should have been opened in "wb" mode, and EOL-style must be handled
|
// should have been opened in "wb" mode, and EOL conversion must be done
|
||||||
// here.
|
// here as it won't be done at stdio level.
|
||||||
|
if ( m_conv->GetMBNulLen() == 2 )
|
||||||
if (m_conv->GetMBNulLen() == 2)
|
|
||||||
{
|
{
|
||||||
strWithLF.Replace("\n", "\r\n");
|
strWithLF.Replace("\n", "\r\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif // __WINDOWS__
|
||||||
|
|
||||||
const wxCharBuffer buf = m_conv->cWX2MB(strWithLF.c_str());
|
return m_conv->cWX2MB(strWithLF.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMessageOutputStderr
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxMessageOutputStderr::wxMessageOutputStderr(FILE *fp, const wxMBConv& conv)
|
||||||
|
: wxMessageOutputWithConv(conv),
|
||||||
|
m_fp(fp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMessageOutputStderr::Output(const wxString& str)
|
||||||
|
{
|
||||||
|
const wxCharBuffer& buf = PrepareForOutput(str);
|
||||||
fwrite(buf, buf.length(), 1, m_fp);
|
fwrite(buf, buf.length(), 1, m_fp);
|
||||||
fflush(m_fp);
|
fflush(m_fp);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user