diff --git a/src/core/curl_get.cc b/src/core/curl_get.cc index b8ec1564..f67623b4 100644 --- a/src/core/curl_get.cc +++ b/src/core/curl_get.cc @@ -1,6 +1,6 @@ #include "config.h" -#include +#include #include #include #include @@ -32,7 +32,7 @@ CurlGet::start() { if (is_busy()) throw torrent::internal_error("Tried to call CurlGet::start on a busy object"); - if (m_out == NULL) + if (m_stream == NULL) throw torrent::internal_error("Tried to call CurlGet::start without a valid output stream"); m_handle = curl_easy_init(); @@ -64,14 +64,14 @@ CurlGet::perform(CURLMsg* msg) { throw torrent::client_error("CurlGet::process got CURLMSG that isn't done"); if (msg->data.result == CURLE_OK) - m_slotDone(); + m_signalDone.emit(); else - m_slotFailed(curl_easy_strerror(msg->data.result)); + m_signalFailed.emit(curl_easy_strerror(msg->data.result)); } size_t curl_get_receive_write(void* data, size_t size, size_t nmemb, void* handle) { - return ((CurlGet*)handle)->m_out->write((char*)data, size * nmemb).fail() ? 0 : size * nmemb; + return ((CurlGet*)handle)->m_stream->write((char*)data, size * nmemb).fail() ? 0 : size * nmemb; } } diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 15acfd48..5d0fc64f 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -1,6 +1,7 @@ #include "config.h" #include +#include #include #include #include @@ -10,7 +11,7 @@ namespace core { DownloadList::iterator -DownloadList::insert(std::istream& str) { +DownloadList::insert(std::istream* str) { torrent::Download d = torrent::download_create(str); iterator itr = Base::insert(end(), Download()); diff --git a/src/core/download_list.h b/src/core/download_list.h index 1793df48..aef08afc 100644 --- a/src/core/download_list.h +++ b/src/core/download_list.h @@ -24,7 +24,7 @@ public: using Base::empty; using Base::size; - iterator insert(std::istream& str); + iterator insert(std::istream* str); void erase(iterator itr); private: diff --git a/src/core/http_queue.cc b/src/core/http_queue.cc index c6b59004..5cd1adc3 100644 --- a/src/core/http_queue.cc +++ b/src/core/http_queue.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "functional.h" @@ -11,29 +12,31 @@ namespace core { -void +HttpQueue::iterator HttpQueue::insert(const std::string& url) { std::auto_ptr h(m_slotFactory()); std::auto_ptr s(new std::stringstream); - h->set_out(s.get()); h->set_url(url); + h->set_stream(s.get()); h->set_user_agent("rtorrent/" VERSION); iterator itr = Base::insert(end(), h.get()); - h->slot_done(sigc::bind(sigc::mem_fun(this, &HttpQueue::receive_done), itr)); - h->slot_failed(sigc::bind<0>(sigc::mem_fun(this, &HttpQueue::receive_failed), itr)); + h->signal_done().connect(sigc::bind(sigc::mem_fun(this, &HttpQueue::erase), itr)); + h->signal_failed().connect(sigc::bind<0>(sigc::hide(sigc::mem_fun(this, &HttpQueue::erase)), itr)); (*itr)->start(); h.release(); s.release(); + + return itr; } void HttpQueue::erase(iterator itr) { - delete (*itr)->get_out(); + delete (*itr)->get_stream(); delete *itr; Base::erase(itr); @@ -41,18 +44,10 @@ HttpQueue::erase(iterator itr) { void HttpQueue::clear() { - std::for_each(begin(), end(), func::on(func::call_delete(), std::mem_fun(&CurlGet::get_out))); + std::for_each(begin(), end(), func::on(func::call_delete(), std::mem_fun(&CurlGet::get_stream))); std::for_each(begin(), end(), func::call_delete()); Base::clear(); } -void -HttpQueue::receive_done(iterator itr) { -} - -void -HttpQueue::receive_failed(iterator itr, std::string msg) { -} - } diff --git a/src/core/http_queue.h b/src/core/http_queue.h index a21422e4..27fe30e5 100644 --- a/src/core/http_queue.h +++ b/src/core/http_queue.h @@ -29,7 +29,9 @@ public: using Base::empty; using Base::size; - void insert(const std::string& url); + // Note that any slots connected to the torrent::Http signals must be + // pushed in front of the erase slot added by HttpQueue::insert. + iterator insert(const std::string& url); void erase(iterator itr); void clear(); @@ -37,9 +39,6 @@ public: void slot_factory(SlotFactory s) { m_slotFactory = s; } private: - void receive_done(iterator itr); - void receive_failed(iterator itr, std::string msg); - SlotFactory m_slotFactory; }; diff --git a/src/core/poll.cc b/src/core/poll.cc index 6ee7d075..5bac37c8 100644 --- a/src/core/poll.cc +++ b/src/core/poll.cc @@ -66,9 +66,9 @@ Poll::work_input() { m_slotReadStdin(key); } -void -Poll::register_http() { - torrent::Http::set_factory(sigc::bind(sigc::ptr_fun(&core::CurlGet::new_object), &m_curlStack)); +Poll::SlotFactory +Poll::get_http_factory() { + return sigc::bind(sigc::ptr_fun(&core::CurlGet::new_object), &m_curlStack); } } diff --git a/src/core/poll.h b/src/core/poll.h index 0c0b51fd..21edb9a6 100644 --- a/src/core/poll.h +++ b/src/core/poll.h @@ -6,33 +6,38 @@ #include "curl_stack.h" +namespace torrent { + class Http; +} + namespace core { class Poll { public: - typedef sigc::slot0 Slot; - typedef sigc::slot1 SlotInt; + typedef sigc::slot0 Slot; + typedef sigc::slot1 SlotInt; + typedef sigc::slot0 SlotFactory; - void poll(); + void poll(); - void register_http(); + SlotFactory get_http_factory(); - void slot_read_stdin(SlotInt s) { m_slotReadStdin = s; } - void slot_select_interrupted(Slot s) { m_slotSelectInterrupted = s; } + void slot_read_stdin(SlotInt s) { m_slotReadStdin = s; } + void slot_select_interrupted(Slot s) { m_slotSelectInterrupted = s; } private: - void work(); - void work_input(); + void work(); + void work_input(); - SlotInt m_slotReadStdin; - Slot m_slotSelectInterrupted; + SlotInt m_slotReadStdin; + Slot m_slotSelectInterrupted; - int m_maxFd; - fd_set m_readSet; - fd_set m_writeSet; - fd_set m_exceptSet; + int m_maxFd; + fd_set m_readSet; + fd_set m_writeSet; + fd_set m_exceptSet; - CurlStack m_curlStack; + CurlStack m_curlStack; }; } diff --git a/src/main.cc b/src/main.cc index 29bf4c18..39f32bc1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -4,8 +4,10 @@ #include #include #include +#include #include #include +#include #ifdef USE_EXECINFO #include @@ -15,6 +17,7 @@ #include "core/poll.h" #include "core/curl_stack.h" +#include "core/http_queue.h" #include "core/download_list.h" #include "ui/control.h" @@ -32,6 +35,7 @@ bool is_shutting_down = false; core::Poll poll; core::DownloadList downloads; +core::HttpQueue httpQueue; bool is_resized() { @@ -113,20 +117,28 @@ main(int argc, char** argv) { inputMain[KEY_RESIZE] = sigc::mem_fun(uiControl.get_display(), &display::Manager::adjust_layout); poll.slot_read_stdin(sigc::mem_fun(uiControl.get_input(), &input::Manager::pressed)); - poll.register_http(); - poll.slot_select_interrupted(sigc::ptr_fun(display::Canvas::do_update)); + torrent::Http::set_factory(poll.get_http_factory()); + httpQueue.slot_factory(poll.get_http_factory()); + torrent::initialize(); torrent::listen_open(6880, 6999); for (int i = 1; i < argc; ++i) { - std::fstream f(argv[i], std::ios::in); + if (std::strncmp(argv[i], "http://", 7)) { + std::fstream f(argv[i], std::ios::in); + + core::DownloadList::iterator itr = downloads.insert(&f); + + itr->open(); + itr->hash_check(); - core::DownloadList::iterator itr = downloads.insert(f); + } else { + core::HttpQueue::iterator itr = httpQueue.insert(argv[i]); - itr->open(); - itr->hash_check(); + (*itr)->signal_done().slots().push_front(sigc::hide_return(sigc::bind(sigc::mem_fun(downloads, &core::DownloadList::insert), (*itr)->get_stream()))); + } } uiControl.get_display().adjust_layout();