* Added a missing READ_PORT case to a switch in handshake.cc.

* Stuff.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1164 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2010-04-19 19:52:42 +00:00
parent 575cafc7a8
commit 9362453391
14 changed files with 444 additions and 84 deletions
+171 -28
View File
@@ -42,7 +42,7 @@
#define RTORRENT_RPC_OBJECT_STORAGE_H
#include <cstring>
#include <tr1/unordered_set>
#include <tr1/unordered_map>
#include <torrent/object.h>
namespace rpc {
@@ -50,42 +50,185 @@ namespace rpc {
// The key size should be such that the value type size which includes
// the next-pointer.
struct object_storage_node_internal {
template <size_t MaxSize>
class fixed_key_type {
public:
typedef char value_type;
typedef const char* iterator;
typedef const char* const_iterator;
typedef uint32_t size_type;
static const size_type max_size = MaxSize - 1;
fixed_key_type() : m_size(0) { m_data[0] = '\0'; }
fixed_key_type(const fixed_key_type& k) : m_size(k.m_size) { std::memcpy(m_data, k.m_data, k.m_size + 1); }
fixed_key_type(const value_type* src_data, size_type src_size) { set_data(src_data, src_size); }
static fixed_key_type from_c_str(const char* str) { fixed_key_type k; k.set_c_str(str); return k; }
static fixed_key_type from_string(const std::string& str) { fixed_key_type k; k.set_c_str(str.c_str(), str.size()); return k; }
static fixed_key_type from_raw_string(const torrent::raw_string& str) { fixed_key_type k; k.set_data(str.data(), str.size()); return k; }
bool empty() const { return m_size == 0;; }
size_type size() const { return m_size; }
iterator begin() const { return m_data; }
iterator end() const { return m_data + m_size; }
value_type* data() { return m_data; }
const value_type* data() const { return m_data; }
const char* c_str() const { return m_data; }
void set_data(const value_type* src_data, size_type src_size);
void set_c_str(const value_type* src_data);
void set_c_str(const value_type* src_data, size_type src_size);
bool operator == (const fixed_key_type& rhs) const { return m_size == rhs.m_size && std::memcmp(m_data, rhs.m_data, m_size) == 0; }
bool operator != (const fixed_key_type& rhs) const { return m_size != rhs.m_size || std::memcmp(m_data, rhs.m_data, m_size) != 0; }
bool operator == (const std::string& rhs) const { return m_size == rhs.size() && std::memcmp(m_data, rhs.data(), m_size) == 0; }
private:
size_type m_size;
char m_data[max_size];
};
struct hash_fixed_key_type {
template <size_t MaxSize>
inline std::size_t operator () (const fixed_key_type<MaxSize>& p) const { return hash(p.data()); }
static inline std::size_t hash(const char* data) {
std::size_t result = 0;
while (*data != '\0')
result = (result * 131) + *data++;
return result;
}
static inline std::size_t hash(const char* data, uint32_t size) {
std::size_t result = 0;
while (size--)
result = (result * 131) + *data++;
return result;
}
};
//
//
//
struct object_storage_node {
torrent::Object object;
char key[0];
char flags;
};
struct object_storage_node : public object_storage_node_internal {
// TODO: Use the size of the unordered_map::value_type with a struct {}.
static const size_t key_size = 128 - sizeof(object_storage_node_internal) - sizeof(void*);
};
struct hash_object_storage_node {
inline std::size_t operator () (const object_storage_node& p);
};
bool operator == (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) == 0; }
bool operator != (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) != 0; }
bool operator < (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) < 0; }
bool operator <= (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) <= 0; }
bool operator > (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) > 0; }
bool operator >= (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) >= 0; }
class object_storage : private std::tr1::unordered_set<object_storage_node, hash_object_storage_node> {
typedef std::tr1::unordered_set<object_storage_node, hash_object_storage_node> base_type;
class object_storage : private std::tr1::unordered_map<fixed_key_type<64>, object_storage_node, hash_fixed_key_type> {
public:
typedef std::tr1::unordered_map<fixed_key_type<64>, object_storage_node, hash_fixed_key_type> base_type;
using base_type::key_type;
using base_type::value_type;
using base_type::iterator;
using base_type::const_iterator;
using base_type::local_iterator;
using base_type::const_local_iterator;
using base_type::begin;
using base_type::end;
using base_type::size;
using base_type::empty;
using base_type::key_eq;
using base_type::bucket;
using base_type::bucket_count;
using base_type::max_bucket_count;
using base_type::load_factor;
using base_type::clear;
using base_type::find;
using base_type::erase;
static const unsigned int flag_generic_type = 0x1;
static const unsigned int flag_value_type = 0x2;
static const unsigned int flag_string_type = 0x4;
static const unsigned int flag_last_type = 0x8;
static const unsigned int mask_type = flag_last_type - 1;
static const size_t key_size = key_type::max_size;
local_iterator find_local(const torrent::raw_string& key);
iterator insert(const char* key_data, uint32_t key_size, const torrent::Object& object, unsigned int flags);
iterator insert(const char* key, const torrent::Object& object, unsigned int flags);
iterator insert(const torrent::raw_string& key, const torrent::Object& object, unsigned int flags);
iterator insert_string(const std::string& key, const torrent::Object& object, unsigned int flags);
// Access functions that throw on error.
const torrent::Object& get(const torrent::raw_string& key);
const torrent::Object& get_c_str(const char* str) { return get(torrent::raw_string(str, std::strlen(str))); }
const torrent::Object& set(const torrent::raw_string& key, const torrent::Object& object);
const torrent::Object& set_c_str(const char* str, const torrent::Object& object) { return set(torrent::raw_string(str, std::strlen(str)), object); }
};
inline std::size_t
hash_object_storage_node::operator () (const object_storage_node& p) {
std::size_t result = 0;
const char* first = p.key;
//
// Implementation:
//
while (*first != '\0')
result = (result * 131) + *first++;
template <size_t MaxSize> inline void
fixed_key_type<MaxSize>::set_data(const value_type* src_data, size_type src_size) {
if (src_size >= max_size) {
new (this) fixed_key_type();
return;
}
return result;
m_size = src_size;
std::memcpy(m_data, src_data, m_size);
m_data[m_size] = '\0';
}
template <size_t MaxSize> inline void
fixed_key_type<MaxSize>::set_c_str(const value_type* src_data) {
value_type* itr = m_data;
const value_type* last = m_data + max_size;
while (itr != last && *src_data != '\0')
*itr++ = *src_data++;
*itr = '\0';
m_size = std::distance(m_data, itr);
}
template <size_t MaxSize> inline void
fixed_key_type<MaxSize>::set_c_str(const value_type* src_data, size_type src_size) {
if (src_size >= max_size) {
new (this) fixed_key_type();
return;
}
m_size = src_size;
std::memcpy(m_data, src_data, m_size + 1);
}
inline object_storage::iterator
object_storage::insert(const char* key, const torrent::Object& object, unsigned int flags) {
return insert(key, std::strlen(key), object, flags);
}
inline object_storage::iterator
object_storage::insert(const torrent::raw_string& key, const torrent::Object& object, unsigned int flags) {
return insert(key.data(), key.size(), object, flags);
}
inline object_storage::iterator
object_storage::insert_string(const std::string& key, const torrent::Object& object, unsigned int flags) {
return insert(key.data(), key.size(), object, flags);
}
}