2007-11-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Preallocate non-requested file which is adjacent forward to 
requested
	file('requested' files means the files given in --select-file 
option)
	if they share a same piece.
	This fixes long pause in the file system which doesn't support 
sparse
	files like FAT32 while downloading.
	* src/MultiFileAllocationIterator.{h, cc}
	* test/MultiFileAllocationIteratorTest.cc
	* src/FileEntry.{h, cc}

	Removed unused _option.
	* src/MultiDiskAdaptor.h
	* test/MultiDiskAdaptorTest.cc
	* src/DefaultPieceStorage.cc

	Set the default value of --seed-ratio to 1.0.
	If 0.0 is given, then seeding continues regardless of share 
ratio.
	* src/version_usage.cc
	* src/option_processing.cc
	* src/BtSetup.cc
	* doc/aria2c.1.txt
	* doc/aria2c.1

	Fixed: Selective download is not working in BitTorrent
	* src/RequestGroup.cc

	Introduced Sequence class. Use this instead of 
Util::unfoldRange()
	* src/PieceStorage.h
	* test/MockPieceStorage.h
	* src/UnknownLengthPieceStorage.h
	* src/DefaultPieceStorage.{h, cc}
	* src/Metalink2RequestGroup.cc
	* src/RequestGroup.cc
	* src/Sequence.h
	* test/SequenceTest.cc
	* src/IntSequence.h
	* src/message.h
	* src/Util.{h, cc}
	* test/UtilTest.cc

	Added new function 'parse' to catch exception thrown by 
subclass's
	parseArg
	* src/OptionHandler.h
	* src/OptionParser.cc
	* src/NameMatchOptionHandler.h
	* src/OptionHandlerImpl.h
	* test/OptionHandlerTest.cc

	Added IntegerRangeOptionHandler. Used for --listen-port and
	--select-file. Now --listen-port accepts range of port.
	* src/OptionHandlerFactory.cc
	* src/version_usage.cc
	* src/OptionHandlerImpl.h
	* src/option_processing.cc
	* src/BtSetup.cc
	* src/PeerListenCommand.{h, cc}
	* doc/aria2c.1.txt
	* doc/aria2c.1
	
	Implemented operator< for Exception class to provide easy way to 
print
	exception stack trace.
	* src/Exception.{h, cc}
	* src/main.cc
	* src/option_processing.cc
pull/1/head
Tatsuhiro Tsujikawa 2007-11-21 16:14:40 +00:00
parent 59fb4066fb
commit c9e3d51054
46 changed files with 873 additions and 211 deletions

View File

@ -1,3 +1,69 @@
2007-11-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Preallocate non-requested file which is adjacent forward to requested
file('requested' files means the files given in --select-file option)
if they share a same piece.
This fixes long pause in the file system which doesn't support sparse
files like FAT32 while downloading.
* src/MultiFileAllocationIterator.{h, cc}
* test/MultiFileAllocationIteratorTest.cc
* src/FileEntry.{h, cc}
Removed unused _option.
* src/MultiDiskAdaptor.h
* test/MultiDiskAdaptorTest.cc
* src/DefaultPieceStorage.cc
Set the default value of --seed-ratio to 1.0.
If 0.0 is given, then seeding continues regardless of share ratio.
* src/version_usage.cc
* src/option_processing.cc
* src/BtSetup.cc
* doc/aria2c.1.txt
* doc/aria2c.1
Fixed: Selective download is not working in BitTorrent
* src/RequestGroup.cc
Introduced Sequence class. Use this instead of Util::unfoldRange()
* src/PieceStorage.h
* test/MockPieceStorage.h
* src/UnknownLengthPieceStorage.h
* src/DefaultPieceStorage.{h, cc}
* src/Metalink2RequestGroup.cc
* src/RequestGroup.cc
* src/Sequence.h
* test/SequenceTest.cc
* src/IntSequence.h
* src/message.h
* src/Util.{h, cc}
* test/UtilTest.cc
Added new function 'parse' to catch exception thrown by subclass's
parseArg
* src/OptionHandler.h
* src/OptionParser.cc
* src/NameMatchOptionHandler.h
* src/OptionHandlerImpl.h
* test/OptionHandlerTest.cc
Added IntegerRangeOptionHandler. Used for --listen-port and
--select-file. Now --listen-port accepts range of port.
* src/OptionHandlerFactory.cc
* src/version_usage.cc
* src/OptionHandlerImpl.h
* src/option_processing.cc
* src/BtSetup.cc
* src/PeerListenCommand.{h, cc}
* doc/aria2c.1.txt
* doc/aria2c.1
Implemented operator< for Exception class to provide easy way to print
exception stack trace.
* src/Exception.{h, cc}
* src/main.cc
* src/option_processing.cc
2007-11-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/version_usage.cc

3
TODO
View File

@ -4,7 +4,6 @@
* Add SSL client cert support
* Better HTTP status handling
* Add the feature which adds or removes URLs on-the-fly.
* Add port range command-line option
* Add max peers command-line option
* Refacturing HttpConnection and FtpConnection
* Query resource by location
@ -57,3 +56,5 @@
-- remaining issues to be implemented for 0.12.0 release
* Update translation
* replace strtol with Util::parseInt
* precision of share ratio

View File

@ -1,11 +1,11 @@
.\" Title: aria2c
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/>
.\" Date: 11/18/2007
.\" Date: 11/22/2007
.\" Manual:
.\" Source:
.\"
.TH "ARIA2C" "1" "11/18/2007" "" ""
.TH "ARIA2C" "1" "11/22/2007" "" ""
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@ -319,6 +319,15 @@ to specify a range: "1\-5"\.
and
\fI\-\fR
can be used together\. When used with the \-M option, index may vary depending on the query(see \-\-metalink\-* options)\.
.sp
.RS 4
.nf
Note: In multi file torrent, it seems that adjacent files specified
by this option are downloaded\. This is by design, not a bug\.
A single piece may include several files or part of files,
and aria2 writes the piece to the appropriate files\.
.fi
.RE
.RE
.PP
\-T, \-\-torrent\-file=TORRENT_FILE
@ -335,11 +344,18 @@ Set to false to prevent aria2 from entering BitTorrent mode even if the filename
.RS 4
Directly read from and write to each file mentioned in \.torrent file\. Default:
\fItrue\fR
.RE
.PP
\-\-listen\-port=PORT
.sp
.RS 4
Set TCP port number for BitTorrent downloads\. Default: 6881\-6999
.nf
\-\-listen\-port=PORT\.\.\.
Set TCP port number for BitTorrent downloads\.
Multiple values can be specified by using \',\',
for example: "6881,6885"\.
You can also use \'\-\' to specify a range: "6881\-6999"\.
\',\' and \'\-\' can be used together\.
Default: 6881\-6999
.fi
.RE
.RE
.PP
\-\-max\-upload\-limit=SPEED
@ -360,7 +376,7 @@ Specify seeding time in minutes\. Also see the \-\-seed\-ratio option\.
.PP
\-\-seed\-ratio=RATIO
.RS 4
Specify share ratio\. Seed completed torrents until share ratio reaches RATIO\. 1\.0 is encouraged\. If \-\-seed\-time option is specified along with this option, seeding ends when at least one of the conditions is satisfied\.
Specify share ratio\. Seed completed torrents until share ratio reaches RATIO\. 1\.0 is encouraged\. Specify 0\.0 if you intend to do seeding regardless of share ratio\. If \-\-seed\-time option is specified along with this option, seeding ends when at least one of the conditions is satisfied\. Default: 1\.0
.RE
.PP
\-\-peer\-id\-prefix=PEERI_ID_PREFIX

View File

@ -229,14 +229,19 @@ http://host/image[000-100:2].img
and exit.
--select-file=INDEX...::
Set file to download by specifing its index.
You can find the file index using the
--show-files option. Multiple indexes can be
specified by using ',', for example: "3,6".
You can also use '-' to specify a range: "1-5".
',' and '-' can be used together.
When used with the -M option, index may vary
depending on the query(see --metalink-* options).
Set file to download by specifing its index.
You can find the file index using the
--show-files option. Multiple indexes can be
specified by using ',', for example: "3,6".
You can also use '-' to specify a range: "1-5".
',' and '-' can be used together.
When used with the -M option, index may vary
depending on the query(see --metalink-* options).
Note: In multi file torrent, it seems that adjacent files specified
by this option are downloaded. This is by design, not a bug.
A single piece may include several files or part of files,
and aria2 writes the piece to the appropriate files.
-T, --torrent-file=TORRENT_FILE::
The path to the .torrent file.
@ -252,9 +257,13 @@ http://host/image[000-100:2].img
mentioned in .torrent file.
Default: 'true'
--listen-port=PORT::
Set TCP port number for BitTorrent downloads.
Default: 6881-6999
--listen-port=PORT...
Set TCP port number for BitTorrent downloads.
Multiple values can be specified by using ',',
for example: "6881,6885".
You can also use '-' to specify a range: "6881-6999".
',' and '-' can be used together.
Default: 6881-6999
--max-upload-limit=SPEED::
Set max upload speed in bytes per sec.
@ -267,11 +276,14 @@ http://host/image[000-100:2].img
--seed-ratio option.
--seed-ratio=RATIO::
Specify share ratio. Seed completed torrents
until share ratio reaches RATIO. 1.0 is
encouraged. If --seed-time option is specified
along with this option, seeding ends when at
least one of the conditions is satisfied.
Specify share ratio. Seed completed torrents
until share ratio reaches RATIO. 1.0 is
encouraged. Specify 0.0 if you intend to do
seeding regardless of share ratio.
If --seed-time option is specified along with
this option, seeding ends when at least one of
the conditions is satisfied.
Default: 1.0
--peer-id-prefix=PEERI_ID_PREFIX::
Specify the prefix of peer ID. The peer ID in

View File

@ -53,6 +53,7 @@
#include "LogFactory.h"
#include "Logger.h"
#include "Util.h"
#include "IntSequence.h"
BtSetup::BtSetup():_logger(LogFactory::getInstance()) {}
@ -85,9 +86,12 @@ Commands BtSetup::setup(RequestGroup* requestGroup,
if(option->defined(PREF_SEED_TIME)) {
unionCri->addSeedCriteria(new TimeSeedCriteria(option->getAsInt(PREF_SEED_TIME)*60));
}
if(option->defined(PREF_SEED_RATIO)) {
unionCri->addSeedCriteria(new ShareRatioSeedCriteria(option->getAsDouble(PREF_SEED_RATIO), btContext));
}
{
double ratio = option->getAsDouble(PREF_SEED_RATIO);
if(ratio > 0.0) {
unionCri->addSeedCriteria(new ShareRatioSeedCriteria(option->getAsDouble(PREF_SEED_RATIO), btContext));
}
}
if(unionCri->getSeedCriterion().size() > 0) {
commands.push_back(new SeedCheckCommand(CUIDCounterSingletonHolder::instance()->newID(),
requestGroup,
@ -98,13 +102,8 @@ Commands BtSetup::setup(RequestGroup* requestGroup,
if(PeerListenCommand::getNumInstance() == 0) {
PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e);
int32_t port;
int32_t listenPort = option->getAsInt(PREF_LISTEN_PORT);
if(listenPort == -1) {
port = listenCommand->bindPort(6881, 6999);
} else {
port = listenCommand->bindPort(listenPort, listenPort);
}
IntSequence seq = Util::parseIntRange(option->get(PREF_LISTEN_PORT));
int32_t port = listenCommand->bindPort(seq);
if(port == -1) {
_logger->error(_("Errors occurred while binding port.\n"));
delete listenCommand;

View File

@ -33,11 +33,6 @@
*/
/* copyright --> */
#include "DefaultDiskWriter.h"
#include "message.h"
#include "prefs.h"
#include "Util.h"
#include <errno.h>
#include <unistd.h>
DefaultDiskWriter::DefaultDiskWriter():AbstractDiskWriter() {}

View File

@ -391,8 +391,11 @@ void DefaultPieceStorage::setFileFilter(const Strings& filePaths)
bitfieldMan->enableFilter();
}
void DefaultPieceStorage::setFileFilter(const Integers& fileIndexes)
void DefaultPieceStorage::setFileFilter(IntSequence seq)
{
Integers fileIndexes = seq.flush();
sort(fileIndexes.begin(), fileIndexes.end());
fileIndexes.erase(unique(fileIndexes.begin(), fileIndexes.end()), fileIndexes.end());
Strings filePaths;
const FileEntries& entries = diskAdaptor->getFileEntries();
for(int32_t i = 0; i < (int32_t)entries.size(); i++) {
@ -441,7 +444,6 @@ void DefaultPieceStorage::initStorage()
MultiDiskAdaptorHandle multiDiskAdaptor = new MultiDiskAdaptor();
multiDiskAdaptor->setPieceLength(downloadContext->getPieceLength());
multiDiskAdaptor->setTopDir(downloadContext->getName());
multiDiskAdaptor->setOption(option);
this->diskAdaptor = multiDiskAdaptor;
} else {
logger->debug("Instantiating CopyDiskAdaptor");
@ -456,11 +458,7 @@ void DefaultPieceStorage::initStorage()
this->diskAdaptor = copyDiskAdaptor;
}
}
string storeDir = downloadContext->getDir();//option->get(PREF_DIR);
// if(storeDir == "") {
// storeDir = ".";
// }
diskAdaptor->setStoreDir(storeDir);
diskAdaptor->setStoreDir(downloadContext->getDir());
diskAdaptor->setFileEntries(downloadContext->getFileEntries());
}

View File

@ -128,7 +128,7 @@ public:
virtual void setFileFilter(const Strings& filePaths);
virtual void setFileFilter(const Integers& fileIndexes);
virtual void setFileFilter(IntSequence seq);
virtual void clearFileFilter();

View File

@ -47,9 +47,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <algorithm>
volatile sig_atomic_t globalHaltRequested;

44
src/Exception.cc Normal file
View File

@ -0,0 +1,44 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "Exception.h"
ostream& operator<<(ostream& o, const Exception& e)
{
o << e.getMsg() << "\n";
for(Exception* cause = e.getCause(); cause; cause = cause->getCause()) {
o << "Cause: " << cause->getMsg() << "\n";
}
return o;
}

View File

@ -63,6 +63,8 @@ public:
const string& getMsg() const { return msg; }
Exception* getCause() const { return cause; }
friend ostream& operator<<(ostream& o, const Exception& e);
};
#endif // _D_EXCEPTION_H_

View File

@ -62,3 +62,8 @@ FileEntry& FileEntry::operator=(const FileEntry& entry)
}
return *this;
}
bool FileEntry::operator<(const FileEntry& fileEntry) const
{
return offset < fileEntry.offset;
}

View File

@ -91,6 +91,8 @@ public:
{
return _uris;
}
bool operator<(const FileEntry& fileEntry) const;
};
typedef SharedHandle<FileEntry> FileEntryHandle;

42
src/IntSequence.h Normal file
View File

@ -0,0 +1,42 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_INT_SEQUENCE_H_
#define _D_INT_SEQUENCE_H_
#include "Sequence.h"
typedef Sequence<int32_t> IntSequence;
#endif // _D_INT_SEQUENCE_H_

View File

@ -32,7 +32,7 @@ SRCS = Socket.h\
Request.cc Request.h\
common.h\
message.h\
Exception.h\
Exception.cc Exception.h\
FatalException.h\
RecoverableException.h\
DlAbortEx.h\

View File

@ -202,29 +202,29 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
DownloadEngine.cc DownloadEngine.h Segment.h GrowSegment.cc \
GrowSegment.h PiecedSegment.cc PiecedSegment.h SegmentMan.cc \
SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \
message.h Exception.h FatalException.h RecoverableException.h \
DlAbortEx.h DlRetryEx.h Logger.h SimpleLogger.cc \
SimpleLogger.h TransferEncoding.h ChunkedEncoding.cc \
ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.h \
File.cc File.h Option.cc Option.h Base64.cc Base64.h \
CookieBox.cc CookieBox.h LogFactory.cc LogFactory.h \
NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
SpeedCalc.cc SpeedCalc.h PeerStat.h BitfieldMan.cc \
BitfieldMan.h BitfieldManFactory.cc BitfieldManFactory.h \
Randomizer.h SimpleRandomizer.cc SimpleRandomizer.h \
FileAllocator.h HttpResponse.cc HttpResponse.h HttpRequest.cc \
HttpRequest.h Range.h AbstractProxyRequestCommand.cc \
AbstractProxyRequestCommand.h AbstractProxyResponseCommand.cc \
AbstractProxyResponseCommand.h Netrc.cc Netrc.h AuthConfig.cc \
AuthConfig.h AuthResolver.h AbstractAuthResolver.h \
DefaultAuthResolver.cc DefaultAuthResolver.h \
NetrcAuthResolver.cc NetrcAuthResolver.h AuthConfigFactory.cc \
AuthConfigFactory.h OptionParser.cc OptionParser.h \
OptionHandlerFactory.cc OptionHandlerFactory.h NameResolver.cc \
NameResolver.h RequestGroup.cc RequestGroup.h \
message.h Exception.cc Exception.h FatalException.h \
RecoverableException.h DlAbortEx.h DlRetryEx.h Logger.h \
SimpleLogger.cc SimpleLogger.h TransferEncoding.h \
ChunkedEncoding.cc ChunkedEncoding.h DiskWriter.h \
AbstractDiskWriter.cc AbstractDiskWriter.h \
DefaultDiskWriter.cc DefaultDiskWriter.h File.cc File.h \
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \
LogFactory.cc LogFactory.h NullLogger.h TimeA2.cc TimeA2.h \
SharedHandle.h HandleRegistry.h FeatureConfig.cc \
FeatureConfig.h DownloadEngineFactory.cc \
DownloadEngineFactory.h RequestInfo.h SpeedCalc.cc SpeedCalc.h \
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
SimpleRandomizer.h FileAllocator.h HttpResponse.cc \
HttpResponse.h HttpRequest.cc HttpRequest.h Range.h \
AbstractProxyRequestCommand.cc AbstractProxyRequestCommand.h \
AbstractProxyResponseCommand.cc AbstractProxyResponseCommand.h \
Netrc.cc Netrc.h AuthConfig.cc AuthConfig.h AuthResolver.h \
AbstractAuthResolver.h DefaultAuthResolver.cc \
DefaultAuthResolver.h NetrcAuthResolver.cc NetrcAuthResolver.h \
AuthConfigFactory.cc AuthConfigFactory.h OptionParser.cc \
OptionParser.h OptionHandlerFactory.cc OptionHandlerFactory.h \
NameResolver.cc NameResolver.h RequestGroup.cc RequestGroup.h \
RequestGroupAware.cc RequestGroupAware.h RequestGroupMan.cc \
RequestGroupMan.h FileAllocationMan.cc FileAllocationMan.h \
FileAllocationCommand.cc FileAllocationCommand.h \
@ -433,7 +433,7 @@ am__objects_12 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
FtpTunnelResponseCommand.$(OBJEXT) SleepCommand.$(OBJEXT) \
DownloadEngine.$(OBJEXT) GrowSegment.$(OBJEXT) \
PiecedSegment.$(OBJEXT) SegmentMan.$(OBJEXT) Util.$(OBJEXT) \
Request.$(OBJEXT) SimpleLogger.$(OBJEXT) \
Request.$(OBJEXT) Exception.$(OBJEXT) SimpleLogger.$(OBJEXT) \
ChunkedEncoding.$(OBJEXT) AbstractDiskWriter.$(OBJEXT) \
DefaultDiskWriter.$(OBJEXT) File.$(OBJEXT) Option.$(OBJEXT) \
Base64.$(OBJEXT) CookieBox.$(OBJEXT) LogFactory.$(OBJEXT) \
@ -694,29 +694,29 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
DownloadEngine.cc DownloadEngine.h Segment.h GrowSegment.cc \
GrowSegment.h PiecedSegment.cc PiecedSegment.h SegmentMan.cc \
SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \
message.h Exception.h FatalException.h RecoverableException.h \
DlAbortEx.h DlRetryEx.h Logger.h SimpleLogger.cc \
SimpleLogger.h TransferEncoding.h ChunkedEncoding.cc \
ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.h \
File.cc File.h Option.cc Option.h Base64.cc Base64.h \
CookieBox.cc CookieBox.h LogFactory.cc LogFactory.h \
NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
SpeedCalc.cc SpeedCalc.h PeerStat.h BitfieldMan.cc \
BitfieldMan.h BitfieldManFactory.cc BitfieldManFactory.h \
Randomizer.h SimpleRandomizer.cc SimpleRandomizer.h \
FileAllocator.h HttpResponse.cc HttpResponse.h HttpRequest.cc \
HttpRequest.h Range.h AbstractProxyRequestCommand.cc \
AbstractProxyRequestCommand.h AbstractProxyResponseCommand.cc \
AbstractProxyResponseCommand.h Netrc.cc Netrc.h AuthConfig.cc \
AuthConfig.h AuthResolver.h AbstractAuthResolver.h \
DefaultAuthResolver.cc DefaultAuthResolver.h \
NetrcAuthResolver.cc NetrcAuthResolver.h AuthConfigFactory.cc \
AuthConfigFactory.h OptionParser.cc OptionParser.h \
OptionHandlerFactory.cc OptionHandlerFactory.h NameResolver.cc \
NameResolver.h RequestGroup.cc RequestGroup.h \
message.h Exception.cc Exception.h FatalException.h \
RecoverableException.h DlAbortEx.h DlRetryEx.h Logger.h \
SimpleLogger.cc SimpleLogger.h TransferEncoding.h \
ChunkedEncoding.cc ChunkedEncoding.h DiskWriter.h \
AbstractDiskWriter.cc AbstractDiskWriter.h \
DefaultDiskWriter.cc DefaultDiskWriter.h File.cc File.h \
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \
LogFactory.cc LogFactory.h NullLogger.h TimeA2.cc TimeA2.h \
SharedHandle.h HandleRegistry.h FeatureConfig.cc \
FeatureConfig.h DownloadEngineFactory.cc \
DownloadEngineFactory.h RequestInfo.h SpeedCalc.cc SpeedCalc.h \
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
SimpleRandomizer.h FileAllocator.h HttpResponse.cc \
HttpResponse.h HttpRequest.cc HttpRequest.h Range.h \
AbstractProxyRequestCommand.cc AbstractProxyRequestCommand.h \
AbstractProxyResponseCommand.cc AbstractProxyResponseCommand.h \
Netrc.cc Netrc.h AuthConfig.cc AuthConfig.h AuthResolver.h \
AbstractAuthResolver.h DefaultAuthResolver.cc \
DefaultAuthResolver.h NetrcAuthResolver.cc NetrcAuthResolver.h \
AuthConfigFactory.cc AuthConfigFactory.h OptionParser.cc \
OptionParser.h OptionHandlerFactory.cc OptionHandlerFactory.h \
NameResolver.cc NameResolver.h RequestGroup.cc RequestGroup.h \
RequestGroupAware.cc RequestGroupAware.h RequestGroupMan.cc \
RequestGroupMan.h FileAllocationMan.cc FileAllocationMan.h \
FileAllocationCommand.cc FileAllocationCommand.h \
@ -925,6 +925,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngineFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Exception.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileAllocationCommand.Po@am__quote@

View File

@ -101,9 +101,8 @@ RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile)
_logger->notice(EX_NO_RESULT_WITH_YOUR_PREFS);
return RequestGroups();
}
Integers selectIndexes = Util::parseIntRange(_option->get(PREF_SELECT_FILE)).flush();
bool useIndex;
Integers selectIndexes;
Util::unfoldRange(_option->get(PREF_SELECT_FILE), selectIndexes);
if(selectIndexes.size()) {
useIndex = true;
} else {

View File

@ -36,7 +36,6 @@
#define _D_MULTI_DISK_ADAPTOR_H_
#include "DiskAdaptor.h"
#include "Option.h"
#include "DiskWriter.h"
#include "File.h"
@ -108,7 +107,6 @@ private:
string topDir;
int32_t pieceLength;
DiskWriterEntries diskWriterEntries;
const Option* option;
void resetDiskWriterEntries();
@ -122,8 +120,7 @@ private:
string getTopDirPath() const;
public:
MultiDiskAdaptor():pieceLength(0),
option(0)
MultiDiskAdaptor():pieceLength(0)
{}
virtual ~MultiDiskAdaptor() {}
@ -169,14 +166,6 @@ public:
int32_t getPieceLength() const {
return pieceLength;
}
void setOption(const Option* option) {
this->option = option;
}
const Option* getOption() const {
return option;
}
};
typedef SharedHandle<MultiDiskAdaptor> MultiDiskAdaptorHandle;

View File

@ -40,7 +40,7 @@
MultiFileAllocationIterator::MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor):
_diskAdaptor(diskAdaptor),
_entries(diskAdaptor->getFileEntries()),
_entries(makeFileEntries(diskAdaptor->getFileEntries(), diskAdaptor->getPieceLength())),
_currentEntry(0),
_offset(0)
{}
@ -51,16 +51,14 @@ void MultiFileAllocationIterator::prepareNextEntry()
{
_currentEntry = 0;
_offset = 0;
while(!_entries.empty()) {
if(!_entries.empty()) {
FileEntryHandle entry = _entries.front();
_entries.pop_front();
if(entry->isRequested()) {
_currentEntry = entry;
_offset = File(_diskAdaptor->getStoreDir()+"/"+
_diskAdaptor->getTopDir()+"/"+
_currentEntry->getPath()).size();
break;
}
_currentEntry = entry;
_offset = File(_diskAdaptor->getStoreDir()+"/"+
_diskAdaptor->getTopDir()+"/"+
_currentEntry->getPath()).size();
}
}
@ -99,3 +97,41 @@ int64_t MultiFileAllocationIterator::getTotalLength()
return _currentEntry->getLength();
}
}
const FileEntries& MultiFileAllocationIterator::getFileEntries() const
{
return _entries;
}
FileEntries MultiFileAllocationIterator::makeFileEntries(const FileEntries& srcEntries, int32_t pieceLength) const
{
if(pieceLength == 0) {
FileEntries entries;
for(FileEntries::const_iterator itr = srcEntries.begin(); itr != srcEntries.end(); ++itr) {
if((*itr)->isRequested()) {
entries.push_back(*itr);
}
}
return entries;
}
FileEntries temp(srcEntries);
temp.push_front(new FileEntry());
FileEntries entries;
FileEntries::const_iterator done = temp.begin();
for(FileEntries::const_iterator itr = temp.begin()+1; itr != temp.end(); ++itr) {
if(!(*itr)->isRequested()) {
continue;
}
int64_t pieceStartOffset = ((*itr)->getOffset()/pieceLength)*pieceLength;
for(FileEntries::const_iterator i = itr-1; i != done; --i) {
if(pieceStartOffset < (*i)->getOffset()+(*i)->getLength()) {
entries.push_back(*i);
} else {
break;
}
}
entries.push_back(*itr);
done = itr;
}
return entries;
}

View File

@ -49,6 +49,8 @@ private:
FileEntries _entries;
FileEntryHandle _currentEntry;
int64_t _offset;
FileEntries makeFileEntries(const FileEntries& srcEntries, int32_t pieceLength) const;
public:
MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor);
@ -66,6 +68,8 @@ public:
}
virtual int64_t getTotalLength();
const FileEntries& getFileEntries() const;
};
typedef SharedHandle<MultiFileAllocationIterator> MultiFileAllocationIteratorHandle;

View File

@ -36,10 +36,13 @@
#define _D_NAME_MATCH_OPTION_HANDLER_H_
#include "OptionHandler.h"
#include "DlAbortEx.h"
class NameMatchOptionHandler : public OptionHandler {
protected:
string _optName;
virtual void parseArg(Option* option, const string& arg) = 0;
public:
NameMatchOptionHandler(const string& optName):_optName(optName) {}
@ -49,6 +52,15 @@ public:
{
return strcasecmp(_optName.c_str(), optName.c_str()) == 0;
}
virtual void parse(Option* option, const string& arg)
{
try {
parseArg(option, arg);
} catch(Exception* e) {
throw new DlAbortEx(e, "Exception occurred while processing option %s", _optName.c_str());
}
}
};
typedef SharedHandle<NameMatchOptionHandler> NameMatchOptionHandlerHandle;

View File

@ -43,7 +43,7 @@ public:
virtual ~OptionHandler() {}
virtual bool canHandle(const string& optName) = 0;
virtual void parseArg(Option* option, const string& arg) = 0;
virtual void parse(Option* option, const string& arg) = 0;
};
typedef SharedHandle<OptionHandler> OptionHandlerHandle;

View File

@ -55,11 +55,11 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(new UnitNumberOptionHandler(PREF_MIN_SEGMENT_SIZE, 1024));
handlers.push_back(new ParameterOptionHandler(PREF_HTTP_PROXY_METHOD,
V_GET, V_TUNNEL));
handlers.push_back(new NumberOptionHandler(PREF_LISTEN_PORT, 1024, UINT16_MAX));
handlers.push_back(new IntegerRangeOptionHandler(PREF_LISTEN_PORT, 1024, UINT16_MAX));
handlers.push_back(new BooleanOptionHandler(PREF_FOLLOW_TORRENT));
handlers.push_back(new BooleanOptionHandler(PREF_NO_PREALLOCATION));
handlers.push_back(new BooleanOptionHandler(PREF_DIRECT_FILE_MAPPING));
handlers.push_back(new DefaultOptionHandler(PREF_SELECT_FILE));
handlers.push_back(new IntegerRangeOptionHandler(PREF_SELECT_FILE, 1, INT32_MAX));
handlers.push_back(new NumberOptionHandler(PREF_SEED_TIME, 0));
handlers.push_back(new FloatNumberOptionHandler(PREF_SEED_RATIO, 0.0));
handlers.push_back(new UnitNumberOptionHandler(PREF_MAX_UPLOAD_LIMIT, 0));

View File

@ -38,6 +38,7 @@
#include "OptionHandler.h"
#include "NameMatchOptionHandler.h"
#include "Util.h"
#include "DlAbortEx.h"
#include "FatalException.h"
#include "prefs.h"
@ -47,7 +48,7 @@ public:
virtual bool canHandle(const string& optName) { return true; }
virtual void parseArg(Option* option, const string& arg) {}
virtual void parse(Option* option, const string& arg) {}
};
class BooleanOptionHandler : public NameMatchOptionHandler {
@ -68,6 +69,29 @@ public:
}
};
class IntegerRangeOptionHandler : public NameMatchOptionHandler {
private:
int32_t _min;
int32_t _max;
public:
IntegerRangeOptionHandler(const string& optName, int32_t min, int32_t max):NameMatchOptionHandler(optName), _min(min), _max(max) {}
virtual ~IntegerRangeOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
IntSequence seq = Util::parseIntRange(optarg);
while(seq.hasNext()) {
int32_t v = seq.next();
if(v < _min || _max < v) {
string msg = _optName+" "+_("must be between %s and %s.");
throw new DlAbortEx(msg.c_str(), Util::llitos(_min).c_str(), Util::llitos(_max).c_str());
}
option->put(_optName, optarg);
}
}
};
class NumberOptionHandler : public NameMatchOptionHandler {
private:
int64_t _min;
@ -79,7 +103,7 @@ public:
virtual void parseArg(Option* option, const string& optarg)
{
int64_t num = strtoll(optarg.c_str(), 0, 10);
int64_t num = Util::parseLLInt(optarg);
parseArg(option, num);
}
@ -217,7 +241,7 @@ public:
virtual void parseArg(Option* option, const string& optarg)
{
pair<string, string> proxy = Util::split(optarg, ":");
int32_t port = strtol(proxy.second.c_str(), 0, 10);
int32_t port = Util::parseInt(proxy.second);
if(proxy.first.empty() || proxy.second.empty() ||
port <= 0 || 65535 < port) {
throw new FatalException(_("unrecognized proxy format"));

View File

@ -47,7 +47,7 @@ void OptionParser::parse(Option* option, istream& is)
}
pair<string, string> nv = Util::split(line, "=");
OptionHandlerHandle handler = getOptionHandlerByName(nv.first);
handler->parseArg(option, nv.second);
handler->parse(option, nv.second);
}
}

View File

@ -58,13 +58,10 @@ PeerListenCommand::~PeerListenCommand()
--__numInstance;
}
int32_t PeerListenCommand::bindPort(int32_t portRangeStart,
int32_t portRangeEnd)
int32_t PeerListenCommand::bindPort(IntSequence& seq)
{
if(portRangeStart > portRangeEnd) {
return -1;
}
for(int32_t port = portRangeStart; port <= portRangeEnd; port++) {
while(seq.hasNext()) {
int32_t port = seq.next();
try {
socket->beginListen(port);
logger->info(MSG_LISTENING_PORT,

View File

@ -37,6 +37,7 @@
#include "Command.h"
#include "Socket.h"
#include "IntSequence.h"
class DownloadEngine;
@ -57,7 +58,7 @@ public:
virtual bool execute();
int32_t bindPort(int32_t portRangeStart, int32_t portRangeEnd);
int32_t bindPort(IntSequence& seq);
void setLowestSpeedLimit(int32_t speed)
{

View File

@ -37,6 +37,7 @@
#include "common.h"
#include "TimeA2.h"
#include "IntSequence.h"
class Piece;
extern typedef SharedHandle<Piece> PieceHandle;
@ -124,7 +125,7 @@ public:
virtual void setFileFilter(const Strings& filePaths) = 0;
virtual void setFileFilter(const Integers& fileIndexes) = 0;
virtual void setFileFilter(IntSequence seq) = 0;
virtual void clearFileFilter() = 0;

View File

@ -73,7 +73,6 @@
#ifdef ENABLE_METALINK
# include "MetalinkPostDownloadHandler.h"
#endif // ENABLE_METALINK
#include <cerrno>
int32_t RequestGroup::_gidCounter = 0;
@ -148,16 +147,17 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD,
getFilePath().c_str());
}
initPieceStorage();
if(btContext->getFileEntries().size() > 1) {
// this is really multi file torrent.
// clear http/ftp uris because the current implementation does not
// allow integrating multi-file torrent and http/ftp.
_logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
_uris.clear();
_pieceStorage->setFileFilter(Util::parseIntRange(_option->get(PREF_SELECT_FILE)));
}
initPieceStorage();
BtProgressInfoFileHandle progressInfoFile =
new DefaultBtProgressInfoFile(_downloadContext,
_pieceStorage,

View File

@ -48,7 +48,6 @@
#include "DownloadContext.h"
#include "Piece.h"
#include "a2io.h"
#include <errno.h>
SegmentEntry::SegmentEntry(int32_t cuid, const SegmentHandle& segment):
cuid(cuid), segment(segment) {}

99
src/Sequence.h Normal file
View File

@ -0,0 +1,99 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_SEQUENCE_H_
#define _D_SEQUENCE_H_
#include <deque>
using namespace std;
template<typename T>
class Sequence
{
public:
// Generates value in [_first, _last). _last is not included.
class Value {
private:
T _first;
T _last;
public:
Value(const T& first, const T& last):_first(first), _last(last) {}
T next()
{
return _first++;
}
bool hasNext() const
{
return _first != _last;
}
};
typedef deque<Value> Values;
private:
Values _values;
public:
Sequence(const Values& values):
_values(values) {}
T next()
{
if(_values.empty()) {
return T();
}
T t = _values.front().next();
if(!_values.front().hasNext()) {
_values.pop_front();
}
return t;
}
bool hasNext()
{
return !_values.empty();
}
deque<T> flush()
{
deque<T> r;
while(hasNext()) {
r.push_back(next());
}
return r;
}
};
#endif // _D_SEQUENCE_H_

View File

@ -154,7 +154,7 @@ public:
virtual void setFileFilter(const Strings& filePaths) {}
virtual void setFileFilter(const Integers& fileIndexes) {}
virtual void setFileFilter(IntSequence seq) {}
virtual void clearFileFilter() {}

View File

@ -464,6 +464,58 @@ void Util::unfoldRange(const string& src, Integers& range) {
range.erase(unique(range.begin(), range.end()), range.end());
}
int32_t Util::parseInt(const string& s, int32_t base)
{
char* stop;
errno = 0;
long int v = strtol(s.c_str(), &stop, base);
if(*stop != '\0') {
throw new DlAbortEx(MSG_ILLEGAL_CHARACTER, stop);
} else if((v == LONG_MIN || v == LONG_MAX) && errno == ERANGE || v > INT32_MAX || v < INT32_MIN) {
throw new DlAbortEx(MSG_OVERFLOW_UNDERFLOW_DETECTED, s.c_str());
}
return v;
}
int64_t Util::parseLLInt(const string& s, int32_t base)
{
char* stop;
errno = 0;
int64_t v = strtoll(s.c_str(), &stop, base);
if(*stop != '\0') {
throw new DlAbortEx(MSG_ILLEGAL_CHARACTER, stop);
} else if((v == INT64_MIN || v == INT64_MAX) && errno == ERANGE) {
throw new DlAbortEx(MSG_OVERFLOW_UNDERFLOW_DETECTED, s.c_str());
}
return v;
}
IntSequence Util::parseIntRange(const string& src)
{
IntSequence::Values values;
string temp = src;
while(temp.size()) {
pair<string, string> p = Util::split(temp, ",");
temp = p.second;
if(p.first.empty()) {
continue;
}
if(p.first.find("-") == string::npos) {
int32_t v = Util::parseInt(p.first.c_str());
values.push_back(IntSequence::Value(v, v+1));
} else {
pair<string, string> vp = Util::split(p.first.c_str(), "-");
if(vp.first.empty() || vp.second.empty()) {
throw new DlAbortEx(MSG_INCOMPLETE_RANGE, p.first.c_str());
}
int32_t v1 = Util::parseInt(vp.first.c_str());
int32_t v2 = Util::parseInt(vp.second.c_str());
values.push_back(IntSequence::Value(v1, v2+1));
}
}
return values;
}
string Util::getContentDispositionFilename(const string& header) {
string keyName = "filename=";
string::size_type attributesp = header.find(keyName);

View File

@ -38,6 +38,7 @@
#include "common.h"
#include "a2time.h"
#include "FileEntry.h"
#include "IntSequence.h"
#include <utility>
#include <deque>
#include <ostream>
@ -112,6 +113,12 @@ public:
static void unfoldRange(const string& src, Integers& range);
static int32_t parseInt(const string& s, int32_t base = 10);
static int64_t parseLLInt(const string& s, int32_t base = 10);
static IntSequence parseIntRange(const string& src);
// this function temporarily put here
static string getContentDispositionFilename(const string& header);

View File

@ -319,7 +319,7 @@ int main(int argc, char* argv[]) {
downloadUri(op, args);
}
} catch(Exception* ex) {
cerr << EX_EXCEPTION_CAUGHT << "\n" << ex->getMsg() << endl;
cerr << EX_EXCEPTION_CAUGHT << "\n" << *ex << endl;
delete ex;
exit(EXIT_FAILURE);
}

View File

@ -126,6 +126,9 @@
#define MSG_DAEMON_FAILED _("daemon failed.")
#define MSG_VERIFICATION_SUCCESSFUL _("Verification finished successfully. file=%s")
#define MSG_VERIFICATION_FAILED _("Checksum error detected. file=%s")
#define MSG_ILLEGAL_CHARACTER _("Illegal character detected: %s")
#define MSG_INCOMPLETE_RANGE _("Incomplete range specified. %s")
#define MSG_OVERFLOW_UNDERFLOW_DETECTED _("Overflow/underflow detected: %s")
#define EX_TIME_OUT _("Timeout.")
#define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.")

View File

@ -71,7 +71,7 @@ Option* option_processing(int argc, char* const argv[])
op->put(PREF_SPLIT, "1");
op->put(PREF_DAEMON, V_FALSE);
op->put(PREF_SEGMENT_SIZE, Util::itos((int32_t)(1024*1024)));
op->put(PREF_LISTEN_PORT, "-1");
op->put(PREF_LISTEN_PORT, "6881-6999");
op->put(PREF_METALINK_SERVERS, "5");
op->put(PREF_FOLLOW_TORRENT,
#ifdef ENABLE_BITTORRENT
@ -124,6 +124,7 @@ Option* option_processing(int argc, char* const argv[])
op->put(PREF_ENABLE_HTTP_KEEP_ALIVE, V_FALSE);
op->put(PREF_ENABLE_HTTP_PIPELINING, V_FALSE);
op->put(PREF_MAX_HTTP_PIPELINING, "2");
op->put(PREF_SEED_RATIO, "1.0");
while(1) {
int optIndex = 0;
int lopt;
@ -407,14 +408,14 @@ Option* option_processing(int argc, char* const argv[])
oparser.parse(op, cfstream);
} catch(Exception* e) {
cerr << "Parse error in " << cfname << endl;
cerr << e->getMsg() << endl;
cerr << *e << endl;
delete e;
exit(EXIT_FAILURE);
}
try {
oparser.parse(op, cmdstream);
} catch(Exception* e) {
cerr << e->getMsg() << endl;
cerr << *e << endl;
delete e;
exit(EXIT_FAILURE);
}

View File

@ -242,7 +242,11 @@ void showUsage() {
cout << _(" --direct-file-mapping=true|false Directly read from and write to each file\n"
" mentioned in .torrent file.\n"
" Default: true") << endl;
cout << _(" --listen-port=PORT Set TCP port number for BitTorrent downloads.\n"
cout << _(" --listen-port=PORT... Set TCP port number for BitTorrent downloads.\n"
" Multiple values can be specified by using ',',\n"
" for example: \"6881,6885\".\n"
" You can also use '-' to specify a range: \"6881-6999\".\n"
" ',' and '-' can be used together.\n"
" Default: 6881-6999") << endl;
cout << _(" --max-upload-limit=SPEED Set max upload speed in bytes per sec.\n"
" 0 means unrestricted.\n"
@ -252,9 +256,12 @@ void showUsage() {
" --seed-ratio option.") << endl;
cout << _(" --seed-ratio=RATIO Specify share ratio. Seed completed torrents\n"
" until share ratio reaches RATIO. 1.0 is\n"
" encouraged. If --seed-time option is specified\n"
" along with this option, seeding ends when at\n"
" least one of the conditions is satisfied.") << endl;
" encouraged. Specify 0.0 if you intend to do\n"
" seeding regardless of share ratio.\n"
" If --seed-time option is specified along with\n"
" this option, seeding ends when at least one of\n"
" the conditions is satisfied.\n"
" Default: 1.0") << endl;
cout << _(" --peer-id-prefix=PEERI_ID_PREFIX Specify the prefix of peer ID. The peer ID in\n"
" in BitTorrent is 20 byte length. If more than 20\n"
" bytes are specified, only first 20\n"

View File

@ -1,6 +1,7 @@
TESTS = aria2c
check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\
SequenceTest.cc\
a2functionalTest.cc\
FileEntryTest.cc\
PieceTest.cc\

View File

@ -112,9 +112,10 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT)
am__aria2c_SOURCES_DIST = AllTest.cc a2functionalTest.cc \
FileEntryTest.cc PieceTest.cc SegmentTest.cc \
GrowSegmentTest.cc SingleFileAllocationIteratorTest.cc \
am__aria2c_SOURCES_DIST = AllTest.cc SequenceTest.cc \
a2functionalTest.cc FileEntryTest.cc PieceTest.cc \
SegmentTest.cc GrowSegmentTest.cc \
SingleFileAllocationIteratorTest.cc \
DefaultBtProgressInfoFileTest.cc \
SingleFileDownloadContextTest.cc RequestGroupTest.cc \
PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
@ -204,9 +205,10 @@ am__aria2c_SOURCES_DIST = AllTest.cc a2functionalTest.cc \
@ENABLE_METALINK_TRUE@ Metalink2RequestGroupTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkPostDownloadHandlerTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkHelperTest.$(OBJEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) a2functionalTest.$(OBJEXT) \
FileEntryTest.$(OBJEXT) PieceTest.$(OBJEXT) \
SegmentTest.$(OBJEXT) GrowSegmentTest.$(OBJEXT) \
am_aria2c_OBJECTS = AllTest.$(OBJEXT) SequenceTest.$(OBJEXT) \
a2functionalTest.$(OBJEXT) FileEntryTest.$(OBJEXT) \
PieceTest.$(OBJEXT) SegmentTest.$(OBJEXT) \
GrowSegmentTest.$(OBJEXT) \
SingleFileAllocationIteratorTest.$(OBJEXT) \
DefaultBtProgressInfoFileTest.$(OBJEXT) \
SingleFileDownloadContextTest.$(OBJEXT) \
@ -416,9 +418,9 @@ target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
TESTS = aria2c
aria2c_SOURCES = AllTest.cc a2functionalTest.cc FileEntryTest.cc \
PieceTest.cc SegmentTest.cc GrowSegmentTest.cc \
SingleFileAllocationIteratorTest.cc \
aria2c_SOURCES = AllTest.cc SequenceTest.cc a2functionalTest.cc \
FileEntryTest.cc PieceTest.cc SegmentTest.cc \
GrowSegmentTest.cc SingleFileAllocationIteratorTest.cc \
DefaultBtProgressInfoFileTest.cc \
SingleFileDownloadContextTest.cc RequestGroupTest.cc \
PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
@ -577,6 +579,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentManTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SequenceTest.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)/SharedHandleTest.Po@am__quote@

View File

@ -109,7 +109,7 @@ public:
virtual void setFileFilter(const Strings& filePaths) {}
virtual void setFileFilter(const Integers& fileIndexes) {}
virtual void setFileFilter(IntSequence seq) {}
virtual void clearFileFilter() {}

View File

@ -11,18 +11,13 @@ class MultiDiskAdaptorTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testReadData);
CPPUNIT_TEST_SUITE_END();
private:
Option* option;
MultiDiskAdaptorHandle adaptor;
public:
MultiDiskAdaptorTest():option(0), adaptor(0) {}
MultiDiskAdaptorTest():adaptor(0) {}
void setUp() {
delete option;
option = new Option();
adaptor = new MultiDiskAdaptor();
adaptor->setPieceLength(2);
adaptor->setOption(new Option());
adaptor->setStoreDir(".");
adaptor->setTopDir(".");
}

View File

@ -7,6 +7,7 @@ class MultiFileAllocationIteratorTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MultiFileAllocationIteratorTest);
CPPUNIT_TEST(testAllocate);
CPPUNIT_TEST(testMakeFileEntries);
CPPUNIT_TEST_SUITE_END();
private:
@ -14,11 +15,54 @@ public:
void setUp() {}
void testAllocate();
void testMakeFileEntries();
};
CPPUNIT_TEST_SUITE_REGISTRATION( MultiFileAllocationIteratorTest );
void MultiFileAllocationIteratorTest::testMakeFileEntries()
{
FileEntryHandle fs[] = {
new FileEntry("file1", 1536, 0),
new FileEntry("file2", 2048, 1536),
new FileEntry("file3", 1024, 3584),
new FileEntry("file4", 1024, 4608),
new FileEntry("file5", 1024, 5632),
new FileEntry("file6", 1024, 6656),
new FileEntry("file7", 256, 7680),
new FileEntry("file8", 768, 7936),
new FileEntry("file9", 256, 8704),
new FileEntry("fileA", 256, 8960),
};
fs[1]->setRequested(false);
fs[3]->setRequested(false);
fs[4]->setRequested(false);
fs[5]->setRequested(false);
fs[6]->setRequested(false);
fs[8]->setRequested(false);
fs[9]->setRequested(false);
MultiDiskAdaptorHandle diskAdaptor = new MultiDiskAdaptor();
diskAdaptor->setFileEntries(FileEntries(&fs[0], &fs[10]));
diskAdaptor->setPieceLength(1024);
MultiFileAllocationIteratorHandle itr = diskAdaptor->fileAllocationIterator();
FileEntries entries = itr->getFileEntries();
sort(entries.begin(), entries.end());
CPPUNIT_ASSERT_EQUAL((size_t)6, entries.size());
CPPUNIT_ASSERT_EQUAL(string("file1"), entries[0]->getPath());
CPPUNIT_ASSERT_EQUAL(string("file2"), entries[1]->getPath());
CPPUNIT_ASSERT_EQUAL(string("file3"), entries[2]->getPath());
CPPUNIT_ASSERT_EQUAL(string("file6"), entries[3]->getPath());
CPPUNIT_ASSERT_EQUAL(string("file7"), entries[4]->getPath());
CPPUNIT_ASSERT_EQUAL(string("file8"), entries[5]->getPath());
}
void MultiFileAllocationIteratorTest::testAllocate()
{
string dir = "/tmp";

View File

@ -52,7 +52,7 @@ void OptionHandlerTest::testNullOptionHandler()
{
NullOptionHandler handler;
CPPUNIT_ASSERT(handler.canHandle("foo"));
handler.parseArg(0, "bar");
handler.parse(0, "bar");
}
void OptionHandlerTest::testBooleanOptionHandler()
@ -61,12 +61,12 @@ void OptionHandlerTest::testBooleanOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, V_TRUE);
handler.parse(&option, V_TRUE);
CPPUNIT_ASSERT_EQUAL(string(V_TRUE), option.get("foo"));
handler.parseArg(&option, V_FALSE);
handler.parse(&option, V_FALSE);
CPPUNIT_ASSERT_EQUAL(string(V_FALSE), option.get("foo"));
try {
handler.parseArg(&option, "hello");
handler.parse(&option, "hello");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -80,7 +80,7 @@ void OptionHandlerTest::testNumberOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "0");
handler.parse(&option, "0");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
}
@ -88,10 +88,10 @@ void OptionHandlerTest::testNumberOptionHandler_min()
{
NumberOptionHandler handler("foo", 1);
Option option;
handler.parseArg(&option, "1");
handler.parse(&option, "1");
CPPUNIT_ASSERT_EQUAL(string("1"), option.get("foo"));
try {
handler.parseArg(&option, "0");
handler.parse(&option, "0");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -104,10 +104,10 @@ void OptionHandlerTest::testNumberOptionHandler_max()
{
NumberOptionHandler handler("foo", -1, 100);
Option option;
handler.parseArg(&option, "100");
handler.parse(&option, "100");
CPPUNIT_ASSERT_EQUAL(string("100"), option.get("foo"));
try {
handler.parseArg(&option, "101");
handler.parse(&option, "101");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -119,19 +119,19 @@ void OptionHandlerTest::testNumberOptionHandler_min_max()
{
NumberOptionHandler handler("foo", 1, 100);
Option option;
handler.parseArg(&option, "1");
handler.parse(&option, "1");
CPPUNIT_ASSERT_EQUAL(string("1"), option.get("foo"));
handler.parseArg(&option, "100");
handler.parse(&option, "100");
CPPUNIT_ASSERT_EQUAL(string("100"), option.get("foo"));
try {
handler.parseArg(&option, "0");
handler.parse(&option, "0");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "101");
handler.parse(&option, "101");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -145,17 +145,17 @@ void OptionHandlerTest::testUnitNumberOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "4294967296");
handler.parse(&option, "4294967296");
CPPUNIT_ASSERT_EQUAL(string("4294967296"), option.get("foo"));
handler.parseArg(&option, "4096M");
handler.parse(&option, "4096M");
CPPUNIT_ASSERT_EQUAL(string("4294967296"), option.get("foo"));
handler.parseArg(&option, "4096K");
handler.parse(&option, "4096K");
CPPUNIT_ASSERT_EQUAL(string("4194304"), option.get("foo"));
handler.parseArg(&option, "K");
handler.parse(&option, "K");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
handler.parseArg(&option, "M");
handler.parse(&option, "M");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
handler.parseArg(&option, "");
handler.parse(&option, "");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
}
@ -165,10 +165,10 @@ void OptionHandlerTest::testParameterOptionHandler_1argInit()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "value1");
handler.parse(&option, "value1");
CPPUNIT_ASSERT_EQUAL(string("value1"), option.get("foo"));
try {
handler.parseArg(&option, "value3");
handler.parse(&option, "value3");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -182,12 +182,12 @@ void OptionHandlerTest::testParameterOptionHandler_2argsInit()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "value1");
handler.parse(&option, "value1");
CPPUNIT_ASSERT_EQUAL(string("value1"), option.get("foo"));
handler.parseArg(&option, "value2");
handler.parse(&option, "value2");
CPPUNIT_ASSERT_EQUAL(string("value2"), option.get("foo"));
try {
handler.parseArg(&option, "value3");
handler.parse(&option, "value3");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -205,12 +205,12 @@ void OptionHandlerTest::testParameterOptionHandler_listInit()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "value1");
handler.parse(&option, "value1");
CPPUNIT_ASSERT_EQUAL(string("value1"), option.get("foo"));
handler.parseArg(&option, "value2");
handler.parse(&option, "value2");
CPPUNIT_ASSERT_EQUAL(string("value2"), option.get("foo"));
try {
handler.parseArg(&option, "value3");
handler.parse(&option, "value3");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -224,9 +224,9 @@ void OptionHandlerTest::testDefaultOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "bar");
handler.parse(&option, "bar");
CPPUNIT_ASSERT_EQUAL(string("bar"), option.get("foo"));
handler.parseArg(&option, "");
handler.parse(&option, "");
CPPUNIT_ASSERT_EQUAL(string(""), option.get("foo"));
}
@ -236,7 +236,7 @@ void OptionHandlerTest::testFloatNumberOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "1.0");
handler.parse(&option, "1.0");
CPPUNIT_ASSERT_EQUAL(string("1.0"), option.get("foo"));
}
@ -244,10 +244,10 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min()
{
FloatNumberOptionHandler handler("foo", 0.0);
Option option;
handler.parseArg(&option, "0.0");
handler.parse(&option, "0.0");
CPPUNIT_ASSERT_EQUAL(string("0.0"), option.get("foo"));
try {
handler.parseArg(&option, "-0.1");
handler.parse(&option, "-0.1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -259,10 +259,10 @@ void OptionHandlerTest::testFloatNumberOptionHandler_max()
{
FloatNumberOptionHandler handler("foo", -1, 10.0);
Option option;
handler.parseArg(&option, "10.0");
handler.parse(&option, "10.0");
CPPUNIT_ASSERT_EQUAL(string("10.0"), option.get("foo"));
try {
handler.parseArg(&option, "10.1");
handler.parse(&option, "10.1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -274,19 +274,19 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
{
FloatNumberOptionHandler handler("foo", 0.0, 10.0);
Option option;
handler.parseArg(&option, "0.0");
handler.parse(&option, "0.0");
CPPUNIT_ASSERT_EQUAL(string("0.0"), option.get("foo"));
handler.parseArg(&option, "10.0");
handler.parse(&option, "10.0");
CPPUNIT_ASSERT_EQUAL(string("10.0"), option.get("foo"));
try {
handler.parseArg(&option, "-0.1");
handler.parse(&option, "-0.1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "10.1");
handler.parse(&option, "10.1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
@ -300,12 +300,12 @@ void OptionHandlerTest::testLogOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "/tmp/log.txt");
handler.parse(&option, "/tmp/log.txt");
CPPUNIT_ASSERT_EQUAL(string("/tmp/log.txt"), option.get(PREF_LOG));
CPPUNIT_ASSERT_EQUAL(string(""), option.get(PREF_STDOUT_LOG));
option.clear();
handler.parseArg(&option, "-");
handler.parse(&option, "-");
CPPUNIT_ASSERT_EQUAL(string(""), option.get(PREF_LOG));
CPPUNIT_ASSERT_EQUAL(string(V_TRUE), option.get(PREF_STDOUT_LOG));
}
@ -316,42 +316,42 @@ void OptionHandlerTest::testHttpProxyOptionHandler()
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "bar:80");
handler.parse(&option, "bar:80");
CPPUNIT_ASSERT_EQUAL(string("bar:80"), option.get(PREF_HTTP_PROXY));
CPPUNIT_ASSERT_EQUAL(string("bar"), option.get(PREF_HTTP_PROXY_HOST));
CPPUNIT_ASSERT_EQUAL(string("80"), option.get(PREF_HTTP_PROXY_PORT));
CPPUNIT_ASSERT_EQUAL(string(V_TRUE), option.get(PREF_HTTP_PROXY_ENABLED));
try {
handler.parseArg(&option, "bar");
handler.parse(&option, "bar");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "bar:");
handler.parse(&option, "bar:");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, ":");
handler.parse(&option, ":");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, ":80");
handler.parse(&option, ":80");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "foo:bar");
handler.parse(&option, "foo:bar");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;

79
test/SequenceTest.cc Normal file
View File

@ -0,0 +1,79 @@
#include "Sequence.h"
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
class SequenceTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(SequenceTest);
CPPUNIT_TEST(testParseAndNext);
CPPUNIT_TEST(testParseAndNext2);
CPPUNIT_TEST(testFlush);
CPPUNIT_TEST_SUITE_END();
public:
void testParseAndNext();
void testParseAndNext2();
void testFlush();
};
CPPUNIT_TEST_SUITE_REGISTRATION(SequenceTest);
typedef Sequence<int32_t> IntSequence;
void SequenceTest::testParseAndNext()
{
IntSequence::Value params[] = {
IntSequence::Value(1, 2),
IntSequence::Value(3, 9),
IntSequence::Value(10, 11),
};
IntSequence seq(IntSequence::Values(&params[0], &params[3]));
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)1, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)3, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)4, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)5, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)6, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)7, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)8, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)10, seq.next());
CPPUNIT_ASSERT(!seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)0, seq.next());
}
void SequenceTest::testParseAndNext2()
{
IntSequence::Value params[] = {
IntSequence::Value(1, 2),
};
IntSequence seq(IntSequence::Values(&params[0], &params[1]));
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)1, seq.next());
CPPUNIT_ASSERT(!seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)0, seq.next());
}
void SequenceTest::testFlush()
{
IntSequence::Value params[] = {
IntSequence::Value(1, 2),
IntSequence::Value(3, 9),
IntSequence::Value(10, 11),
};
IntSequence seq(IntSequence::Values(&params[0], &params[3]));
deque<int32_t> r = seq.flush();
int32_t answers[] = { 1, 3, 4, 5, 6, 7, 8, 10 };
CPPUNIT_ASSERT(equal(r.begin(), r.end(), &answers[0]));
}

View File

@ -32,6 +32,10 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testAlphaToNum);
CPPUNIT_TEST(testMkdirs);
CPPUNIT_TEST(testConvertBitfield);
CPPUNIT_TEST(testParseIntRange);
CPPUNIT_TEST(testParseIntRange_invalidRange);
CPPUNIT_TEST(testParseInt);
CPPUNIT_TEST(testParseLLInt);
CPPUNIT_TEST_SUITE_END();
private:
@ -61,6 +65,10 @@ public:
void testAlphaToNum();
void testMkdirs();
void testConvertBitfield();
void testParseIntRange();
void testParseIntRange_invalidRange();
void testParseInt();
void testParseLLInt();
};
@ -407,3 +415,123 @@ void UtilTest::testConvertBitfield()
Util::toHex(destBitfield.getBitfield(),
destBitfield.getBitfieldLength()));
}
void UtilTest::testParseIntRange()
{
IntSequence seq = Util::parseIntRange("1,3-8,10");
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)1, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)3, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)4, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)5, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)6, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)7, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)8, seq.next());
CPPUNIT_ASSERT(seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)10, seq.next());
CPPUNIT_ASSERT(!seq.hasNext());
CPPUNIT_ASSERT_EQUAL((int32_t)0, seq.next());
}
void UtilTest::testParseIntRange_invalidRange()
{
try {
IntSequence seq = Util::parseIntRange("-1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
IntSequence seq = Util::parseIntRange("2147483648");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
IntSequence seq = Util::parseIntRange("2147483647-2147483648");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
IntSequence seq = Util::parseIntRange("1-2x");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
IntSequence seq = Util::parseIntRange("3x-4");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
}
void UtilTest::testParseInt()
{
CPPUNIT_ASSERT_EQUAL((int32_t)-1, Util::parseInt("-1"));
CPPUNIT_ASSERT_EQUAL((int32_t)2147483647, Util::parseInt("2147483647"));
try {
Util::parseInt("2147483648");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::parseInt("-2147483649");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::parseInt("12x");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
}
void UtilTest::testParseLLInt()
{
CPPUNIT_ASSERT_EQUAL((int64_t)-1, Util::parseLLInt("-1"));
CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL,
Util::parseLLInt("9223372036854775807"));
try {
Util::parseLLInt("9223372036854775808");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::parseLLInt("-9223372036854775809");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::parseLLInt("12x");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
}