* 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:
rakshasa
2007-01-17 15:18:33 +00:00
parent d030c5401e
commit e59b5bf7b6
19 changed files with 414 additions and 133 deletions
+20
View File
@@ -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
View File
@@ -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);
+54 -7
View File
@@ -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.");
}
}
}
}
+37 -13
View File
@@ -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
+22
View File
@@ -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);
+20 -6
View File
@@ -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)); }