Explorar o código

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

	To add --seed-time and --seed-ratio command-line option:
	* src/Option.h (getAsDouble): New function.
	* src/Option.cc (getAsDouble): New function.
	* src/SeedCheckCommand.h: New class.
	* src/SeedCheckCommand.cc: New class.
	* src/DownloadEngineFactory.cc
	(SeedCheckCommand.h): Included.
	(UnionSeedCriteria.h): Included.
	(TimeSeedCriteria.h): Included.
	(ShareRatioSeedCriteria.h): Included.
	(newTorrentConsoleEngine): Added the processing of seed option.
	* src/SeedCriteria.h: New class.
	* src/ShareRatioSeedCriteria.h: New class.
	* src/TimeSeedCriteria.h: New class.
	* src/UnionSeedCriteria.h: New class.
	* src/prefs.h
	(PREF_SEED_TIME): New definition.
	(PREF_SEED_RATIO): New definition.
	* src/main.cc
	(showUsage): Added --seed-time and --seed-ratio option.
	(main): Added --seed-time and --seed-ratio option.
	Made default log file name "/dev/null".
	* src/SharedHandle.h
	(SharedHandle): Copy constructor. Made it assignable from the
	SharedHandle of the subclasses.
	(operator=): Made it assignable from the SharedHandle of the
	subclasses.
	(getRefCount): New function.
	
	To add notice log level and the switch to write log to stdout. 
This
	switch is configurable per log level.
	* src/Logger.h
	(notice): New function.
	(LEVEL): Added NOTICE. Assigned an explicit value to each log 
level
	constant.
	* src/LogFactory.cc
	(getInstance): The use of NullLogger was removed. A log message 
with
	notice log level was made written to stdout along with log file.
	* src/NullLogger.h
	(notice): New function.
	* src/SimpleLogger.h
	(writeHeader): Added the 'file' argument.
	(writeLog): Added the 'file' argument.
	(writeFile): New function.
	(stdoutField): New variable.
	(SimpleLogger): Removed the default constructor.
	(SimpleLogger): Made the default value of logfile 0.
	(debug): Added 'virtual' keyword.
	(info): Added 'virtual' keyword.
	(warn): Added 'virtual' keyword.
	(error): Added 'virtual' keyword.
	(notice): New function.
	(setStdout): New function.
	* src/SimpleLogger.cc
	(WRITE_LOG): Replaced writeLog with writeFile.
	(WRITE_LOG_EX): Replaced writeLog with writeFile.
	(SimpleLogger): Removed the default constructor.
	(setStdout): New function.
	(writeLog): Added the handling of NOTICE log level.
	(writeFile): New function.
	(notice): New function.

	* src/TorrentMan.h: Updated doc.

	* src/BitfieldMan.h: Updated doc.
	
	* src/TrackerWatcherCommand.cc
	(execute): Return true if error occurred in the request to the 
tracker
	and halt is requested.

	* src/TrackerUpdateCommand.cc
	(execute): Return true if error occurred in the request to the 
tracker
	and halt is requested.

	* src/TorrentConsoleDownloadEngine.h
	(onSelectiveDownloadingCompletes): Removed.
	* src/TorrentConsoleDownloadEngine.cc
	(onSelectiveDownloadingCompletes): Removed.
	* src/TorrentDownloadEngine.h
	(onEndOfRun): Added 'virtual' keyword.
	(afterEachIteration): Removed.
	(onSelectiveDownloadingCompletes): Removed.
	* src/TorrentDownloadEngine.cc
	(onEndOfRun): Removed filenameFixed.
	(afterEachIteration): Removed.	
	* src/TorrentMan.cc
	(completePiece): Call onDownloadComplete here.
	(onDownloadComplete): Added 2 log messages.
Tatsuhiro Tsujikawa %!s(int64=19) %!d(string=hai) anos
pai
achega
3b2a98393e

+ 91 - 2
ChangeLog

@@ -1,10 +1,100 @@
+2006-08-27  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	To add --seed-time and --seed-ratio command-line option:
+	* src/Option.h (getAsDouble): New function.
+	* src/Option.cc (getAsDouble): New function.
+	* src/SeedCheckCommand.h: New class.
+	* src/SeedCheckCommand.cc: New class.
+	* src/DownloadEngineFactory.cc
+	(SeedCheckCommand.h): Included.
+	(UnionSeedCriteria.h): Included.
+	(TimeSeedCriteria.h): Included.
+	(ShareRatioSeedCriteria.h): Included.
+	(newTorrentConsoleEngine): Added the processing of seed option.
+	* src/SeedCriteria.h: New class.
+	* src/ShareRatioSeedCriteria.h: New class.
+	* src/TimeSeedCriteria.h: New class.
+	* src/UnionSeedCriteria.h: New class.
+	* src/prefs.h
+	(PREF_SEED_TIME): New definition.
+	(PREF_SEED_RATIO): New definition.
+	* src/main.cc
+	(showUsage): Added --seed-time and --seed-ratio option.
+	(main): Added --seed-time and --seed-ratio option.
+	Made default log file name "/dev/null".
+	* src/SharedHandle.h
+	(SharedHandle): Copy constructor. Made it assignable from the
+	SharedHandle of the subclasses.
+	(operator=): Made it assignable from the SharedHandle of the
+	subclasses.
+	(getRefCount): New function.
+	
+	To add notice log level and the switch to write log to stdout. This
+	switch is configurable per log level.
+	* src/Logger.h
+	(notice): New function.
+	(LEVEL): Added NOTICE. Assigned an explicit value to each log level
+	constant.
+	* src/LogFactory.cc
+	(getInstance): The use of NullLogger was removed. A log message with
+	notice log level was made written to stdout along with log file.
+	* src/NullLogger.h
+	(notice): New function.
+	* src/SimpleLogger.h
+	(writeHeader): Added the 'file' argument.
+	(writeLog): Added the 'file' argument.
+	(writeFile): New function.
+	(stdoutField): New variable.
+	(SimpleLogger): Removed the default constructor.
+	(SimpleLogger): Made the default value of logfile 0.
+	(debug): Added 'virtual' keyword.
+	(info): Added 'virtual' keyword.
+	(warn): Added 'virtual' keyword.
+	(error): Added 'virtual' keyword.
+	(notice): New function.
+	(setStdout): New function.
+	* src/SimpleLogger.cc
+	(WRITE_LOG): Replaced writeLog with writeFile.
+	(WRITE_LOG_EX): Replaced writeLog with writeFile.
+	(SimpleLogger): Removed the default constructor.
+	(setStdout): New function.
+	(writeLog): Added the handling of NOTICE log level.
+	(writeFile): New function.
+	(notice): New function.
+
+	* src/TorrentMan.h: Updated doc.
+
+	* src/BitfieldMan.h: Updated doc.
+	
+	* src/TrackerWatcherCommand.cc
+	(execute): Return true if error occurred in the request to the tracker
+	and halt is requested.
+
+	* src/TrackerUpdateCommand.cc
+	(execute): Return true if error occurred in the request to the tracker
+	and halt is requested.
+
+	* src/TorrentConsoleDownloadEngine.h
+	(onSelectiveDownloadingCompletes): Removed.
+	* src/TorrentConsoleDownloadEngine.cc
+	(onSelectiveDownloadingCompletes): Removed.
+	* src/TorrentDownloadEngine.h
+	(onEndOfRun): Added 'virtual' keyword.
+	(afterEachIteration): Removed.
+	(onSelectiveDownloadingCompletes): Removed.
+	* src/TorrentDownloadEngine.cc
+	(onEndOfRun): Removed filenameFixed.
+	(afterEachIteration): Removed.	
+	* src/TorrentMan.cc
+	(completePiece): Call onDownloadComplete here.
+	(onDownloadComplete): Added 2 log messages.
+
 2006-08-21  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
         To fix compilation problem on gcc4.1.1(patch#1542283 by tizianomueller)
 	* src/NameResolver.h: Added the prototype declaration of callback().
 	
 	To support c-ares library:
-	
 	* src/AbstractCommand.cc: Replaced HAVE_LIBARES with ENABLE_ASYNC_DNS
 	* src/FeatureConfig.cc: Replaced HAVE_LIBARES with ENABLE_ASYNC_DNS
 	* src/FtpInitiateConnectionCommand.h:
@@ -26,7 +116,6 @@
 
 	To fix the bug that causes compilation failure with metalink-support
 	disabled(bug#1543587):
-
 	* src/main.cc: Fixed with the patch by tizianomueller.
 
 	* Release 0.7.2

+ 4 - 1
TODO

@@ -13,4 +13,7 @@
 * List available os, version, etc for metalink
 * ipv6(RFC2428 for ftp)
 * Add some criteria to stop seeding.
-* Add silent mode.
+* Add silent mode.
+* Add NOTIFY log level. A message categorized in this level is printed in
+ a console along with a log file.
+* Do onDownloadComplete in TorrentMan::completePiece().

+ 3 - 0
src/BitfieldMan.h

@@ -156,6 +156,9 @@ public:
   void setAllBit();
 
   void addFilter(long long int offset, long long int length);
+  /**
+   * Clears filter and disables filter
+   */
   void clearFilter();
   
   void enableFilter();

+ 17 - 1
src/DownloadEngineFactory.cc

@@ -31,8 +31,12 @@
 # include "TrackerWatcherCommand.h"
 # include "TrackerUpdateCommand.h"
 # include "TorrentAutoSaveCommand.h"
+# include "SeedCheckCommand.h"
 # include "PeerChokeCommand.h"
 # include "HaveEraseCommand.h"
+# include "UnionSeedCriteria.h"
+# include "TimeSeedCriteria.h"
+# include "ShareRatioSeedCriteria.h"
 #endif // ENABLE_BITTORRENT
 
 ConsoleDownloadEngine*
@@ -117,7 +121,19 @@ DownloadEngineFactory::newTorrentConsoleEngine(const Option* op,
 					      te, 10));
   te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(),
 					      te, 10));
-  
+
+  SharedHandle<UnionSeedCriteria> unionCri = new UnionSeedCriteria();
+  if(op->defined(PREF_SEED_TIME)) {
+    unionCri->addSeedCriteria(new TimeSeedCriteria(op->getAsInt(PREF_SEED_TIME)*60));
+  }
+  if(op->defined(PREF_SEED_RATIO)) {
+    unionCri->addSeedCriteria(new ShareRatioSeedCriteria(op->getAsDouble(PREF_SEED_RATIO), te->torrentMan));
+  }
+  if(unionCri->getSeedCriterion().size() > 0) {
+    te->commands.push_back(new SeedCheckCommand(te->torrentMan->getNewCuid(),
+						te,
+						unionCri));
+  }
   return te;
 }
 #endif // ENABLE_BITTORRENT

+ 4 - 8
src/LogFactory.cc

@@ -21,20 +21,16 @@
 /* copyright --> */
 #include "LogFactory.h"
 #include "SimpleLogger.h"
-#include "NullLogger.h"
 
 string LogFactory::filename;
 Logger* LogFactory::logger = NULL;
 
 Logger* LogFactory::getInstance() {
   if(logger == NULL) {
-    if(filename.empty()) {
-      logger = new NullLogger();
-    } else {
-      SimpleLogger* slogger = new SimpleLogger();
-      slogger->openFile(filename);
-      logger = slogger;
-    }
+    SimpleLogger* slogger = new SimpleLogger();
+    slogger->openFile(filename);
+    slogger->setStdout(Logger::NOTICE, true);
+    logger = slogger;
   }
   return logger;
 }

+ 7 - 4
src/Logger.h

@@ -35,16 +35,19 @@ public:
   virtual void debug(const char* msg, Exception* ex, ...) const = 0;
   virtual void info(const char* msg, ...) const = 0;
   virtual void info(const char* msg, Exception* ex, ...) const = 0;
+  virtual void notice(const char* msg, ...) const = 0;
+  virtual void notice(const char* msg, Exception* ex, ...) const = 0;
   virtual void warn(const char* msg, ...) const = 0;
   virtual void warn(const char* msg, Exception* ex, ...) const = 0;
   virtual void error(const char*  msg, ...) const = 0;
   virtual void error(const char* msg, Exception* ex, ...) const = 0;
 
   enum LEVEL {
-    DEBUG,
-    INFO,
-    WARN,
-    ERROR
+    DEBUG  = 1 << 0,
+    INFO   = 1 << 1,
+    NOTICE = 1 << 2,
+    WARN   = 1 << 3,
+    ERROR  = 1 << 4,
   };
 };
 

+ 6 - 1
src/Makefile.am

@@ -116,7 +116,12 @@ SRCS += MetaEntry.h\
 	SimplePeerMessage.cc SimplePeerMessage.h\
 	PeerMessageFactory.cc PeerMessageFactory.h\
 	HaveEraseCommand.cc HaveEraseCommand.h\
-	TorrentRequestInfo.cc TorrentRequestInfo.h
+	TorrentRequestInfo.cc TorrentRequestInfo.h\
+	SeedCriteria.h\
+	TimeSeedCriteria.h\
+	ShareRatioSeedCriteria.h\
+	UnionSeedCriteria.h\
+	SeedCheckCommand.cc SeedCheckCommand.h
 endif # ENABLE_BITTORRENT
 
 if ENABLE_METALINK

+ 13 - 4
src/Makefile.in

@@ -93,7 +93,12 @@ bin_PROGRAMS = aria2c$(EXEEXT)
 @ENABLE_BITTORRENT_TRUE@	SimplePeerMessage.cc SimplePeerMessage.h\
 @ENABLE_BITTORRENT_TRUE@	PeerMessageFactory.cc PeerMessageFactory.h\
 @ENABLE_BITTORRENT_TRUE@	HaveEraseCommand.cc HaveEraseCommand.h\
-@ENABLE_BITTORRENT_TRUE@	TorrentRequestInfo.cc TorrentRequestInfo.h
+@ENABLE_BITTORRENT_TRUE@	TorrentRequestInfo.cc TorrentRequestInfo.h\
+@ENABLE_BITTORRENT_TRUE@	SeedCriteria.h\
+@ENABLE_BITTORRENT_TRUE@	TimeSeedCriteria.h\
+@ENABLE_BITTORRENT_TRUE@	ShareRatioSeedCriteria.h\
+@ENABLE_BITTORRENT_TRUE@	UnionSeedCriteria.h\
+@ENABLE_BITTORRENT_TRUE@	SeedCheckCommand.cc SeedCheckCommand.h
 
 @ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\
 @ENABLE_METALINK_TRUE@	MetalinkEntry.cc MetalinkEntry.h\
@@ -197,8 +202,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	SuggestPieceMessage.cc SuggestPieceMessage.h \
 	SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \
 	PeerMessageFactory.h HaveEraseCommand.cc HaveEraseCommand.h \
-	TorrentRequestInfo.cc TorrentRequestInfo.h Metalinker.cc \
-	Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
+	TorrentRequestInfo.cc TorrentRequestInfo.h SeedCriteria.h \
+	TimeSeedCriteria.h ShareRatioSeedCriteria.h \
+	UnionSeedCriteria.h SeedCheckCommand.cc SeedCheckCommand.h \
+	Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
 	MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
 	Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \
 	MetalinkRequestInfo.cc MetalinkRequestInfo.h
@@ -251,7 +258,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 @ENABLE_BITTORRENT_TRUE@	SimplePeerMessage.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	PeerMessageFactory.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	HaveEraseCommand.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@	TorrentRequestInfo.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@	TorrentRequestInfo.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@	SeedCheckCommand.$(OBJEXT)
 @ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkEntry.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkResource.$(OBJEXT) \
@@ -646,6 +654,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestMessage.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestSlot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SeedCheckCommand.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentMan.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentSplitter.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitor.Po@am__quote@

+ 2 - 0
src/NullLogger.h

@@ -34,6 +34,8 @@ public:
   virtual void debug(const char* msg, Exception* ex, ...) const {}
   virtual void info(const char* msg, ...) const {}
   virtual void info(const char* msg, Exception* ex, ...) const {}
+  virtual void notice(const char* msg, ...) const {}
+  virtual void notice(const char* msg, Exception* ex, ...) const {}
   virtual void warn(const char* msg, ...) const {}
   virtual void warn(const char* msg, Exception* ex, ...) const {}
   virtual void error(const char*  msg, ...) const {}

+ 9 - 0
src/Option.cc

@@ -69,3 +69,12 @@ bool Option::getAsBool(const string& name) const {
     return false;
   }
 }
+
+double Option::getAsDouble(const string& name) const {
+  string value = get(name);
+  if(value == "") {
+    return 0.0;
+  } else {
+    return strtod(value.c_str(), 0);
+  }
+}

+ 1 - 0
src/Option.h

@@ -41,6 +41,7 @@ public:
   int getAsInt(const string& name) const;
   long long int getAsLLInt(const string& name) const;
   bool getAsBool(const string& name) const;
+  double getAsDouble(const string& name) const;
 };
 
 #endif // _D_OPTION_H_

+ 47 - 0
src/SeedCheckCommand.cc

@@ -0,0 +1,47 @@
+/* <!-- 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 "SeedCheckCommand.h"
+
+bool SeedCheckCommand::execute() {
+  if(e->torrentMan->isHalt()) {
+    return true;
+  }
+  if(!seedCriteria.get()) {
+    return false;
+  }
+  if(checkPoint.elapsed(1)) {
+    if(!checkStarted) {
+      if(e->torrentMan->downloadComplete()) {
+	checkStarted = true;
+	seedCriteria->reset();
+      }
+    }
+    if(checkStarted) {
+      if(seedCriteria->evaluate()) {
+	logger->notice("CUID#%d - Seeding is over.", cuid);
+	e->torrentMan->setHalt(true);
+      }
+    }
+  }
+  e->commands.push_back(this);
+  return false;
+}

+ 53 - 0
src/SeedCheckCommand.h

@@ -0,0 +1,53 @@
+/* <!-- 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_SEED_CHECK_COMMAND_H_
+#define _D_SEED_CHECK_COMMAND_H_
+
+#include "Command.h"
+#include "TorrentDownloadEngine.h"
+#include "TimeA2.h"
+#include "SeedCriteria.h"
+
+class SeedCheckCommand : public Command {
+private:
+  TorrentDownloadEngine* e;
+  Time checkPoint;
+  SeedCriteriaHandle seedCriteria;
+  bool checkStarted;
+public:
+  SeedCheckCommand(int cuid, TorrentDownloadEngine* e,
+		   SeedCriteriaHandle seedCriteria)
+    :Command(cuid),
+     e(e),
+     seedCriteria(seedCriteria),
+     checkStarted(false) {}
+
+  virtual ~SeedCheckCommand() {}
+
+  virtual bool execute();
+
+  void setSeedCriteria(SeedCriteriaHandle seedCriteria) {
+    this->seedCriteria = seedCriteria;
+  }
+};
+
+#endif // _D_SEED_CHECK_COMMAND_H_

+ 47 - 0
src/SeedCriteria.h

@@ -0,0 +1,47 @@
+/* <!-- 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_SEED_CRITERIA_H_
+#define _D_SEED_CRITERIA_H_
+
+#include "common.h"
+#include "SharedHandle.h"
+
+class SeedCriteria {
+public:
+  virtual ~SeedCriteria() {}
+
+  /**
+   * Returns true if criteria is met.
+   */
+  virtual bool evaluate() = 0;
+
+  /**
+   * Used for reseting status.
+   */
+  virtual void reset() = 0;
+};
+
+typedef SharedHandle<SeedCriteria> SeedCriteriaHandle;
+
+typedef deque<SeedCriteriaHandle> SeedCriterion;
+
+#endif // _D_SEED_CRITERIA_H_

+ 57 - 0
src/ShareRatioSeedCriteria.h

@@ -0,0 +1,57 @@
+/* <!-- 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_SHARE_RATIO_SEED_CRITERIA_H_
+#define _D_SHARE_RATIO_SEED_CRITERIA_H_
+
+#include "SeedCriteria.h"
+#include "TorrentMan.h"
+
+class ShareRatioSeedCriteria : public SeedCriteria {
+private:
+  double ratio;
+  TorrentMan* torrentMan;
+public:
+  ShareRatioSeedCriteria(double ratio, TorrentMan* torrentMan)
+    :ratio(ratio),
+     torrentMan(torrentMan) {}
+  virtual ~ShareRatioSeedCriteria() {}
+
+  virtual void reset() {}
+
+  virtual bool evaluate() {
+    if(torrentMan->getDownloadLength() == 0) {
+      return false;
+    }
+    return ratio <=
+      ((double)torrentMan->getUploadLength())/torrentMan->getDownloadLength();
+  }
+
+  void setRatio(double ratio) {
+    this->ratio = ratio;
+  }
+
+  double getRatio() const {
+    return ratio;
+  }
+};
+
+#endif // _D_SHARE_RATIO_SEED_CRITERIA_H_

+ 12 - 5
src/SharedHandle.h

@@ -47,7 +47,9 @@ private:
 public:
   SharedHandle():obj(new T()), ucount(new int(1)) {}
   SharedHandle(T* obj):obj(obj), ucount(new int(1)) {}
-  SharedHandle(const SharedHandle<T>& t):obj(t.obj), ucount(t.ucount) {
+
+  template<class S>
+  SharedHandle(const SharedHandle<S>& t):obj(t.get()), ucount(t.getRefCount()) {
     ++*ucount;
   }
 
@@ -58,14 +60,15 @@ public:
     }
   }
 
-  SharedHandle<T>& operator=(const SharedHandle<T>& t) {
-    ++*t.ucount;
+  template<class S>
+  SharedHandle<T>& operator=(const SharedHandle<S>& t) {
+    ++*t.getRefCount();
     if(--*ucount == 0) {
       delete obj;
       delete ucount;
     }
-    obj = t.obj;
-    ucount = t.ucount;
+    obj = t.get();
+    ucount = t.getRefCount();
     return *this;
   }
 
@@ -76,6 +79,10 @@ public:
   T* get() const {
     return obj;
   }
+
+  int* getRefCount() const {
+    return ucount;
+  }
 };
 
 template<class T>

+ 34 - 11
src/SimpleLogger.cc

@@ -31,20 +31,16 @@
 #define WRITE_LOG(LEVEL, MSG) \
 va_list ap;\
 va_start(ap, MSG);\
-writeLog(Logger::LEVEL, MSG, ap);\
+writeFile(Logger::LEVEL, MSG, ap);\
 va_end(ap);
 
 #define WRITE_LOG_EX(LEVEL, MSG, EX) \
 va_list ap;\
 va_start(ap, EX);\
-writeLog(Logger::LEVEL, MSG, ap, EX);\
+writeFile(Logger::LEVEL, MSG, ap, EX);\
 va_end(ap);
 
-SimpleLogger::SimpleLogger():file(NULL) {}
-
-SimpleLogger::SimpleLogger(FILE* logfile) {
-  file = logfile;
-}
+SimpleLogger::SimpleLogger(FILE* logfile):file(logfile), stdoutField(0) {}
 
 SimpleLogger::~SimpleLogger() {
   closeFile();
@@ -63,17 +59,28 @@ void SimpleLogger::closeFile() {
   }
 }
 
-void SimpleLogger::writeHeader(string date, string level) const {
+void SimpleLogger::setStdout(int level, bool enabled) {
+  if(enabled) {
+    stdoutField |= level;
+  } else {
+    stdoutField &= ~level;
+  }
+}
+
+void SimpleLogger::writeHeader(FILE* file, string date, string level) const {
   fprintf(file, "%s - %s - ", date.c_str(), level.c_str());
 }
 
-void SimpleLogger::writeLog(int level, const char* msg, va_list ap, Exception* e) const
+void SimpleLogger::writeLog(FILE* file, int level, const char* msg, va_list ap, Exception* e) const
 {
   string levelStr;
   switch(level) {
   case Logger::DEBUG:
     levelStr = "DEBUG";
     break;
+  case Logger::NOTICE:
+    levelStr = "NOTICE";
+    break;
   case Logger::WARN:
     levelStr = "WARN";
     break;
@@ -88,15 +95,23 @@ void SimpleLogger::writeLog(int level, const char* msg, va_list ap, Exception* e
   char datestr[26];
   ctime_r(&now, datestr);
   datestr[strlen(datestr)-1] = '\0';
-  writeHeader(datestr, levelStr);
+  writeHeader(file, datestr, levelStr);
   vfprintf(file, string(Util::replace(msg, "\r", "")+"\n").c_str(), ap);
   if(e != NULL) {
-    writeHeader(datestr, levelStr);
+    writeHeader(file, datestr, levelStr);
     fprintf(file, "exception: %s\n", Util::replace(e->getMsg(), "\r", "").c_str());
   }
   fflush(file);
 }
 
+void SimpleLogger::writeFile(int level, const char* msg, va_list ap, Exception* e) const {
+  writeLog(file, level, msg, ap, e);
+  if(stdoutField&level) {
+    fprintf(stdout, "\n");
+    writeLog(stdout, level, msg, ap, e);
+  }
+}
+
 void SimpleLogger::debug(const char* msg, ...) const {
   WRITE_LOG(DEBUG, msg);
 }
@@ -113,6 +128,14 @@ void SimpleLogger::info(const char* msg, Exception* e, ...) const {
   WRITE_LOG_EX(INFO, msg, e);
 }
 
+void SimpleLogger::notice(const char* msg, ...) const {
+  WRITE_LOG(NOTICE, msg);
+}
+
+void SimpleLogger::notice(const char* msg, Exception* e, ...) const {
+  WRITE_LOG_EX(INFO, msg, e);
+}
+
 void SimpleLogger::warn(const char* msg, ...) const {
   WRITE_LOG(WARN, msg);
 }

+ 17 - 12
src/SimpleLogger.h

@@ -26,24 +26,29 @@
 
 class SimpleLogger:public Logger {
 private:
-  void writeHeader(string date, string level) const;
-  void writeLog(int level, const char* msg, va_list ap, Exception* e = NULL) const;
+  void writeFile(int level, const char* msg, va_list ap, Exception* e = 0) const;
+  void writeHeader(FILE* file, string date, string level) const;
+  void writeLog(FILE* file, int level, const char* msg, va_list ap, Exception* e = 0) const;
   FILE* file;
+  int stdoutField;
 public:
-  SimpleLogger();
-  SimpleLogger(FILE* logfile);
+  SimpleLogger(FILE* logfile = 0);
   ~SimpleLogger();
 
   void openFile(const string& filename);
   void closeFile();
-  void debug(const char* msg, ...) const;
-  void debug(const char* msg, Exception* ex, ...) const;
-  void info(const char* msg, ...) const;
-  void info(const char* msg, Exception* ex, ...) const;
-  void warn(const char* msg, ...) const;
-  void warn(const char* msg, Exception* ex, ...) const;
-  void error(const char* msg, ...) const;
-  void error(const char* msg, Exception* ex, ...) const;
+  virtual void debug(const char* msg, ...) const;
+  virtual void debug(const char* msg, Exception* ex, ...) const;
+  virtual void info(const char* msg, ...) const;
+  virtual void info(const char* msg, Exception* ex, ...) const;
+  virtual void notice(const char* msg, ...) const;
+  virtual void notice(const char* msg, Exception* ex, ...) const;
+  virtual void warn(const char* msg, ...) const;
+  virtual void warn(const char* msg, Exception* ex, ...) const;
+  virtual void error(const char* msg, ...) const;
+  virtual void error(const char* msg, Exception* ex, ...) const;
+
+  void setStdout(int level, bool enabled);
 };
 
 #endif // _D_SIMPLE_LOGGER_H_

+ 54 - 0
src/TimeSeedCriteria.h

@@ -0,0 +1,54 @@
+/* <!-- 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_TIME_SEED_CRITERIA_H_
+#define _D_TIME_SEED_CRITERIA_H_
+
+#include "SeedCriteria.h"
+#include "TimeA2.h"
+
+class TimeSeedCriteria : public SeedCriteria {
+private:
+  // How much time the client does seeding in seconds.
+  int duration;
+  Time watch;
+public:
+  TimeSeedCriteria(int duration):duration(duration) {}
+  virtual ~TimeSeedCriteria() {}
+
+  virtual void reset() {
+    watch.reset();
+  }
+
+  virtual bool evaluate() {
+    return watch.elapsed(duration);
+  }
+
+  void setDuration(int duration) {
+    this->duration = duration;
+  }
+
+  int getDuration() const {
+    return duration;
+  }
+};
+
+#endif // _D_TIME_SEED_CRITERIA_H_

+ 0 - 5
src/TorrentConsoleDownloadEngine.cc

@@ -26,11 +26,6 @@ TorrentConsoleDownloadEngine::TorrentConsoleDownloadEngine() {}
 
 TorrentConsoleDownloadEngine::~TorrentConsoleDownloadEngine() {}
 
-void TorrentConsoleDownloadEngine::onSelectiveDownloadingCompletes() {
-  printf("\nDownload of selected files has completed.\n");
-  fflush(stdout);
-}
-
 void TorrentConsoleDownloadEngine::sendStatistics() {
   printf("\r                                                                             ");
   printf("\r");

+ 0 - 1
src/TorrentConsoleDownloadEngine.h

@@ -27,7 +27,6 @@
 class TorrentConsoleDownloadEngine : public TorrentDownloadEngine {
 protected:
   virtual void sendStatistics();
-  void onSelectiveDownloadingCompletes();
 public:
   TorrentConsoleDownloadEngine();
   ~TorrentConsoleDownloadEngine();

+ 1 - 14
src/TorrentDownloadEngine.cc

@@ -33,26 +33,13 @@ TorrentDownloadEngine::~TorrentDownloadEngine() {
 
 void TorrentDownloadEngine::onEndOfRun() {
   torrentMan->diskAdaptor->closeFile();
-  if(filenameFixed && torrentMan->downloadComplete()) {
+  if(torrentMan->downloadComplete()) {
     torrentMan->remove();
   } else {
     torrentMan->save();
   }
 }
 
-void TorrentDownloadEngine::afterEachIteration() {
-  if(!filenameFixed && torrentMan->downloadComplete()) {
-    if(torrentMan->isSelectiveDownloadingMode()) {
-      onSelectiveDownloadingCompletes();
-    }
-    logger->info("The download was complete.");
-    torrentMan->onDownloadComplete();
-    if(torrentMan->downloadComplete()) {
-      filenameFixed = true;
-    }
-  }
-}
-
 void TorrentDownloadEngine::initStatistics() {
   downloadSpeed = 0;
   uploadSpeed = 0;

+ 1 - 3
src/TorrentDownloadEngine.h

@@ -55,9 +55,7 @@ protected:
   long long int totalLength;
 
   int calculateSpeed(long long int sessionLength, int elapsed);
-  void onEndOfRun();
-  void afterEachIteration();
-  virtual void onSelectiveDownloadingCompletes() = 0;
+  virtual void onEndOfRun();
   virtual void sendStatistics() = 0;
 public:
   TorrentDownloadEngine();

+ 11 - 2
src/TorrentMan.cc

@@ -277,12 +277,18 @@ void TorrentMan::completePiece(const Piece& piece) {
   if(!hasPiece(piece.getIndex())) {
     addDownloadLength(piece.getLength());
   }
-  bitfield->setBit(piece.getIndex());
-  bitfield->unsetUseBit(piece.getIndex());
   deleteUsedPiece(piece);
   if(!isEndGame()) {
     reduceUsedPieces(100);
   }
+  if(downloadComplete()) {
+    return;
+  }
+  bitfield->setBit(piece.getIndex());
+  bitfield->unsetUseBit(piece.getIndex());
+  if(downloadComplete()) {
+    onDownloadComplete();
+  }
 }
 
 void TorrentMan::cancelPiece(const Piece& piece) {
@@ -647,7 +653,10 @@ void TorrentMan::onDownloadComplete() {
   save();
   diskAdaptor->onDownloadComplete();
   if(isSelectiveDownloadingMode()) {
+    logger->notice("Download of selected files has completed.");
     finishSelectiveDownloadingMode();
+  } else {
+    logger->info("The download has completed.");
   }
 }
 

+ 11 - 1
src/TorrentMan.h

@@ -151,7 +151,17 @@ public:
   void syncPiece(Piece& piece);
   bool hasPiece(int index) const;
   void initBitfield();
+  /**
+   * Returns true if the number of missing block is less than or equal to
+   * END_GAME_PIECE_NUM.
+   * If file filter is enabled, only a range specified by the filter is
+   * concerned.
+   */
   bool isEndGame() const;
+  /**
+   * Returns true if download has completed. If file filter is enabled,
+   * returns true if download of a range specified by the filter has completed.
+   */
   bool downloadComplete() const;
   bool hasAllPieces() const;
   void setBitfield(unsigned char* bitfield, int len);
@@ -176,7 +186,7 @@ public:
 
   string getPieceHash(int index) const;
 
-  // Addes piece index to advertise to other commands. They send have message
+  // Adds piece index to advertise to other commands. They send have message
   // based on this information.
   void advertisePiece(int cuid, int index);
 

+ 3 - 0
src/TrackerUpdateCommand.cc

@@ -66,6 +66,9 @@ char* TrackerUpdateCommand::getTrackerResponse(int& trackerResponseLength) {
 }
 
 bool TrackerUpdateCommand::execute() {
+  if(e->segmentMan->errors > 0 && e->torrentMan->isHalt()) {
+    return true;
+  }
   if(!e->segmentMan->finished()) {
     return prepareForRetry();
   }

+ 4 - 0
src/TrackerWatcherCommand.cc

@@ -37,6 +37,9 @@ TrackerWatcherCommand::~TrackerWatcherCommand() {}
 
 bool TrackerWatcherCommand::execute() {
   if(e->segmentMan->errors > 0) {
+    if(e->torrentMan->isHalt()) {
+      return true;
+    }
     // we assume the tracker request has failed.
     e->torrentMan->trackers = 0;
     e->segmentMan->init();
@@ -62,6 +65,7 @@ bool TrackerWatcherCommand::execute() {
 	e->torrentMan->req->setTrackerEvent(Request::AFTER_COMPLETED);
       } else {
 	if(e->torrentMan->req->getTrackerEvent() == Request::STARTED) {
+	  // in case where download had completed when aria2c started.
 	  e->torrentMan->req->setTrackerEvent(Request::AFTER_COMPLETED);
 	} else if(e->torrentMan->req->getTrackerEvent() != Request::AFTER_COMPLETED) {
 	  e->torrentMan->req->setTrackerEvent(Request::COMPLETED);

+ 69 - 0
src/UnionSeedCriteria.h

@@ -0,0 +1,69 @@
+/* <!-- 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_UNION_SEED_CRITERIA_H_
+#define _D_UNION_SEED_CRITERIA_H_
+
+#include "SeedCriteria.h"
+
+class UnionSeedCriteria : public SeedCriteria {
+private:
+  SeedCriterion criterion;
+
+  class Reset {
+  public:
+    void operator()(SeedCriteriaHandle cri) {
+      cri->reset();
+    }
+  };
+
+  class Eval {
+  public:
+    bool operator()(SeedCriteriaHandle cri) {
+      return cri->evaluate();
+    }
+  };
+public:
+  UnionSeedCriteria() {}
+  virtual ~UnionSeedCriteria() {}
+
+    
+  virtual void reset() {
+    for_each(criterion.begin(), criterion.end(), Reset());
+  }
+
+  virtual bool evaluate() {
+    SeedCriterion::iterator itr = find_if(criterion.begin(),
+					  criterion.end(),
+					  Eval());
+    return itr != criterion.end();
+  }
+
+  void addSeedCriteria(SeedCriteriaHandle cri) {
+    criterion.push_back(cri);
+  }
+
+  const SeedCriterion& getSeedCriterion() const {
+    return criterion;
+  }
+};
+      
+#endif // _D_UNION_SEED_CRITERIA_H_

+ 30 - 0
src/main.cc

@@ -175,6 +175,12 @@ void showUsage() {
 	    "                              ',' like \"3,6\".\n"
 	    "                              You can also use '-' to specify rangelike \"1-5\".\n"
 	    "                              ',' and '-' can be used together.") << endl;
+  cout << _(" --seed-time=MINUTES          Specify seeding time in minutes. See also\n"
+	    "                              --seed-ratio option.") << endl;
+  cout << _(" --seed-ratio=RATIO           Specify seed share ratio. 1.0 is encouraged.\n"
+	    "                              If --seed-time option is specified along with\n"
+	    "                              this option, seeding ends when at least one of\n"
+	    "                              the condition is met.") << endl;
 #endif // ENABLE_BITTORRENT
 #ifdef ENABLE_METALINK
   cout << _(" -M, --metalink-file=METALINK_FILE The file path to .metalink file.") << endl;
@@ -332,6 +338,8 @@ int main(int argc, char* argv[]) {
       { "direct-file-mapping", required_argument, &lopt, 19 },
       { "upload-limit", required_argument, &lopt, 20 },
       { "select-file", required_argument, &lopt, 21 },
+      { "seed-time", required_argument, &lopt, 22 },
+      { "seed-ratio", required_argument, &lopt, 23 },
 #endif // ENABLE_BITTORRENT
 #ifdef ENABLE_METALINK
       { "metalink-file", required_argument, NULL, 'M' },
@@ -492,6 +500,26 @@ int main(int argc, char* argv[]) {
       case 21:
 	op->put(PREF_SELECT_FILE, optarg);
 	break;
+      case 22: {
+	int seedTime = (int)strtol(optarg, NULL, 10);
+	if(seedTime < 0) {
+	  cerr << _("seed-time must be greater than or equal to 0.") << endl;
+	  showUsage();
+	  exit(EXIT_FAILURE);
+	}
+	op->put(PREF_SEED_TIME, Util::itos(seedTime));
+	break;
+      }
+      case 23: {
+	double ratio = (int)strtod(optarg, NULL);
+	if(ratio < 0.0) {
+	  cerr << _("seed-ratio must be greater than or equal to 0.0.") << endl;
+	  showUsage();
+	  exit(EXIT_FAILURE);
+	}
+	op->put(PREF_SEED_RATIO, optarg);
+	break;
+      }
       case 100:
 	op->put(PREF_METALINK_VERSION, optarg);
 	break;
@@ -637,6 +665,8 @@ int main(int argc, char* argv[]) {
     LogFactory::setLogFile("/dev/stdout");
   } else if(op->get(PREF_LOG).size()) {
     LogFactory::setLogFile(op->get(PREF_LOG));
+  } else {
+    LogFactory::setLogFile("/dev/null");
   }
   // make sure logger is configured properly.
   try {

+ 4 - 0
src/prefs.h

@@ -122,6 +122,10 @@
 #define PREF_FOLLOW_TORRENT "follow_torrent"
 // values: 1*digit *( (,|-) 1*digit)
 #define PREF_SELECT_FILE "select_file"
+// values: 1*digit
+#define PREF_SEED_TIME "seed_time"
+// values: 1*digit ['.' [ 1*digit ] ]
+#define PREF_SEED_RATIO "seed_ratio"
 
 /**
  * Metalink related preferences

+ 3 - 1
test/Makefile.am

@@ -35,7 +35,9 @@ aria2c_SOURCES = AllTest.cc\
 	Xml2MetalinkProcessorTest.cc\
 	MetalinkerTest.cc\
 	MetalinkEntryTest.cc\
-	FeatureConfigTest.cc
+	FeatureConfigTest.cc\
+	ShareRatioSeedCriteriaTest.cc\
+	TimeSeedCriteriaTest.cc
 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
 #aria2c_LDFLAGS = ${CPPUNIT_LIBS}
 

+ 8 - 2
test/Makefile.in

@@ -74,7 +74,9 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
 	RejectMessageTest.$(OBJEXT) AllowedFastMessageTest.$(OBJEXT) \
 	SuggestPieceMessageTest.$(OBJEXT) \
 	Xml2MetalinkProcessorTest.$(OBJEXT) MetalinkerTest.$(OBJEXT) \
-	MetalinkEntryTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT)
+	MetalinkEntryTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) \
+	ShareRatioSeedCriteriaTest.$(OBJEXT) \
+	TimeSeedCriteriaTest.$(OBJEXT)
 aria2c_OBJECTS = $(am_aria2c_OBJECTS)
 am__DEPENDENCIES_1 =
 aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@@ -263,7 +265,9 @@ aria2c_SOURCES = AllTest.cc\
 	Xml2MetalinkProcessorTest.cc\
 	MetalinkerTest.cc\
 	MetalinkEntryTest.cc\
-	FeatureConfigTest.cc
+	FeatureConfigTest.cc\
+	ShareRatioSeedCriteriaTest.cc\
+	TimeSeedCriteriaTest.cc
 
 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
 #aria2c_LDFLAGS = ${CPPUNIT_LIBS}
@@ -355,7 +359,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestMessageTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitorTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShareRatioSeedCriteriaTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessageTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentManTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessageTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@

+ 31 - 0
test/ShareRatioSeedCriteriaTest.cc

@@ -0,0 +1,31 @@
+#include "ShareRatioSeedCriteria.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class ShareRatioSeedCriteriaTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(ShareRatioSeedCriteriaTest);
+  CPPUNIT_TEST(testEvaluate);
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  void testEvaluate();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ShareRatioSeedCriteriaTest);
+
+void ShareRatioSeedCriteriaTest::testEvaluate() {
+  TorrentMan torrentMan;
+  torrentMan.setDownloadLength(4294967296LL);
+  torrentMan.setUploadLength(4294967296LL);
+
+  ShareRatioSeedCriteria cri(1.0, &torrentMan);
+  CPPUNIT_ASSERT(cri.evaluate());
+
+  cri.setRatio(2.0);
+  CPPUNIT_ASSERT(!cri.evaluate());
+  // check div by zero
+  torrentMan.setDownloadLength(0);
+  CPPUNIT_ASSERT(!cri.evaluate());
+}

+ 25 - 0
test/TimeSeedCriteriaTest.cc

@@ -0,0 +1,25 @@
+#include "TimeSeedCriteria.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class TimeSeedCriteriaTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(TimeSeedCriteriaTest);
+  CPPUNIT_TEST(testEvaluate);
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  void testEvaluate();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeedCriteriaTest);
+
+void TimeSeedCriteriaTest::testEvaluate() {
+  TimeSeedCriteria cri(1);
+  sleep(1);
+  CPPUNIT_ASSERT(cri.evaluate());
+  cri.reset();
+  cri.setDuration(10);
+  CPPUNIT_ASSERT(!cri.evaluate());
+}