瀏覽代碼

2009-02-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Rewritten BDE to make it efficient.
	* src/bencode.cc
	* src/bencode.h
Tatsuhiro Tsujikawa 16 年之前
父節點
當前提交
3ae7633f32
共有 3 個文件被更改,包括 264 次插入126 次删除
  1. 6 0
      ChangeLog
  2. 31 121
      src/bencode.cc
  3. 227 5
      src/bencode.h

+ 6 - 0
ChangeLog

@@ -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>
 
 	Removed function throw list.

+ 31 - 121
src/bencode.cc

@@ -39,7 +39,6 @@
 
 #include "StringFormat.h"
 #include "Util.h"
-#include "RecoverableException.h"
 
 namespace aria2 {
 
@@ -50,28 +49,28 @@ const BDE BDE::none;
 BDE::BDE():_type(TYPE_NONE) {}
 
 BDE::BDE(Integer integer):_type(TYPE_INTEGER),
-				  _integer(new Integer(integer)) {}
+			  _bobject(new BInteger(integer)) {}
 
 
 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),
-			      _string(new std::string(cstring)) {}
+			      _bobject(new BString(std::string(cstring))) {}
 
 BDE::BDE(const char* data, size_t length):
   _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):
   _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;
   bde._type = TYPE_DICT;
-  bde._dict.reset(new Dict());
+  bde._bobject.reset(new BDict());
   return bde;
 }
 
@@ -79,7 +78,7 @@ BDE BDE::list()
 {
   BDE bde;
   bde._type = TYPE_LIST;
-  bde._list.reset(new List());
+  bde._bobject.reset(new BList());
   return bde;
 }
 
@@ -98,11 +97,7 @@ bool BDE::isInteger() const
 
 BDE::Integer BDE::i() const
 {
-  if(isInteger()) {
-    return *_integer.get();
-  } else {
-    throw RecoverableException("Not Integer");
-  }
+  return _bobject->i();
 }
 
 // String Interface
@@ -114,20 +109,12 @@ bool BDE::isString() const
 
 const std::string& BDE::s() const
 {
-  if(isString()) {
-    return *_string.get();
-  } else {
-    throw RecoverableException("Not String");
-  }
+  return _bobject->s();
 }
 
 const unsigned char* BDE::uc() const
 {
-  if(isString()) {
-    return reinterpret_cast<const unsigned char*>(_string->data());
-  } else {
-    throw RecoverableException("Not String");
-  }
+  return _bobject->uc();
 }
 
 // Dictionary Interface
@@ -139,79 +126,46 @@ bool BDE::isDict() const
 
 BDE& BDE::operator[](const std::string& key)
 {
-  if(isDict()) {
-    return (*_dict.get())[key];
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  return _bobject->operator[](key);
 }
 
 const BDE& BDE::operator[](const std::string& key) const
 {
-  if(isDict()) {
-    BDE::Dict::const_iterator i = _dict->find(key);
-    if(i == _dict->end()) {
-      return none;
-    } else {
-      return (*i).second;
-    }
+  if(_bobject->containsKey(key)) {
+    return _bobject->operator[](key);
   } else {
-    throw RecoverableException("Not Dict");
+    return none;
   }
 }
 
 bool BDE::containsKey(const std::string& key) const
 {
-  if(isDict()) {
-    return _dict->find(key) != _dict->end();
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  return _bobject->containsKey(key);
 }
 
-void BDE::removeKey(const std::string& key) const
+void BDE::removeKey(const std::string& key)
 {
-  if(isDict()) {
-    _dict->erase(key);
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  _bobject->removeKey(key);
 }
 
 BDE::Dict::iterator BDE::dictBegin()
 {
-  if(isDict()) {
-    return _dict->begin();
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  return _bobject->dictBegin();
 }
 
 BDE::Dict::const_iterator BDE::dictBegin() const
 {
-  if(isDict()) {
-    return _dict->begin();
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  return _bobject->dictBegin();
 }
 
 BDE::Dict::iterator BDE::dictEnd()
 {
-  if(isDict()) {
-    return _dict->end();
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  return _bobject->dictEnd();
 }
 
 BDE::Dict::const_iterator BDE::dictEnd() const
 {
-  if(isDict()) {
-    return _dict->end();
-  } else {
-    throw RecoverableException("Not Dict");
-  }
+  return _bobject->dictEnd();
 }
 
 // List Interface
@@ -223,98 +177,54 @@ bool BDE::isList() const
 
 void BDE::append(const BDE& bde)
 {
-  if(isList()) {
-    _list->push_back(bde);
-  } else {
-    throw RecoverableException("Not List");
-  }
+  _bobject->append(bde);
 }
 
 void BDE::operator<<(const BDE& bde)
 {
-  if(isList()) {
-    _list->push_back(bde);
-  } else {
-    throw RecoverableException("Not List");
-  }
+  _bobject->operator<<(bde);
 }
 
 BDE& BDE::operator[](size_t index)
 {
-  if(isList()) {
-    return (*_list.get())[index];
-  } else {
-    throw RecoverableException("Not List");
-  }
+  return _bobject->operator[](index);
 }
 
 const BDE& BDE::operator[](size_t index) const
 {
-  if(isList()) {
-    return (*_list.get())[index];
-  } else {
-    throw RecoverableException("Not List");
-  }
+  return _bobject->operator[](index);
 }
 
 BDE::List::iterator BDE::listBegin()
 {
-  if(isList()) {
-    return _list->begin();
-  } else {
-    throw RecoverableException("Not List");
-  }
+  return _bobject->listBegin();
 }
 
 BDE::List::const_iterator BDE::listBegin() const
 {
-  if(isList()) {
-    return _list->begin();
-  } else {
-    throw RecoverableException("Not List");
-  }
+  return _bobject->listBegin();
 }
 
 BDE::List::iterator BDE::listEnd()
 {
-  if(isList()) {
-    return _list->end();
-  } else {
-    throw RecoverableException("Not List");
-  }
+  return _bobject->listEnd();
 }
 
 BDE::List::const_iterator BDE::listEnd() const
 {
-  if(isList()) {
-    return _list->end();
-  } else {
-    throw RecoverableException("Not List");
-  }
+  return _bobject->listEnd();
 }
 
 // Callable from List and Dict
 size_t BDE::size() const
 {
-  if(isDict()) {
-    return _dict->size();
-  } else if(isList()) {
-    return _list->size();
-  } else {
-    throw RecoverableException("Not Dict nor List");
-  }
+  return _bobject->size();
 }
 
 // Callable from List and Dict
 bool BDE::empty() const
 {
-  if(isDict()) {
-    return _dict->empty();
-  } else if(isList()) {
-    return _list->empty();
-  } else {
-    throw RecoverableException("Not Dict nor List");
-  }
+  return _bobject->empty();
 }
 
 static BDE decodeiter(std::istream& ss);

+ 227 - 5
src/bencode.h

@@ -43,6 +43,8 @@
 #include <iosfwd>
 
 #include "SharedHandle.h"
+#include "A2STR.h"
+#include "RecoverableException.h"
 
 namespace aria2 {
 
@@ -64,12 +66,232 @@ private:
     TYPE_LIST,
   };
 
+  class BObject {
+  public:
+    ////////////////////////////////////////////////////////////////////////////
+    // Integer Interface
+
+    // 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<Dict> _dict;
-  SharedHandle<List> _list;
-  SharedHandle<std::string> _string;
-  SharedHandle<Integer> _integer;
 
+  SharedHandle<BObject> _bobject;
 public:
   BDE();
 
@@ -140,7 +362,7 @@ public:
 
   // Removes specified key from 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.
   // Requires this object to be Dict.