From: Ingo Ruhnke Date: Tue, 26 Aug 2014 07:05:30 +0000 (+0200) Subject: Added file writing and then-callback to Downloader X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=d7571001a764a419628b668b38e252fe1276b923;p=supertux.git Added file writing and then-callback to Downloader --- diff --git a/src/addon/downloader.cpp b/src/addon/downloader.cpp index 349dc27fb..f07915ec5 100644 --- a/src/addon/downloader.cpp +++ b/src/addon/downloader.cpp @@ -18,8 +18,10 @@ #include "addon/downloader.hpp" #include +#include #include #include +#include #include #include "util/log.hpp" @@ -57,16 +59,27 @@ private: std::array m_error_buffer; TransferStatusPtr m_status; + std::unique_ptr m_fout; public: - Transfer(Downloader& downloader, TransferId id, const std::string& url) : + Transfer(Downloader& downloader, TransferId id, + const std::string& url, + const std::string& outfile) : m_downloader(downloader), m_id(id), m_url(url), m_handle(), m_error_buffer(), - m_status(new TransferStatus(id)) + m_status(new TransferStatus(id)), + m_fout(PHYSFS_openWrite(outfile.c_str()), PHYSFS_close) { + if (!m_fout) + { + std::ostringstream out; + out << "PHYSFS_openRead() failed: " << PHYSFS_getLastError(); + throw std::runtime_error(out.str()); + } + m_handle = curl_easy_init(); if (!m_handle) { @@ -118,13 +131,13 @@ public: size_t on_data(void* ptr, size_t size, size_t nmemb) { + PHYSFS_write(m_fout.get(), ptr, size, nmemb); return size * nmemb; } void on_progress(curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { - log_info << "progress: " << dlnow << "/" << dltotal << std::endl; m_status->dltotal = dltotal; m_status->dlnow = dlnow; @@ -258,9 +271,23 @@ Downloader::update() switch(msg->msg) { case CURLMSG_DONE: - curl_multi_remove_handle(m_multi_handle, msg->easy_handle); - log_info << "DOWNLOAD DONE" << std::endl; - //FIXME: finish_transfer(msg->easy_handle); + { + log_info << "Download completed" << std::endl; + curl_multi_remove_handle(m_multi_handle, msg->easy_handle); + auto it = std::find_if(m_transfers.begin(), m_transfers.end(), + [&msg](const std::unique_ptr& rhs) { + return rhs->get_curl_handle() == msg->easy_handle; + }); + assert(it != m_transfers.end()); + TransferStatusPtr status = (*it)->get_status(); + m_transfers.erase(it); + + status->status = TransferStatus::COMPLETED; + if (status->callback) + { + status->callback(); + } + } break; default: @@ -271,9 +298,9 @@ Downloader::update() } TransferStatusPtr -Downloader::request_download(const std::string& url, const std::string& filename) +Downloader::request_download(const std::string& url, const std::string& outfile) { - std::unique_ptr transfer(new Transfer(*this, m_next_transfer_id++, url)); + std::unique_ptr transfer(new Transfer(*this, m_next_transfer_id++, url, outfile)); curl_multi_add_handle(m_multi_handle, transfer->get_curl_handle()); m_transfers.push_back(std::move(transfer)); return m_transfers.back()->get_status(); diff --git a/src/addon/downloader.hpp b/src/addon/downloader.hpp index 814c4a2bb..5aab70dee 100644 --- a/src/addon/downloader.hpp +++ b/src/addon/downloader.hpp @@ -39,6 +39,7 @@ public: int dlnow; int ultotal; int ulnow; + std::function callback; TransferStatus(TransferId id_) : id(id_), @@ -46,8 +47,14 @@ public: dltotal(0), dlnow(0), ultotal(0), - ulnow(0) + ulnow(0), + callback() {} + + void then(const std::function& callback_) + { + callback = callback_; + } }; typedef std::shared_ptr TransferStatusPtr;