00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #ifndef _WXCURL_THREAD_H_
00012 #define _WXCURL_THREAD_H_
00013
00014
00015 #include "wx/defs.h"
00016 #include "wx/thread.h"
00017
00018 #include "wx/curl/base.h"
00019
00020
00022 enum wxCurlProtocol
00023 {
00024 wxCP_INVALID = -1,
00025
00026 wxCP_HTTP,
00027 wxCP_FTP
00028 };
00029
00031 enum wxCurlThreadError
00032 {
00033 wxCTE_NO_ERROR = wxTHREAD_NO_ERROR,
00034
00035 wxCTE_NO_RESOURCE = wxTHREAD_NO_RESOURCE,
00036 wxCTE_ALREADY_RUNNING = wxTHREAD_RUNNING,
00037 wxCTE_INVALID_PROTOCOL,
00038 wxCTE_NO_VALID_STREAM,
00039 wxCTE_ABORTED,
00040 wxCTE_CURL_ERROR
00042 };
00043
00045 #define wxCURL_THREAD_STACK_SIZE 2048
00046
00047
00048
00049
00050
00051
00053 class WXDLLIMPEXP_CURL wxCurlBaseThread : public wxThread
00054 {
00055 protected:
00056
00058 wxString m_url;
00059
00061 wxCurlBase *m_pCurl;
00062
00064 wxCurlProtocol m_protocol;
00065
00067 wxEvtHandler *m_pHandler;
00068 int m_nId;
00069
00073 bool m_bAbort;
00074 wxMutex m_bAbortMutex;
00075
00076 public:
00077 wxCurlBaseThread(wxEvtHandler *handler = NULL,
00078 int id = wxID_ANY)
00079 : wxThread(wxTHREAD_JOINABLE)
00080 {
00081 m_protocol = wxCP_INVALID;
00082 m_pCurl = NULL;
00083
00084 m_nId = id;
00085 m_pHandler = handler;
00086
00087 m_bAbort = false;
00088 }
00089
00090 public:
00091
00093 virtual bool IsOk() const
00094 { return !m_url.empty() && m_pCurl!=NULL; }
00095
00098 virtual wxCurlThreadError StartTransfer() = 0;
00099
00101 virtual void Abort();
00102
00104 virtual wxCurlThreadError Wait();
00105
00107 virtual wxCurlThreadError Pause();
00108
00110 virtual wxCurlThreadError Resume();
00111
00112
00113 public:
00114
00117 void SetEvtHandler(wxEvtHandler *handler, int id = wxID_ANY)
00118 {
00119 wxCHECK_RET(!IsAlive(), wxT("Cannot use this function after the tranfer has begun"));
00120 m_pHandler=handler; m_nId=id;
00121 }
00122
00124 wxCurlThreadError SetURL(const wxString &url);
00125
00126 public:
00127
00128 wxEvtHandler *GetEvtHandler() const
00129 { return m_pHandler; }
00130 int GetId() const
00131 { return m_nId; }
00132
00138 wxCurlBase *GetCurlSession() const
00139 { return m_pCurl; }
00140
00144 wxCurlProtocol GetProtocol() const
00145 { return m_protocol; }
00146
00148 wxString GetURL() const
00149 { return m_url; }
00150
00151 public:
00152
00155 static wxCurlProtocol GetProtocolFromURL(const wxString &url);
00156
00162 static wxCurlBase *CreateHandlerFor(wxCurlProtocol prot);
00163
00164 protected:
00165
00166 virtual bool TestDestroy();
00167 virtual void OnExit();
00168
00169
00170
00171
00172
00173 virtual wxCurlThreadError Create(unsigned int stackSize)
00174 { return (wxCurlThreadError)wxThread::Create(stackSize); }
00175 virtual wxCurlThreadError Run()
00176 { return (wxCurlThreadError)wxThread::Run(); }
00177 virtual wxCurlThreadError Delete()
00178 { return (wxCurlThreadError)wxThread::Delete(); }
00179 };
00180
00181
00182
00183
00184
00185
00186 class WXDLLIMPEXP_CURL wxCurlDownloadThread;
00187
00188
00189 class wxCurlDownloadThreadOutputFilter : public wxOutputStream
00190 {
00191 protected:
00192 wxCurlDownloadThread *m_thread;
00193 wxOutputStream *m_stream;
00194
00195 public:
00196 wxCurlDownloadThreadOutputFilter(wxCurlDownloadThread *thread)
00197 { m_thread = thread; m_stream = NULL; }
00198
00199 void SetStream(wxOutputStream *realStream)
00200 { m_stream = realStream; }
00201
00202 virtual size_t OnSysWrite(const void *buffer, size_t bufsize);
00203
00204 virtual bool IsOk() const
00205 { return m_thread && m_stream && m_stream->IsOk(); }
00206
00207 wxOutputStream *GetRealStream() const
00208 { return m_stream; }
00209
00210 wxFileOffset GetLength() const
00211 { return m_stream->GetLength(); }
00212
00213 bool Close()
00214 { return m_stream->Close(); }
00215 };
00216
00217
00218
00219
00220
00221
00224 class WXDLLIMPEXP_CURL wxCurlDownloadThread : public wxCurlBaseThread
00225 {
00226 friend class wxCurlDownloadThreadOutputFilter;
00227
00228 protected:
00229
00231 wxCurlDownloadThreadOutputFilter m_output;
00232
00233 public:
00234 wxCurlDownloadThread(wxEvtHandler *handler = NULL,
00235 int id = wxID_ANY,
00236 const wxString &url = wxEmptyString,
00237 wxOutputStream *out = NULL)
00238 : wxCurlBaseThread(handler, id),
00239 m_output(this)
00240 {
00241 if (!url.IsEmpty())
00242 Download(url, out);
00243 }
00244
00245 public:
00246
00249 wxCurlThreadError SetOutputStream(wxOutputStream *out = NULL);
00250
00252 wxOutputStream *GetOutputStream() const
00253 {
00254 wxCHECK_MSG(!IsRunning(), NULL,
00255 wxT("You cannot access the output stream while the thread is running!"));
00256 return m_output.GetRealStream();
00257 }
00258
00260 virtual bool IsOk() const
00261 { return wxCurlBaseThread::IsOk() && m_output.IsOk(); }
00262
00265 wxCurlThreadError Download(const wxString &url, wxOutputStream *out = NULL);
00266
00269 wxCurlThreadError Download();
00270
00271 protected:
00272
00273
00274 virtual wxCurlThreadError StartTransfer()
00275 { return Download(); }
00276
00277 virtual void *Entry();
00278 };
00279
00280
00281
00282
00283
00284
00285 class WXDLLIMPEXP_CURL wxCurlUploadThread;
00286
00287
00288 class wxCurlUploadThreadInputFilter : public wxInputStream
00289 {
00290 protected:
00291 wxCurlUploadThread *m_thread;
00292 wxInputStream *m_stream;
00293
00294 public:
00295 wxCurlUploadThreadInputFilter(wxCurlUploadThread *thread)
00296 { m_thread = thread; m_stream = NULL; }
00297
00298 void SetStream(wxInputStream *realStream)
00299 { m_stream = realStream; }
00300
00301 virtual size_t OnSysRead(void *buffer, size_t bufsize);
00302
00303 virtual bool IsOk() const
00304 { return m_thread && m_stream && m_stream->IsOk(); }
00305
00306 wxInputStream *GetRealStream() const
00307 { return m_stream; }
00308
00309 wxFileOffset GetLength() const
00310 { return m_stream->GetLength(); }
00311
00312 char Peek()
00313 { return m_stream->Peek(); }
00314 };
00315
00316
00317
00318
00319
00320
00323 class WXDLLIMPEXP_CURL wxCurlUploadThread : public wxCurlBaseThread
00324 {
00325 friend class wxCurlUploadThreadInputFilter;
00326
00327 protected:
00328
00330 wxCurlUploadThreadInputFilter m_input;
00331
00332 public:
00333 wxCurlUploadThread(wxEvtHandler *handler = NULL,
00334 int id = wxID_ANY,
00335 const wxString &url = wxEmptyString,
00336 wxInputStream *in = NULL)
00337 : wxCurlBaseThread(handler, id),
00338 m_input(this)
00339 {
00340 if (!url.IsEmpty())
00341 Upload(url, in);
00342 }
00343
00344 public:
00345
00348 wxCurlThreadError SetInputStream(wxInputStream *in = NULL);
00349
00351 wxInputStream *GetInputStream() const
00352 {
00353 wxCHECK_MSG(!IsRunning(), NULL,
00354 wxT("You cannot access the output stream while the thread is running!"));
00355 return m_input.GetRealStream();
00356 }
00357
00359 virtual bool IsOk() const
00360 { return wxCurlBaseThread::IsOk() && m_input.IsOk(); }
00361
00364 wxCurlThreadError Upload(const wxString &url, wxInputStream *in = NULL);
00365
00368 wxCurlThreadError Upload();
00369
00370 protected:
00371
00372
00373 virtual wxCurlThreadError StartTransfer()
00374 { return Upload(); }
00375
00376 virtual void *Entry();
00377 };
00378
00379
00380 #endif // _WXCURL_THREAD_H_
00381