diff --git a/Makefile.in b/Makefile.in
index ae4db8a245..280a2cb067 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -451,6 +451,7 @@ ALL_BASE_HEADERS = \
wx/protocol/file.h \
wx/protocol/ftp.h \
wx/protocol/http.h \
+ wx/protocol/log.h \
wx/protocol/protocol.h \
wx/sckaddr.h \
wx/sckipc.h \
@@ -647,6 +648,7 @@ ALL_PORTS_BASE_HEADERS = \
wx/protocol/file.h \
wx/protocol/ftp.h \
wx/protocol/http.h \
+ wx/protocol/log.h \
wx/protocol/protocol.h \
wx/sckaddr.h \
wx/sckipc.h \
diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl
index bb458ea250..3aa2b73060 100644
--- a/build/bakefiles/files.bkl
+++ b/build/bakefiles/files.bkl
@@ -580,6 +580,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/protocol/file.h
wx/protocol/ftp.h
wx/protocol/http.h
+ wx/protocol/log.h
wx/protocol/protocol.h
wx/sckaddr.h
wx/sckipc.h
diff --git a/build/msw/wx_net.dsp b/build/msw/wx_net.dsp
index 37dd4498c2..e2f61cf4e8 100644
--- a/build/msw/wx_net.dsp
+++ b/build/msw/wx_net.dsp
@@ -598,6 +598,10 @@ SOURCE=..\..\include\wx\protocol\http.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\protocol\log.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\protocol\protocol.h
# End Source File
# Begin Source File
diff --git a/build/msw/wx_vc7_net.vcproj b/build/msw/wx_vc7_net.vcproj
index 417d246324..72d7730d07 100644
--- a/build/msw/wx_vc7_net.vcproj
+++ b/build/msw/wx_vc7_net.vcproj
@@ -818,6 +818,9 @@
+
+
diff --git a/build/msw/wx_vc8_net.vcproj b/build/msw/wx_vc8_net.vcproj
index 9f9af1b089..90339ae10c 100644
--- a/build/msw/wx_vc8_net.vcproj
+++ b/build/msw/wx_vc8_net.vcproj
@@ -1114,6 +1114,10 @@
RelativePath="..\..\include\wx\protocol\http.h"
>
+
+
diff --git a/build/msw/wx_vc9_net.vcproj b/build/msw/wx_vc9_net.vcproj
index 115f9a0328..25eefa32b7 100644
--- a/build/msw/wx_vc9_net.vcproj
+++ b/build/msw/wx_vc9_net.vcproj
@@ -1110,6 +1110,10 @@
RelativePath="..\..\include\wx\protocol\http.h"
>
+
+
diff --git a/docs/changes.txt b/docs/changes.txt
index 3ca763a24b..9940b7bff4 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -370,6 +370,7 @@ All:
- Added wxStrnlen() for safe computation of string length.
- Added wxImage::Clear() (troelsk).
- Added wxLog::Log().
+- Added wxProtocolLog and use it in wxFTP.
- Added wxXmlResource::GetResourceNode().
All (Unix):
diff --git a/include/wx/protocol/log.h b/include/wx/protocol/log.h
new file mode 100644
index 0000000000..d11be42de3
--- /dev/null
+++ b/include/wx/protocol/log.h
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/protocol/log.h
+// Purpose: wxProtocolLog class for logging network exchanges
+// Author: Troelsk, Vadim Zeitlin
+// Created: 2009-03-06
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PROTOCOL_LOG_H_
+#define _WX_PROTOCOL_LOG_H_
+
+#include "wx/string.h"
+
+// ----------------------------------------------------------------------------
+// wxProtocolLog: simple class for logging network requests and responses
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_NET wxProtocolLog
+{
+public:
+ // Create object doing the logging using wxLogTrace() with the specified
+ // trace mask.
+ wxProtocolLog(const wxString& traceMask)
+ : m_traceMask(traceMask)
+ {
+ }
+
+ // Virtual dtor for the base class
+ virtual ~wxProtocolLog() { }
+
+ // Called by wxProtocol-derived classes to actually log something
+ virtual void LogRequest(const wxString& str)
+ {
+ DoLogString("==> " + str);
+ }
+
+ virtual void LogResponse(const wxString& str)
+ {
+ DoLogString("<== " + str);
+ }
+
+protected:
+ // Can be overridden by the derived classes.
+ virtual void DoLogString(const wxString& str);
+
+private:
+ const wxString m_traceMask;
+
+ wxDECLARE_NO_COPY_CLASS(wxProtocolLog);
+};
+
+#endif // _WX_PROTOCOL_LOG_H_
+
diff --git a/include/wx/protocol/protocol.h b/include/wx/protocol/protocol.h
index f26d22ba89..aaf3a63bf9 100644
--- a/include/wx/protocol/protocol.h
+++ b/include/wx/protocol/protocol.h
@@ -24,6 +24,8 @@
#include "wx/socket.h"
#endif
+class WXDLLIMPEXP_FWD_NET wxProtocolLog;
+
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
@@ -55,6 +57,7 @@ class WXDLLIMPEXP_NET wxProtocol
{
public:
wxProtocol();
+ virtual ~wxProtocol();
#if wxUSE_SOCKETS
bool Reconnect();
@@ -89,6 +92,30 @@ public:
{ SetDefaultTimeout(seconds); }
+ // logging support: each wxProtocol object may have the associated logger
+ // (by default there is none) which is used to log network requests and
+ // responses
+
+ // set the logger, deleting the old one and taking ownership of this one
+ void SetLog(wxProtocolLog *log);
+
+ // return the current logger, may be NULL
+ wxProtocolLog *GetLog() const { return m_log; }
+
+ // detach the existing logger without deleting it, the caller is
+ // responsible for deleting the returned pointer if it's non-NULL
+ wxProtocolLog *DetachLog()
+ {
+ wxProtocolLog * const log = m_log;
+ m_log = NULL;
+ return log;
+ }
+
+ // these functions forward to the same functions with the same names in
+ // wxProtocolLog if we have a valid logger and do nothing otherwise
+ void LogRequest(const wxString& str);
+ void LogResponse(const wxString& str);
+
protected:
// the timeout associated with the protocol:
wxUint32 m_uiDefaultTimeout;
@@ -100,6 +127,8 @@ protected:
wxProtocolError m_lastError;
private:
+ wxProtocolLog *m_log;
+
DECLARE_DYNAMIC_CLASS_NO_COPY(wxProtocol)
};
diff --git a/interface/wx/protocol/log.h b/interface/wx/protocol/log.h
new file mode 100644
index 0000000000..7570a8d34a
--- /dev/null
+++ b/interface/wx/protocol/log.h
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/protocol/log.h
+// Purpose: interface of wxProtocolLog
+// Author: Vadim Zeitlin
+// Created: 2009-03-06
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ Class allowing to log network operations performed by wxProtocol.
+
+ @library{wxnet}
+ @category{net}
+
+ @see wxProtocol
+*/
+class wxProtocolLog
+{
+public:
+ /**
+ Create object doing the logging using wxLogTrace() with the specified
+ trace mask.
+
+ If you override DoLogString() in your class the @a traceMask may be
+ left empty but it must have a valid value if you rely on the default
+ DoLogString() implementation.
+ */
+ wxProtocolLog(const wxString& traceMask);
+
+ /**
+ Called by wxProtocol-derived objects to log strings sent to the server.
+
+ Default implementation prepends a client-to-server marker to @a str and
+ calls DoLogString().
+ */
+ virtual void LogRequest(const wxString& str);
+
+ /**
+ Called by wxProtocol-derived objects to log strings received from the
+ server.
+
+ Default implementation prepends a server-to-client marker to @a str and
+ calls DoLogString().
+ */
+ virtual void LogResponse(const wxString& str);
+
+protected:
+ /**
+ Log the given string.
+
+ This function is called from LogRequest() and LogResponse() and by
+ default uses wxLogTrace() with the trace mask specified in the
+ constructor but can be overridden to do something different by the
+ derived classes.
+ */
+ virtual void DoLogString(const wxString& str);
+};
+
+
diff --git a/interface/wx/protocol/protocol.h b/interface/wx/protocol/protocol.h
index ea076402de..dc1586ac52 100644
--- a/interface/wx/protocol/protocol.h
+++ b/interface/wx/protocol/protocol.h
@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
-// Name: protocol/protocol.h
+// Name: wx/protocol/protocol.h
// Purpose: interface of wxProtocol
// Author: wxWidgets team
// RCS-ID: $Id$
@@ -107,5 +107,50 @@ public:
@see wxSocketBase::SetTimeout
*/
void SetDefaultTimeout(wxUint32 Value);
+
+ /**
+ @name Logging support.
+
+ Each wxProtocol object may have the associated logger (by default there
+ is none) which is used to log network requests and responses.
+
+ @see wxProtocolLog
+ */
+ //@{
+
+ /**
+ Set the logger, deleting the old one and taking ownership of this one.
+
+ @param log
+ New logger allocated on the heap or @NULL.
+ */
+ void SetLog(wxProtocolLog *log);
+
+ /**
+ Return the current logger, may be @NULL.
+ */
+ wxProtocolLog *GetLog() const { return m_log; }
+
+ /**
+ Detach the existing logger without deleting it.
+
+ The caller is responsible for deleting the returned pointer if it's
+ non-@c NULL.
+ */
+ wxProtocolLog *DetachLog();
+
+ /**
+ Call wxProtocolLog::LogRequest() if we have a valid logger or do
+ nothing otherwise.
+ */
+ void LogRequest(const wxString& str);
+
+ /**
+ Call wxProtocolLog::LogResponse() if we have a valid logger or do
+ nothing otherwise.
+ */
+ void LogResponse(const wxString& str);
+
+ //@}
};
diff --git a/samples/console/console.cpp b/samples/console/console.cpp
index 8a9a0705c6..a1af04971c 100644
--- a/samples/console/console.cpp
+++ b/samples/console/console.cpp
@@ -2455,6 +2455,7 @@ static void TestSocketClient()
#ifdef TEST_FTP
#include "wx/protocol/ftp.h"
+#include "wx/protocol/log.h"
#define FTP_ANONYMOUS
@@ -4403,6 +4404,7 @@ int main(int argc, char **argv)
// wxFTP cannot be a static variable as its ctor needs to access
// wxWidgets internals after it has been initialized
ftp = new wxFTP;
+ ftp->SetLog(new wxProtocolLog(FTP_TRACE_MASK));
if ( TestFtpConnect() )
{
diff --git a/src/common/ftp.cpp b/src/common/ftp.cpp
index e2854eeb6b..9b1cd2513b 100644
--- a/src/common/ftp.cpp
+++ b/src/common/ftp.cpp
@@ -257,7 +257,7 @@ char wxFTP::SendCommand(const wxString& command)
cmd = command;
}
- wxLogTrace(FTP_TRACE_MASK, _T("==> %s"), cmd.c_str());
+ LogRequest(cmd);
#endif // __WXDEBUG__
m_lastError = wxPROTO_NOERR;
@@ -301,6 +301,8 @@ char wxFTP::GetResult()
return 0;
}
+ LogResponse(line);
+
if ( !m_lastResult.empty() )
{
// separate from last line
@@ -317,11 +319,6 @@ char wxFTP::GetResult()
{
badReply = true;
}
- else
- {
- wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
- code.c_str(), line.c_str());
- }
}
else // line has at least 4 chars
{
@@ -331,8 +328,6 @@ char wxFTP::GetResult()
if ( firstLine )
{
code = wxString(line, LEN_CODE);
- wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
- code.c_str(), line.c_str() + LEN_CODE + 1);
switch ( chMarker )
{
@@ -357,15 +352,6 @@ char wxFTP::GetResult()
{
endOfReply = true;
}
-
- wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
- code.c_str(), line.c_str() + LEN_CODE + 1);
- }
- else
- {
- // just part of reply
- wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
- code.c_str(), line.c_str());
}
}
}
@@ -1008,8 +994,7 @@ int wxFTP::GetFileSize(const wxString& fileName)
&filesize) != 9 )
{
// Hmm... Invalid response
- wxLogTrace(FTP_TRACE_MASK,
- _T("Invalid LIST response"));
+ wxLogDebug(wxT("Invalid LIST response"));
}
}
else // Windows-style response (?)
@@ -1019,8 +1004,7 @@ int wxFTP::GetFileSize(const wxString& fileName)
&filesize) != 4 )
{
// something bad happened..?
- wxLogTrace(FTP_TRACE_MASK,
- _T("Invalid or unknown LIST response"));
+ wxLogDebug(wxT("Invalid or unknown LIST response"));
}
}
}
diff --git a/src/common/protocol.cpp b/src/common/protocol.cpp
index 4a06cf857b..2dfb4b40ab 100644
--- a/src/common/protocol.cpp
+++ b/src/common/protocol.cpp
@@ -19,6 +19,7 @@
#if wxUSE_PROTOCOL
#include "wx/protocol/protocol.h"
+#include "wx/protocol/log.h"
#ifndef WX_PRECOMP
#include "wx/module.h"
@@ -64,6 +65,7 @@ wxProtocol::wxProtocol()
#endif
{
m_lastError = wxPROTO_NOERR;
+ m_log = NULL;
SetDefaultTimeout(60); // default timeout is 60 seconds
}
@@ -95,6 +97,10 @@ void wxProtocol::SetDefaultTimeout(wxUint32 Value)
#endif
}
+wxProtocol::~wxProtocol()
+{
+ delete m_log;
+}
// ----------------------------------------------------------------------------
// Read a line from socket
@@ -179,4 +185,31 @@ wxProtocolError wxProtocol::ReadLine(wxString& result)
#endif // wxUSE_SOCKETS
+// ----------------------------------------------------------------------------
+// logging
+// ----------------------------------------------------------------------------
+
+void wxProtocol::SetLog(wxProtocolLog *log)
+{
+ delete m_log;
+ m_log = log;
+}
+
+void wxProtocol::LogRequest(const wxString& str)
+{
+ if ( m_log )
+ m_log->LogRequest(str);
+}
+
+void wxProtocol::LogResponse(const wxString& str)
+{
+ if ( m_log )
+ m_log->LogResponse(str);
+}
+
+void wxProtocolLog::DoLogString(const wxString& WXUNUSED_UNLESS_DEBUG(str))
+{
+ wxLogTrace(m_traceMask, "%s", str);
+}
+
#endif // wxUSE_PROTOCOL
diff --git a/wxGTK.spec b/wxGTK.spec
index 7bd321f1ff..aa3ca9669b 100644
--- a/wxGTK.spec
+++ b/wxGTK.spec
@@ -360,6 +360,7 @@ wx/fs_inet.h
wx/protocol/file.h
wx/protocol/ftp.h
wx/protocol/http.h
+wx/protocol/log.h
wx/protocol/protocol.h
wx/sckaddr.h
wx/sckipc.h
diff --git a/wxMotif.spec b/wxMotif.spec
index d1c674579b..03ac42fe17 100644
--- a/wxMotif.spec
+++ b/wxMotif.spec
@@ -265,6 +265,7 @@ wx/fs_inet.h
wx/protocol/file.h
wx/protocol/ftp.h
wx/protocol/http.h
+wx/protocol/log.h
wx/protocol/protocol.h
wx/sckaddr.h
wx/sckipc.h
diff --git a/wxX11.spec b/wxX11.spec
index 5a532f693f..657ae14529 100644
--- a/wxX11.spec
+++ b/wxX11.spec
@@ -289,6 +289,7 @@ wx/fs_inet.h
wx/protocol/file.h
wx/protocol/ftp.h
wx/protocol/http.h
+wx/protocol/log.h
wx/protocol/protocol.h
wx/sckaddr.h
wx/sckipc.h