Parcourir la source

2006-07-27 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	* src/PeerMessage.h
	(Piece.h): Included.
	(SharedHandle.h): Included.
	(invalidate): New variable.
	(uploading): New variable.
	(isInvalidate): New function.
	(isUploading): New function.
	(onPush): New function.
	(onChoked): New function.
	(onCanceled): New function.
	(onAbortPiece): New function.
	(PeerMessageHandle): New type definition.
	
	* src/PeerMessage.cc
	(PeerMessage): Added the initialization for invalidate and 
uploading.
	
	* src/CancelMessage.h
	(CancelMessage): Rewritten.

	* src/RejectMessage.h
	(RejectMessage): Rewritten.

	* src/Metalinker.h
	(operator=): Defined.
	
	* src/MetaEntry.h
	(operator=): Defined.

	* src/MetalinkResource.h
	(operator=): Defined.
	
	* src/AllowedFastMessage.h
	(AllowedFastMessage): Rewritten.

	* src/HandshakeMessage.h
	(HandshakeMessage): New function(overload).
	
	* src/HandshakeMessage.cc
	(HandshakeMessage): Rewritten.
	(init): New function.

	* src/HaveMessage.h
	(HaveMessage): Rewritten.
	
	* src/Time.h
	(operator=): Defined the function body here.
	* src/Time.cc
	(operator=): Removed.
	
	* src/SocketCore.h
	(operator==): Defined here.
	(operator!=): Defined here.
	(operator<): Defined here.
	* src/SocketCore.cc
	(operator==): Removed.
	(operator<): Removed.

	* src/BitfieldMan.h
	(operator=): Defined the function body here.
	* src/BitfieldMan.cc
	(operator=): Removed.

	* src/TorrentMan.h
	(deleteErrorPeer): Removed.
	(deleteUnusedPeer); New function.
	* src/TorrentMan.cc
	(addPeer): Call deleteUnusedPeer.
	(deleteErrorPeer): Removed.
	(deleteUnusedPeer): New function.

	* src/PeerAbstractCommand.h
	(setNoCheck): New function.
	(noCheck): New variable.
	* src/PeerAbstractCommand.cc
	(PeerAbstractCommand): Added the initialization of noCheck.
	(execute): Added a check for noCheck.
	(setNoCheck): New function.

	* src/Util.h
	(stdio.h): Included.
	* src/Util.cc
	(unistd.h): Included.

	* src/DefaultDiskWriter.cc
	(unistd.h): Included.

	* src/Peer.h
	(operator==): Defined the function body here.
	(operator!=): Defined the function body here.
	* src/Peer.cc
	(operator==): Removed.
	(operator!=): Removed.

	* src/Piece.h
	(Piece): Defined the function body here(copy constructor).
	(operator=): Defined the function body here.
	(operator==): Defined the function body here.
	* src/Piece.cc
	(Piece): Removed(copy constructor).
	(operator=): Removed.
	(operator==): Removed.
	
	* src/PeerMessageUtil.h
	(ChokeMessage.h): Removed.
	(UnchokeMessage.h): Removed.
	(InterestedMessage.h): Removed.
	(NotInterestedMessage.h): Removed.
	(HaveMessage.h): Removed.
	(BitfieldMessage.h): Removed.
	(RequestMessage.h): Removed.
	(CancelMessage.h): Removed.
	(PieceMessage.h): Removed.
	(HandshakeMessage.h): Removed.
	(KeepAliveMessage.h): Removed.
	(PortMessage.h): Removed.
	(HaveAllMessage.h): Removed.
	(HaveNoneMessage.h): Removed.
	(PeerConnection.h): Removed.
	(HandshakeMessage.h): Included.

	* src/BitfieldMessage.h
	(init): New function.
	(BitfieldMessage): Rewritten.
	(BitfieldMessage): New function(overload).

	* src/RequestSlot.h
	(operator=): Defined the function body here.
	(operator==): Defined the function body here.
	* src/RequestSlot.cc
	(operator=): Removed.
	(operator==): Removed.
	
	To remove the dependency on the PeerMessage subclass from
	PeerInteraction:

	* src/PeerMessageFactory.h: New class.
	* src/PeerMessageFactory.cc: New class.
	* src/SimplePeerMessage.cc
	(send): If invalidate is true then do nothing.
	* src/PeerInteractionCommand.cc
	(HandshakeMessage.h): Included.
	(KeepAliveMessage.h): Included.
	(ChokeMessage.h): Included.
	(UnchokeMessage.h): Included.
	(HaveMessage.h): Included.
	(executeInternal): Call setNoCheck().
	Removed setWriteCheckSocket(socket).
	* src/PeerInteraction.h
	(ChokeMessage.h): Removed.
	(UnchokeMessage.h): Removed.
	(InterestedMessage.h): Removed.
	(NotInterestedMessage.h): Removed.
	(HaveMessage.h): Removed.
	(BitfieldMessage.h): Removed.
	(RequestMessage.h): Removed.
	(CancelMessage.h): Removed.
	(PieceMessage.h): Removed.
	(HandshakeMessage.h): Removed.
	(KeepAliveMessage.h): Removed.
	(PortMessage.h): Removed.
	(HaveAllMessage.h): Removed.
	(HaveNoneMessage.h): Removed.
	(RejectMessage.h): Removed.
	(AllowedFastMessage.h): Removed.
	(SuggestPieceMessage.h): Removed.
	(PeerMessageFactory.h): Included.
	(PeerMessageHandle): Removed typedef of PeerMessageHandle.
	(HandshakeMessageHandle): Removed typedef of 
HandshakeMessageHandle.
	(PeerMessageFactory): New variable.
	(createPeerMessage): Removed.
	(createHandshakeMessage): Removed.
	(setPeerMessageCommonProperty): Removed.
	(addRequestSlot): New function.
	(receiveHandshake): Changed the return value type to 
PeerMessageHandle.
	(getPeerMessageFactory): New function.
	(createRequestMessage): Removed.
	(createCancelMessage): Removed.
	(createPieceMessage): Removed.
	(createHaveMessage): Removed.
	(createChokeMessage): Removed.
	(createUnchokeMessage): Removed.
	(createInterestedMessage): Removed.
	(createNotInterestedMessage): Removed.
	(createBitfieldMessage): Removed.
	(createKeepAliveMessage): Removed.
	(createHaveAllMessage): Removed.
	(createHaveNoneMessage): Removed.
	(createRejectMessage): Removed.
	(createAllowedFastMessage): Removed.	
	* src/PeerInteraction.cc
	(PeerInteraction): Allocate PeerMessageFactory here.
	(~PeerInteraction): Deallocate PeerMessageFactory here.
	(sendMessages): Use msg->isUploading() instead of msg->getId() 
==
	PieceMessage::ID.
	(addMessage): Simplified by using PeerMessage::onPush().
	(addRequestSlot): New function.
	(rejectAllPieceMessageInQueue): Simplified by using
	PeerMessage::onChoked().
	(rejectPieceMessageInQueue): Simplified by using
	PeerMessage::onCanceled().
	(abortPiece): Simplified by using PeerMessage::abortPiece().
	(receiveHandshake): Changed the return value type to 
PeerMessageHandle.
	(createHandshakeMessage): Removed.
	(createPeerMessage): Removed.
	(sendHandshake): Call 
PeerMessageFactory::createHandshakeMessage().
	(setPeerMessageCommonProperty): Removed.
	(createRequestMessage): Removed.
	(createCancelMessage): Removed.
	(createPieceMessage): Removed.
	(createHaveMessage): Removed.
	(createChokeMessage): Removed.
	(createUnchokeMessage): Removed.
	(createInterestedMessage): Removed.
	(createNotInterestedMessage): Removed.
	(createBitfieldMessage): Removed.
	(createKeepAliveMessage): Removed.
	(createHaveAllMessage): Removed.
	(createHaveNoneMessage): Removed.
	(createRejectMessage): Removed.
	(createAllowedFastMessage): Removed.
	* src/PieceMessage.h
	(createRejectMessage): New function.
	(PieceMessage): Rewritten.
	(onChoked): New function.
	(onCanceled): New function.
	* src/PieceMessage.cc
	(send): If invalidate is true then do nothing, just return.
	(createRejectMessage): New function.
	(onChoked): New function.
	(onCanceled): New function.
	* src/RequestMessage.h
	(RequestMessage): Rewritten.
	(onPush): New function.
	(onAbortPiece): New function.
	* src/RequestMessage.cc
	(onPush): New function.
	(onAbortPiece): New function.
	
	Update fd_set when a socket is added or deleted in order to 
improve
	performance:

	* src/DownloadEngine.h
	(rfdset): New variable.
	(wfdset): New variable.
	(updateFdSet): New function.
	* src/DownloadEngine.cc
	(SetDescriptor::operator()): Use SockCmdMap::value_type.
	(AccumulateActiveCommandUuid::operator()): Use 
SockCmdMap::value_type.
	(waitData): Copy rfdset and wfdset.
	(updateFdSet): New function.
	(addSocket): Call updateFdSet.
	(deleteSocket): Call updateFdSet.
Tatsuhiro Tsujikawa il y a 19 ans
Parent
commit
ba4e5b776b

+ 255 - 0
ChangeLog

@@ -1,3 +1,258 @@
+2006-07-27  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	* src/PeerMessage.h
+	(Piece.h): Included.
+	(SharedHandle.h): Included.
+	(invalidate): New variable.
+	(uploading): New variable.
+	(isInvalidate): New function.
+	(isUploading): New function.
+	(onPush): New function.
+	(onChoked): New function.
+	(onCanceled): New function.
+	(onAbortPiece): New function.
+	(PeerMessageHandle): New type definition.
+	
+	* src/PeerMessage.cc
+	(PeerMessage): Added the initialization for invalidate and uploading.
+	
+	* src/CancelMessage.h
+	(CancelMessage): Rewritten.
+
+	* src/RejectMessage.h
+	(RejectMessage): Rewritten.
+
+	* src/Metalinker.h
+	(operator=): Defined.
+	
+	* src/MetaEntry.h
+	(operator=): Defined.
+
+	* src/MetalinkResource.h
+	(operator=): Defined.
+	
+	* src/AllowedFastMessage.h
+	(AllowedFastMessage): Rewritten.
+
+	* src/HandshakeMessage.h
+	(HandshakeMessage): New function(overload).
+	
+	* src/HandshakeMessage.cc
+	(HandshakeMessage): Rewritten.
+	(init): New function.
+
+	* src/HaveMessage.h
+	(HaveMessage): Rewritten.
+	
+	* src/Time.h
+	(operator=): Defined the function body here.
+	* src/Time.cc
+	(operator=): Removed.
+	
+	* src/SocketCore.h
+	(operator==): Defined here.
+	(operator!=): Defined here.
+	(operator<): Defined here.
+	* src/SocketCore.cc
+	(operator==): Removed.
+	(operator<): Removed.
+
+	* src/BitfieldMan.h
+	(operator=): Defined the function body here.
+	* src/BitfieldMan.cc
+	(operator=): Removed.
+
+	* src/TorrentMan.h
+	(deleteErrorPeer): Removed.
+	(deleteUnusedPeer); New function.
+	* src/TorrentMan.cc
+	(addPeer): Call deleteUnusedPeer.
+	(deleteErrorPeer): Removed.
+	(deleteUnusedPeer): New function.
+
+	* src/PeerAbstractCommand.h
+	(setNoCheck): New function.
+	(noCheck): New variable.
+	* src/PeerAbstractCommand.cc
+	(PeerAbstractCommand): Added the initialization of noCheck.
+	(execute): Added a check for noCheck.
+	(setNoCheck): New function.
+
+	* src/Util.h
+	(stdio.h): Included.
+	* src/Util.cc
+	(unistd.h): Included.
+
+	* src/DefaultDiskWriter.cc
+	(unistd.h): Included.
+
+	* src/Peer.h
+	(operator==): Defined the function body here.
+	(operator!=): Defined the function body here.
+	* src/Peer.cc
+	(operator==): Removed.
+	(operator!=): Removed.
+
+	* src/Piece.h
+	(Piece): Defined the function body here(copy constructor).
+	(operator=): Defined the function body here.
+	(operator==): Defined the function body here.
+	* src/Piece.cc
+	(Piece): Removed(copy constructor).
+	(operator=): Removed.
+	(operator==): Removed.
+	
+	* src/PeerMessageUtil.h
+	(ChokeMessage.h): Removed.
+	(UnchokeMessage.h): Removed.
+	(InterestedMessage.h): Removed.
+	(NotInterestedMessage.h): Removed.
+	(HaveMessage.h): Removed.
+	(BitfieldMessage.h): Removed.
+	(RequestMessage.h): Removed.
+	(CancelMessage.h): Removed.
+	(PieceMessage.h): Removed.
+	(HandshakeMessage.h): Removed.
+	(KeepAliveMessage.h): Removed.
+	(PortMessage.h): Removed.
+	(HaveAllMessage.h): Removed.
+	(HaveNoneMessage.h): Removed.
+	(PeerConnection.h): Removed.
+	(HandshakeMessage.h): Included.
+
+	* src/BitfieldMessage.h
+	(init): New function.
+	(BitfieldMessage): Rewritten.
+	(BitfieldMessage): New function(overload).
+
+	* src/RequestSlot.h
+	(operator=): Defined the function body here.
+	(operator==): Defined the function body here.
+	* src/RequestSlot.cc
+	(operator=): Removed.
+	(operator==): Removed.
+	
+	To remove the dependency on the PeerMessage subclass from
+	PeerInteraction:
+
+	* src/PeerMessageFactory.h: New class.
+	* src/PeerMessageFactory.cc: New class.
+	* src/SimplePeerMessage.cc
+	(send): If invalidate is true then do nothing.
+	* src/PeerInteractionCommand.cc
+	(HandshakeMessage.h): Included.
+	(KeepAliveMessage.h): Included.
+	(ChokeMessage.h): Included.
+	(UnchokeMessage.h): Included.
+	(HaveMessage.h): Included.
+	(executeInternal): Call setNoCheck().
+	Removed setWriteCheckSocket(socket).
+	* src/PeerInteraction.h
+	(ChokeMessage.h): Removed.
+	(UnchokeMessage.h): Removed.
+	(InterestedMessage.h): Removed.
+	(NotInterestedMessage.h): Removed.
+	(HaveMessage.h): Removed.
+	(BitfieldMessage.h): Removed.
+	(RequestMessage.h): Removed.
+	(CancelMessage.h): Removed.
+	(PieceMessage.h): Removed.
+	(HandshakeMessage.h): Removed.
+	(KeepAliveMessage.h): Removed.
+	(PortMessage.h): Removed.
+	(HaveAllMessage.h): Removed.
+	(HaveNoneMessage.h): Removed.
+	(RejectMessage.h): Removed.
+	(AllowedFastMessage.h): Removed.
+	(SuggestPieceMessage.h): Removed.
+	(PeerMessageFactory.h): Included.
+	(PeerMessageHandle): Removed typedef of PeerMessageHandle.
+	(HandshakeMessageHandle): Removed typedef of HandshakeMessageHandle.
+	(PeerMessageFactory): New variable.
+	(createPeerMessage): Removed.
+	(createHandshakeMessage): Removed.
+	(setPeerMessageCommonProperty): Removed.
+	(addRequestSlot): New function.
+	(receiveHandshake): Changed the return value type to PeerMessageHandle.
+	(getPeerMessageFactory): New function.
+	(createRequestMessage): Removed.
+	(createCancelMessage): Removed.
+	(createPieceMessage): Removed.
+	(createHaveMessage): Removed.
+	(createChokeMessage): Removed.
+	(createUnchokeMessage): Removed.
+	(createInterestedMessage): Removed.
+	(createNotInterestedMessage): Removed.
+	(createBitfieldMessage): Removed.
+	(createKeepAliveMessage): Removed.
+	(createHaveAllMessage): Removed.
+	(createHaveNoneMessage): Removed.
+	(createRejectMessage): Removed.
+	(createAllowedFastMessage): Removed.	
+	* src/PeerInteraction.cc
+	(PeerInteraction): Allocate PeerMessageFactory here.
+	(~PeerInteraction): Deallocate PeerMessageFactory here.
+	(sendMessages): Use msg->isUploading() instead of msg->getId() ==
+	PieceMessage::ID.
+	(addMessage): Simplified by using PeerMessage::onPush().
+	(addRequestSlot): New function.
+	(rejectAllPieceMessageInQueue): Simplified by using
+	PeerMessage::onChoked().
+	(rejectPieceMessageInQueue): Simplified by using
+	PeerMessage::onCanceled().
+	(abortPiece): Simplified by using PeerMessage::abortPiece().
+	(receiveHandshake): Changed the return value type to PeerMessageHandle.
+	(createHandshakeMessage): Removed.
+	(createPeerMessage): Removed.
+	(sendHandshake): Call PeerMessageFactory::createHandshakeMessage().
+	(setPeerMessageCommonProperty): Removed.
+	(createRequestMessage): Removed.
+	(createCancelMessage): Removed.
+	(createPieceMessage): Removed.
+	(createHaveMessage): Removed.
+	(createChokeMessage): Removed.
+	(createUnchokeMessage): Removed.
+	(createInterestedMessage): Removed.
+	(createNotInterestedMessage): Removed.
+	(createBitfieldMessage): Removed.
+	(createKeepAliveMessage): Removed.
+	(createHaveAllMessage): Removed.
+	(createHaveNoneMessage): Removed.
+	(createRejectMessage): Removed.
+	(createAllowedFastMessage): Removed.
+	* src/PieceMessage.h
+	(createRejectMessage): New function.
+	(PieceMessage): Rewritten.
+	(onChoked): New function.
+	(onCanceled): New function.
+	* src/PieceMessage.cc
+	(send): If invalidate is true then do nothing, just return.
+	(createRejectMessage): New function.
+	(onChoked): New function.
+	(onCanceled): New function.
+	* src/RequestMessage.h
+	(RequestMessage): Rewritten.
+	(onPush): New function.
+	(onAbortPiece): New function.
+	* src/RequestMessage.cc
+	(onPush): New function.
+	(onAbortPiece): New function.
+	
+	Update fd_set when a socket is added or deleted in order to improve
+	performance:
+
+	* src/DownloadEngine.h
+	(rfdset): New variable.
+	(wfdset): New variable.
+	(updateFdSet): New function.
+	* src/DownloadEngine.cc
+	(SetDescriptor::operator()): Use SockCmdMap::value_type.
+	(AccumulateActiveCommandUuid::operator()): Use SockCmdMap::value_type.
+	(waitData): Copy rfdset and wfdset.
+	(updateFdSet): New function.
+	(addSocket): Call updateFdSet.
+	(deleteSocket): Call updateFdSet.
+	
 2006-07-21  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
         To add the support for Metalink3.0 backward compatible links:

+ 4 - 1
src/AllowedFastMessage.h

@@ -33,7 +33,10 @@ private:
 protected:
   virtual void onSendComplete();
 public:
-  AllowedFastMessage():SimplePeerMessage(), index(0), pieces(0) {}
+  AllowedFastMessage(int index = 0)
+    :SimplePeerMessage(),
+     index(index),
+     pieces(0) {}
 
   virtual ~AllowedFastMessage() {}
 

+ 0 - 29
src/BitfieldMan.cc

@@ -62,35 +62,6 @@ BitfieldMan::~BitfieldMan() {
   }
 }
 
-BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan) {
-  if(this != &bitfieldMan) {
-    blockLength = bitfieldMan.blockLength;
-    totalLength = bitfieldMan.totalLength;
-    if(bitfieldLength != bitfieldMan.bitfieldLength) {
-      delete [] bitfield;
-      delete [] useBitfield;
-      bitfield = new unsigned char[bitfieldMan.bitfieldLength];
-      useBitfield = new unsigned char[bitfieldMan.bitfieldLength];
-    }
-    blocks = bitfieldMan.blocks;
-    bitfieldLength = bitfieldMan.bitfieldLength;
-    memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
-    memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
-    filterEnabled = bitfieldMan.filterEnabled;
-    if(bitfieldLength != bitfieldMan.bitfieldLength) {
-      delete [] filterBitfield;
-      filterBitfield = 0;
-    }
-    if(bitfieldMan.filterBitfield) {
-      if(!filterBitfield) {
-	filterBitfield = new unsigned char[bitfieldLength];
-      }
-      memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
-    }
-  }
-  return *this;
-}
-
 int BitfieldMan::countSetBit(const unsigned char* bitfield, int len) const {
   int count = 0;
   int size = sizeof(unsigned int);

+ 28 - 1
src/BitfieldMan.h

@@ -48,7 +48,34 @@ public:
   BitfieldMan(const BitfieldMan& bitfieldMan);
   ~BitfieldMan();
 
-  BitfieldMan& operator=(const BitfieldMan& bitfieldMan);
+  BitfieldMan& operator=(const BitfieldMan& bitfieldMan) {
+    if(this != &bitfieldMan) {
+      blockLength = bitfieldMan.blockLength;
+      totalLength = bitfieldMan.totalLength;
+      if(bitfieldLength != bitfieldMan.bitfieldLength) {
+	delete [] bitfield;
+	delete [] useBitfield;
+	bitfield = new unsigned char[bitfieldMan.bitfieldLength];
+	useBitfield = new unsigned char[bitfieldMan.bitfieldLength];
+      }
+      blocks = bitfieldMan.blocks;
+      bitfieldLength = bitfieldMan.bitfieldLength;
+      memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
+      memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
+      filterEnabled = bitfieldMan.filterEnabled;
+      if(bitfieldLength != bitfieldMan.bitfieldLength) {
+	delete [] filterBitfield;
+	filterBitfield = 0;
+      }
+      if(bitfieldMan.filterBitfield) {
+	if(!filterBitfield) {
+	  filterBitfield = new unsigned char[bitfieldLength];
+	}
+	memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
+      }
+    }
+    return *this;
+  }
 
   int getBlockLength() const { return blockLength; }
   int getLastBlockLength() const {

+ 21 - 3
src/BitfieldMessage.h

@@ -33,10 +33,28 @@ private:
 
   char* msg;
   int msgLength;
+
+  void init() {
+    bitfield = 0;
+    bitfieldLength = 0;
+    pieces = 0;
+    msg = 0;
+    msgLength = 0;
+  }
 public:
-  BitfieldMessage():SimplePeerMessage(),
-		    bitfield(NULL), bitfieldLength(0),
-		    pieces(0), msg(NULL), msgLength(0) {}
+  BitfieldMessage()
+    :SimplePeerMessage()
+  {
+    init();
+  }
+
+  BitfieldMessage(const unsigned char* bitfield,
+		  int bitfieldLength)
+    :SimplePeerMessage()
+  {
+    init();
+    setBitfield(bitfield, bitfieldLength);
+  }
 
   virtual ~BitfieldMessage() {
     if(bitfield != NULL) {

+ 7 - 3
src/CancelMessage.h

@@ -36,9 +36,13 @@ private:
 
   char msg[17];
 public:
-  CancelMessage():SimplePeerMessage(),
-		  index(0), begin(0), length(0),
-		  pieces(0), pieceLength(0) {}
+  CancelMessage(int index = 0, int begin = 0, int length = 0)
+    :SimplePeerMessage(),
+     index(index),
+     begin(begin),
+     length(length),
+     pieces(0),
+     pieceLength(0) {}
 
   virtual ~CancelMessage() {}
 

+ 1 - 0
src/DefaultDiskWriter.cc

@@ -22,6 +22,7 @@
 #include "DefaultDiskWriter.h"
 #include "DlAbortEx.h"
 #include <errno.h>
+#include <unistd.h>
 
 DefaultDiskWriter::DefaultDiskWriter():AbstractDiskWriter(), totalLength(0) {}
 

+ 15 - 8
src/DownloadEngine.cc

@@ -119,7 +119,7 @@ public:
   SetDescriptor(int* max_ptr, fd_set* fds_ptr)
     :fds_ptr(fds_ptr), max_ptr(max_ptr) {}
 
-  void operator()(const pair<SocketHandle, CommandUuid>& pa) {
+  void operator()(const SockCmdMap::value_type& pa) {
     int fd = pa.first->getSockfd();
     FD_SET(fd, fds_ptr);
     if(*max_ptr < fd) {
@@ -137,7 +137,7 @@ public:
 			      fd_set* fds_ptr)
     :activeCommandUuids_ptr(activeCommandUuids_ptr), fds_ptr(fds_ptr) {}
 
-  void operator()(const pair<SocketHandle, CommandUuid>& pa) {
+  void operator()(const SockCmdMap::value_type& pa) {
     if(FD_ISSET(pa.first->getSockfd(), fds_ptr)) {
       activeCommandUuids_ptr->push_back(pa.second);
     }
@@ -151,15 +151,12 @@ void DownloadEngine::waitData(CommandUuids& activeCommandUuids) {
   while(1) {
     struct timeval tv;
     
-    FD_ZERO(&rfds);
-    FD_ZERO(&wfds);
-    int max = 0;
-    for_each(rsockmap.begin(), rsockmap.end(), SetDescriptor(&max, &rfds));
-    for_each(wsockmap.begin(), wsockmap.end(), SetDescriptor(&max, &wfds));
+    memcpy(&rfds, &rfdset, sizeof(fd_set));
+    memcpy(&wfds, &wfdset, sizeof(fd_set));
 
     tv.tv_sec = 1;
     tv.tv_usec = 0;
-    retval = select(max+1, &rfds, &wfds, NULL, &tv);
+    retval = select(fdmax+1, &rfds, &wfds, NULL, &tv);
     if(retval != -1 || errno != EINTR) {
       break;
     }
@@ -176,6 +173,14 @@ void DownloadEngine::waitData(CommandUuids& activeCommandUuids) {
   }
 }
 
+void DownloadEngine::updateFdSet() {
+  fdmax = 0;
+  FD_ZERO(&rfdset);
+  FD_ZERO(&wfdset);
+  for_each(rsockmap.begin(), rsockmap.end(), SetDescriptor(&fdmax, &rfdset));
+  for_each(wsockmap.begin(), wsockmap.end(), SetDescriptor(&fdmax, &wfdset));
+}
+
 bool DownloadEngine::addSocket(SockCmdMap& sockmap,
 			       const SocketHandle& socket,
 			       const CommandUuid& commandUuid) {
@@ -184,6 +189,7 @@ bool DownloadEngine::addSocket(SockCmdMap& sockmap,
   if(itr == sockmap.end()) {
     SockCmdMap::value_type vt(socket, commandUuid);
     sockmap.insert(vt);
+    updateFdSet();
     return true;
   } else {
     return false;
@@ -199,6 +205,7 @@ bool DownloadEngine::deleteSocket(SockCmdMap& sockmap,
     return false;
   } else {
     sockmap.erase(itr);
+    updateFdSet();
     return true;
   }
 }

+ 6 - 1
src/DownloadEngine.h

@@ -39,7 +39,10 @@ private:
   void waitData(CommandUuids& activeCommandUuids);
   SockCmdMap rsockmap;
   SockCmdMap wsockmap;
-  
+  fd_set rfdset;
+  fd_set wfdset;
+  int fdmax;
+
   void shortSleep() const;
   bool addSocket(SockCmdMap& sockmap, const SocketHandle& socket,
 		 const CommandUuid& commandUuid);
@@ -64,6 +67,8 @@ public:
 
   void cleanQueue();
 
+  void updateFdSet();
+
   bool addSocketForReadCheck(const SocketHandle& socket,
 			     const CommandUuid& commandUuid);
   bool deleteSocketForReadCheck(const SocketHandle& socket,

+ 12 - 0
src/HandshakeMessage.cc

@@ -25,6 +25,18 @@
 #include "Util.h"
 
 HandshakeMessage::HandshakeMessage() {
+  init();
+}
+
+HandshakeMessage::HandshakeMessage(const unsigned char* infoHash,
+				   const char* peerId)
+{
+  init();
+  memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
+  memcpy(this->peerId, peerId, PEER_ID_LENGTH);
+}
+
+void HandshakeMessage::init() {
   this->pstrlen = 19;
   this->pstr = PSTR;
   memset(this->reserved, 0, sizeof(this->reserved));

+ 2 - 0
src/HandshakeMessage.h

@@ -31,6 +31,7 @@
 class HandshakeMessage : public SimplePeerMessage {
 private:
   char msg[HANDSHAKE_MESSAGE_LENGTH];
+  void init();
 public:
   char pstrlen;
   string pstr;
@@ -39,6 +40,7 @@ public:
   char peerId[PEER_ID_LENGTH];
 public:
   HandshakeMessage();
+  HandshakeMessage(const unsigned char* infoHash, const char* peerId);
 
   static HandshakeMessage* create(const char* data, int dataLength);
 

+ 4 - 1
src/HaveMessage.h

@@ -33,7 +33,10 @@ private:
 protected:
   virtual bool sendPredicate() const;
 public:
-  HaveMessage():SimplePeerMessage(), index(0), pieces(0) {}
+  HaveMessage(int index = 0)
+    :SimplePeerMessage(),
+     index(index),
+     pieces(0) {}
 
   virtual ~HaveMessage() {}
 

+ 5 - 3
src/Makefile.am

@@ -50,7 +50,8 @@ SRCS =  Socket.h\
 	messageDigest.h\
 	LogFactory.cc LogFactory.h\
 	NullLogger.h\
-	Time.cc Time.h
+	Time.cc Time.h\
+	SharedHandle.h
 
 if ENABLE_BITTORRENT
 SRCS += MetaEntry.h\
@@ -105,7 +106,7 @@ SRCS += MetaEntry.h\
 	AllowedFastMessage.cc AllowedFastMessage.h\
 	SuggestPieceMessage.cc SuggestPieceMessage.h\
 	SimplePeerMessage.cc SimplePeerMessage.h\
-	SharedHandle.h
+	PeerMessageFactory.cc PeerMessageFactory.h
 endif # ENABLE_BITTORRENT
 
 if ENABLE_METALINK
@@ -120,7 +121,8 @@ noinst_LIBRARIES = libaria2c.a
 libaria2c_a_SOURCES = $(SRCS)
 aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
 	@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
+#aria2c_LDFLAGS = -pg
 AM_CPPFLAGS =  -Wall\
 	-I../lib -I../intl -I$(top_srcdir)/intl\
 	@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-	-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
+	-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg

+ 17 - 13
src/Makefile.in

@@ -90,7 +90,7 @@ bin_PROGRAMS = aria2c$(EXEEXT)
 @ENABLE_BITTORRENT_TRUE@	AllowedFastMessage.cc AllowedFastMessage.h\
 @ENABLE_BITTORRENT_TRUE@	SuggestPieceMessage.cc SuggestPieceMessage.h\
 @ENABLE_BITTORRENT_TRUE@	SimplePeerMessage.cc SimplePeerMessage.h\
-@ENABLE_BITTORRENT_TRUE@	SharedHandle.h
+@ENABLE_BITTORRENT_TRUE@	PeerMessageFactory.cc PeerMessageFactory.h
 
 @ENABLE_METALINK_TRUE@am__append_2 = Metalinker.cc Metalinker.h\
 @ENABLE_METALINK_TRUE@	MetalinkEntry.cc MetalinkEntry.h\
@@ -154,12 +154,12 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
 	Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
 	LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
-	MetaEntry.h Data.cc Data.h Dictionary.cc Dictionary.h List.cc \
-	List.h MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
-	ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \
-	PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \
-	PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \
-	PeerInitiateConnectionCommand.cc \
+	SharedHandle.h MetaEntry.h Data.cc Data.h Dictionary.cc \
+	Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \
+	MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h TorrentMan.cc \
+	TorrentMan.h PeerConnection.cc PeerConnection.h \
+	PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
+	PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
 	PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
 	PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \
 	BitfieldMan.h TorrentDownloadEngine.cc TorrentDownloadEngine.h \
@@ -187,9 +187,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	HaveNoneMessage.cc HaveNoneMessage.h RejectMessage.cc \
 	RejectMessage.h AllowedFastMessage.cc AllowedFastMessage.h \
 	SuggestPieceMessage.cc SuggestPieceMessage.h \
-	SimplePeerMessage.cc SimplePeerMessage.h SharedHandle.h \
-	Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
-	MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
+	SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \
+	PeerMessageFactory.h Metalinker.cc Metalinker.h \
+	MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
+	MetalinkResource.h MetalinkProcessor.h \
 	Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
 @ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	Dictionary.$(OBJEXT) List.$(OBJEXT) \
@@ -236,7 +237,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 @ENABLE_BITTORRENT_TRUE@	RejectMessage.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	AllowedFastMessage.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	SuggestPieceMessage.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@	SimplePeerMessage.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@	SimplePeerMessage.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@	PeerMessageFactory.$(OBJEXT)
 @ENABLE_METALINK_TRUE@am__objects_2 = Metalinker.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkEntry.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkResource.$(OBJEXT) \
@@ -453,16 +455,17 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
 	AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
 	Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
 	LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
-	$(am__append_1) $(am__append_2)
+	SharedHandle.h $(am__append_1) $(am__append_2)
 noinst_LIBRARIES = libaria2c.a
 libaria2c_a_SOURCES = $(SRCS)
 aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
 	@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
 
+#aria2c_LDFLAGS = -pg
 AM_CPPFLAGS = -Wall\
 	-I../lib -I../intl -I$(top_srcdir)/intl\
 	@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-	-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
+	-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg
 
 all: all-am
 
@@ -601,6 +604,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerInteractionCommand.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerListenCommand.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageFactory.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtil.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceMessage.Po@am__quote@

+ 12 - 1
src/MetalinkEntry.h

@@ -43,7 +43,18 @@ public:
   MetalinkEntry();
   ~MetalinkEntry();
 
-  MetalinkEntry& operator=(const MetalinkEntry& metalinkEntry);
+  MetalinkEntry& operator=(const MetalinkEntry& metalinkEntry) {
+    if(this != &metalinkEntry) {
+      this->filename = metalinkEntry.filename;
+      this->version = metalinkEntry.version;
+      this->language = metalinkEntry.language;
+      this->os = metalinkEntry.os;
+      this->size = metalinkEntry.size;
+      this->md5 = metalinkEntry.md5;
+      this->sha1 = metalinkEntry.sha1;
+    }
+    return *this;
+  }
 
   bool check(const string& filename) const;
 

+ 9 - 1
src/MetalinkResource.h

@@ -41,7 +41,15 @@ public:
   MetalinkResource();
   ~MetalinkResource();
 
-  MetalinkResource& operator=(const MetalinkResource& metalinkResource);
+  MetalinkResource& operator=(const MetalinkResource& metalinkResource) {
+    if(this != &metalinkResource) {
+      this->url = metalinkResource.url;
+      this->type = metalinkResource.type;
+      this->location = metalinkResource.location;
+      this->preference = metalinkResource.preference;
+    }
+    return *this;
+  }
 };
 
 #endif // _D_METALINK_RESOURCE_H_

+ 6 - 1
src/Metalinker.h

@@ -37,7 +37,12 @@ public:
   Metalinker();
   ~Metalinker();
 
-  Metalinker& operator=(const Metalinker& metalinker);
+  Metalinker& operator=(const Metalinker& metalinker) {
+    if(this != &metalinker) {
+      this->entries = metalinker.entries;
+    }
+    return *this;
+  }
 
   MetalinkEntry* queryEntry(const string& version, const string& language,
 			    const string& os) const;

+ 0 - 8
src/Peer.cc

@@ -82,11 +82,3 @@ void Peer::setAllBitfield() {
 void Peer::updateLatency(int latency) {
   this->latency = (this->latency*20+latency*80)/200;
 }
-
-bool operator==(const Peer& p1, const Peer& p2) {
-  return p1.ipaddr == p2.ipaddr && p1.port == p2.port;
-}
-
-bool operator!=(const Peer& p1, const Peer& p2) {
-  return !(p1 == p2);
-}

+ 8 - 3
src/Peer.h

@@ -83,6 +83,14 @@ public:
     }
   }
 
+  bool operator==(const Peer& p) {
+    return ipaddr == p.ipaddr && port == p.port;
+  }
+  
+  bool operator!=(const Peer& p) {
+    return !(*this == p);
+  }
+
   void resetStatus();
 
   void addDeltaUpload(int length) {
@@ -149,9 +157,6 @@ public:
   int getLatency() const { return latency; }
 };
 
-bool operator==(const Peer& p1, const Peer& p2);
-bool operator!=(const Peer& p1, const Peer& p2);
-
 typedef SharedHandle<Peer> PeerHandle;
 
 #endif // _D_PEER_H_

+ 7 - 2
src/PeerAbstractCommand.cc

@@ -31,7 +31,7 @@ PeerAbstractCommand::PeerAbstractCommand(int cuid, const PeerHandle& peer,
 					 const SocketHandle& s)
   :Command(cuid), e(e), socket(s), peer(peer),
   checkSocketIsReadable(false), checkSocketIsWritable(false),
-  uploadLimitCheck(false), uploadLimit(0) {
+  uploadLimitCheck(false), uploadLimit(0), noCheck(false) {
   setReadCheckSocket(socket);
   timeout = e->option->getAsInt(PREF_TIMEOUT);
   e->torrentMan->connections++;
@@ -48,7 +48,8 @@ bool PeerAbstractCommand::execute() {
     return true;
   }
   try {
-    if(uploadLimitCheck && (uploadLimit == 0 ||
+    if(noCheck ||
+       uploadLimitCheck && (uploadLimit == 0 ||
 			    e->getUploadSpeed() <= uploadLimit*1024) ||
        checkSocketIsReadable && readCheckTarget->isReadable(0) ||
        checkSocketIsWritable && writeCheckTarget->isWritable(0)) {
@@ -144,3 +145,7 @@ void PeerAbstractCommand::setUploadLimit(int uploadLimit) {
 void PeerAbstractCommand::setUploadLimitCheck(bool check) {
   this->uploadLimitCheck = check;
 }
+
+void PeerAbstractCommand::setNoCheck(bool check) {
+  this->noCheck = check;
+}

+ 2 - 0
src/PeerAbstractCommand.h

@@ -46,6 +46,7 @@ protected:
   void disableWriteCheckSocket();
   void setUploadLimit(int uploadLimit);
   void setUploadLimitCheck(bool check);
+  void setNoCheck(bool check);
 private:
   bool checkSocketIsReadable;
   bool checkSocketIsWritable;
@@ -53,6 +54,7 @@ private:
   SocketHandle writeCheckTarget;
   bool uploadLimitCheck;
   int uploadLimit;
+  bool noCheck;
 public:
   PeerAbstractCommand(int cuid, const PeerHandle& peer,
 		      TorrentDownloadEngine* e,

+ 41 - 276
src/PeerInteraction.cc

@@ -38,11 +38,13 @@ PeerInteraction::PeerInteraction(int cuid,
    peer(peer),
    quickReplied(false) {
   peerConnection = new PeerConnection(cuid, socket, op);
+  peerMessageFactory = new PeerMessageFactory(cuid, this, peer);
   logger = LogFactory::getInstance();
 }
 
 PeerInteraction::~PeerInteraction() {
   delete peerConnection;
+  delete peerMessageFactory;
 }
 
 bool PeerInteraction::isSendingMessageInProgress() const {
@@ -61,9 +63,7 @@ void PeerInteraction::sendMessages(int uploadSpeed) {
     PeerMessageHandle msg = messageQueue.front();
     messageQueue.pop_front();
     if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
-       msg->getId() == PieceMessage::ID && !msg->isInProgress()) {
-      //!((PieceMessage*)msg)->isPendingCountMax()) {
-      //((PieceMessage*)msg)->incrementPendingCount();
+       msg->isUploading() && !msg->isInProgress()) {
       tempQueue.push_back(msg);
     } else {
       msg->send();
@@ -77,68 +77,26 @@ void PeerInteraction::sendMessages(int uploadSpeed) {
 }
 
 void PeerInteraction::addMessage(const PeerMessageHandle& peerMessage) {
+  peerMessage->onPush();
   messageQueue.push_back(peerMessage);
-  if(peerMessage->getId() == RequestMessage::ID) {
-    RequestMessage* requestMessage = (RequestMessage*)peerMessage.get();
-    RequestSlot requestSlot(requestMessage->getIndex(),
-			    requestMessage->getBegin(),
-			    requestMessage->getLength(),
-			    requestMessage->getBlockIndex());
-    requestSlots.push_back(requestSlot);
-  }
+}
+
+void PeerInteraction::addRequestSlot(const RequestSlot& requestSlot) {
+  requestSlots.push_back(requestSlot);
 }
 
 void PeerInteraction::rejectAllPieceMessageInQueue() {
-  MessageQueue tempQueue;
-  for(MessageQueue::iterator itr = messageQueue.begin();
-      itr != messageQueue.end();) {
-    // Don't delete piece message which is in the allowed fast set.
-    if((*itr)->getId() == PieceMessage::ID && !(*itr)->isInProgress()
-       && !isInFastSet(((PieceMessage*)(*itr).get())->getIndex())) {
-      PieceMessage* pieceMessage = (PieceMessage*)(*itr).get();
-      logger->debug("CUID#%d - Reject piece message in queue because"
-		    " peer has been choked. index=%d, begin=%d, length=%d",
-		    cuid,
-		    pieceMessage->getIndex(),
-		    pieceMessage->getBegin(),
-		    pieceMessage->getBlockLength());
-      if(peer->isFastExtensionEnabled()) {
-	tempQueue.push_back(createRejectMessage(pieceMessage->getIndex(),
-						pieceMessage->getBegin(),
-						pieceMessage->getBlockLength()));
-      }
-      itr = messageQueue.erase(itr);
-    } else {
-      itr++;
-    }
+  int size = messageQueue.size();
+  for(int i = 0; i < size; i++) {
+    messageQueue.at(i)->onChoked();
   }
-  copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
 }
 
 void PeerInteraction::rejectPieceMessageInQueue(int index, int begin, int length) {
-  MessageQueue tempQueue;
-  for(MessageQueue::iterator itr = messageQueue.begin();
-      itr != messageQueue.end();) {
-    if((*itr)->getId() == PieceMessage::ID && !(*itr)->isInProgress()) {
-      PieceMessage* pieceMessage = (PieceMessage*)(*itr).get();
-      if(pieceMessage->getIndex() == index &&
-	 pieceMessage->getBegin() == begin &&
-	 pieceMessage->getBlockLength() == length) {
-	logger->debug("CUID#%d - Reject piece message in queue because cancel"
-		      " message received. index=%d, begin=%d, length=%d",
-		      cuid, index, begin, length);
-	itr = messageQueue.erase(itr);
-	if(peer->isFastExtensionEnabled()) {
-	  tempQueue.push_back(createRejectMessage(index, begin, length));
-	}
-      } else {
-	itr++;
-      }
-    } else {
-      itr++;
-    }
+  int size = messageQueue.size();
+  for(int i = 0; i < size; i++) {
+    messageQueue.at(i)->onCanceled(index, begin, length);
   }
-  copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
 }
 
 void PeerInteraction::onChoked() {
@@ -162,16 +120,10 @@ void PeerInteraction::abortAllPieces() {
 
 void PeerInteraction::abortPiece(Piece& piece) {
   if(!Piece::isNull(piece)) {
-    for(MessageQueue::iterator itr = messageQueue.begin();
-	itr != messageQueue.end();) {
-      if((*itr)->getId() == RequestMessage::ID &&
-	!(*itr)->isInProgress() &&
-	 ((RequestMessage*)(*itr).get())->getIndex() == piece.getIndex()) {
-	itr = messageQueue.erase(itr);
-      } else {
-	itr++;
-      }
-    }  
+    int size = messageQueue.size();
+    for(int i = 0; i < size; i++) {
+      messageQueue.at(i)->onAbortPiece(piece);
+    }
     for(RequestSlots::iterator itr = requestSlots.begin();
 	itr != requestSlots.end();) {
       if(itr->getIndex() == piece.getIndex()) {
@@ -218,9 +170,9 @@ void PeerInteraction::checkRequestSlot() {
 	logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
 		      " the block has been acquired.", cuid,
 		      slot.getBlockIndex());
-	addMessage(createCancelMessage(slot.getIndex(),
-				       slot.getBegin(),
-				       slot.getLength()));
+	addMessage(peerMessageFactory->createCancelMessage(slot.getIndex(),
+							   slot.getBegin(),
+							   slot.getLength()));
 	itr = requestSlots.erase(itr); 
       } else {
 	itr++;
@@ -264,7 +216,7 @@ int PeerInteraction::countRequestSlot() const {
   return requestSlots.size();
 }
 
-HandshakeMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
+PeerMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
   char msg[HANDSHAKE_MESSAGE_LENGTH];
   int msgLength = HANDSHAKE_MESSAGE_LENGTH;
   bool retval = peerConnection->receiveHandshake(msg, msgLength);
@@ -279,107 +231,27 @@ HandshakeMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
   if(!retval) {
     return NULL;
   }
-  HandshakeMessageHandle handshakeMessage(createHandshakeMessage(msg, msgLength));
+  PeerMessageHandle handshakeMessage(peerMessageFactory->createHandshakeMessage(msg, msgLength));
   handshakeMessage->check();
-  if(handshakeMessage->isFastExtensionSupported()) {
+  if(((HandshakeMessage*)handshakeMessage.get())->isFastExtensionSupported()) {
     peer->setFastExtensionEnabled(true);
     logger->info("CUID#%d - Fast extension enabled.", cuid);
   }
   return handshakeMessage;
 }
 
-HandshakeMessageHandle PeerInteraction::createHandshakeMessage(const char* msg, int msgLength) {
-  HandshakeMessage* message = HandshakeMessage::create(msg, msgLength);
-
-  setPeerMessageCommonProperty(message);
-  return message;
-}
-
 PeerMessageHandle PeerInteraction::receiveMessage() {
   char msg[MAX_PAYLOAD_LEN];
   int msgLength = 0;
   if(!peerConnection->receiveMessage(msg, msgLength)) {
     return NULL;
   }
-  PeerMessageHandle peerMessage(createPeerMessage(msg, msgLength));
+  PeerMessageHandle peerMessage =
+    peerMessageFactory->createPeerMessage(msg, msgLength);
   peerMessage->check();
   return peerMessage;
 }
 
-PeerMessageHandle PeerInteraction::createPeerMessage(const char* msg, int msgLength) {
-  PeerMessage* peerMessage;
-  if(msgLength == 0) {
-    // keep-alive
-    peerMessage = new KeepAliveMessage();
-  } else {
-    int id = PeerMessageUtil::getId(msg);
-    switch(id) {
-    case ChokeMessage::ID:
-      peerMessage = ChokeMessage::create(msg, msgLength);
-      break;
-    case UnchokeMessage::ID:
-      peerMessage = UnchokeMessage::create(msg, msgLength);
-      break;
-    case InterestedMessage::ID:
-      peerMessage = InterestedMessage::create(msg, msgLength);
-      break;
-    case NotInterestedMessage::ID:
-      peerMessage = NotInterestedMessage::create(msg, msgLength);
-      break;
-    case HaveMessage::ID:
-      peerMessage = HaveMessage::create(msg, msgLength);
-      ((HaveMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      break;
-    case BitfieldMessage::ID:
-      peerMessage = BitfieldMessage::create(msg, msgLength);
-      ((BitfieldMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      break;
-    case RequestMessage::ID:
-      peerMessage = RequestMessage::create(msg, msgLength);
-      ((RequestMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      ((RequestMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
-      break;
-    case CancelMessage::ID:
-      peerMessage = CancelMessage::create(msg, msgLength);
-      ((CancelMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      ((CancelMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
-      break;
-    case PieceMessage::ID:
-      peerMessage = PieceMessage::create(msg, msgLength);
-      ((PieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      ((PieceMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
-      break;
-    case PortMessage::ID:
-      peerMessage = PortMessage::create(msg, msgLength);
-      break;
-    case HaveAllMessage::ID:
-      peerMessage = HaveAllMessage::create(msg, msgLength);
-      break;
-    case HaveNoneMessage::ID:
-      peerMessage = HaveNoneMessage::create(msg, msgLength);
-      break;
-    case RejectMessage::ID:
-      peerMessage = RejectMessage::create(msg, msgLength);
-      ((RejectMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      ((RejectMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
-      break;
-    case SuggestPieceMessage::ID:
-      peerMessage = SuggestPieceMessage::create(msg, msgLength);
-      ((SuggestPieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      break;
-    case AllowedFastMessage::ID:
-      peerMessage = AllowedFastMessage::create(msg, msgLength);
-      ((AllowedFastMessage*)peerMessage)->setPieces(torrentMan->pieces);
-      break;
-    default:
-      throw new DlAbortEx("Invalid message id. id = %d", id);
-    }
-  }
-  setPeerMessageCommonProperty(peerMessage);
-  return peerMessage;
-}
-
-
 void PeerInteraction::syncPiece() {
   for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
     torrentMan->syncPiece(*itr);
@@ -396,7 +268,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
   if(pieces.empty() && !torrentMan->hasMissingPiece(peer)) {
     if(peer->amInterested) {
       logger->debug("CUID#%d - Not interested in the peer", cuid);
-      addMessage(createNotInterestedMessage());
+      addMessage(peerMessageFactory->createNotInterestedMessage());
     }
   } else {
     if(peer->peerChoking) {
@@ -423,7 +295,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
     }
     if(!peer->amInterested) {
       logger->debug("CUID#%d - Interested in the peer", cuid);
-      addMessage(createInterestedMessage());
+      addMessage(peerMessageFactory->createInterestedMessage());
     }
   }
 }
@@ -466,7 +338,8 @@ void PeerInteraction::addRequests() {
 	  bitr++) {
 	int blockIndex = *bitr;
 	if(!isInRequestSlot(piece.getIndex(), blockIndex)) {
-	  addMessage(createRequestMessage(piece.getIndex(), blockIndex));
+	  addMessage(peerMessageFactory->createRequestMessage(piece,
+							      blockIndex));
 	  count++;
 	}
       }
@@ -476,7 +349,8 @@ void PeerInteraction::addRequests() {
 	if(blockIndex == -1) {
 	  break;
 	}
-	addMessage(createRequestMessage(piece.getIndex(), blockIndex));
+	addMessage(peerMessageFactory->createRequestMessage(piece,
+							    blockIndex));
       }
     }
     if(countRequestSlot() >= MAX_PENDING_REQUEST) {
@@ -487,26 +361,25 @@ void PeerInteraction::addRequests() {
 }
 
 void PeerInteraction::sendHandshake() {
-  HandshakeMessage* handshake = new HandshakeMessage();
-  memcpy(handshake->infoHash, torrentMan->getInfoHash(), INFO_HASH_LENGTH);
-  memcpy(handshake->peerId, torrentMan->peerId.c_str(), PEER_ID_LENGTH);
-  setPeerMessageCommonProperty(handshake);
-  addMessage(handshake);
+  PeerMessageHandle handle =
+    peerMessageFactory->createHandshakeMessage(torrentMan->getInfoHash(),
+					       torrentMan->peerId.c_str());
+  addMessage(handle);
   sendMessages(0);
 }
 
 void PeerInteraction::sendBitfield() {
   if(peer->isFastExtensionEnabled()) {
     if(torrentMan->hasAllPieces()) {
-      addMessage(createHaveAllMessage());
+      addMessage(peerMessageFactory->createHaveAllMessage());
     } else if(torrentMan->getDownloadLength() > 0) {
-      addMessage(createBitfieldMessage());
+      addMessage(peerMessageFactory->createBitfieldMessage());
     } else {
-      addMessage(createHaveNoneMessage());
+      addMessage(peerMessageFactory->createHaveNoneMessage());
     }
   } else {
     if(torrentMan->getDownloadLength() > 0) {
-      addMessage(createBitfieldMessage());
+      addMessage(peerMessageFactory->createBitfieldMessage());
     }
   }
   sendMessages(0);
@@ -518,7 +391,7 @@ void PeerInteraction::sendAllowedFast() {
 				   torrentMan->pieces, ALLOWED_FAST_SET_SIZE);
     for(Integers::const_iterator itr = fastSet.begin();
 	itr != fastSet.end(); itr++) {
-      addMessage(createAllowedFastMessage(*itr));
+      addMessage(peerMessageFactory->createAllowedFastMessage(*itr));
     }
   }
 }
@@ -550,111 +423,3 @@ void PeerInteraction::addFastSetIndex(int index) {
     fastSet.push_back(index);
   }
 }
-
-void PeerInteraction::setPeerMessageCommonProperty(PeerMessage* peerMessage) {
-  peerMessage->setPeer(peer);
-  peerMessage->setCuid(cuid);
-  peerMessage->setPeerInteraction(this);  
-}
-
-RequestMessage* PeerInteraction::createRequestMessage(int index, int blockIndex) {
-  RequestMessage* msg = new RequestMessage();
-  Piece piece = getDownloadPiece(index);
-  msg->setIndex(piece.getIndex());
-  msg->setBegin(blockIndex*piece.getBlockLength());
-  msg->setLength(piece.getBlockLength(blockIndex));
-  msg->setBlockIndex(blockIndex);
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-CancelMessage* PeerInteraction::createCancelMessage(int index, int begin, int length) {
-  CancelMessage* msg = new CancelMessage();
-  msg->setIndex(index);
-  msg->setBegin(begin);
-  msg->setLength(length);
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-PieceMessage* PeerInteraction::createPieceMessage(int index, int begin, int length) {
-  PieceMessage* msg = new PieceMessage();
-  msg->setIndex(index);
-  msg->setBegin(begin);
-  msg->setBlockLength(length);
-  setPeerMessageCommonProperty(msg);
-  return msg;  
-}
-
-HaveMessage* PeerInteraction::createHaveMessage(int index) {
-  HaveMessage* msg = new HaveMessage();
-  msg->setIndex(index);
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-ChokeMessage* PeerInteraction::createChokeMessage() {
-  ChokeMessage* msg = new ChokeMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-UnchokeMessage* PeerInteraction::createUnchokeMessage() {
-  UnchokeMessage* msg = new UnchokeMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-InterestedMessage* PeerInteraction::createInterestedMessage() {
-  InterestedMessage* msg = new InterestedMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-NotInterestedMessage* PeerInteraction::createNotInterestedMessage() {
-  NotInterestedMessage* msg = new NotInterestedMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-BitfieldMessage* PeerInteraction::createBitfieldMessage() {
-  BitfieldMessage* msg = new BitfieldMessage();
-  msg->setBitfield(getTorrentMan()->getBitfield(),
-		   getTorrentMan()->getBitfieldLength());
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-KeepAliveMessage* PeerInteraction::createKeepAliveMessage() {
-  KeepAliveMessage* msg = new KeepAliveMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-HaveAllMessage* PeerInteraction::createHaveAllMessage() {
-  HaveAllMessage* msg = new HaveAllMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-HaveNoneMessage* PeerInteraction::createHaveNoneMessage() {
-  HaveNoneMessage* msg = new HaveNoneMessage();
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-RejectMessage* PeerInteraction::createRejectMessage(int index, int begin, int length) {
-  RejectMessage* msg = new RejectMessage();
-  msg->setIndex(index);
-  msg->setBegin(begin);
-  msg->setLength(length);
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}
-
-AllowedFastMessage* PeerInteraction::createAllowedFastMessage(int index) {
-  AllowedFastMessage* msg = new AllowedFastMessage();
-  msg->setIndex(index);
-  setPeerMessageCommonProperty(msg);
-  return msg;
-}

+ 7 - 37
src/PeerInteraction.h

@@ -24,31 +24,13 @@
 
 #include "common.h"
 #include "PeerConnection.h"
-#include "ChokeMessage.h"
-#include "UnchokeMessage.h"
-#include "InterestedMessage.h"
-#include "NotInterestedMessage.h"
-#include "HaveMessage.h"
-#include "BitfieldMessage.h"
-#include "RequestMessage.h"
-#include "CancelMessage.h"
-#include "PieceMessage.h"
-#include "HandshakeMessage.h"
-#include "KeepAliveMessage.h"
-#include "PortMessage.h"
-#include "HaveAllMessage.h"
-#include "HaveNoneMessage.h"
-#include "RejectMessage.h"
-#include "AllowedFastMessage.h"
-#include "SuggestPieceMessage.h"
 #include "RequestSlot.h"
 #include "SharedHandle.h"
+#include "PeerMessageFactory.h"
 
 #define REQUEST_TIME_OUT 60
 #define ALLOWED_FAST_SET_SIZE 10
 
-typedef SharedHandle<PeerMessage> PeerMessageHandle;
-typedef SharedHandle<HandshakeMessage> HandshakeMessageHandle;
 typedef deque<RequestSlot> RequestSlots;
 typedef deque<PeerMessageHandle> MessageQueue;
 
@@ -63,15 +45,13 @@ private:
   PeerConnection* peerConnection;
   PeerHandle peer;
   Pieces pieces;
+  PeerMessageFactory* peerMessageFactory;
   // allowed fast piece indexes that local client has sent
   Integers fastSet;
   bool quickReplied;
   const Logger* logger;
 
   void getNewPieceAndSendInterest(int pieceNum);
-  PeerMessageHandle createPeerMessage(const char* msg, int msgLength);
-  HandshakeMessageHandle createHandshakeMessage(const char* msg, int msgLength);
-  void setPeerMessageCommonProperty(PeerMessage* peerMessage);
   int countRequestSlot() const;
 public:
   PeerInteraction(int cuid,
@@ -82,6 +62,7 @@ public:
   ~PeerInteraction();
 
   void addMessage(const PeerMessageHandle& peerMessage);
+  void addRequestSlot(const RequestSlot& requestSlot);
   void rejectPieceMessageInQueue(int index, int begin, int length);
   void rejectAllPieceMessageInQueue();
   void onChoked();
@@ -120,22 +101,11 @@ public:
   void sendAllowedFast();
 
   PeerMessageHandle receiveMessage();
-  HandshakeMessageHandle receiveHandshake(bool quickReply = false);
+  PeerMessageHandle receiveHandshake(bool quickReply = false);
 
-  RequestMessage* createRequestMessage(int index, int blockIndex);
-  CancelMessage* createCancelMessage(int index, int begin, int length);
-  PieceMessage* createPieceMessage(int index, int begin, int length);
-  HaveMessage* createHaveMessage(int index);
-  ChokeMessage* createChokeMessage();
-  UnchokeMessage* createUnchokeMessage();
-  InterestedMessage* createInterestedMessage();
-  NotInterestedMessage* createNotInterestedMessage();
-  BitfieldMessage* createBitfieldMessage();
-  KeepAliveMessage* createKeepAliveMessage();
-  HaveAllMessage* createHaveAllMessage();
-  HaveNoneMessage* createHaveNoneMessage();
-  RejectMessage* createRejectMessage(int index, int begin, int length);
-  AllowedFastMessage* createAllowedFastMessage(int index);
+  const PeerMessageFactory* getPeerMessageFactory() const {
+    return peerMessageFactory;
+  }
 };
 
 #endif // _D_PEER_INTERACTION_H_

+ 27 - 15
src/PeerInteractionCommand.cc

@@ -22,6 +22,11 @@
 #include "PeerInteractionCommand.h"
 #include "PeerInitiateConnectionCommand.h"
 #include "PeerMessageUtil.h"
+#include "HandshakeMessage.h"
+#include "KeepAliveMessage.h"
+#include "ChokeMessage.h"
+#include "UnchokeMessage.h"
+#include "HaveMessage.h"
 #include "DlAbortEx.h"
 #include "Util.h"
 #include "message.h"
@@ -62,6 +67,7 @@ bool PeerInteractionCommand::executeInternal() {
   }
   disableWriteCheckSocket();
   setUploadLimitCheck(false);
+  setNoCheck(false);
 
   switch(sequence) {
   case INITIATOR_SEND_HANDSHAKE:
@@ -75,12 +81,12 @@ bool PeerInteractionCommand::executeInternal() {
 	break;
       }
     }
-    HandshakeMessageHandle handshakeMessage =
+    PeerMessageHandle handshakeMessage =
       peerInteraction->receiveHandshake();
-    if(handshakeMessage.get() == NULL) {
+    if(handshakeMessage.get() == 0) {
       break;
     }
-    peer->setPeerId(handshakeMessage->peerId);
+    peer->setPeerId(((HandshakeMessage*)handshakeMessage.get())->peerId);
     logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
 		 peer->ipaddr.c_str(), peer->port,
 		 handshakeMessage->toString().c_str());
@@ -91,12 +97,12 @@ bool PeerInteractionCommand::executeInternal() {
     break;
   }
   case RECEIVER_WAIT_HANDSHAKE: {
-    HandshakeMessageHandle handshakeMessage =
+    PeerMessageHandle handshakeMessage =
       peerInteraction->receiveHandshake(true);
-    if(handshakeMessage.get() == NULL) {
+    if(handshakeMessage.get() == 0) {
       break;
     }
-    peer->setPeerId(handshakeMessage->peerId);
+    peer->setPeerId(((HandshakeMessage*)handshakeMessage.get())->peerId);
     logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
 		 peer->ipaddr.c_str(), peer->port,
 		 handshakeMessage->toString().c_str());
@@ -121,10 +127,9 @@ bool PeerInteractionCommand::executeInternal() {
   }
   if(peerInteraction->countMessageInQueue() > 0) {
     if(peerInteraction->isSendingMessageInProgress()) {
-      setWriteCheckSocket(socket);
-    } else {
       setUploadLimitCheck(true);
     }
+    setNoCheck(true);
   }
   e->commands.push_back(this);
   return false;
@@ -164,11 +169,13 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
 void PeerInteractionCommand::decideChoking() {
   if(peer->shouldBeChoking()) {
     if(!peer->amChoking) {
-      peerInteraction->addMessage(peerInteraction->createChokeMessage());
+      peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				  createChokeMessage());
     }
   } else {
     if(peer->amChoking) {
-      peerInteraction->addMessage(peerInteraction->createUnchokeMessage());
+      peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				  createUnchokeMessage());
     }
   }
 }
@@ -231,7 +238,8 @@ void PeerInteractionCommand::onAbort(Exception* ex) {
 void PeerInteractionCommand::sendKeepAlive() {
   if(keepAliveCheckPoint.elapsed(KEEP_ALIVE_INTERVAL)) {
     if(peerInteraction->countMessageInQueue() == 0) {
-      peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
+      peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				  createKeepAliveMessage());
       peerInteraction->sendMessages(e->getUploadSpeed());
     }
     keepAliveCheckPoint.reset();
@@ -245,16 +253,20 @@ void PeerInteractionCommand::checkHave() {
   if(indexes.size() >= 20) {
     if(peer->isFastExtensionEnabled()) {
       if(e->torrentMan->hasAllPieces()) {
-	peerInteraction->addMessage(peerInteraction->createHaveAllMessage());
+	peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				    createHaveAllMessage());
       } else {
-	peerInteraction->addMessage(peerInteraction->createBitfieldMessage());
+	peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				    createBitfieldMessage());
       }
     } else {
-      peerInteraction->addMessage(peerInteraction->createBitfieldMessage());
+      peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				  createBitfieldMessage());
     }
   } else {
     for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
-      peerInteraction->addMessage(peerInteraction->createHaveMessage(*itr));
+      peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				  createHaveMessage(*itr));
     }
   }
 }

+ 4 - 1
src/PeerMessage.cc

@@ -22,6 +22,9 @@
 #include "PeerMessage.h"
 #include "LogFactory.h"
 
-PeerMessage::PeerMessage():inProgress(false) {
+PeerMessage::PeerMessage()
+  :inProgress(false),
+   invalidate(false),
+   uploading(false) {
   logger = LogFactory::getInstance();
 }

+ 12 - 0
src/PeerMessage.h

@@ -25,6 +25,8 @@
 #include "common.h"
 #include "Logger.h"
 #include "Peer.h"
+#include "Piece.h"
+#include "SharedHandle.h"
 #include <string>
 
 class PeerInteraction;
@@ -32,6 +34,8 @@ class PeerInteraction;
 class PeerMessage {
 protected:
   bool inProgress;
+  bool invalidate;
+  bool uploading;
   int cuid;
   PeerHandle peer;
   PeerInteraction* peerInteraction;
@@ -42,6 +46,8 @@ public:
   virtual ~PeerMessage() {}
 
   bool isInProgress() const { return inProgress; }
+  bool isInvalidate() const { return invalidate; }
+  bool isUploading() const { return uploading; }
 
   int getCuid() const { return cuid; }
   void setCuid(int cuid) {
@@ -61,6 +67,12 @@ public:
   virtual void send() = 0;
   virtual void check() const {}
   virtual string toString() const = 0;
+  virtual void onPush() {}
+  virtual void onChoked() {}
+  virtual void onCanceled(int index, int begin, int blockLength) {}
+  virtual void onAbortPiece(const Piece& piece) {}
 };
 
+typedef SharedHandle<PeerMessage> PeerMessageHandle;
+
 #endif // _D_PEER_MESSAGE_H_

+ 268 - 0
src/PeerMessageFactory.cc

@@ -0,0 +1,268 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/* copyright --> */
+#include "PeerMessageFactory.h"
+#include "PeerInteraction.h"
+#include "PeerMessageUtil.h"
+#include "ChokeMessage.h"
+#include "UnchokeMessage.h"
+#include "InterestedMessage.h"
+#include "NotInterestedMessage.h"
+#include "HaveMessage.h"
+#include "BitfieldMessage.h"
+#include "RequestMessage.h"
+#include "CancelMessage.h"
+#include "PieceMessage.h"
+#include "HandshakeMessage.h"
+#include "KeepAliveMessage.h"
+#include "PortMessage.h"
+#include "HaveAllMessage.h"
+#include "HaveNoneMessage.h"
+#include "RejectMessage.h"
+#include "AllowedFastMessage.h"
+#include "SuggestPieceMessage.h"
+#include "RequestSlot.h"
+#include "DlAbortEx.h"
+
+PeerMessageFactory::PeerMessageFactory(int cuid,
+				       PeerInteraction* peerInteraction,
+				       const PeerHandle& peer)
+  :cuid(cuid),
+   peerInteraction(peerInteraction),
+   peer(peer) {}
+
+PeerMessageFactory::~PeerMessageFactory() {}
+
+PeerMessageHandle PeerMessageFactory::createPeerMessage(const char* msg, int msgLength) const {
+  PeerMessage* peerMessage;
+  if(msgLength == 0) {
+    // keep-alive
+    peerMessage = new KeepAliveMessage();
+  } else {
+    int id = PeerMessageUtil::getId(msg);
+    switch(id) {
+    case ChokeMessage::ID:
+      peerMessage = ChokeMessage::create(msg, msgLength);
+      break;
+    case UnchokeMessage::ID:
+      peerMessage = UnchokeMessage::create(msg, msgLength);
+      break;
+    case InterestedMessage::ID:
+      peerMessage = InterestedMessage::create(msg, msgLength);
+      break;
+    case NotInterestedMessage::ID:
+      peerMessage = NotInterestedMessage::create(msg, msgLength);
+      break;
+    case HaveMessage::ID:
+      peerMessage = HaveMessage::create(msg, msgLength);
+      ((HaveMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->
+					     pieces);
+      break;
+    case BitfieldMessage::ID:
+      peerMessage = BitfieldMessage::create(msg, msgLength);
+      ((BitfieldMessage*)peerMessage)->setPieces(peerInteraction->
+						 getTorrentMan()->pieces);
+      break;
+    case RequestMessage::ID:
+      peerMessage = RequestMessage::create(msg, msgLength);
+      ((RequestMessage*)peerMessage)->setPieces(peerInteraction->
+						getTorrentMan()->pieces);
+      ((RequestMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
+      break;
+    case CancelMessage::ID:
+      peerMessage = CancelMessage::create(msg, msgLength);
+      ((CancelMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+      ((CancelMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
+      break;
+    case PieceMessage::ID:
+      peerMessage = PieceMessage::create(msg, msgLength);
+      ((PieceMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+      ((PieceMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
+      break;
+    case PortMessage::ID:
+      peerMessage = PortMessage::create(msg, msgLength);
+      break;
+    case HaveAllMessage::ID:
+      peerMessage = HaveAllMessage::create(msg, msgLength);
+      break;
+    case HaveNoneMessage::ID:
+      peerMessage = HaveNoneMessage::create(msg, msgLength);
+      break;
+    case RejectMessage::ID:
+      peerMessage = RejectMessage::create(msg, msgLength);
+      ((RejectMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+      ((RejectMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
+      break;
+    case SuggestPieceMessage::ID:
+      peerMessage = SuggestPieceMessage::create(msg, msgLength);
+      ((SuggestPieceMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+      break;
+    case AllowedFastMessage::ID:
+      peerMessage = AllowedFastMessage::create(msg, msgLength);
+      ((AllowedFastMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
+      break;
+    default:
+      throw new DlAbortEx("Invalid message id. id = %d", id);
+    }
+  }
+  PeerMessageHandle handle = PeerMessageHandle(peerMessage);
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle
+PeerMessageFactory::createHandshakeMessage(const char* msg, int msgLength) const
+{
+  PeerMessageHandle handle =
+    PeerMessageHandle(HandshakeMessage::create(msg, msgLength));
+  
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle
+PeerMessageFactory::createHandshakeMessage(const unsigned char* infoHash,
+					  const char* peerId) const
+{
+  PeerMessageHandle handle =
+    PeerMessageHandle(new HandshakeMessage(infoHash, peerId));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+void
+PeerMessageFactory::setPeerMessageCommonProperty(PeerMessageHandle& peerMessage) const
+{
+  peerMessage->setPeer(peer);
+  peerMessage->setCuid(cuid);
+  peerMessage->setPeerInteraction(peerInteraction);
+}
+
+PeerMessageHandle PeerMessageFactory::createRequestMessage(const Piece& piece,
+							   int blockIndex) const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new RequestMessage(piece.getIndex(),
+					 blockIndex*piece.getBlockLength(),
+					 piece.getBlockLength(blockIndex),
+					 blockIndex));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createCancelMessage(int index,
+							  int begin,
+							  int length) const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new CancelMessage(index, begin, length));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createPieceMessage(int index,
+							 int begin,
+							 int length) const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new PieceMessage(index, begin, length));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createHaveMessage(int index) const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new HaveMessage(index));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createChokeMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new ChokeMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createUnchokeMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new UnchokeMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createInterestedMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new InterestedMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createNotInterestedMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new NotInterestedMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createBitfieldMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new BitfieldMessage(peerInteraction->getTorrentMan()->
+					  getBitfield(),
+					  peerInteraction->getTorrentMan()->
+					  getBitfieldLength()));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createKeepAliveMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new KeepAliveMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createHaveAllMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new HaveAllMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createHaveNoneMessage() const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new HaveNoneMessage());
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createRejectMessage(int index,
+							  int begin,
+							  int length) const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new RejectMessage(index, begin, length));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}
+
+PeerMessageHandle PeerMessageFactory::createAllowedFastMessage(int index) const {
+  PeerMessageHandle handle =
+    PeerMessageHandle(new AllowedFastMessage(index));
+  setPeerMessageCommonProperty(handle);
+  return handle;
+}

+ 73 - 0
src/PeerMessageFactory.h

@@ -0,0 +1,73 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/* copyright --> */
+#ifndef _D_PEER_MESSAGE_FACTORY_H_
+#define _D_PEER_MESSAGE_FACTORY_H_
+
+#include "common.h"
+#include "PeerMessage.h"
+#include "HandshakeMessage.h"
+
+class PeerInteraction;
+
+class PeerMessageFactory {
+private:
+  int cuid;
+  PeerInteraction* peerInteraction;
+  PeerHandle peer;
+
+  void setPeerMessageCommonProperty(PeerMessageHandle& peerMessage) const;
+public:
+  PeerMessageFactory(int cuid,
+		     PeerInteraction* peerInteraction,
+		     const PeerHandle& peer);
+
+  ~PeerMessageFactory();
+
+  PeerMessageHandle
+  createPeerMessage(const char* msg, int msgLength) const;
+
+  PeerMessageHandle
+  createHandshakeMessage(const char* msg,
+			 int msgLength) const;
+
+  PeerMessageHandle
+  createHandshakeMessage(const unsigned char* infoHash,
+			 const char* peerId) const;
+
+  PeerMessageHandle createRequestMessage(const Piece& piece,
+					 int blockIndex) const;
+  PeerMessageHandle createCancelMessage(int index, int begin, int length) const;
+  PeerMessageHandle createPieceMessage(int index, int begin, int length) const;
+  PeerMessageHandle createHaveMessage(int index) const;
+  PeerMessageHandle createChokeMessage() const;
+  PeerMessageHandle createUnchokeMessage() const;
+  PeerMessageHandle createInterestedMessage() const;
+  PeerMessageHandle createNotInterestedMessage() const;
+  PeerMessageHandle createBitfieldMessage() const;
+  PeerMessageHandle createKeepAliveMessage() const;
+  PeerMessageHandle createHaveAllMessage() const;
+  PeerMessageHandle createHaveNoneMessage() const;
+  PeerMessageHandle createRejectMessage(int index, int begin, int length) const;
+  PeerMessageHandle createAllowedFastMessage(int index) const;
+};
+
+#endif // _D_PEER_MESSAGE_FACTORY_H_

+ 1 - 15
src/PeerMessageUtil.h

@@ -22,22 +22,8 @@
 #ifndef _D_PEER_MESSAGE_UTIL_H_
 #define _D_PEER_MESSAGE_UTIL_H_
 
-#include "ChokeMessage.h"
-#include "UnchokeMessage.h"
-#include "InterestedMessage.h"
-#include "NotInterestedMessage.h"
-#include "HaveMessage.h"
-#include "BitfieldMessage.h"
-#include "RequestMessage.h"
-#include "CancelMessage.h"
-#include "PieceMessage.h"
-#include "HandshakeMessage.h"
-#include "KeepAliveMessage.h"
-#include "PortMessage.h"
-#include "HaveAllMessage.h"
-#include "HaveNoneMessage.h"
-#include "PeerConnection.h"
 #include "common.h"
+#include "HandshakeMessage.h"
 
 #define MAX_BLOCK_LENGTH (128*1024)
 

+ 0 - 30
src/Piece.cc

@@ -23,36 +23,6 @@
 
 Piece Piece::nullPiece;
 
-Piece::Piece(const Piece& piece) {
-  index = piece.index;
-  length = piece.length;
-  if(piece.bitfield == NULL) {
-    bitfield = NULL;
-  } else {
-    bitfield = new BitfieldMan(*piece.bitfield);
-  }
-}
-
-Piece& Piece::operator=(const Piece& piece) {
-  if(this != &piece) {
-    index = piece.index;
-    length = piece.length;
-    if(bitfield != NULL) {
-      delete bitfield;
-    }
-    if(piece.bitfield == NULL) {
-      bitfield = NULL;
-    } else {
-      bitfield = new BitfieldMan(*piece.bitfield);
-    }
-  }
-  return *this;
-}
-
-bool Piece::operator==(const Piece& piece) const {
-  return index == piece.index;
-}
-
 void Piece::completeBlock(int blockIndex) {
   bitfield->setBit(blockIndex);
   bitfield->unsetUseBit(blockIndex);

+ 30 - 3
src/Piece.h

@@ -37,13 +37,40 @@ public:
   Piece(int index, int length):index(index), length(length) {
     bitfield = new BitfieldMan(BLOCK_LENGTH, length);
   }
-  Piece(const Piece& piece);
+
+  Piece(const Piece& piece) {
+    index = piece.index;
+    length = piece.length;
+    if(piece.bitfield == NULL) {
+      bitfield = NULL;
+    } else {
+      bitfield = new BitfieldMan(*piece.bitfield);
+    }
+  }
+
   ~Piece() {
     delete bitfield;
   }
 
-  Piece& operator=(const Piece& piece);
-  bool operator==(const Piece& piece) const;
+  Piece& operator=(const Piece& piece) {
+    if(this != &piece) {
+      index = piece.index;
+      length = piece.length;
+      if(bitfield != NULL) {
+	delete bitfield;
+      }
+      if(piece.bitfield == NULL) {
+	bitfield = NULL;
+      } else {
+	bitfield = new BitfieldMan(*piece.bitfield);
+      }
+    }
+    return *this;
+  }
+  
+  bool operator==(const Piece& piece) const {
+    return index == piece.index;
+  }
 
   int getMissingUnusedBlockIndex() const;
   int getMissingBlockIndex() const;

+ 49 - 0
src/PieceMessage.cc

@@ -109,6 +109,9 @@ int PieceMessage::getMessageHeaderLength() {
 }
 
 void PieceMessage::send() {
+  if(invalidate) {
+    return;
+  }
   TorrentMan* torrentMan = peerInteraction->getTorrentMan();
   PeerConnection* peerConnection = peerInteraction->getPeerConnection();
   if(!headerSent) {
@@ -227,3 +230,49 @@ void PieceMessage::erasePieceOnDisk(const Piece& piece) {
   }
 }
 
+PeerMessageHandle PieceMessage::createRejectMessage(int index,
+						    int begin,
+						    int blockLength) const {
+  return peerInteraction->getPeerMessageFactory()->
+    createRejectMessage(index,
+			begin,
+			blockLength);
+}
+
+void PieceMessage::onChoked() {
+  if(!invalidate &&
+     !inProgress &&
+     !peerInteraction->isInFastSet(index)) {
+    logger->debug("CUID#%d - Reject piece message in queue because"
+		  " the peer has been choked. index=%d, begin=%d, length=%d",
+		  cuid,
+		  index,
+		  begin,
+		  blockLength);
+
+    if(peer->isFastExtensionEnabled()) {
+      peerInteraction->addMessage(createRejectMessage(index,
+						      begin,
+						      blockLength));
+    }
+    invalidate = true;
+  }
+}
+
+void PieceMessage::onCanceled(int index, int begin, int blockLength) {
+  if(!invalidate &&
+     !inProgress &&
+     this->index == index &&
+     this->begin == begin &&
+     this->blockLength == blockLength) {
+    logger->debug("CUID#%d - Reject piece message in queue because cancel"
+		  " message received. index=%d, begin=%d, length=%d",
+		  cuid, index, begin, blockLength);
+    if(peer->isFastExtensionEnabled()) {
+      peerInteraction->addMessage(createRejectMessage(index,
+						      begin,
+						      blockLength));
+    }
+    invalidate = true;
+  }
+}

+ 17 - 5
src/PieceMessage.h

@@ -45,12 +45,22 @@ private:
   void onGotWrongPiece(Piece& piece);
   void erasePieceOnDisk(const Piece& piece);
   int sendPieceData(long long int offset, int length) const;
+  PeerMessageHandle createRejectMessage(int index, int begin, int blockLength) const;
 public:
-  PieceMessage():PeerMessage(),
-		 index(0), begin(0), block(NULL), blockLength(0),
-		 leftDataLength(0), headerSent(false),
-		 pendingCount(0),
-		 pieces(0), pieceLength(0) {}
+  PieceMessage(int index = 0, int begin = 0, int blockLength = 0)
+    :PeerMessage(),
+     index(index),
+     begin(begin),
+     block(0),
+     blockLength(blockLength),
+     leftDataLength(0),
+     headerSent(false),
+     pendingCount(0),
+     pieces(0),
+     pieceLength(0)
+  {
+    uploading = true;
+  }
 
   virtual ~PieceMessage() {
     if(block != NULL) {
@@ -93,6 +103,8 @@ public:
   virtual void send();
   virtual void check() const;
   virtual string toString() const;
+  virtual void onChoked();
+  virtual void onCanceled(int index, int begin, int blockLength);
 };
 
 #endif // _D_PIECE_MESSAGE_H_

+ 7 - 3
src/RejectMessage.h

@@ -36,9 +36,13 @@ private:
 
   char msg[17];
 public:
-  RejectMessage():SimplePeerMessage(),
-		  index(0), begin(0), length(0),
-		  pieces(0), pieceLength(0) {}
+  RejectMessage(int index = 0, int begin = 0, int length = 0)
+    :SimplePeerMessage(),
+     index(index),
+     begin(begin),
+     length(length),
+     pieces(0),
+     pieceLength(0) {}
 
   virtual ~RejectMessage() {}
 

+ 17 - 2
src/RequestMessage.cc

@@ -46,10 +46,12 @@ void RequestMessage::receivedAction() {
   if(torrentMan->hasPiece(index) &&
      (!peer->amChoking ||
       peer->amChoking && peerInteraction->isInFastSet(index))) {
-    peerInteraction->addMessage(peerInteraction->createPieceMessage(index, begin, length));
+    peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				createPieceMessage(index, begin, length));
   } else {
     if(peer->isFastExtensionEnabled()) {
-      peerInteraction->addMessage(peerInteraction->createRejectMessage(index, begin, length));
+      peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
+				  createRejectMessage(index, begin, length));
     }
   }
 }
@@ -87,3 +89,16 @@ string RequestMessage::toString() const {
   return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+
     ", length="+Util::itos(length);
 }
+
+void RequestMessage::onPush() {
+  RequestSlot requestSlot(index, begin, length, blockIndex);
+  peerInteraction->addRequestSlot(requestSlot);
+}
+
+void RequestMessage::onAbortPiece(const Piece& piece) {
+  if(!invalidate &&
+     !inProgress &&
+     this->index == piece.getIndex()) {
+    invalidate = true;
+  }
+}

+ 12 - 3
src/RequestMessage.h

@@ -37,9 +37,16 @@ private:
   
   char msg[17];
 public:
-  RequestMessage():SimplePeerMessage(),
-		   index(0), begin(0), length(0), blockIndex(0),
-		   pieces(0), pieceLength(0) {}
+  RequestMessage(int index = 0, int begin = 0, int length = 0,
+		 int blockIndex = 0)
+    :SimplePeerMessage(),
+     index(index),
+     begin(begin),
+     length(length),
+     blockIndex(blockIndex),
+     pieces(0),
+     pieceLength(0) {}
+
   virtual ~RequestMessage() {}
 
   enum ID_t {
@@ -73,6 +80,8 @@ public:
   virtual int getMessageLength();
   virtual void check() const;
   virtual string toString() const;
+  virtual void onPush();
+  virtual void onAbortPiece(const Piece& piece);
 };
 
 #endif // _D_REQUEST_MESSAGE_H_

+ 0 - 13
src/RequestSlot.cc

@@ -29,13 +29,6 @@ RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
   copy(requestSlot);
 }
 
-RequestSlot& RequestSlot::operator=(const RequestSlot& requestSlot) {
-  if(this != &requestSlot) {
-    copy(requestSlot);
-  }
-  return *this;
-}
-
 void RequestSlot::copy(const RequestSlot& requestSlot) {
   index = requestSlot.index;
   begin = requestSlot.begin;
@@ -62,9 +55,3 @@ bool RequestSlot::isNull(const RequestSlot& requestSlot) {
   return requestSlot.index == 0 && requestSlot.begin == 0&&
     requestSlot.length == 0;
 }
-
-bool RequestSlot::operator==(const RequestSlot& requestSlot) const {
-  return index == requestSlot.index &&
-    begin == requestSlot.begin &&
-    length == requestSlot.length;
-}

+ 12 - 3
src/RequestSlot.h

@@ -38,15 +38,24 @@ public:
   RequestSlot(const RequestSlot& requestSlot);
   ~RequestSlot() {}
 
-  RequestSlot& operator=(const RequestSlot& requestSlot);
+  RequestSlot& operator=(const RequestSlot& requestSlot) {
+    if(this != &requestSlot) {
+      copy(requestSlot);
+    }
+    return *this;
+  }
+
+  bool operator==(const RequestSlot& requestSlot) const {
+    return index == requestSlot.index &&
+      begin == requestSlot.begin &&
+      length == requestSlot.length;
+  }
 
   void setDispatchedTime();
 
   bool isTimeout(int timeoutSec) const;
   int getLatencyInMillis() const;
 
-  bool operator==(const RequestSlot& requestSlot) const;
-
   int getIndex() const { return index; }
   void setIndex(int index) { this->index = index; }
   int getBegin() const { return begin; }

+ 3 - 0
src/SimplePeerMessage.cc

@@ -28,6 +28,9 @@ SimplePeerMessage::SimplePeerMessage():leftDataLength(0) {}
 SimplePeerMessage::~SimplePeerMessage() {}
 
 void SimplePeerMessage::send() {
+  if(invalidate) {
+    return;
+  }
   if(sendPredicate() || inProgress) {
     const char* msg = getMessage();
     int msgLength = getMessageLength();

+ 0 - 12
src/SocketCore.cc

@@ -455,15 +455,3 @@ void SocketCore::initiateSecureConnection() {
   }
 #endif // HAVE_LIBGNUTLS
 }
-
-bool operator==(const SocketCore& s1, const SocketCore& s2) {
-  return s1.sockfd == s2.sockfd;
-}
-
-bool operator!=(const SocketCore& s1, const SocketCore& s2) {
-  return s1.sockfd != s2.sockfd;
-}
-
-bool operator<(const SocketCore& s1, const SocketCore& s2) {
-  return s1.sockfd < s2.sockfd;
-}

+ 13 - 0
src/SocketCore.h

@@ -182,5 +182,18 @@ public:
    * connection must be established  before calling this method.
    */
   void initiateSecureConnection() ;
+
+  bool operator==(const SocketCore& s) {
+    return sockfd == s.sockfd;
+  }
+  
+  bool operator!=(const SocketCore& s) {
+    return !(*this == s);
+  }
+  
+  bool operator<(const SocketCore& s) {
+    return sockfd < s.sockfd;
+  }
+
 };
 #endif // _D_SOCKET_CORE_H_

+ 0 - 7
src/Time.cc

@@ -32,13 +32,6 @@ Time::Time(const Time& time) {
 
 Time::~Time() {}
 
-Time& Time::operator=(const Time& time) {
-  if(this != &time) {
-    tv = time.tv;
-  }
-  return *this;
-}
-
 void Time::reset() {
   gettimeofday(&tv, 0);
 }

+ 7 - 1
src/Time.h

@@ -35,7 +35,13 @@ public:
   // this object was created.
   Time();
   Time(const Time& time);
-  Time& operator=(const Time& time);
+
+  Time& operator=(const Time& time) {
+    if(this != &time) {
+      tv = time.tv;
+    }
+    return *this;
+  }
 
   ~Time();
 

+ 20 - 17
src/TorrentMan.cc

@@ -82,7 +82,7 @@ void TorrentMan::updatePeers(const Peers& peers) {
 
 bool TorrentMan::addPeer(const PeerHandle& peer) {
   if(peers.size() >= MAX_PEER_LIST_SIZE) {
-    deleteErrorPeer();
+    deleteUnusedPeer(peers.size()-MAX_PEER_LIST_SIZE+15);
   }
   Peers::iterator itr = find(peers.begin(), peers.end(), peer);
   if(itr == peers.end()) {
@@ -117,11 +117,13 @@ bool TorrentMan::isPeerAvailable() const {
   return getPeer() != nullPeer;
 }
 
-void TorrentMan::deleteErrorPeer() {
-  for(Peers::iterator itr = peers.begin(); itr != peers.end();) {
+void TorrentMan::deleteUnusedPeer(int delSize) {
+  for(Peers::iterator itr = peers.begin();
+      itr != peers.end() && delSize > 0;) {
     const PeerHandle& p = *itr;
-    if(p->error > 0 && p->cuid == 0) {
+    if(p->cuid == 0) {
       itr = peers.erase(itr);
+      delSize--;
     } else {
       itr++;
     }
@@ -656,18 +658,19 @@ void TorrentMan::advertisePiece(int cuid, int index) {
   haves.push_front(entry);
 };
 
-PieceIndexes TorrentMan::getAdvertisedPieceIndexes(int myCuid,
-						   const Time& lastCheckTime) const {
-    PieceIndexes indexes;
-    for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
-      const Haves::value_type& have = *itr;
-      if(have.cuid == myCuid) {
-	continue;
-      }
-      if(lastCheckTime.isNewer(have.registeredTime)) {
-	break;
-      }
-      indexes.push_back(have.index);
+PieceIndexes
+TorrentMan::getAdvertisedPieceIndexes(int myCuid,
+				      const Time& lastCheckTime) const {
+  PieceIndexes indexes;
+  for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
+    const Haves::value_type& have = *itr;
+    if(have.cuid == myCuid) {
+      continue;
     }
-    return indexes;
+    if(lastCheckTime.isNewer(have.registeredTime)) {
+      break;
+    }
+    indexes.push_back(have.index);
   }
+  return indexes;
+}

+ 1 - 1
src/TorrentMan.h

@@ -138,7 +138,7 @@ public:
   const Peers& getPeers() const { return peers; }
   PeerHandle getPeer() const;
   bool isPeerAvailable() const;
-  void deleteErrorPeer();
+  void deleteUnusedPeer(int delSize);
 
   bool hasMissingPiece(const PeerHandle& peer) const;
   int getMissingPieceIndex(const PeerHandle& peer) const;

+ 1 - 0
src/Util.cc

@@ -31,6 +31,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <unistd.h>
 
 string Util::itos(int value, bool comma) {
   string str = llitos(value, comma);

+ 1 - 0
src/Util.h

@@ -30,6 +30,7 @@
 #include <utility>
 #include <deque>
 #include <sys/time.h>
+#include <stdio.h>
 
 using namespace std;