mirror of https://github.com/axmolengine/axmol.git
Add get header and callback for Downloader
This commit is contained in:
parent
51f949540c
commit
ec41965add
|
@ -52,7 +52,7 @@ size_t bufferWriteFunc(void *ptr, size_t size, size_t nmemb, void *userdata)
|
|||
Downloader::StreamData *streamBuffer = (Downloader::StreamData *)userdata;
|
||||
size_t written = size * nmemb;
|
||||
// Avoid pointer overflow
|
||||
if (streamBuffer->offset + written <= static_cast<size_t>(streamBuffer->total))
|
||||
if (streamBuffer->offset + written <= static_cast<size_t>(streamBuffer->total))
|
||||
{
|
||||
memcpy(streamBuffer->buffer + streamBuffer->offset, ptr, written);
|
||||
streamBuffer->offset += written;
|
||||
|
@ -273,28 +273,74 @@ void Downloader::prepareDownload(const std::string &srcUrl, const std::string &s
|
|||
}
|
||||
}
|
||||
|
||||
bool Downloader::prepareHeader(void *curl, const std::string &srcUrl) const
|
||||
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
Downloader::HeaderInfo Downloader::prepare(const std::string &srcUrl)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_URL, srcUrl.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
||||
if (curl_easy_perform(curl) == CURLE_OK)
|
||||
return true;
|
||||
return prepareHeader(srcUrl);
|
||||
}
|
||||
#endif
|
||||
|
||||
Downloader::HeaderInfo Downloader::prepareHeader(const std::string &srcUrl, void* header/* = nullptr */)
|
||||
{
|
||||
bool headerGiven = true;
|
||||
HeaderInfo info;
|
||||
info.valid = false;
|
||||
|
||||
if (!header)
|
||||
{
|
||||
headerGiven = false;
|
||||
header = curl_easy_init();
|
||||
}
|
||||
|
||||
curl_easy_setopt(header, CURLOPT_URL, srcUrl.c_str());
|
||||
curl_easy_setopt(header, CURLOPT_HEADER, 1);
|
||||
curl_easy_setopt(header, CURLOPT_NOBODY, 1);
|
||||
if (curl_easy_perform(header) == CURLE_OK)
|
||||
{
|
||||
char *url;
|
||||
char *contentType;
|
||||
curl_easy_getinfo(header, CURLINFO_EFFECTIVE_URL, &url);
|
||||
curl_easy_getinfo(header, CURLINFO_CONTENT_TYPE, &contentType);
|
||||
curl_easy_getinfo(header, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &info.contentSize);
|
||||
curl_easy_getinfo(header, CURLINFO_RESPONSE_CODE, &info.responseCode);
|
||||
info.url = url;
|
||||
info.contentType = contentType;
|
||||
info.valid = true;
|
||||
|
||||
if (_onHeader)
|
||||
{
|
||||
_onHeader(srcUrl, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
{
|
||||
info.contentSize = -1;
|
||||
std::string msg = StringUtils::format("Can not get content size of file (%s) : Request header failed", srcUrl.c_str());
|
||||
this->notifyError(ErrorCode::PREPARE_HEADER_ERROR, msg);
|
||||
}
|
||||
|
||||
if (!headerGiven) {
|
||||
curl_easy_cleanup(header);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
long Downloader::getContentSize(const std::string &srcUrl) const
|
||||
long Downloader::getContentSize(const std::string &srcUrl)
|
||||
{
|
||||
double contentLength = -1;
|
||||
CURL *header = curl_easy_init();
|
||||
if (prepareHeader(header, srcUrl))
|
||||
{
|
||||
curl_easy_getinfo(header, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
|
||||
}
|
||||
curl_easy_cleanup(header);
|
||||
|
||||
return contentLength;
|
||||
HeaderInfo info = prepareHeader(srcUrl);
|
||||
return info.contentSize;
|
||||
}
|
||||
|
||||
void Downloader::getHeaderAsync(const std::string &srcUrl, const HeaderCallback &callback)
|
||||
{
|
||||
setHeaderCallback(callback);
|
||||
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
auto t = std::thread(&Downloader::prepare, this, srcUrl);
|
||||
#else
|
||||
auto t = std::thread(&Downloader::prepareHeader, this, srcUrl, nullptr);
|
||||
#endif
|
||||
t.detach();
|
||||
}
|
||||
|
||||
void Downloader::downloadToBufferAsync(const std::string &srcUrl, unsigned char *buffer, const long &size, const std::string &customId/* = ""*/)
|
||||
|
@ -482,11 +528,10 @@ void Downloader::batchDownloadSync(const DownloadUnits &units, const std::string
|
|||
CURL *header = curl_easy_init();
|
||||
// Make a resume request
|
||||
curl_easy_setopt(header, CURLOPT_RESUME_FROM_LARGE, 0);
|
||||
if (prepareHeader(header, units.begin()->second.srcUrl))
|
||||
HeaderInfo headerInfo = prepareHeader(units.begin()->second.srcUrl, header);
|
||||
if (headerInfo.valid)
|
||||
{
|
||||
long responseCode;
|
||||
curl_easy_getinfo(header, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
if (responseCode == HTTP_CODE_SUPPORT_RESUME)
|
||||
if (headerInfo.responseCode == HTTP_CODE_SUPPORT_RESUME)
|
||||
{
|
||||
_supportResuming = true;
|
||||
}
|
||||
|
@ -682,4 +727,4 @@ void Downloader::groupBatchDownload(const DownloadUnits &units)
|
|||
clearBatchDownloadData();
|
||||
}
|
||||
|
||||
NS_CC_EXT_END
|
||||
NS_CC_EXT_END
|
|
@ -60,7 +60,9 @@ public:
|
|||
|
||||
INVALID_URL,
|
||||
|
||||
INVALID_STORAGE_PATH
|
||||
INVALID_STORAGE_PATH,
|
||||
|
||||
PREPARE_HEADER_ERROR
|
||||
};
|
||||
|
||||
struct Error
|
||||
|
@ -99,11 +101,21 @@ public:
|
|||
unsigned char *buffer;
|
||||
};
|
||||
|
||||
struct HeaderInfo
|
||||
{
|
||||
bool valid;
|
||||
std::string url;
|
||||
std::string contentType;
|
||||
double contentSize;
|
||||
double responseCode;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, DownloadUnit> DownloadUnits;
|
||||
|
||||
typedef std::function<void(const Downloader::Error &)> ErrorCallback;
|
||||
typedef std::function<void(double, double, const std::string &, const std::string &)> ProgressCallback;
|
||||
typedef std::function<void(const std::string &, const std::string &, const std::string &)> SuccessCallback;
|
||||
typedef std::function<void(const std::string &, const HeaderInfo &)> HeaderCallback;
|
||||
|
||||
int getConnectionTimeout();
|
||||
|
||||
|
@ -114,6 +126,8 @@ public:
|
|||
void setProgressCallback(const ProgressCallback &callback) { _onProgress = callback; };
|
||||
|
||||
void setSuccessCallback(const SuccessCallback &callback) { _onSuccess = callback; };
|
||||
|
||||
void setHeaderCallback(const HeaderCallback &callback) { _onHeader = callback; };
|
||||
|
||||
ErrorCallback getErrorCallback() const { return _onError; };
|
||||
|
||||
|
@ -121,7 +135,11 @@ public:
|
|||
|
||||
SuccessCallback getSuccessCallback() const { return _onSuccess; };
|
||||
|
||||
long getContentSize(const std::string &srcUrl) const;
|
||||
HeaderCallback getHeaderCallback() const { return _onHeader; };
|
||||
|
||||
long getContentSize(const std::string &srcUrl);
|
||||
|
||||
void getHeaderAsync(const std::string &srcUrl, const HeaderCallback &callback);
|
||||
|
||||
void downloadToBufferAsync(const std::string &srcUrl, unsigned char *buffer, const long &size, const std::string &customId = "");
|
||||
|
||||
|
@ -152,7 +170,10 @@ protected:
|
|||
|
||||
void prepareDownload(const std::string &srcUrl, const std::string &storagePath, const std::string &customId, bool resumeDownload, FileDescriptor *fDesc, ProgressData *pData);
|
||||
|
||||
bool prepareHeader(void *curl, const std::string &srcUrl) const;
|
||||
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
HeaderInfo prepare(const std::string &srcUrl);
|
||||
#endif
|
||||
HeaderInfo prepareHeader(const std::string &srcUrl, void* header = nullptr);
|
||||
|
||||
void downloadToBuffer(const std::string &srcUrl, const std::string &customId, const StreamData &buffer, const ProgressData &data);
|
||||
|
||||
|
@ -175,6 +196,8 @@ private:
|
|||
ProgressCallback _onProgress;
|
||||
|
||||
SuccessCallback _onSuccess;
|
||||
|
||||
HeaderCallback _onHeader;
|
||||
|
||||
std::string getFileNameFromUrl(const std::string &srcUrl);
|
||||
|
||||
|
@ -193,4 +216,4 @@ int downloadProgressFunc(Downloader::ProgressData *ptr, double totalToDownload,
|
|||
|
||||
NS_CC_EXT_END
|
||||
|
||||
#endif /* defined(__Downloader__) */
|
||||
#endif /* defined(__Downloader__) */
|
Loading…
Reference in New Issue