diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 969134f2..ff06e1ec 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -13,6 +13,8 @@ libsub_core_a_SOURCES = \ download.h \ download_list.cc \ download_list.h \ + download_store.cc \ + download_store.h \ manager.cc \ manager.h \ poll.cc \ diff --git a/src/core/download.h b/src/core/download.h index a429ce37..a466b454 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -16,12 +16,12 @@ public: const std::string& get_tracker_msg() { return m_trackerMsg; } - void open() { m_download.open(); } - void close() { m_download.close(); } - void start() { m_download.start(); } void stop() { m_download.stop(); } + void open() { m_download.open(); } + void close() { m_download.close(); } + bool operator == (const std::string& str) { return str == m_download.get_hash(); } private: diff --git a/src/core/download_list.cc b/src/core/download_list.cc index ee22a869..6e99fe8f 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -1,11 +1,11 @@ #include "config.h" #include -#include -#include -#include #include +#include "utils/functional.h" + +#include "download.h" #include "download_list.h" namespace core { @@ -14,18 +14,26 @@ DownloadList::iterator DownloadList::insert(std::istream* str) { torrent::Download d = torrent::download_create(str); - iterator itr = Base::insert(end(), Download()); - itr->set_download(d); + iterator itr = Base::insert(end(), new Download); + (*itr)->set_download(d); return itr; } void DownloadList::erase(iterator itr) { - itr->release_download(); + (*itr)->release_download(); - torrent::download_remove(itr->get_hash()); + torrent::download_remove((*itr)->get_hash()); + delete *itr; Base::erase(itr); } +void +DownloadList::clear() { + std::for_each(begin(), end(), func::call_delete()); + + Base::clear(); +} + } diff --git a/src/core/download_list.h b/src/core/download_list.h index 6f7fa67f..e70d0a55 100644 --- a/src/core/download_list.h +++ b/src/core/download_list.h @@ -2,14 +2,15 @@ #define RTORRENT_CORE_DOWNLOAD_LIST_H #include - -#include "download.h" +#include namespace core { -class DownloadList : private std::list { +class Download; + +class DownloadList : private std::list { public: - typedef std::list Base; + typedef std::list Base; using Base::iterator; using Base::const_iterator; @@ -24,8 +25,13 @@ public: using Base::empty; using Base::size; + ~DownloadList() { clear(); } + iterator insert(std::istream* str); void erase(iterator itr); + +private: + void clear(); }; } diff --git a/src/core/download_store.cc b/src/core/download_store.cc new file mode 100644 index 00000000..fca69b2e --- /dev/null +++ b/src/core/download_store.cc @@ -0,0 +1,53 @@ +#include "config.h" + +#include +#include +#include +#include + +#include "utils/parse.h" + +#include "download.h" +#include "download_store.h" + +namespace core { + +void +DownloadStore::activate(const std::string& path) { + m_path = path; + + if (m_path.empty()) + throw std::logic_error("core::DownloadStore::activate(...) received an empty path"); + + if (*m_path.rbegin() != '/') + m_path += '/'; +} + +void +DownloadStore::disable() { + m_path = ""; +} + +void +DownloadStore::save(Download* d) { + std::fstream f(create_filename(d).c_str(), std::ios::out | std::ios::trunc); + + if (!f.is_open()) + throw std::runtime_error("core::DownloadStore::save(...) could not open file"); + + f << torrent::download_bencode(d->get_hash()); + + if (f.fail()) + throw std::runtime_error("core::DownloadStore::save(...) could not write torrent"); +} + +void +DownloadStore::remove(Download* d) { +} + +std::string +DownloadStore::create_filename(Download* d) { + return m_path + utils::string_to_hex(d->get_hash()) + ".torrent"; +} + +} diff --git a/src/core/session_manager.h b/src/core/download_store.h similarity index 65% rename from src/core/session_manager.h rename to src/core/download_store.h index 8ef9482c..f8a01e5e 100644 --- a/src/core/session_manager.h +++ b/src/core/download_store.h @@ -1,5 +1,5 @@ -#ifndef RTORRENT_CORE_SESSION_MANAGER_H -#define RTORRENT_CORE_SESSION_MANAGER_H +#ifndef RTORRENT_CORE_DOWNLOAD_STORE_H +#define RTORRENT_CORE_DOWNLOAD_STORE_H #include @@ -7,7 +7,7 @@ namespace core { class Download; -class SessionManager { +class DownloadStore { public: void activate(const std::string& path); @@ -19,6 +19,8 @@ public: void remove(Download* d); private: + std::string create_filename(Download* d); + std::string m_path; }; diff --git a/src/core/manager.cc b/src/core/manager.cc index 330d6752..f932848a 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -8,6 +8,7 @@ #include #include +#include "download.h" #include "manager.h" #include "curl_get.h" @@ -40,11 +41,11 @@ Manager::insert(const std::string& uri) { void Manager::erase(DownloadList::iterator itr) { - if (itr->get_download().is_active()) + if ((*itr)->get_download().is_active()) throw std::logic_error("core::Manager::erase(...) called on an active download"); - if (itr->get_download().is_open()) - itr->close(); + if ((*itr)->get_download().is_open()) + (*itr)->close(); m_downloadList.erase(itr); } @@ -60,7 +61,7 @@ Manager::start(Download* d) { if (d->get_download().is_hash_checked()) d->start(); else - m_hashQueue.insert(d, sigc::mem_fun(*d, &Download::start)); + m_hashQueue.insert(d, sigc::mem_fun(d, &Download::start)); } void @@ -68,6 +69,9 @@ Manager::stop(Download* d) { m_hashQueue.remove(d); d->stop(); + + d->get_download().hash_save(); + m_downloadStore.save(d); } void @@ -79,7 +83,8 @@ Manager::create_file(const std::string& uri) { itr = m_downloadList.insert(&f); - start(&*itr); + start(*itr); + m_downloadStore.save(*itr); } catch (torrent::local_error& e) { // What to do? Keep in list for now. @@ -101,7 +106,8 @@ Manager::receive_http_done(CurlGet* http) { try { itr = m_downloadList.insert(http->get_stream()); - start(&*itr); + start(*itr); + m_downloadStore.save(*itr); } catch (torrent::local_error& e) { // What to do? Keep in list for now. diff --git a/src/core/manager.h b/src/core/manager.h index e47639cf..d2e68386 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -2,6 +2,7 @@ #define RTORRENT_CORE_MANAGER_H #include "download_list.h" +#include "download_store.h" #include "hash_queue.h" #include "http_queue.h" #include "poll.h" @@ -15,36 +16,38 @@ public: Manager() : m_portFirst(6890), m_portLast(6999) {} - DownloadList& get_download_list() { return m_downloadList; } - HashQueue& get_hash_queue() { return m_hashQueue; } - HttpQueue& get_http_queue() { return m_httpQueue; } + DownloadList& get_download_list() { return m_downloadList; } + DownloadStore& get_download_store() { return m_downloadStore; } + HashQueue& get_hash_queue() { return m_hashQueue; } + HttpQueue& get_http_queue() { return m_httpQueue; } - Poll& get_poll() { return m_poll; } + Poll& get_poll() { return m_poll; } - void initialize(); - void cleanup(); + void initialize(); + void cleanup(); - void insert(const std::string& uri); - void erase(DownloadList::iterator itr); + void insert(const std::string& uri); + void erase(DownloadList::iterator itr); - void start(Download* d); - void stop(Download* d); + void start(Download* d); + void stop(Download* d); - void set_port_range(int a, int b) { m_portFirst = a; m_portLast = b; } + void set_port_range(int a, int b) { m_portFirst = a; m_portLast = b; } private: - void receive_http_done(CurlGet* http); + void receive_http_done(CurlGet* http); - void create_file(const std::string& uri); - void create_http(const std::string& uri); + void create_file(const std::string& uri); + void create_http(const std::string& uri); - DownloadList m_downloadList; - HashQueue m_hashQueue; - HttpQueue m_httpQueue; - Poll m_poll; + DownloadList m_downloadList; + DownloadStore m_downloadStore; + HashQueue m_hashQueue; + HttpQueue m_httpQueue; + Poll m_poll; - int m_portFirst; - int m_portLast; + int m_portFirst; + int m_portLast; }; } diff --git a/src/core/session_manager.cc b/src/core/session_manager.cc deleted file mode 100644 index 992d89a9..00000000 --- a/src/core/session_manager.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include "config.h" - -#include "download.h" -#include "session_manager.h" - -namespace core { - -void -SessionManager::activate(const std::string& path) { - m_path = path; - - if (m_path.empty()) - throw std::logic_error("core::SessionManager::activate(...) received an empty path"); - - if (m_path.rbegin() != '/') - m_path += '/'; -} - -void -SessionManager::disable() { - m_path = ""; -} - -void -SessionManager::save(Download* d) { - std::fstream f( - - -} - -void -SessionManager::remove(Download* d) { -} - -} diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc index 4d07d4dd..d9f6a0f6 100644 --- a/src/display/window_download_list.cc +++ b/src/display/window_download_list.cc @@ -1,5 +1,7 @@ #include "config.h" +#include "core/download.h" + #include "canvas.h" #include "utils.h" #include "window_download_list.h" @@ -52,26 +54,26 @@ WindowDownloadList::redraw() { while (itr != m_list->end() && y < m_canvas->get_height()) { m_canvas->print(0, pos++, "%c %s", itr == *m_focus ? '*' : ' ', - itr->get_download().get_name().c_str()); + (*itr)->get_download().get_name().c_str()); - if (itr->get_download().get_chunks_done() != itr->get_download().get_chunks_total() || !itr->get_download().is_open()) + if ((*itr)->get_download().get_chunks_done() != (*itr)->get_download().get_chunks_total() || !(*itr)->get_download().is_open()) m_canvas->print(0, pos++, "%c Torrent: %.1f / %.1f MiB Rate:%5.1f /%5.1f KiB Uploaded: %.1f MiB", itr == *m_focus ? '*' : ' ', - (double)itr->get_download().get_bytes_done() / (double)(1 << 20), - (double)itr->get_download().get_bytes_total() / (double)(1 << 20), - (double)itr->get_download().get_rate_up() / 1024.0, - (double)itr->get_download().get_rate_down() / 1024.0, - (double)itr->get_download().get_bytes_up() / (double)(1 << 20)); + (double)(*itr)->get_download().get_bytes_done() / (double)(1 << 20), + (double)(*itr)->get_download().get_bytes_total() / (double)(1 << 20), + (double)(*itr)->get_download().get_rate_up() / 1024.0, + (double)(*itr)->get_download().get_rate_down() / 1024.0, + (double)(*itr)->get_download().get_bytes_up() / (double)(1 << 20)); else m_canvas->print(0, pos++, "%c Torrent: Done %.1f MiB Rate:%5.1f /%5.1f KiB Uploaded: %.1f MiB", itr == *m_focus ? '*' : ' ', - (double)itr->get_download().get_bytes_total() / (double)(1 << 20), - (double)itr->get_download().get_rate_up() / 1024.0, - (double)itr->get_download().get_rate_down() / 1024.0, - (double)itr->get_download().get_bytes_up() / (double)(1 << 20)); + (double)(*itr)->get_download().get_bytes_total() / (double)(1 << 20), + (double)(*itr)->get_download().get_rate_up() / 1024.0, + (double)(*itr)->get_download().get_rate_down() / 1024.0, + (double)(*itr)->get_download().get_bytes_up() / (double)(1 << 20)); - m_canvas->print(0, pos++, "%c %s", itr == *m_focus ? '*' : ' ', print_download_status(&*itr).c_str()); + m_canvas->print(0, pos++, "%c %s", itr == *m_focus ? '*' : ' ', print_download_status(*itr).c_str()); ++itr; } diff --git a/src/main.cc b/src/main.cc index dac8d23e..537de0cf 100644 --- a/src/main.cc +++ b/src/main.cc @@ -13,6 +13,7 @@ #include #endif +#include "core/download.h" #include "display/canvas.h" #include "ui/control.h" #include "ui/download_list.h" @@ -57,13 +58,13 @@ do_shutdown(ui::Control* c) { torrent::listen_close(); std::for_each(c->get_core().get_download_list().begin(), c->get_core().get_download_list().end(), - std::mem_fun_ref(&core::Download::stop)); + std::bind1st(std::mem_fun(&core::Manager::stop), &c->get_core())); } else { // Close all torrents, this will stop all tracker connections and cause // a quick shutdown. std::for_each(c->get_core().get_download_list().begin(), c->get_core().get_download_list().end(), - std::mem_fun_ref(&core::Download::close)); + std::mem_fun(&core::Download::close)); } @@ -98,9 +99,7 @@ main(int argc, char** argv) { optionParser.insert_flag('h', sigc::ptr_fun(&print_help)); optionParser.insert_option('p', sigc::bind(sigc::ptr_fun(OptionParser::call_int_pair), sigc::mem_fun(uiControl.get_core(), &core::Manager::set_port_range))); - - // Test function. - optionParser.insert_option('s', sigc::ptr_fun(&test_dir)); + optionParser.insert_option('s', sigc::mem_fun(uiControl.get_core().get_download_store(), &core::DownloadStore::activate)); int firstArg = optionParser.process(argc, argv); diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index e2134dc5..d1fbd838 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -4,6 +4,8 @@ #include #include +#include "core/download.h" + #include "input/bindings.h" #include "input/text_input.h" @@ -110,7 +112,7 @@ DownloadList::receive_start_download() { if (m_focus == m_control->get_core().get_download_list().end()) return; - m_control->get_core().start(&*m_focus); + m_control->get_core().start(*m_focus); } void @@ -118,8 +120,8 @@ DownloadList::receive_stop_download() { if (m_focus == m_control->get_core().get_download_list().end()) return; - if (m_focus->get_download().is_active()) - m_control->get_core().stop(&*m_focus); + if ((*m_focus)->get_download().is_active()) + m_control->get_core().stop(*m_focus); else m_control->get_core().erase(m_focus); } @@ -134,7 +136,7 @@ DownloadList::receive_view_download() { disable(); - m_download = new Download(&*m_focus, m_control); + m_download = new Download(*m_focus, m_control); m_download->activate(); m_download->get_bindings()[KEY_LEFT] = sigc::mem_fun(*this, &DownloadList::receive_exit_download);