Set wxWebResponseCURL buffer size as soon as known
Currently for wxWebRequestCURL objects using memory storage, a download is processed by appending to a wxMemoryBuffer each time the write callback is called. For a large transfer, this can result in many, many reallocation calls and can block the main application. This commit uses the progress callback for wxWebRequestCURL objects added in a previous commit to set a minimum size for the buffer as soon as it is known.
This commit is contained in:
@@ -187,6 +187,10 @@ protected:
|
|||||||
|
|
||||||
void ReportDataReceived(size_t sizeReceived);
|
void ReportDataReceived(size_t sizeReceived);
|
||||||
|
|
||||||
|
// This function can optionally be called to preallocate the read buffer,
|
||||||
|
// if the total amount of data to be downloaded is known in advance.
|
||||||
|
void PreAllocBuffer(size_t sizeNeeded);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Called by wxWebRequestImpl only.
|
// Called by wxWebRequestImpl only.
|
||||||
friend class wxWebRequestImpl;
|
friend class wxWebRequestImpl;
|
||||||
|
@@ -114,11 +114,12 @@ public:
|
|||||||
// Methods called from libcurl callbacks
|
// Methods called from libcurl callbacks
|
||||||
size_t CURLOnWrite(void *buffer, size_t size);
|
size_t CURLOnWrite(void *buffer, size_t size);
|
||||||
size_t CURLOnHeader(const char* buffer, size_t size);
|
size_t CURLOnHeader(const char* buffer, size_t size);
|
||||||
int CURLOnProgress();
|
int CURLOnProgress(curl_off_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxWebRequestHeaderMap m_headers;
|
wxWebRequestHeaderMap m_headers;
|
||||||
wxString m_statusText;
|
wxString m_statusText;
|
||||||
|
wxFileOffset m_knownDownloadSize;
|
||||||
|
|
||||||
CURL* GetHandle() const
|
CURL* GetHandle() const
|
||||||
{ return static_cast<wxWebRequestCURL&>(m_request).GetHandle(); }
|
{ return static_cast<wxWebRequestCURL&>(m_request).GetHandle(); }
|
||||||
|
@@ -688,6 +688,11 @@ void* wxWebResponseImpl::GetDataBuffer(size_t sizeNeeded)
|
|||||||
return m_readBuffer.GetAppendBuf(sizeNeeded);
|
return m_readBuffer.GetAppendBuf(sizeNeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWebResponseImpl::PreAllocBuffer(size_t sizeNeeded)
|
||||||
|
{
|
||||||
|
m_readBuffer.SetBufSize(sizeNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
void wxWebResponseImpl::ReportDataReceived(size_t sizeReceived)
|
void wxWebResponseImpl::ReportDataReceived(size_t sizeReceived)
|
||||||
{
|
{
|
||||||
m_readBuffer.UngetAppendBuf(sizeReceived);
|
m_readBuffer.UngetAppendBuf(sizeReceived);
|
||||||
|
@@ -67,7 +67,7 @@ static size_t wxCURLHeader(char *buffer, size_t size, size_t nitems, void *userd
|
|||||||
return static_cast<wxWebResponseCURL*>(userdata)->CURLOnHeader(buffer, size * nitems);
|
return static_cast<wxWebResponseCURL*>(userdata)->CURLOnHeader(buffer, size * nitems);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxCURLXferInfo(void* clientp, curl_off_t WXUNUSED(dltotal),
|
int wxCURLXferInfo(void* clientp, curl_off_t dltotal,
|
||||||
curl_off_t WXUNUSED(dlnow),
|
curl_off_t WXUNUSED(dlnow),
|
||||||
curl_off_t WXUNUSED(ultotal),
|
curl_off_t WXUNUSED(ultotal),
|
||||||
curl_off_t WXUNUSED(ulnow))
|
curl_off_t WXUNUSED(ulnow))
|
||||||
@@ -75,7 +75,7 @@ int wxCURLXferInfo(void* clientp, curl_off_t WXUNUSED(dltotal),
|
|||||||
wxCHECK_MSG( clientp, 0, "invalid curl progress callback data" );
|
wxCHECK_MSG( clientp, 0, "invalid curl progress callback data" );
|
||||||
|
|
||||||
wxWebResponseCURL* response = reinterpret_cast<wxWebResponseCURL*>(clientp);
|
wxWebResponseCURL* response = reinterpret_cast<wxWebResponseCURL*>(clientp);
|
||||||
return response->CURLOnProgress();
|
return response->CURLOnProgress(dltotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxCURLProgress(void* clientp, double dltotal, double dlnow, double ultotal,
|
int wxCURLProgress(void* clientp, double dltotal, double dlnow, double ultotal,
|
||||||
@@ -90,6 +90,8 @@ int wxCURLProgress(void* clientp, double dltotal, double dlnow, double ultotal,
|
|||||||
wxWebResponseCURL::wxWebResponseCURL(wxWebRequestCURL& request) :
|
wxWebResponseCURL::wxWebResponseCURL(wxWebRequestCURL& request) :
|
||||||
wxWebResponseImpl(request)
|
wxWebResponseImpl(request)
|
||||||
{
|
{
|
||||||
|
m_knownDownloadSize = 0;
|
||||||
|
|
||||||
curl_easy_setopt(GetHandle(), CURLOPT_WRITEDATA, static_cast<void*>(this));
|
curl_easy_setopt(GetHandle(), CURLOPT_WRITEDATA, static_cast<void*>(this));
|
||||||
curl_easy_setopt(GetHandle(), CURLOPT_HEADERDATA, static_cast<void*>(this));
|
curl_easy_setopt(GetHandle(), CURLOPT_HEADERDATA, static_cast<void*>(this));
|
||||||
|
|
||||||
@@ -152,8 +154,17 @@ size_t wxWebResponseCURL::CURLOnHeader(const char * buffer, size_t size)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxWebResponseCURL::CURLOnProgress()
|
int wxWebResponseCURL::CURLOnProgress(curl_off_t total)
|
||||||
{
|
{
|
||||||
|
if ( m_knownDownloadSize != total )
|
||||||
|
{
|
||||||
|
if ( m_request.GetStorage() == wxWebRequest::Storage_Memory )
|
||||||
|
{
|
||||||
|
PreAllocBuffer(static_cast<size_t>(total));
|
||||||
|
}
|
||||||
|
m_knownDownloadSize = total;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user