mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-14 22:22:31 +00:00
* Make VariableMap handle both global and core::Download
variables. Variable now has functions for both void and core::Download*, where the core::Download* is discarded if necessary. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@847 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -44,6 +44,26 @@ namespace utils {
|
||||
|
||||
const torrent::Object Variable::m_emptyObject;
|
||||
|
||||
// Consider throwing an exception.
|
||||
const torrent::Object&
|
||||
Variable::get() {
|
||||
return m_emptyObject;
|
||||
}
|
||||
|
||||
void
|
||||
Variable::set(const torrent::Object& arg) {
|
||||
}
|
||||
|
||||
const torrent::Object&
|
||||
Variable::get_d(core::Download* download) {
|
||||
return get();
|
||||
}
|
||||
|
||||
void
|
||||
Variable::set_d(core::Download* download, const torrent::Object& arg) {
|
||||
set(arg);
|
||||
}
|
||||
|
||||
const char*
|
||||
Variable::string_to_value_unit(const char* pos, value_type* value, int base, int unit) {
|
||||
char* last;
|
||||
|
||||
+10
-2
@@ -39,6 +39,10 @@
|
||||
|
||||
#include <torrent/object.h>
|
||||
|
||||
namespace core {
|
||||
class Download;
|
||||
}
|
||||
|
||||
namespace utils {
|
||||
|
||||
class Variable {
|
||||
@@ -52,8 +56,12 @@ public:
|
||||
Variable() {}
|
||||
virtual ~Variable() {}
|
||||
|
||||
virtual const torrent::Object& get() = 0;
|
||||
virtual void set(const torrent::Object& arg) = 0;
|
||||
virtual const torrent::Object& get();
|
||||
virtual void set(const torrent::Object& arg);
|
||||
|
||||
// The default action is to throw away the 'download' argument.
|
||||
virtual const torrent::Object& get_d(core::Download* download);
|
||||
virtual void set_d(core::Download* download, const torrent::Object& arg);
|
||||
|
||||
static const char* string_to_value_unit(const char* pos, value_type* value, int base, int unit);
|
||||
static bool string_to_value_unit_nothrow(const char* pos, value_type* value, int base, int unit);
|
||||
|
||||
@@ -102,22 +102,22 @@ VariableBool::set(const torrent::Object& arg) {
|
||||
}
|
||||
|
||||
const torrent::Object&
|
||||
VariableObject::get() {
|
||||
VariableObject::get_d(core::Download* download) {
|
||||
if (m_root.empty())
|
||||
return m_bencode->get_key(m_key);
|
||||
return download->bencode()->get_key(m_key);
|
||||
else
|
||||
return m_bencode->get_key(m_root).get_key(m_key);
|
||||
return download->bencode()->get_key(m_root).get_key(m_key);
|
||||
}
|
||||
|
||||
void
|
||||
VariableObject::set(const torrent::Object& arg) {
|
||||
VariableObject::set_d(core::Download* download, const torrent::Object& arg) {
|
||||
// Consider removing if TYPE_NONE.
|
||||
torrent::Object* root;
|
||||
|
||||
if (m_root.empty())
|
||||
root = m_bencode;
|
||||
root = download->bencode();
|
||||
else
|
||||
root = &m_bencode->get_key(m_root);
|
||||
root = &download->bencode()->get_key(m_root);
|
||||
|
||||
switch (m_type) {
|
||||
case torrent::Object::TYPE_NONE:
|
||||
@@ -200,7 +200,7 @@ VariableValueSlot::set(const torrent::Object& arg) {
|
||||
const torrent::Object&
|
||||
VariableStringSlot::get() {
|
||||
if (!m_slotGet.is_valid())
|
||||
return m_cache;
|
||||
return m_cache = torrent::Object();
|
||||
|
||||
m_cache = m_slotGet();
|
||||
|
||||
@@ -224,4 +224,51 @@ VariableStringSlot::set(const torrent::Object& arg) {
|
||||
}
|
||||
}
|
||||
|
||||
const torrent::Object&
|
||||
VariableStringSlot::get_d(core::Download* download) {
|
||||
// Should clear the cache.
|
||||
if (!m_slotGetDownload.is_valid()) {
|
||||
if (!m_slotGet.is_valid())
|
||||
return m_cache = torrent::Object();
|
||||
|
||||
m_cache = m_slotGet();
|
||||
|
||||
} else {
|
||||
m_cache = m_slotGetDownload(download);
|
||||
}
|
||||
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
void
|
||||
VariableStringSlot::set_d(core::Download* download, const torrent::Object& arg) {
|
||||
if (!m_slotSetDownload.is_valid()) {
|
||||
if (!m_slotSet.is_valid())
|
||||
return;
|
||||
|
||||
switch (arg.type()) {
|
||||
case torrent::Object::TYPE_STRING:
|
||||
m_slotSet(arg.as_string());
|
||||
break;
|
||||
case torrent::Object::TYPE_NONE:
|
||||
m_slotSet(std::string());
|
||||
break;
|
||||
default:
|
||||
throw torrent::input_error("Not a string.");
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (arg.type()) {
|
||||
case torrent::Object::TYPE_STRING:
|
||||
m_slotSetDownload(download, arg.as_string());
|
||||
break;
|
||||
case torrent::Object::TYPE_NONE:
|
||||
m_slotSetDownload(download, std::string());
|
||||
break;
|
||||
default:
|
||||
throw torrent::input_error("Not a string.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "variable.h"
|
||||
#include "core/download.h"
|
||||
|
||||
namespace utils {
|
||||
|
||||
@@ -82,17 +83,13 @@ class VariableObject : public Variable {
|
||||
public:
|
||||
typedef torrent::Object::type_type Type;
|
||||
|
||||
VariableObject(torrent::Object* b,
|
||||
const std::string& root,
|
||||
const std::string& key,
|
||||
Type t = torrent::Object::TYPE_NONE) :
|
||||
m_bencode(b), m_root(root), m_key(key), m_type(t) {}
|
||||
VariableObject(const std::string& root, const std::string& key, Type t = torrent::Object::TYPE_NONE) :
|
||||
m_root(root), m_key(key), m_type(t) {}
|
||||
|
||||
virtual const torrent::Object& get();
|
||||
virtual void set(const torrent::Object& arg);
|
||||
virtual const torrent::Object& get_d(core::Download* download);
|
||||
virtual void set_d(core::Download* download, const torrent::Object& arg);
|
||||
|
||||
private:
|
||||
torrent::Object* m_bencode;
|
||||
std::string m_root;
|
||||
std::string m_key;
|
||||
Type m_type;
|
||||
@@ -169,27 +166,54 @@ private:
|
||||
|
||||
class VariableStringSlot : public Variable {
|
||||
public:
|
||||
typedef rak::function0<string_type> slot_get_type;
|
||||
typedef rak::function1<void, const string_type&> slot_set_type;
|
||||
typedef rak::function0<string_type> slot_get_type;
|
||||
typedef rak::function1<string_type, core::Download*> slot_get_d_type;
|
||||
typedef rak::function1<void, const string_type&> slot_set_type;
|
||||
typedef rak::function2<void, core::Download*, const string_type&> slot_set_d_type;
|
||||
|
||||
template <typename SlotGet, typename SlotSet>
|
||||
VariableStringSlot(SlotGet* slotGet, SlotSet* slotSet) {
|
||||
m_slotGet.set(rak::convert_fn<string_type>(slotGet));
|
||||
m_slotSet.set(rak::convert_fn<void, const string_type&>(slotSet));
|
||||
m_slotGetDownload.set(NULL);
|
||||
m_slotSetDownload.set(NULL);
|
||||
}
|
||||
|
||||
template <typename SlotGet>
|
||||
VariableStringSlot(SlotGet* slotGet, void* slotSet) {
|
||||
m_slotGet.set(rak::convert_fn<string_type>(slotGet));
|
||||
template <typename SlotGetDownload>
|
||||
VariableStringSlot(void* slotGet, void* slotSet, SlotGetDownload* slotGetDownload, void* slotSetDownload) {
|
||||
m_slotGet.set(NULL);
|
||||
m_slotSet.set(NULL);
|
||||
m_slotGetDownload.set(rak::convert_fn<string_type, core::Download*>(slotGetDownload));
|
||||
m_slotSetDownload.set(NULL);
|
||||
}
|
||||
|
||||
template <typename SlotGetDownload, typename SlotSetDownload>
|
||||
VariableStringSlot(void* slotGet, void* slotSet, SlotGetDownload* slotGetDownload, SlotSetDownload* slotSetDownload) {
|
||||
m_slotGet.set(NULL);
|
||||
m_slotSet.set(NULL);
|
||||
m_slotGetDownload.set(rak::convert_fn<string_type, core::Download*>(slotGetDownload));
|
||||
m_slotSetDownload.set(rak::convert_fn<void, core::Download*, const string_type&>(slotSetDownload));
|
||||
}
|
||||
|
||||
// template <typename SlotGet, typename SlotSet, typename SlotGetDownload, typename SlotSetDownload>
|
||||
// VariableStringSlot(SlotGet* slotGet, SlotSet* slotSet, SlotGetDownload* slotGetDownload, SlotSetDownload* slotSetDownload) {
|
||||
// m_slotGet.set(slotGet != NULL ? rak::convert_fn<string_type>(slotGet) : NULL);
|
||||
// m_slotSet.set(slotSet != NULL ? rak::convert_fn<void, const string_type&>(slotSet) : NULL);
|
||||
// m_slotGetDownload.set(slotGetDownload != NULL ? rak::convert_fn<string_type, core::Download*>(slotGetDownload) : NULL);
|
||||
// m_slotSetDownload.set(slotSetDownload != NULL ? rak::convert_fn<void, core::Download*, const string_type&>(slotSetDownload) : NULL);
|
||||
// }
|
||||
|
||||
virtual const torrent::Object& get();
|
||||
virtual void set(const torrent::Object& arg);
|
||||
|
||||
virtual const torrent::Object& get_d(core::Download* download);
|
||||
virtual void set_d(core::Download* download, const torrent::Object& arg);
|
||||
|
||||
private:
|
||||
slot_get_type m_slotGet;
|
||||
slot_set_type m_slotSet;
|
||||
slot_get_d_type m_slotGetDownload;
|
||||
slot_set_d_type m_slotSetDownload;
|
||||
|
||||
// Store the cache here to avoid unnessesary copying and such. This
|
||||
// should not result in any unresonable memory usage since few
|
||||
|
||||
@@ -74,6 +74,16 @@ VariableMap::get(key_type key) const {
|
||||
return itr->second->get();
|
||||
}
|
||||
|
||||
const VariableMap::mapped_type&
|
||||
VariableMap::get_d(core::Download* download, key_type key) const {
|
||||
const_iterator itr = base_type::find(key);
|
||||
|
||||
if (itr == base_type::end())
|
||||
throw torrent::input_error("Variable \"" + std::string(key) + "\" does not exist.");
|
||||
|
||||
return itr->second->get_d(download);
|
||||
}
|
||||
|
||||
void
|
||||
VariableMap::set(key_type key, const mapped_type& arg) {
|
||||
iterator itr = base_type::find(key);
|
||||
@@ -86,6 +96,18 @@ VariableMap::set(key_type key, const mapped_type& arg) {
|
||||
itr->second->set(arg);
|
||||
}
|
||||
|
||||
void
|
||||
VariableMap::set_d(core::Download* download, key_type key, const mapped_type& arg) {
|
||||
iterator itr = base_type::find(key);
|
||||
|
||||
// Later, allow the user to create new variables. Have a slot to
|
||||
// register that thing.
|
||||
if (itr == base_type::end())
|
||||
throw torrent::input_error("Variable \"" + std::string(key) + "\" does not exist.");
|
||||
|
||||
itr->second->set_d(download, arg);
|
||||
}
|
||||
|
||||
struct variable_map_is_space : std::unary_function<char, bool> {
|
||||
bool operator () (char c) const {
|
||||
return std::isspace(c);
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
#include <iosfwd>
|
||||
#include <torrent/object.h>
|
||||
|
||||
namespace core {
|
||||
class Download;
|
||||
}
|
||||
|
||||
namespace torrent {
|
||||
class Object;
|
||||
}
|
||||
@@ -78,15 +82,25 @@ public:
|
||||
|
||||
void insert(key_type key, Variable* v);
|
||||
|
||||
// Consider taking char* start and finish instead of std::string to
|
||||
// avoid copying. Or make a view class.
|
||||
// Consider uninlining the helper functions.
|
||||
|
||||
const mapped_type& get(key_type key) const;
|
||||
const std::string& get_string(key_type key) const { return get(key).as_string(); }
|
||||
mapped_value_type get_value(key_type key) const { return get(key).as_value(); }
|
||||
const mapped_type& get_d(core::Download* download, key_type key) const;
|
||||
|
||||
const std::string& get_string(key_type key) const { return get(key).as_string(); }
|
||||
const std::string& get_d_string(core::Download* download, key_type key) const { return get_d(download, key).as_string(); }
|
||||
|
||||
mapped_value_type get_value(key_type key) const { return get(key).as_value(); }
|
||||
mapped_value_type get_d_value(core::Download* download, key_type key) const { return get_d(download, key).as_value(); }
|
||||
|
||||
void set(key_type key, const mapped_type& arg);
|
||||
void set_string(key_type key, const std::string& arg) { set(key, mapped_type(arg)); }
|
||||
void set_value(key_type key, mapped_value_type arg) { set(key, mapped_type(arg)); }
|
||||
void set_d(core::Download* download, key_type key, const mapped_type& arg);
|
||||
|
||||
void set_string(key_type key, const std::string& arg) { set(key, mapped_type(arg)); }
|
||||
void set_d_string(core::Download* download, key_type key, const std::string& arg) { set_d(download, key, mapped_type(arg)); }
|
||||
|
||||
void set_value(key_type key, mapped_value_type arg) { set(key, mapped_type(arg)); }
|
||||
void set_d_value(core::Download* download, key_type key, mapped_value_type arg) { set_d(download, key, mapped_type(arg)); }
|
||||
|
||||
void set_std_string(const std::string& key, const std::string& arg) { set(key.c_str(), mapped_type(arg)); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user