diff --git a/configure.ac b/configure.ac index 985faf7b..629ae467 100644 --- a/configure.ac +++ b/configure.ac @@ -35,18 +35,19 @@ AC_ARG_ENABLE(werror, AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1) -PKG_CHECK_MODULES(STUFF, sigc++-2.0 libtorrent >= 0.4.8, - CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS"; - LIBS="$LIBS $STUFF_LIBS") - TORRENT_CHECK_CURL() TORRENT_OTFD() +PKG_CHECK_MODULES(STUFF, sigc++-2.0 libtorrent >= 0.4.8, + CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS $CURL_CFLAGS"; + LIBS="$LIBS $STUFF_LIBS $CURL_LIBS") + AC_DEFINE(HAVE_CONFIG_H, 1, true if config.h was included) AC_OUTPUT([ Makefile src/Makefile src/display/Makefile + src/engine/Makefile src/input/Makefile ]) diff --git a/scripts/checks.m4 b/scripts/checks.m4 index 10518ab8..7ad76c2b 100644 --- a/scripts/checks.m4 +++ b/scripts/checks.m4 @@ -17,6 +17,9 @@ AC_DEFUN([TORRENT_CHECK_CURL], [ if test x$ok != x0; then my_cv_curl_vers="$ver" AC_MSG_RESULT([$my_cv_curl_vers]) + + CURL_CFLAGS=`curl-config --cflags` + CURL_LIBS=`curl-config --libs` else AC_MSG_RESULT(FAILED) AC_MSG_ERROR([$ver is too old. Need version $check or higher.]) diff --git a/src/Makefile.am b/src/Makefile.am index 53724948..c3b4ff25 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,16 +1,14 @@ SUBDIRS = \ display \ + engine \ input bin_PROGRAMS = rtorrent rtorrent_LDADD = \ $(top_srcdir)/src/display/libsub_display.a \ + $(top_srcdir)/src/engine/libsub_engine.a \ $(top_srcdir)/src/input/libsub_input.a rtorrent_SOURCES = \ - downloads.cc \ - downloads.h \ - main.cc \ - poll.cc \ - poll.h + main.cc diff --git a/src/curl_stack.h b/src/curl_stack.h deleted file mode 100644 index ed08dc31..00000000 --- a/src/curl_stack.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef LIBTORRENT_CURL_STACK_H -#define LIBTORRENT_CURL_STACK_H - -#include - -class CurlStack { - friend class CurlGet; - - public: - typedef std::list CurlGetList; - - CurlStack(); - ~CurlStack(); - - int get_size() const { return m_size; } - bool is_busy() const { return !m_getList.empty(); } - - void perform(); - - void fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int& maxFd); - - static void global_init(); - static void global_cleanup(); - - protected: - void add_get(CurlGet* get); - void remove_get(CurlGet* get); - - private: - void* m_handle; - - int m_size; - CurlGetList m_getList; -}; - -#endif - diff --git a/src/display/window_downloads.cc b/src/display/window_downloads.cc index 4e2a6c85..93b64da6 100644 --- a/src/display/window_downloads.cc +++ b/src/display/window_downloads.cc @@ -1,11 +1,11 @@ #include "config.h" -#include "window_downloads.h" #include "canvas.h" +#include "window_downloads.h" namespace display { -WindowDownloads::WindowDownloads(Downloads* d) : +WindowDownloads::WindowDownloads(engine::Downloads* d) : Window(new Canvas, true), m_downloads(d) { } @@ -17,7 +17,7 @@ WindowDownloads::redraw() { int pos = 1; - for (Downloads::iterator itr = m_downloads->begin(); itr != m_downloads->end(); ++itr, ++pos) + for (engine::Downloads::iterator itr = m_downloads->begin(); itr != m_downloads->end(); ++itr, ++pos) m_canvas->print(1, pos, "Download: %s", itr->get_name().c_str()); } diff --git a/src/display/window_downloads.h b/src/display/window_downloads.h index ea88dddc..28d61864 100644 --- a/src/display/window_downloads.h +++ b/src/display/window_downloads.h @@ -1,19 +1,19 @@ #ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOADS_H #define RTORRENT_DISPLAY_WINDOW_DOWNLOADS_H -#include "downloads.h" #include "window.h" +#include "engine/downloads.h" namespace display { class WindowDownloads : public Window { public: - WindowDownloads(Downloads* d); + WindowDownloads(engine::Downloads* d); virtual void redraw(); private: - Downloads* m_downloads; + engine::Downloads* m_downloads; }; } diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am new file mode 100644 index 00000000..c3ea3d63 --- /dev/null +++ b/src/engine/Makefile.am @@ -0,0 +1,14 @@ +noinst_LIBRARIES = libsub_engine.a + +libsub_engine_a_SOURCES = \ + curl_get.cc \ + curl_get.h \ + curl_stack.cc \ + curl_stack.h \ + downloads.cc \ + downloads.h \ + poll.cc \ + poll.h + + +INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) diff --git a/src/curl_get.cc b/src/engine/curl_get.cc similarity index 88% rename from src/curl_get.cc rename to src/engine/curl_get.cc index e3ae11b5..6301c9ef 100644 --- a/src/curl_get.cc +++ b/src/engine/curl_get.cc @@ -1,12 +1,14 @@ #include "config.h" -#include "curl_get.h" -#include "curl_stack.h" -#include - #include #include #include +#include + +#include "curl_get.h" +#include "curl_stack.h" + +namespace engine { CurlGet::~CurlGet() { close(); @@ -27,7 +29,8 @@ CurlGet::new_object(CurlStack* s) { return new CurlGet(s); } -void CurlGet::set_url(const std::string& url) { +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"); @@ -39,7 +42,8 @@ CurlGet::get_url() const { return m_url; } -void CurlGet::set_out(std::ostream* out) { +void +CurlGet::set_out(std::ostream* out) { if (is_busy()) throw torrent::local_error("Tried to call CurlGet::set_url on a busy object"); @@ -63,7 +67,8 @@ CurlGet::get_user_agent() { return m_useragent; } -void CurlGet::start() { +void +CurlGet::start() { if (is_busy()) throw torrent::local_error("Tried to call CurlGet::start on a busy object"); @@ -80,7 +85,8 @@ void CurlGet::start() { m_stack->add_get(this); } -void CurlGet::close() { +void +CurlGet::close() { if (!is_busy()) return; @@ -91,7 +97,8 @@ void CurlGet::close() { m_handle = NULL; } -void CurlGet::perform(CURLMsg* msg) { +void +CurlGet::perform(CURLMsg* msg) { if (msg->msg != CURLMSG_DONE) throw torrent::client_error("CurlGet::process got CURLMSG that isn't done"); @@ -103,7 +110,8 @@ void CurlGet::perform(CURLMsg* msg) { } } -size_t curl_get_receive_write(void* data, size_t size, size_t nmemb, void* handle) { +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; } @@ -117,3 +125,4 @@ CurlGet::signal_failed() { return m_failed; } +} diff --git a/src/curl_get.h b/src/engine/curl_get.h similarity index 67% rename from src/curl_get.h rename to src/engine/curl_get.h index 98dfbdcc..d89e0a14 100644 --- a/src/curl_get.h +++ b/src/engine/curl_get.h @@ -1,5 +1,5 @@ -#ifndef LIBTORRENT_CURL_GET_H -#define LIBTORRENT_CURL_GET_H +#ifndef RTORRENT_ENGINE_CURL_GET_H +#define RTORRENT_ENGINE_CURL_GET_H #include #include @@ -9,6 +9,8 @@ struct CURLMsg; +namespace engine { + class CurlGet : public torrent::Http { public: friend class CurlStack; @@ -36,22 +38,24 @@ class CurlGet : public torrent::Http { SignalFailed& signal_failed(); protected: - CURL* handle() { return m_handle; } + CURL* handle() { return m_handle; } - void perform(CURLMsg* msg); + void perform(CURLMsg* msg); private: - friend size_t curl_get_receive_write(void* data, size_t size, size_t nmemb, void* handle); + 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; + std::string m_url; + std::string m_useragent; + std::ostream* m_out; + CURL* m_handle; - CurlStack* m_stack; + CurlStack* m_stack; sigc::signal0 m_done; sigc::signal1 m_failed; }; +} + #endif diff --git a/src/curl_stack.cc b/src/engine/curl_stack.cc similarity index 67% rename from src/curl_stack.cc rename to src/engine/curl_stack.cc index a16f0aaf..32f40889 100644 --- a/src/curl_stack.cc +++ b/src/engine/curl_stack.cc @@ -1,13 +1,32 @@ -#include "curl_get.h" -#include "curl_stack.h" +#include "config.h" + +#include +#include +#include #include -#include -#include +#include "curl_get.h" +#include "curl_stack.h" -using namespace algo; +namespace engine { -namespace torrent { +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()), @@ -21,7 +40,8 @@ CurlStack::~CurlStack() { curl_multi_cleanup((CURLM*)m_handle); } -void CurlStack::perform() { +void +CurlStack::perform() { int s; CURLMcode code; @@ -39,8 +59,10 @@ void CurlStack::perform() { CURLMsg* msg = curl_multi_info_read((CURLM*)m_handle, &t); CurlGetList::iterator itr = std::find_if(m_getList.begin(), m_getList.end(), - eq(call_member(&CurlGet::handle), - value(msg->easy_handle))); + equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); + +// eq(call_member(&CurlGet::handle), +// value(msg->easy_handle))); if (itr == m_getList.end()) throw torrent::client_error("Could not find CurlGet with the right easy_handle"); @@ -52,27 +74,29 @@ void CurlStack::perform() { } while (code == CURLM_CALL_MULTI_PERFORM); } -void CurlStack::fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int& maxFd) { +void +CurlStack::fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int* maxFd) { int f; if (curl_multi_fdset((CURLM*)m_handle, readfds, writefds, exceptfds, &f) > 0) throw torrent::local_error("Error calling curl_multi_fdset"); - maxFd = std::max(f, maxFd); + *maxFd = std::max(f, *maxFd); } -void CurlStack::add_get(CurlGet* get) { +void +CurlStack::add_get(CurlGet* get) { CURLMcode code; if ((code = curl_multi_add_handle((CURLM*)m_handle, get->handle())) > 0) throw torrent::local_error("curl_multi_add_handle \"" + std::string(curl_multi_strerror(code))); m_size++; - m_getList.push_back(get); } -void CurlStack::remove_get(CurlGet* get) { +void +CurlStack::remove_get(CurlGet* get) { if (curl_multi_remove_handle((CURLM*)m_handle, get->handle()) > 0) throw torrent::local_error("Error calling curl_multi_remove_handle"); @@ -81,16 +105,17 @@ void CurlStack::remove_get(CurlGet* get) { if (itr == m_getList.end()) throw torrent::client_error("Could not find CurlGet when calling CurlStack::remove"); - m_getList.erase(itr); - m_size--; + m_getList.erase(itr); } -void CurlStack::global_init() { +void +CurlStack::global_init() { curl_global_init(CURL_GLOBAL_ALL); } -void CurlStack::global_cleanup() { +void +CurlStack::global_cleanup() { curl_global_cleanup(); } diff --git a/src/engine/curl_stack.h b/src/engine/curl_stack.h new file mode 100644 index 00000000..7efeb25f --- /dev/null +++ b/src/engine/curl_stack.h @@ -0,0 +1,41 @@ +#ifndef RTORRENT_ENGINE_CURL_STACK_H +#define RTORRENT_ENGINE_CURL_STACK_H + +#include + +namespace engine { + +class CurlStack { + public: + friend class CurlGet; + + typedef std::list CurlGetList; + + CurlStack(); + ~CurlStack(); + + int get_size() const { return m_size; } + bool is_busy() const { return !m_getList.empty(); } + + void perform(); + + // TODO: Set fd_set's only once? + void fdset(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int* maxFd); + + static void global_init(); + static void global_cleanup(); + + protected: + void add_get(CurlGet* get); + void remove_get(CurlGet* get); + + private: + void* m_handle; + + int m_size; + CurlGetList m_getList; +}; + +} + +#endif diff --git a/src/downloads.cc b/src/engine/downloads.cc similarity index 93% rename from src/downloads.cc rename to src/engine/downloads.cc index 13d9708b..dcaf9526 100644 --- a/src/downloads.cc +++ b/src/engine/downloads.cc @@ -4,6 +4,8 @@ #include "downloads.h" +namespace engine { + void Downloads::create(std::istream& str) { torrent::Download d = torrent::download_create(str); @@ -17,3 +19,5 @@ Downloads::erase(iterator itr) { Base::erase(itr); } + +} diff --git a/src/downloads.h b/src/engine/downloads.h similarity index 82% rename from src/downloads.h rename to src/engine/downloads.h index e6253360..03ffa34c 100644 --- a/src/downloads.h +++ b/src/engine/downloads.h @@ -1,9 +1,11 @@ -#ifndef RTORRENT_DOWNLOADS_H -#define RTORRENT_DOWNLOADS_H +#ifndef RTORRENT_ENGINE_DOWNLOADS_H +#define RTORRENT_ENGINE_DOWNLOADS_H #include #include +namespace engine { + class Downloads : private std::list { public: typedef std::list Base; @@ -22,4 +24,6 @@ public: void erase(iterator itr); }; +} + #endif diff --git a/src/poll.cc b/src/engine/poll.cc similarity index 96% rename from src/poll.cc rename to src/engine/poll.cc index 4f5dd5cc..6b27fbb4 100644 --- a/src/poll.cc +++ b/src/engine/poll.cc @@ -5,6 +5,8 @@ #include "poll.h" +namespace engine { + void Poll::poll() { FD_ZERO(&m_readSet); @@ -33,3 +35,5 @@ Poll::work() { m_readStdin(key); } } + +} diff --git a/src/poll.h b/src/engine/poll.h similarity index 73% rename from src/poll.h rename to src/engine/poll.h index 870577fc..66b638aa 100644 --- a/src/poll.h +++ b/src/engine/poll.h @@ -1,16 +1,18 @@ -#ifndef RTORRENT_POLL_H -#define RTORRENT_POLL_H +#ifndef RTORRENT_ENGINE_POLL_H +#define RTORRENT_ENGINE_POLL_H #include #include +namespace engine { + class Poll { public: typedef sigc::slot1 SlotInt; Poll() : m_running(true) {} - bool is_running() { return m_running; } + bool is_running() { return m_running; } void poll(); void work(); @@ -27,4 +29,6 @@ private: fd_set m_exceptSet; }; +} + #endif diff --git a/src/main.cc b/src/main.cc index ada8d499..89ba7224 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,21 +3,27 @@ #include #include #include +#include +#include #include "display/canvas.h" #include "display/manager.h" #include "display/window_downloads.h" + +#include "engine/poll.h" +#include "engine/curl_stack.h" +#include "engine/curl_get.h" +#include "engine/downloads.h" + #include "input/bindings.h" #include "input/manager.h" -#include "poll.h" -#include "downloads.h" - int main(int argc, char** argv) { try { - Poll poll; - Downloads downloads; + engine::Poll poll; + engine::Downloads downloads; + engine::CurlStack curlStack; display::Canvas::init(); display::Manager display; @@ -32,6 +38,8 @@ int main(int argc, char** argv) { torrent::initialize(); torrent::listen_open(6880, 6999); + torrent::Http::set_factory(sigc::bind(sigc::ptr_fun(&engine::CurlGet::new_object), &curlStack)); + for (int i = 1; i < argc; ++i) { std::fstream f(argv[i], std::ios::in);