mirror of https://github.com/aria2/aria2
2009-02-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten BDE to make it efficient. * src/bencode.cc * src/bencode.hpull/1/head
parent
eafb1bc615
commit
3ae7633f32
|
@ -1,3 +1,9 @@
|
||||||
|
2009-02-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Rewritten BDE to make it efficient.
|
||||||
|
* src/bencode.cc
|
||||||
|
* src/bencode.h
|
||||||
|
|
||||||
2009-02-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2009-02-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Removed function throw list.
|
Removed function throw list.
|
||||||
|
|
152
src/bencode.cc
152
src/bencode.cc
|
@ -39,7 +39,6 @@
|
||||||
|
|
||||||
#include "StringFormat.h"
|
#include "StringFormat.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "RecoverableException.h"
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -50,28 +49,28 @@ const BDE BDE::none;
|
||||||
BDE::BDE():_type(TYPE_NONE) {}
|
BDE::BDE():_type(TYPE_NONE) {}
|
||||||
|
|
||||||
BDE::BDE(Integer integer):_type(TYPE_INTEGER),
|
BDE::BDE(Integer integer):_type(TYPE_INTEGER),
|
||||||
_integer(new Integer(integer)) {}
|
_bobject(new BInteger(integer)) {}
|
||||||
|
|
||||||
|
|
||||||
BDE::BDE(const std::string& string):_type(TYPE_STRING),
|
BDE::BDE(const std::string& string):_type(TYPE_STRING),
|
||||||
_string(new std::string(string)) {}
|
_bobject(new BString(std::string(string))) {}
|
||||||
|
|
||||||
BDE::BDE(const char* cstring):_type(TYPE_STRING),
|
BDE::BDE(const char* cstring):_type(TYPE_STRING),
|
||||||
_string(new std::string(cstring)) {}
|
_bobject(new BString(std::string(cstring))) {}
|
||||||
|
|
||||||
BDE::BDE(const char* data, size_t length):
|
BDE::BDE(const char* data, size_t length):
|
||||||
_type(TYPE_STRING),
|
_type(TYPE_STRING),
|
||||||
_string(new std::string(&data[0], &data[length])) {}
|
_bobject(new BString(std::string(&data[0], &data[length]))) {}
|
||||||
|
|
||||||
BDE::BDE(const unsigned char* data, size_t length):
|
BDE::BDE(const unsigned char* data, size_t length):
|
||||||
_type(TYPE_STRING),
|
_type(TYPE_STRING),
|
||||||
_string(new std::string(&data[0], &data[length])) {}
|
_bobject(new BString(std::string(&data[0], &data[length]))) {}
|
||||||
|
|
||||||
BDE BDE::dict()
|
BDE BDE::dict()
|
||||||
{
|
{
|
||||||
BDE bde;
|
BDE bde;
|
||||||
bde._type = TYPE_DICT;
|
bde._type = TYPE_DICT;
|
||||||
bde._dict.reset(new Dict());
|
bde._bobject.reset(new BDict());
|
||||||
return bde;
|
return bde;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ BDE BDE::list()
|
||||||
{
|
{
|
||||||
BDE bde;
|
BDE bde;
|
||||||
bde._type = TYPE_LIST;
|
bde._type = TYPE_LIST;
|
||||||
bde._list.reset(new List());
|
bde._bobject.reset(new BList());
|
||||||
return bde;
|
return bde;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,11 +97,7 @@ bool BDE::isInteger() const
|
||||||
|
|
||||||
BDE::Integer BDE::i() const
|
BDE::Integer BDE::i() const
|
||||||
{
|
{
|
||||||
if(isInteger()) {
|
return _bobject->i();
|
||||||
return *_integer.get();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Integer");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String Interface
|
// String Interface
|
||||||
|
@ -114,20 +109,12 @@ bool BDE::isString() const
|
||||||
|
|
||||||
const std::string& BDE::s() const
|
const std::string& BDE::s() const
|
||||||
{
|
{
|
||||||
if(isString()) {
|
return _bobject->s();
|
||||||
return *_string.get();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not String");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char* BDE::uc() const
|
const unsigned char* BDE::uc() const
|
||||||
{
|
{
|
||||||
if(isString()) {
|
return _bobject->uc();
|
||||||
return reinterpret_cast<const unsigned char*>(_string->data());
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not String");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dictionary Interface
|
// Dictionary Interface
|
||||||
|
@ -139,79 +126,46 @@ bool BDE::isDict() const
|
||||||
|
|
||||||
BDE& BDE::operator[](const std::string& key)
|
BDE& BDE::operator[](const std::string& key)
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->operator[](key);
|
||||||
return (*_dict.get())[key];
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BDE& BDE::operator[](const std::string& key) const
|
const BDE& BDE::operator[](const std::string& key) const
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
if(_bobject->containsKey(key)) {
|
||||||
BDE::Dict::const_iterator i = _dict->find(key);
|
return _bobject->operator[](key);
|
||||||
if(i == _dict->end()) {
|
|
||||||
return none;
|
|
||||||
} else {
|
|
||||||
return (*i).second;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw RecoverableException("Not Dict");
|
return none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BDE::containsKey(const std::string& key) const
|
bool BDE::containsKey(const std::string& key) const
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->containsKey(key);
|
||||||
return _dict->find(key) != _dict->end();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BDE::removeKey(const std::string& key) const
|
void BDE::removeKey(const std::string& key)
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
_bobject->removeKey(key);
|
||||||
_dict->erase(key);
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::Dict::iterator BDE::dictBegin()
|
BDE::Dict::iterator BDE::dictBegin()
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->dictBegin();
|
||||||
return _dict->begin();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::Dict::const_iterator BDE::dictBegin() const
|
BDE::Dict::const_iterator BDE::dictBegin() const
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->dictBegin();
|
||||||
return _dict->begin();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::Dict::iterator BDE::dictEnd()
|
BDE::Dict::iterator BDE::dictEnd()
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->dictEnd();
|
||||||
return _dict->end();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::Dict::const_iterator BDE::dictEnd() const
|
BDE::Dict::const_iterator BDE::dictEnd() const
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->dictEnd();
|
||||||
return _dict->end();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List Interface
|
// List Interface
|
||||||
|
@ -223,98 +177,54 @@ bool BDE::isList() const
|
||||||
|
|
||||||
void BDE::append(const BDE& bde)
|
void BDE::append(const BDE& bde)
|
||||||
{
|
{
|
||||||
if(isList()) {
|
_bobject->append(bde);
|
||||||
_list->push_back(bde);
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BDE::operator<<(const BDE& bde)
|
void BDE::operator<<(const BDE& bde)
|
||||||
{
|
{
|
||||||
if(isList()) {
|
_bobject->operator<<(bde);
|
||||||
_list->push_back(bde);
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE& BDE::operator[](size_t index)
|
BDE& BDE::operator[](size_t index)
|
||||||
{
|
{
|
||||||
if(isList()) {
|
return _bobject->operator[](index);
|
||||||
return (*_list.get())[index];
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BDE& BDE::operator[](size_t index) const
|
const BDE& BDE::operator[](size_t index) const
|
||||||
{
|
{
|
||||||
if(isList()) {
|
return _bobject->operator[](index);
|
||||||
return (*_list.get())[index];
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::List::iterator BDE::listBegin()
|
BDE::List::iterator BDE::listBegin()
|
||||||
{
|
{
|
||||||
if(isList()) {
|
return _bobject->listBegin();
|
||||||
return _list->begin();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::List::const_iterator BDE::listBegin() const
|
BDE::List::const_iterator BDE::listBegin() const
|
||||||
{
|
{
|
||||||
if(isList()) {
|
return _bobject->listBegin();
|
||||||
return _list->begin();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::List::iterator BDE::listEnd()
|
BDE::List::iterator BDE::listEnd()
|
||||||
{
|
{
|
||||||
if(isList()) {
|
return _bobject->listEnd();
|
||||||
return _list->end();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE::List::const_iterator BDE::listEnd() const
|
BDE::List::const_iterator BDE::listEnd() const
|
||||||
{
|
{
|
||||||
if(isList()) {
|
return _bobject->listEnd();
|
||||||
return _list->end();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callable from List and Dict
|
// Callable from List and Dict
|
||||||
size_t BDE::size() const
|
size_t BDE::size() const
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->size();
|
||||||
return _dict->size();
|
|
||||||
} else if(isList()) {
|
|
||||||
return _list->size();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict nor List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callable from List and Dict
|
// Callable from List and Dict
|
||||||
bool BDE::empty() const
|
bool BDE::empty() const
|
||||||
{
|
{
|
||||||
if(isDict()) {
|
return _bobject->empty();
|
||||||
return _dict->empty();
|
|
||||||
} else if(isList()) {
|
|
||||||
return _list->empty();
|
|
||||||
} else {
|
|
||||||
throw RecoverableException("Not Dict nor List");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BDE decodeiter(std::istream& ss);
|
static BDE decodeiter(std::istream& ss);
|
||||||
|
|
234
src/bencode.h
234
src/bencode.h
|
@ -43,6 +43,8 @@
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
|
#include "A2STR.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -64,12 +66,232 @@ private:
|
||||||
TYPE_LIST,
|
TYPE_LIST,
|
||||||
};
|
};
|
||||||
|
|
||||||
TYPE _type;
|
class BObject {
|
||||||
SharedHandle<Dict> _dict;
|
public:
|
||||||
SharedHandle<List> _list;
|
////////////////////////////////////////////////////////////////////////////
|
||||||
SharedHandle<std::string> _string;
|
// Integer Interface
|
||||||
SharedHandle<Integer> _integer;
|
|
||||||
|
|
||||||
|
// Returns Integer.
|
||||||
|
virtual Integer i() const
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not Integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// String Interface
|
||||||
|
|
||||||
|
// Returns std::string.
|
||||||
|
virtual const std::string& s() const
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not String");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns std::string.data() casted to unsigned char*.
|
||||||
|
// Use s().size() to get length.
|
||||||
|
virtual const unsigned char* uc() const
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not String");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Dictionary Interface
|
||||||
|
|
||||||
|
// Returns the reference to BDE object associated with given key.
|
||||||
|
// If the key is not found, new pair with that key is created
|
||||||
|
// using default values, which is then returned. In other words,
|
||||||
|
// this is the same behavior of std::map's operator[].
|
||||||
|
virtual BDE& operator[](const std::string& key)
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not Dict");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the given key is found in dict.
|
||||||
|
virtual bool containsKey(const std::string& key) const
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not Dict");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes specified key from dict.
|
||||||
|
virtual void removeKey(const std::string& key)
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not Dict");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a read/write iterator that points to the first pair in
|
||||||
|
// the dict.
|
||||||
|
virtual Dict::iterator dictBegin()
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not Dict");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a read/write read-only iterator that points to one past
|
||||||
|
// the last pair in the dict.
|
||||||
|
virtual Dict::iterator dictEnd()
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not Dict");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// List Interface
|
||||||
|
|
||||||
|
// Appends given bde to list.
|
||||||
|
virtual void append(const BDE& bde)
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not List");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alias for append()
|
||||||
|
virtual void operator<<(const BDE& bde)
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not List");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the reference of the object at the given index.
|
||||||
|
virtual BDE& operator[](size_t index)
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not List");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a read/write iterator that points to the first object
|
||||||
|
// in list.
|
||||||
|
virtual List::iterator listBegin()
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not List");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a read/write iterator that points to the one past the
|
||||||
|
// last object in list.
|
||||||
|
virtual List::iterator listEnd()
|
||||||
|
{
|
||||||
|
throw RecoverableException("Not List");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns size of list or dict.
|
||||||
|
virtual size_t size() const
|
||||||
|
{
|
||||||
|
throw RecoverableException("Neither Dict nor List");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if size of list or dict is 0.
|
||||||
|
virtual bool empty() const
|
||||||
|
{
|
||||||
|
throw RecoverableException("Neither Dict nor List");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BInteger : public BObject {
|
||||||
|
private:
|
||||||
|
Integer _integer;
|
||||||
|
public:
|
||||||
|
BInteger(Integer i):_integer(i) {}
|
||||||
|
|
||||||
|
virtual BDE::Integer i() const
|
||||||
|
{
|
||||||
|
return _integer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BString : public BObject {
|
||||||
|
private:
|
||||||
|
std::string _string;
|
||||||
|
public:
|
||||||
|
BString(const std::string& string):_string(string) {}
|
||||||
|
|
||||||
|
virtual const std::string& s() const
|
||||||
|
{
|
||||||
|
return _string;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const unsigned char* uc() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const unsigned char*>(_string.data());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BDict : public BObject {
|
||||||
|
private:
|
||||||
|
Dict _dict;
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual BDE& operator[](const std::string& key)
|
||||||
|
{
|
||||||
|
return _dict[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool containsKey(const std::string& key) const
|
||||||
|
{
|
||||||
|
return _dict.find(key) != _dict.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void removeKey(const std::string& key)
|
||||||
|
{
|
||||||
|
_dict.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual BDE::Dict::iterator dictBegin()
|
||||||
|
{
|
||||||
|
return _dict.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual BDE::Dict::iterator dictEnd()
|
||||||
|
{
|
||||||
|
return _dict.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t size() const
|
||||||
|
{
|
||||||
|
return _dict.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool empty() const
|
||||||
|
{
|
||||||
|
return _dict.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BList : public BObject {
|
||||||
|
private:
|
||||||
|
List _list;
|
||||||
|
public:
|
||||||
|
virtual void append(const BDE& bde)
|
||||||
|
{
|
||||||
|
_list.push_back(bde);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator<<(const BDE& bde)
|
||||||
|
{
|
||||||
|
_list.push_back(bde);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual BDE& operator[](size_t index)
|
||||||
|
{
|
||||||
|
return _list[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual BDE::List::iterator listBegin()
|
||||||
|
{
|
||||||
|
return _list.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual BDE::List::iterator listEnd()
|
||||||
|
{
|
||||||
|
return _list.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t size() const
|
||||||
|
{
|
||||||
|
return _list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool empty() const
|
||||||
|
{
|
||||||
|
return _list.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TYPE _type;
|
||||||
|
|
||||||
|
SharedHandle<BObject> _bobject;
|
||||||
public:
|
public:
|
||||||
BDE();
|
BDE();
|
||||||
|
|
||||||
|
@ -140,7 +362,7 @@ public:
|
||||||
|
|
||||||
// Removes specified key from dict.
|
// Removes specified key from dict.
|
||||||
// Requires this object to be Dict.
|
// Requires this object to be Dict.
|
||||||
void removeKey(const std::string& key) const;
|
void removeKey(const std::string& key);
|
||||||
|
|
||||||
// Returns a read/write iterator that points to the first pair in the dict.
|
// Returns a read/write iterator that points to the first pair in the dict.
|
||||||
// Requires this object to be Dict.
|
// Requires this object to be Dict.
|
||||||
|
|
Loading…
Reference in New Issue