Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "FileManager.h"
- USING_NS_CC;
- FileManager* FileManager::getInstance()
- {
- static FileManager sm_pSharedInstance;
- return &sm_pSharedInstance;
- }
- FileManager::FileManager()
- {
- _downloading = false;
- _successCallback = nullptr;
- _errorCallback = nullptr;
- }
- bool FileManager::checkInternetConnection(const std::string &url)
- {
- auto curl = curl_easy_init();
- if (curl) {
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- curl_easy_setopt(curl, CURLOPT_USERAGENT, curl_version());
- curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
- auto res = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
- return (res == CURLE_OK);
- }
- else
- return false;
- }
- typedef size_t(*CURL_WRITEFUNCTION_PTR)(char*, size_t, size_t, FILE*);
- typedef int(*CURL_PROGRESSFUNCTION_PTR)(bool, double, double, double, double);
- void FileManager::startDownload(const std::string &url, const std::string &path)
- {
- if (!this->checkInternetConnection(url)) {
- if (_noConnectionCallback) _noConnectionCallback();
- return;
- }
- auto curlm = curl_multi_init();
- auto curl = curl_easy_init();
- FILE *fp;
- if(curl) {
- _downloading = true;
- fp = fopen(path.c_str(),"wb");
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
- curl_easy_setopt(curl, CURLOPT_USERAGENT, curl_version());
- auto writeCallback = [](char *ptr, size_t size, size_t nmemb, FILE *stream) -> size_t {
- auto written = fwrite(ptr, size, nmemb, stream);
- return written;
- };
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, static_cast<CURL_WRITEFUNCTION_PTR>(writeCallback));
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
- auto progressCallback = [](bool downloading, double dltotal, double dlnow, double ultotal, double ulnow) -> int {
- if (!downloading) {
- return 1;
- }
- //auto percent = dlnow * 100.0 / dltotal;
- //CCLOG("download progress %.0lf%%", percent);
- return 0;
- };
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, static_cast<CURL_PROGRESSFUNCTION_PTR>(progressCallback));
- curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, _downloading);
- CCLOG("download started");
- curl_multi_add_handle(curlm, curl);
- Director::getInstance()->getScheduler()->schedule( [this, &path, curlm, curl, fp](float dt) mutable {
- int transfers;
- auto res = curl_multi_perform(curlm, &transfers);
- auto doneCallback = [&] () {
- curl_multi_remove_handle(curlm, curl);
- curl_easy_cleanup(curl);
- if (transfers < 1)
- curl_multi_cleanup(curlm);
- Director::getInstance()->getScheduler()->unschedule("curl_loop", this);
- };
- if (res != CURLM_OK) {
- auto error = std::string(curl_multi_strerror(res));
- clearerr(fp);
- fclose(fp);
- FILEUTILS->removeFile(path);
- doneCallback();
- CCLOG("downloading error: %s", error.c_str());
- if (_errorCallback) _errorCallback(path, error);
- } else {
- int msgq = 0;
- auto m = curl_multi_info_read(curlm, &msgq);
- if(m && (m->msg == CURLMSG_DONE)) {
- if (_downloading) {
- //downloading done
- _downloading = false;
- fclose(fp);
- doneCallback();
- CCLOG("downloaded success");
- if (_successCallback) _successCallback(path);
- } else {
- //downloading canceled
- clearerr(fp);
- fclose(fp);
- FILEUTILS->removeFile(path);
- doneCallback();
- CCLOG("download canceled");
- if (_canceledCallback) _canceledCallback();
- }
- }
- }
- }, this, 0, CC_REPEAT_FOREVER, 0, false, "curl_loop");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement