mirror of https://github.com/aria2/aria2
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.ccpull/1/head
parent
59fb4066fb
commit
c9e3d51054
66
ChangeLog
66
ChangeLog
|
@ -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
3
TODO
|
@ -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
|
||||
|
|
30
doc/aria2c.1
30
doc/aria2c.1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
||||
|
|
|
@ -62,3 +62,8 @@ FileEntry& FileEntry::operator=(const FileEntry& entry)
|
|||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool FileEntry::operator<(const FileEntry& fileEntry) const
|
||||
{
|
||||
return offset < fileEntry.offset;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,8 @@ public:
|
|||
{
|
||||
return _uris;
|
||||
}
|
||||
|
||||
bool operator<(const FileEntry& fileEntry) const;
|
||||
};
|
||||
|
||||
typedef SharedHandle<FileEntry> FileEntryHandle;
|
||||
|
|
|
@ -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_
|
|
@ -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\
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -73,7 +73,6 @@
|
|||
#ifdef ENABLE_METALINK
|
||||
# include "MetalinkPostDownloadHandler.h"
|
||||
#endif // ENABLE_METALINK
|
||||
#include <cerrno>
|
||||
|
||||
int32_t RequestGroup::_gidCounter = 0;
|
||||
|
||||
|
@ -148,15 +147,16 @@ 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();
|
||||
}
|
||||
|
||||
initPieceStorage();
|
||||
_pieceStorage->setFileFilter(Util::parseIntRange(_option->get(PREF_SELECT_FILE)));
|
||||
}
|
||||
|
||||
BtProgressInfoFileHandle progressInfoFile =
|
||||
new DefaultBtProgressInfoFile(_downloadContext,
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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_
|
|
@ -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() {}
|
||||
|
||||
|
|
52
src/Util.cc
52
src/Util.cc
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
TESTS = aria2c
|
||||
check_PROGRAMS = $(TESTS)
|
||||
aria2c_SOURCES = AllTest.cc\
|
||||
SequenceTest.cc\
|
||||
a2functionalTest.cc\
|
||||
FileEntryTest.cc\
|
||||
PieceTest.cc\
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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(".");
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(¶ms[0], ¶ms[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(¶ms[0], ¶ms[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(¶ms[0], ¶ms[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]));
|
||||
}
|
128
test/UtilTest.cc
128
test/UtilTest.cc
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue