diff --git a/src/core/Makefile.am b/src/core/Makefile.am index f45cd69c..f380edf1 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -5,6 +5,8 @@ libsub_core_a_SOURCES = \ curl_get.h \ curl_stack.cc \ curl_stack.h \ + http_queue.cc \ + http_queue.h \ download.cc \ download.h \ download_list.cc \ diff --git a/src/core/curl_get.cc b/src/core/curl_get.cc index d14f775b..b8ec1564 100644 --- a/src/core/curl_get.cc +++ b/src/core/curl_get.cc @@ -10,13 +10,7 @@ namespace core { -CurlGet::~CurlGet() { - close(); -} - CurlGet::CurlGet(CurlStack* s) : - m_useragent("rtorrent_unknown"), - m_out(NULL), m_handle(NULL), m_stack(s) { @@ -24,60 +18,27 @@ CurlGet::CurlGet(CurlStack* s) : throw torrent::client_error("Tried to create CurlGet without a valid CurlStack"); } +CurlGet::~CurlGet() { + close(); +} + CurlGet* CurlGet::new_object(CurlStack* s) { return new CurlGet(s); } -void -CurlGet::set_url(const std::string& url) { - if (is_busy()) - throw torrent::local_error("Tried to call CurlGet::set_url on a busy object"); - - m_url = url; -} - -const std::string& -CurlGet::get_url() const { - return m_url; -} - -void -CurlGet::set_out(std::ostream* out) { - if (is_busy()) - throw torrent::local_error("Tried to call CurlGet::set_url on a busy object"); - - m_out = out; -} - -std::ostream* -CurlGet::get_out() { - return m_out; -} - -void -CurlGet::set_user_agent(const std::string& s) { - curl_easy_setopt(m_handle, CURLOPT_USERAGENT, s.c_str()); - - m_useragent = s; -} - -const std::string& -CurlGet::get_user_agent() { - return m_useragent; -} - void CurlGet::start() { if (is_busy()) - throw torrent::local_error("Tried to call CurlGet::start on a busy object"); + throw torrent::internal_error("Tried to call CurlGet::start on a busy object"); if (m_out == NULL) - throw torrent::local_error("Tried to call CurlGet::start without a valid output stream"); + throw torrent::internal_error("Tried to call CurlGet::start without a valid output stream"); m_handle = curl_easy_init(); curl_easy_setopt(m_handle, CURLOPT_URL, m_url.c_str()); + curl_easy_setopt(m_handle, CURLOPT_USERAGENT, m_userAgent.c_str()); curl_easy_setopt(m_handle, CURLOPT_WRITEFUNCTION, &curl_get_receive_write); curl_easy_setopt(m_handle, CURLOPT_WRITEDATA, this); curl_easy_setopt(m_handle, CURLOPT_FORBID_REUSE, 1); @@ -102,12 +63,10 @@ CurlGet::perform(CURLMsg* msg) { if (msg->msg != CURLMSG_DONE) throw torrent::client_error("CurlGet::process got CURLMSG that isn't done"); - if (msg->data.result == CURLE_OK) { - m_done.emit(); - - } else { - m_failed.emit(curl_easy_strerror(msg->data.result)); - } + if (msg->data.result == CURLE_OK) + m_slotDone(); + else + m_slotFailed(curl_easy_strerror(msg->data.result)); } size_t @@ -115,14 +74,4 @@ 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; } -CurlGet::SignalDone& -CurlGet::signal_done() { - return m_done; -} - -CurlGet::SignalFailed& -CurlGet::signal_failed() { - return m_failed; -} - } diff --git a/src/core/curl_get.h b/src/core/curl_get.h index ac8b810b..88afc718 100644 --- a/src/core/curl_get.h +++ b/src/core/curl_get.h @@ -23,20 +23,8 @@ class CurlGet : public torrent::Http { void start(); void close(); - void set_url(const std::string& url); - const std::string& get_url() const; - - void set_out(std::ostream* out); - std::ostream* get_out(); - - void set_user_agent(const std::string& s); - const std::string& get_user_agent(); - bool is_busy() { return m_handle; } - SignalDone& signal_done(); - SignalFailed& signal_failed(); - protected: CURL* handle() { return m_handle; } @@ -48,15 +36,9 @@ class CurlGet : public torrent::Http { friend size_t curl_get_receive_write(void* data, size_t size, size_t nmemb, void* handle); - std::string m_url; - std::string m_useragent; - std::ostream* m_out; CURL* m_handle; CurlStack* m_stack; - - sigc::signal0 m_done; - sigc::signal1 m_failed; }; } diff --git a/src/core/curl_stack.cc b/src/core/curl_stack.cc index 9eb2bb28..8b41b94a 100644 --- a/src/core/curl_stack.cc +++ b/src/core/curl_stack.cc @@ -1,33 +1,15 @@ #include "config.h" #include -#include #include #include +#include "functional.h" #include "curl_get.h" #include "curl_stack.h" namespace core { -template -struct _equal { - _equal(Type t, Ftor f) : m_t(t), m_f(f) {} - - template - bool operator () (Arg& a) { - return m_t == m_f(a); - } - - Type m_t; - Ftor m_f; -}; - -template -_equal equal(Type t, Ftor f) { - return _equal(t, f); -} - CurlStack::CurlStack() : m_handle((void*)curl_multi_init()), m_size(0) { @@ -59,10 +41,7 @@ CurlStack::perform() { CURLMsg* msg = curl_multi_info_read((CURLM*)m_handle, &t); CurlGetList::iterator itr = std::find_if(m_getList.begin(), m_getList.end(), - equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); - -// eq(call_member(&CurlGet::handle), -// value(msg->easy_handle))); + func::equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); if (itr == m_getList.end()) throw torrent::client_error("Could not find CurlGet with the right easy_handle"); diff --git a/src/core/download_list.cc b/src/core/download_list.cc index af0cd84a..15acfd48 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -10,7 +10,7 @@ namespace core { DownloadList::iterator -DownloadList::create(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 505c68d9..1793df48 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 create(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 new file mode 100644 index 00000000..c6b59004 --- /dev/null +++ b/src/core/http_queue.cc @@ -0,0 +1,58 @@ +#include "config.h" + +#include +#include +#include +#include + +#include "functional.h" +#include "http_queue.h" +#include "curl_get.h" + +namespace core { + +void +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_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)); + + (*itr)->start(); + + h.release(); + s.release(); +} + +void +HttpQueue::erase(iterator itr) { + delete (*itr)->get_out(); + delete *itr; + + Base::erase(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::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 new file mode 100644 index 00000000..a21422e4 --- /dev/null +++ b/src/core/http_queue.h @@ -0,0 +1,48 @@ +#ifndef RTORRENT_CORE_HTTP_QUEUE_H +#define RTORRENT_CORE_HTTP_QUEUE_H + +#include +#include +#include + +namespace torrent { + class Http; +} + +namespace core { + +class HttpQueue : private std::list { +public: + typedef std::list Base; + typedef sigc::slot0 SlotFactory; + + using Base::iterator; + using Base::const_iterator; + using Base::reverse_iterator; + using Base::const_reverse_iterator; + + using Base::begin; + using Base::end; + using Base::rbegin; + using Base::rend; + + using Base::empty; + using Base::size; + + void insert(const std::string& url); + void erase(iterator itr); + + void clear(); + + 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; +}; + +} + +#endif diff --git a/src/display/manager.cc b/src/display/manager.cc index 777f2dea..d0a020c3 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -2,7 +2,8 @@ #include #include -#include + +#include "functional.h" #include "canvas.h" #include "manager.h" @@ -10,22 +11,6 @@ namespace display { -template -struct _accumulate { - _accumulate(Type& t, Ftor f) : m_t(t), m_f(f) {} - - template - void operator () (Arg& a) { m_t += m_f(a); } - - Type& m_t; - Ftor m_f; -}; - -template -_accumulate accumulate(Type& t, Ftor f) { - return _accumulate(t, f); -} - Manager::iterator Manager::erase(Window* w) { iterator itr = std::find(begin(), end(), w); @@ -41,8 +26,8 @@ Manager::adjust_layout() { int countDynamic = 0; int staticHeight = 0; - std::for_each(begin(), end(), accumulate(staticHeight, std::mem_fun(&Window::get_min_height))); - std::for_each(begin(), end(), accumulate(countDynamic, std::mem_fun(&Window::is_dynamic))); + std::for_each(begin(), end(), func::accumulate(staticHeight, std::mem_fun(&Window::get_min_height))); + std::for_each(begin(), end(), func::accumulate(countDynamic, std::mem_fun(&Window::is_dynamic))); int dynamic = std::max(0, Canvas::get_screen_height() - staticHeight); int height = 0, h; diff --git a/src/functional.h b/src/functional.h new file mode 100644 index 00000000..64d08fdd --- /dev/null +++ b/src/functional.h @@ -0,0 +1,79 @@ +#ifndef RTORRENT_FUNCTIONAL_H +#define RTORRENT_FUNCTIONAL_H + +#include + +namespace func { + +template +struct _accumulate { + _accumulate(Type& t, Ftor f) : m_t(t), m_f(f) {} + + template + void operator () (Arg& a) { m_t += m_f(a); } + + Type& m_t; + Ftor m_f; +}; + +template +inline _accumulate +accumulate(Type& t, Ftor f) { + return _accumulate(t, f); +} + +template +struct _equal { + _equal(Type t, Ftor f) : m_t(t), m_f(f) {} + + template + bool operator () (Arg& a) { + return m_t == m_f(a); + } + + Type m_t; + Ftor m_f; +}; + +template +inline _equal +equal(Type t, Ftor f) { + return _equal(t, f); +} + +template +struct _on : public std::unary_function { + + _on(Dest d, Src s) : m_dest(d), m_src(s) {} + + typename Dest::result_type operator () (typename Src::argument_type arg) { + return m_dest(m_src(arg)); + } + + Dest m_dest; + Src m_src; +}; + +template +inline _on +on(Dest d, Src s) { + return _on(d, s); +} + +struct _call_delete + : public std::unary_function { + + template + void operator () (Type* t) { + delete t; + } +}; + +inline _call_delete +call_delete() { + return _call_delete(); +} + +} + +#endif diff --git a/src/main.cc b/src/main.cc index 3c450882..29bf4c18 100644 --- a/src/main.cc +++ b/src/main.cc @@ -123,7 +123,7 @@ main(int argc, char** argv) { for (int i = 1; i < argc; ++i) { std::fstream f(argv[i], std::ios::in); - core::DownloadList::iterator itr = downloads.create(f); + core::DownloadList::iterator itr = downloads.insert(f); itr->open(); itr->hash_check();