2007-03-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

To add the ability to resume downloading a partially downloaded 
file
	which is downloaded from the beginning:
	* src/FileAllocator.h: Made abstract class. New 
DefaultFileAllocator
	takes this role.
	* src/main.cc: Added -c option.
	* src/BitfieldMan.h, src/BitfieldMan.cc (setBitRange): New 
function.
	* src/DiskWriter.h (openExistingFile): Added totalLength 
argument.
	* src/prefs.h (PREF_CONTINUE): New definition.
	* src/SegmentMan.h, src/SegmentMan.cc (markPieceDone): New 
function.
	* src/DefaultDiskWriter.cc
	(createNewDiskWriter): Add GlowFileAllocator to the new object.
	* src/AbstractDiskWriter.h
	(glowFileAllocator): New variable.
	* src/AbstractDiskWriter.cc
	(openExistingFile): Now preallocate file space from the end of 
the
	existing file if totalLength argument is specified and grater 
than 0.
	* src/UrlRequestInfo.cc: If -c option is specified and the file
	to download exists in local, continue the download of the file.
	--allow-overwrite=true is assumed in this context.
	* src/DefaultFileAllocator.h, src/DefaultFileAllocator.cc: New 
class.
	* src/GlowFileAllocator.h, src/GlowFileAllocator.cc: New class.

	Throw exception if --check-integrity=true is specified but chunk
	checksums are not provided:
	* src/UrlRequestInfo.cc
pull/1/head
Tatsuhiro Tsujikawa 2007-03-24 14:32:49 +00:00
parent 5649cf6cda
commit a37aaa9c0c
28 changed files with 498 additions and 62 deletions

View File

@ -1,3 +1,31 @@
2007-03-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add the ability to resume downloading a partially downloaded file
which is downloaded from the beginning:
* src/FileAllocator.h: Made abstract class. New DefaultFileAllocator
takes this role.
* src/main.cc: Added -c option.
* src/BitfieldMan.h, src/BitfieldMan.cc (setBitRange): New function.
* src/DiskWriter.h (openExistingFile): Added totalLength argument.
* src/prefs.h (PREF_CONTINUE): New definition.
* src/SegmentMan.h, src/SegmentMan.cc (markPieceDone): New function.
* src/DefaultDiskWriter.cc
(createNewDiskWriter): Add GlowFileAllocator to the new object.
* src/AbstractDiskWriter.h
(glowFileAllocator): New variable.
* src/AbstractDiskWriter.cc
(openExistingFile): Now preallocate file space from the end of the
existing file if totalLength argument is specified and grater than 0.
* src/UrlRequestInfo.cc: If -c option is specified and the file
to download exists in local, continue the download of the file.
--allow-overwrite=true is assumed in this context.
* src/DefaultFileAllocator.h, src/DefaultFileAllocator.cc: New class.
* src/GlowFileAllocator.h, src/GlowFileAllocator.cc: New class.
Throw exception if --check-integrity=true is specified but chunk
checksums are not provided:
* src/UrlRequestInfo.cc
2007-03-21 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-03-21 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/Request.h: Use AuthResolver to get authentication information. * src/Request.h: Use AuthResolver to get authentication information.

3
TODO
View File

@ -28,4 +28,5 @@
* -c command line option to continue the download of existing file assuming * -c command line option to continue the download of existing file assuming
that it was downloaded from the beginning. that it was downloaded from the beginning.
* Continue file allocation with existing file * Continue file allocation with existing file
* keep-alive * Netrc, mode 600, enabled in ftp, http, all
* preallocate file in MultiDiskAdaptor

View File

@ -47,6 +47,7 @@
AbstractDiskWriter::AbstractDiskWriter(): AbstractDiskWriter::AbstractDiskWriter():
fd(0), fd(0),
fileAllocator(0), fileAllocator(0),
glowFileAllocator(0),
logger(LogFactory::getInstance()) logger(LogFactory::getInstance())
{} {}
@ -71,7 +72,7 @@ void AbstractDiskWriter::closeFile() {
} }
} }
void AbstractDiskWriter::openExistingFile(const string& filename) { void AbstractDiskWriter::openExistingFile(const string& filename, int64_t totalLength) {
this->filename = filename; this->filename = filename;
File f(filename); File f(filename);
if(!f.isFile()) { if(!f.isFile()) {
@ -81,6 +82,14 @@ void AbstractDiskWriter::openExistingFile(const string& filename) {
if((fd = open(filename.c_str(), O_RDWR, S_IRUSR|S_IWUSR)) < 0) { if((fd = open(filename.c_str(), O_RDWR, S_IRUSR|S_IWUSR)) < 0) {
throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno)); throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno));
} }
if(f.size() < totalLength) {
if(!fileAllocator.isNull()) {
logger->notice("Allocating file %s, %s bytes",
filename.c_str(),
Util::ullitos(totalLength).c_str());
glowFileAllocator->allocate(fd, totalLength);
}
}
} }
void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags) { void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags) {

View File

@ -44,6 +44,7 @@ protected:
string filename; string filename;
int32_t fd; int32_t fd;
FileAllocatorHandle fileAllocator; FileAllocatorHandle fileAllocator;
FileAllocatorHandle glowFileAllocator;
const Logger* logger; const Logger* logger;
void createFile(const string& filename, int32_t addFlags = 0); void createFile(const string& filename, int32_t addFlags = 0);
@ -62,7 +63,7 @@ public:
virtual void closeFile(); virtual void closeFile();
virtual void openExistingFile(const string& filename); virtual void openExistingFile(const string& filename, int64_t totalLength = 0);
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
virtual string messageDigest(int64_t offset, int64_t length, virtual string messageDigest(int64_t offset, int64_t length,
@ -73,9 +74,15 @@ public:
virtual int32_t readData(char* data, int32_t len, int64_t offset); virtual int32_t readData(char* data, int32_t len, int64_t offset);
void setFileAllocator(const FileAllocatorHandle& fileAllocator) { void setFileAllocator(const FileAllocatorHandle& fileAllocator)
{
this->fileAllocator = fileAllocator; this->fileAllocator = fileAllocator;
} }
void setGlowFileAllocator(const FileAllocatorHandle& fileAllocator)
{
this->glowFileAllocator = fileAllocator;
}
}; };
#endif // _D_ABSTRACT_DISK_WRITER_H_ #endif // _D_ABSTRACT_DISK_WRITER_H_

View File

@ -645,6 +645,14 @@ void BitfieldMan::unsetBitRange(int32_t startIndex, int32_t endIndex)
updateCache(); updateCache();
} }
void BitfieldMan::setBitRange(int32_t startIndex, int32_t endIndex)
{
for(int32_t i = startIndex; i <= endIndex; ++i) {
setBit(i);
}
updateCache();
}
bool BitfieldMan::isBitSetOffsetRange(int64_t offset, int64_t length) const bool BitfieldMan::isBitSetOffsetRange(int64_t offset, int64_t length) const
{ {
if(length <= 0) { if(length <= 0) {

View File

@ -255,6 +255,8 @@ public:
void unsetBitRange(int32_t startIndex, int32_t endIndex); void unsetBitRange(int32_t startIndex, int32_t endIndex);
void setBitRange(int32_t startIndex, int32_t endIndex);
bool isBitSetOffsetRange(int64_t offset, int64_t length) const; bool isBitSetOffsetRange(int64_t offset, int64_t length) const;
int64_t getMissingUnusedLength(int32_t startingIndex) const; int64_t getMissingUnusedLength(int32_t startingIndex) const;

View File

@ -68,7 +68,8 @@ void ByteArrayDiskWriter::closeFile() {
clear(); clear();
} }
void ByteArrayDiskWriter::openExistingFile(const string& filename) { void ByteArrayDiskWriter::openExistingFile(const string& filename,
int64_t totalLength) {
openFile(filename); openFile(filename);
} }

View File

@ -55,7 +55,7 @@ public:
virtual void closeFile(); virtual void closeFile();
virtual void openExistingFile(const string& filename); virtual void openExistingFile(const string& filename, int64_t totalLength = 0);
// position is ignored // position is ignored
virtual void writeData(const char* data, int32_t len, int64_t position = 0); virtual void writeData(const char* data, int32_t len, int64_t position = 0);

View File

@ -35,7 +35,8 @@
#include "DefaultDiskWriter.h" #include "DefaultDiskWriter.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "message.h" #include "message.h"
#include "FileAllocator.h" #include "DefaultFileAllocator.h"
#include "GlowFileAllocator.h"
#include "prefs.h" #include "prefs.h"
#include "Util.h" #include "Util.h"
#include <errno.h> #include <errno.h>
@ -69,11 +70,16 @@ DefaultDiskWriter* DefaultDiskWriter::createNewDiskWriter(const Option* option)
{ {
DefaultDiskWriter* diskWriter = new DefaultDiskWriter(); DefaultDiskWriter* diskWriter = new DefaultDiskWriter();
if(option->get(PREF_FILE_ALLOCATION) == V_PREALLOC) { if(option->get(PREF_FILE_ALLOCATION) == V_PREALLOC) {
FileAllocatorHandle allocator = new FileAllocator(); DefaultFileAllocatorHandle allocator = new DefaultFileAllocator();
allocator->setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor()); allocator->setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor());
diskWriter->setFileAllocator(allocator); diskWriter->setFileAllocator(allocator);
GlowFileAllocatorHandle glowAllocator = new GlowFileAllocator();
glowAllocator->setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor());
diskWriter->setGlowFileAllocator(glowAllocator);
} else { } else {
diskWriter->setFileAllocator(0); diskWriter->setFileAllocator(0);
diskWriter->setGlowFileAllocator(0);
} }
return diskWriter; return diskWriter;
} }

View File

@ -1,4 +1,3 @@
/* <!-- copyright */ /* <!-- copyright */
/* /*
* aria2 - The high speed download utility * aria2 - The high speed download utility
@ -33,14 +32,14 @@
* files in the program, then also delete it here. * files in the program, then also delete it here.
*/ */
/* copyright --> */ /* copyright --> */
#include "FileAllocator.h" #include "DefaultFileAllocator.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "TimeA2.h" #include "TimeA2.h"
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
void FileAllocator::allocate(int fd, int64_t totalLength) void DefaultFileAllocator::allocate(int fd, int64_t totalLength)
{ {
if(0 != lseek(fd, 0, SEEK_SET)) { if(0 != lseek(fd, 0, SEEK_SET)) {
throw new DlAbortEx("Seek failed: %s", strerror(errno)); throw new DlAbortEx("Seek failed: %s", strerror(errno));

View File

@ -0,0 +1,51 @@
/* <!-- 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_DEFAULT_FILE_ALLOCATOR_H_
#define _D_DEFAULT_FILE_ALLOCATOR_H_
#include "FileAllocator.h"
class DefaultFileAllocator : public FileAllocator {
public:
DefaultFileAllocator() {}
virtual ~DefaultFileAllocator() {}
virtual void allocate(int fd, int64_t totalLength);
};
typedef SharedHandle<DefaultFileAllocator> DefaultFileAllocatorHandle;
#endif // _D_DEFAULT_FILE_ALLOCATOR_H_

View File

@ -62,7 +62,7 @@ public:
diskAdaptor->closeFile(); diskAdaptor->closeFile();
} }
virtual void openExistingFile(const string& filename) virtual void openExistingFile(const string& filename, int64_t totalLength = 0)
{ {
diskAdaptor->openExistingFile(); diskAdaptor->openExistingFile();
} }

View File

@ -70,7 +70,7 @@ public:
* *
* @param filename the file name to be opened. * @param filename the file name to be opened.
*/ */
virtual void openExistingFile(const string& filename) = 0; virtual void openExistingFile(const string& filename, int64_t totalLength = 0) = 0;
/* /*
* Writes len bytes from data to this binary stream at offset position. * Writes len bytes from data to this binary stream at offset position.

View File

@ -40,14 +40,14 @@
#include "NullFileAllocationMonitor.h" #include "NullFileAllocationMonitor.h"
class FileAllocator { class FileAllocator {
private: protected:
FileAllocationMonitorHandle fileAllocationMonitor; FileAllocationMonitorHandle fileAllocationMonitor;
public: public:
FileAllocator():fileAllocationMonitor(new NullFileAllocationMonitor()) {} FileAllocator():fileAllocationMonitor(new NullFileAllocationMonitor()) {}
~FileAllocator() {} virtual ~FileAllocator() {}
void allocate(int fd, int64_t totalLength); virtual void allocate(int fd, int64_t totalLength) = 0;
void setFileAllocationMonitor(const FileAllocationMonitorHandle& monitor) void setFileAllocationMonitor(const FileAllocationMonitorHandle& monitor)
{ {

74
src/GlowFileAllocator.cc Normal file
View File

@ -0,0 +1,74 @@
/* <!-- 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 "GlowFileAllocator.h"
#include "DlAbortEx.h"
#include "TimeA2.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
void GlowFileAllocator::allocate(int fd, int64_t totalLength)
{
struct stat fs;
if(fstat(fd, &fs) < 0) {
throw new DlAbortEx("fstat filed: %s", strerror(errno));
}
if(fs.st_size != lseek(fd, 0, SEEK_END)) {
throw new DlAbortEx("Seek failed: %s", strerror(errno));
}
int32_t bufSize = 4096;
char buf[4096];
memset(buf, 0, bufSize);
int64_t x = (totalLength-fs.st_size+bufSize-1)/bufSize;
fileAllocationMonitor->setMinValue(0);
fileAllocationMonitor->setMaxValue(totalLength);
fileAllocationMonitor->setCurrentValue(fs.st_size);
fileAllocationMonitor->showProgress();
Time cp;
for(int64_t i = 0; i < x; ++i) {
if(write(fd, buf, bufSize) < 0) {
throw new DlAbortEx("Allocation failed: %s", strerror(errno));
}
if(cp.elapsedInMillis(500)) {
fileAllocationMonitor->setCurrentValue(i*bufSize);
fileAllocationMonitor->showProgress();
cp.reset();
}
}
fileAllocationMonitor->setCurrentValue(totalLength);
fileAllocationMonitor->showProgress();
ftruncate(fd, totalLength);
}

51
src/GlowFileAllocator.h Normal file
View File

@ -0,0 +1,51 @@
/* <!-- 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_GLOW_FILE_ALLOCATOR_H_
#define _D_GLOW_FILE_ALLOCATOR_H_
#include "FileAllocator.h"
class GlowFileAllocator : public FileAllocator {
public:
GlowFileAllocator() {}
virtual ~GlowFileAllocator() {}
virtual void allocate(int fd, int64_t totalLength);
};
typedef SharedHandle<GlowFileAllocator> GlowFileAllocatorHandle;
#endif // _D_GLOW_FILE_ALLOCATOR_H_

View File

@ -61,7 +61,7 @@ SRCS = Socket.h\
BitfieldManFactory.cc BitfieldManFactory.h\ BitfieldManFactory.cc BitfieldManFactory.h\
Randomizer.h\ Randomizer.h\
SimpleRandomizer.cc SimpleRandomizer.h\ SimpleRandomizer.cc SimpleRandomizer.h\
FileAllocator.cc FileAllocator.h\ FileAllocator.h\
FileAllocationMonitor.cc FileAllocationMonitor.h\ FileAllocationMonitor.cc FileAllocationMonitor.h\
ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h\ ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h\
ChunkChecksumValidator.cc ChunkChecksumValidator.h\ ChunkChecksumValidator.cc ChunkChecksumValidator.h\
@ -76,7 +76,9 @@ SRCS = Socket.h\
AbstractAuthResolver.h\ AbstractAuthResolver.h\
DefaultAuthResolver.cc DefaultAuthResolver.h\ DefaultAuthResolver.cc DefaultAuthResolver.h\
NetrcAuthResolver.cc NetrcAuthResolver.h\ NetrcAuthResolver.cc NetrcAuthResolver.h\
RequestFactory.cc RequestFactory.h RequestFactory.cc RequestFactory.h\
DefaultFileAllocator.cc DefaultFileAllocator.h\
GlowFileAllocator.cc GlowFileAllocator.h
# debug_new.cpp # debug_new.cpp
if ENABLE_ASYNC_DNS if ENABLE_ASYNC_DNS

View File

@ -210,18 +210,19 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \ UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \ PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \ BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
SimpleRandomizer.h FileAllocator.cc FileAllocator.h \ SimpleRandomizer.h FileAllocator.h FileAllocationMonitor.cc \
FileAllocationMonitor.cc FileAllocationMonitor.h \ FileAllocationMonitor.h ConsoleFileAllocationMonitor.cc \
ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h \ ConsoleFileAllocationMonitor.h ChunkChecksumValidator.cc \
ChunkChecksumValidator.cc ChunkChecksumValidator.h \ ChunkChecksumValidator.h HttpResponse.cc HttpResponse.h \
HttpResponse.cc HttpResponse.h HttpRequest.cc HttpRequest.h \ HttpRequest.cc HttpRequest.h Range.h \
Range.h AbstractProxyRequestCommand.cc \ AbstractProxyRequestCommand.cc AbstractProxyRequestCommand.h \
AbstractProxyRequestCommand.h AbstractProxyResponseCommand.cc \ AbstractProxyResponseCommand.cc AbstractProxyResponseCommand.h \
AbstractProxyResponseCommand.h Netrc.cc Netrc.h AuthConfig.cc \ Netrc.cc Netrc.h AuthConfig.cc AuthConfig.h AuthResolver.h \
AuthConfig.h AuthResolver.h AbstractAuthResolver.h \ AbstractAuthResolver.h DefaultAuthResolver.cc \
DefaultAuthResolver.cc DefaultAuthResolver.h \ DefaultAuthResolver.h NetrcAuthResolver.cc NetrcAuthResolver.h \
NetrcAuthResolver.cc NetrcAuthResolver.h RequestFactory.cc \ RequestFactory.cc RequestFactory.h DefaultFileAllocator.cc \
RequestFactory.h NameResolver.cc NameResolver.h MetaEntry.h \ DefaultFileAllocator.h GlowFileAllocator.cc \
GlowFileAllocator.h NameResolver.cc NameResolver.h MetaEntry.h \
Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \ Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \
MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \ MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \ ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \
@ -384,13 +385,14 @@ am__objects_4 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
DownloadEngineFactory.$(OBJEXT) UrlRequestInfo.$(OBJEXT) \ DownloadEngineFactory.$(OBJEXT) UrlRequestInfo.$(OBJEXT) \
SpeedCalc.$(OBJEXT) BitfieldMan.$(OBJEXT) \ SpeedCalc.$(OBJEXT) BitfieldMan.$(OBJEXT) \
BitfieldManFactory.$(OBJEXT) SimpleRandomizer.$(OBJEXT) \ BitfieldManFactory.$(OBJEXT) SimpleRandomizer.$(OBJEXT) \
FileAllocator.$(OBJEXT) FileAllocationMonitor.$(OBJEXT) \ FileAllocationMonitor.$(OBJEXT) \
ConsoleFileAllocationMonitor.$(OBJEXT) \ ConsoleFileAllocationMonitor.$(OBJEXT) \
ChunkChecksumValidator.$(OBJEXT) HttpResponse.$(OBJEXT) \ ChunkChecksumValidator.$(OBJEXT) HttpResponse.$(OBJEXT) \
HttpRequest.$(OBJEXT) AbstractProxyRequestCommand.$(OBJEXT) \ HttpRequest.$(OBJEXT) AbstractProxyRequestCommand.$(OBJEXT) \
AbstractProxyResponseCommand.$(OBJEXT) Netrc.$(OBJEXT) \ AbstractProxyResponseCommand.$(OBJEXT) Netrc.$(OBJEXT) \
AuthConfig.$(OBJEXT) DefaultAuthResolver.$(OBJEXT) \ AuthConfig.$(OBJEXT) DefaultAuthResolver.$(OBJEXT) \
NetrcAuthResolver.$(OBJEXT) RequestFactory.$(OBJEXT) \ NetrcAuthResolver.$(OBJEXT) RequestFactory.$(OBJEXT) \
DefaultFileAllocator.$(OBJEXT) GlowFileAllocator.$(OBJEXT) \
$(am__objects_1) $(am__objects_2) $(am__objects_3) $(am__objects_1) $(am__objects_2) $(am__objects_3)
am_libaria2c_a_OBJECTS = $(am__objects_4) am_libaria2c_a_OBJECTS = $(am__objects_4)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
@ -594,18 +596,19 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \ UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \ PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \ BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
SimpleRandomizer.h FileAllocator.cc FileAllocator.h \ SimpleRandomizer.h FileAllocator.h FileAllocationMonitor.cc \
FileAllocationMonitor.cc FileAllocationMonitor.h \ FileAllocationMonitor.h ConsoleFileAllocationMonitor.cc \
ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h \ ConsoleFileAllocationMonitor.h ChunkChecksumValidator.cc \
ChunkChecksumValidator.cc ChunkChecksumValidator.h \ ChunkChecksumValidator.h HttpResponse.cc HttpResponse.h \
HttpResponse.cc HttpResponse.h HttpRequest.cc HttpRequest.h \ HttpRequest.cc HttpRequest.h Range.h \
Range.h AbstractProxyRequestCommand.cc \ AbstractProxyRequestCommand.cc AbstractProxyRequestCommand.h \
AbstractProxyRequestCommand.h AbstractProxyResponseCommand.cc \ AbstractProxyResponseCommand.cc AbstractProxyResponseCommand.h \
AbstractProxyResponseCommand.h Netrc.cc Netrc.h AuthConfig.cc \ Netrc.cc Netrc.h AuthConfig.cc AuthConfig.h AuthResolver.h \
AuthConfig.h AuthResolver.h AbstractAuthResolver.h \ AbstractAuthResolver.h DefaultAuthResolver.cc \
DefaultAuthResolver.cc DefaultAuthResolver.h \ DefaultAuthResolver.h NetrcAuthResolver.cc NetrcAuthResolver.h \
NetrcAuthResolver.cc NetrcAuthResolver.h RequestFactory.cc \ RequestFactory.cc RequestFactory.h DefaultFileAllocator.cc \
RequestFactory.h $(am__append_1) $(am__append_2) \ DefaultFileAllocator.h GlowFileAllocator.cc \
GlowFileAllocator.h $(am__append_1) $(am__append_2) \
$(am__append_3) $(am__append_3)
noinst_LIBRARIES = libaria2c.a noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
@ -743,6 +746,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtRequestFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtRequestFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultFileAllocator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerStorage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerStorage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPieceStorage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPieceStorage.Po@am__quote@
@ -757,7 +761,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfig.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)/File.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileAllocationMonitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileAllocationMonitor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileAllocator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileEntry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpConnection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpConnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpDownloadCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpDownloadCommand.Po@am__quote@
@ -765,6 +768,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpNegotiationCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpNegotiationCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelRequestCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelRequestCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelResponseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelResponseCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GlowFileAllocator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveEraseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveEraseCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.Po@am__quote@

View File

@ -450,6 +450,27 @@ void SegmentMan::markAllPiecesDone()
} }
} }
void SegmentMan::markPieceDone(int64_t length)
{
if(bitfield) {
if(length == bitfield->getTotalLength()) {
bitfield->setAllBit();
} else {
int32_t numSegment = length/bitfield->getBlockLength();
int32_t remainingLength = length%bitfield->getBlockLength();
bitfield->setBitRange(0, numSegment-1);
if(remainingLength > 0) {
SegmentHandle segment = new Segment();
segment->index = numSegment;
segment->length = bitfield->getBlockLength(numSegment);
segment->segmentLength = bitfield->getBlockLength();
segment->writtenLength = remainingLength;
usedSegmentEntries.push_back(new SegmentEntry(0, segment));
}
}
}
}
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
void SegmentMan::checkIntegrity() void SegmentMan::checkIntegrity()
{ {

View File

@ -285,6 +285,8 @@ public:
void markAllPiecesDone(); void markAllPiecesDone();
void markPieceDone(int64_t length);
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
void checkIntegrity(); void checkIntegrity();

View File

@ -41,6 +41,10 @@
#include "FatalException.h" #include "FatalException.h"
#include "message.h" #include "message.h"
#include "RequestFactory.h" #include "RequestFactory.h"
#include "GlowFileAllocator.h"
#include "File.h"
#include "DefaultDiskWriter.h"
#include "DlAbortEx.h"
std::ostream& operator<<(std::ostream& o, const HeadResult& hr) { std::ostream& operator<<(std::ostream& o, const HeadResult& hr) {
o << "filename = " << hr.filename << ", " << "totalLength = " << hr.totalLength; o << "filename = " << hr.filename << ", " << "totalLength = " << hr.totalLength;
@ -184,11 +188,41 @@ RequestInfos UrlRequestInfo::execute() {
} }
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
if(e->segmentMan->segmentFileExists()) { if(op->get(PREF_CONTINUE) == V_TRUE && e->segmentMan->fileExists()) {
e->segmentMan->load(); if(e->segmentMan->totalSize == 0) {
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath()); logger->notice("Cannot get file length. Download aborted.");
#ifdef ENABLE_MESSAGE_DIGEST return RequestInfos();
}
File existingFile(e->segmentMan->getFilePath());
if(e->segmentMan->totalSize < existingFile.size()) {
logger->notice("The local file length is larger than the remote file size. Download aborted.");
return RequestInfos();
}
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
e->segmentMan->totalSize);
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath(),
e->segmentMan->totalSize);
if(e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) { if(e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
#ifdef ENABLE_MESSAGE_DIGEST
if(!e->segmentMan->isChunkChecksumValidationReady()) {
throw new DlAbortEx("Chunk checksums are not provided.");
}
e->segmentMan->markAllPiecesDone();
e->segmentMan->checkIntegrity();
#endif // ENABLE_MESSAGE_DIGEST
} else {
e->segmentMan->markPieceDone(existingFile.size());
}
} else if(e->segmentMan->segmentFileExists()) {
e->segmentMan->load();
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath(),
e->segmentMan->totalSize);
#ifdef ENABLE_MESSAGE_DIGEST
if(op->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
if(!e->segmentMan->isChunkChecksumValidationReady()) {
throw new DlAbortEx("Chunk checksums are not provided.");
}
e->segmentMan->checkIntegrity(); e->segmentMan->checkIntegrity();
} }
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
@ -202,7 +236,13 @@ RequestInfos UrlRequestInfo::execute() {
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE), e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
e->segmentMan->totalSize); e->segmentMan->totalSize);
if(e->segmentMan->fileExists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) { if(e->segmentMan->fileExists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath()); #ifdef ENABLE_MESSAGE_DIGEST
if(!e->segmentMan->isChunkChecksumValidationReady()) {
throw new DlAbortEx("Chunk checksums are not provided.");
}
#endif // ENABLE_MESSAGE_DIGEST
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath(),
e->segmentMan->totalSize);
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
e->segmentMan->markAllPiecesDone(); e->segmentMan->markAllPiecesDone();
e->segmentMan->checkIntegrity(); e->segmentMan->checkIntegrity();

View File

@ -352,6 +352,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE); op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
op->put(PREF_CHECK_INTEGRITY, V_FALSE); op->put(PREF_CHECK_INTEGRITY, V_FALSE);
op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc"); op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc");
op->put(PREF_CONTINUE, V_FALSE);
while(1) { while(1) {
int optIndex = 0; int optIndex = 0;
int lopt; int lopt;
@ -383,7 +384,8 @@ int main(int argc, char* argv[]) {
{ "file-allocation", required_argument, 0, 'a' }, { "file-allocation", required_argument, 0, 'a' },
{ "allow-overwrite", required_argument, &lopt, 202 }, { "allow-overwrite", required_argument, &lopt, 202 },
{ "check-integrity", required_argument, &lopt, 203 }, { "check-integrity", required_argument, &lopt, 203 },
{" realtime-chunk-checksum", required_argument, &lopt, 204 }, { "realtime-chunk-checksum", required_argument, &lopt, 204 },
{ "continue", no_argument, NULL, 'c' },
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
{ "torrent-file", required_argument, NULL, 'T' }, { "torrent-file", required_argument, NULL, 'T' },
{ "listen-port", required_argument, &lopt, 15 }, { "listen-port", required_argument, &lopt, 15 },
@ -411,7 +413,7 @@ int main(int argc, char* argv[]) {
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
c = getopt_long(argc, argv, "Dd:o:l:s:pt:m:vhST:M:C:a:", longOpts, &optIndex); c = getopt_long(argc, argv, "Dd:o:l:s:pt:m:vhST:M:C:a:c", longOpts, &optIndex);
if(c == -1) { if(c == -1) {
break; break;
} }
@ -717,6 +719,9 @@ int main(int argc, char* argv[]) {
} }
break; break;
} }
case 'c':
op->put(PREF_CONTINUE, V_TRUE);
break;
case 'v': case 'v':
showVersion(); showVersion();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View File

@ -92,6 +92,8 @@
#define PREF_CHECK_INTEGRITY "check_integrity" #define PREF_CHECK_INTEGRITY "check_integrity"
// value: string that your file system recognizes as a file name. // value: string that your file system recognizes as a file name.
#define PREF_NETRC_PATH "netrc_path" #define PREF_NETRC_PATH "netrc_path"
// value:
#define PREF_CONTINUE "continue"
/** /**
* FTP related preferences * FTP related preferences

View File

@ -17,6 +17,7 @@ class BitfieldManTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testGetSparceMissingUnusedIndex); CPPUNIT_TEST(testGetSparceMissingUnusedIndex);
CPPUNIT_TEST(testIsBitSetOffsetRange); CPPUNIT_TEST(testIsBitSetOffsetRange);
CPPUNIT_TEST(testGetMissingUnusedLength); CPPUNIT_TEST(testGetMissingUnusedLength);
CPPUNIT_TEST(testSetBitRange);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
RandomizerHandle fixedNumberRandomizer; RandomizerHandle fixedNumberRandomizer;
@ -39,6 +40,7 @@ public:
void testGetSparceMissingUnusedIndex(); void testGetSparceMissingUnusedIndex();
void testIsBitSetOffsetRange(); void testIsBitSetOffsetRange();
void testGetMissingUnusedLength(); void testGetMissingUnusedLength();
void testSetBitRange();
}; };
@ -303,3 +305,21 @@ void BitfieldManTest::testGetMissingUnusedLength()
// from index 1 // from index 1
CPPUNIT_ASSERT_EQUAL((int64_t)3*blockLength, bf.getMissingUnusedLength(1)); CPPUNIT_ASSERT_EQUAL((int64_t)3*blockLength, bf.getMissingUnusedLength(1));
} }
void BitfieldManTest::testSetBitRange()
{
int32_t blockLength = 1024*1024;
int64_t totalLength = 10*blockLength;
BitfieldMan bf(blockLength, totalLength);
bf.setBitRange(0, 4);
for(int32_t i = 0; i < 5; ++i) {
CPPUNIT_ASSERT(bf.isBitSet(i));
}
for(int32_t i = 5; i < 10; ++i) {
CPPUNIT_ASSERT(!bf.isBitSet(i));
}
CPPUNIT_ASSERT_EQUAL(int64_t(5*blockLength), bf.getCompletedLength());
}

View File

@ -0,0 +1,58 @@
#include "GlowFileAllocator.h"
#include "File.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fstream>
#include <iomanip>
#include <cppunit/extensions/HelperMacros.h>
class GlowFileAllocatorTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(GlowFileAllocatorTest);
CPPUNIT_TEST(testAllocate);
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {}
void testAllocate();
};
CPPUNIT_TEST_SUITE_REGISTRATION( GlowFileAllocatorTest );
void GlowFileAllocatorTest::testAllocate()
{
string fn = "/tmp/aria2_GlowFileAllocatorTest_testAllocate";
ofstream of(fn.c_str());
of << "0123456789";
of.close();
File x("/tmp/aria2_GlowFileAllocatorTest_testAllocate");
CPPUNIT_ASSERT_EQUAL((int64_t)10, x.size());
int fd;
if((fd = open(fn.c_str(), O_RDWR, S_IRUSR|S_IWUSR)) < 0) {
CPPUNIT_FAIL("cannot open file");
}
GlowFileAllocator allocator;
allocator.allocate(fd, 4097);
if(close(fd) < 0) {
CPPUNIT_FAIL("cannot close file");
}
ifstream is(fn.c_str());
char buf[11];
is >> std::setw(sizeof(buf)) >> buf;
CPPUNIT_ASSERT(strcmp("0123456789", buf) == 0);
File f(fn);
CPPUNIT_ASSERT_EQUAL((int64_t)4097, f.size());
}

View File

@ -1,13 +1,15 @@
TESTS = aria2c TESTS = aria2c
check_PROGRAMS = $(TESTS) check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\ aria2c_SOURCES = AllTest.cc\
SegmentManTest.cc\
BitfieldManTest.cc\
GlowFileAllocatorTest.cc\
RequestTest.cc\ RequestTest.cc\
HttpRequestTest.cc\ HttpRequestTest.cc\
NetrcTest.cc\ NetrcTest.cc\
SingletonHolderTest.cc\ SingletonHolderTest.cc\
HttpHeaderTest.cc\ HttpHeaderTest.cc\
HttpResponseTest.cc\ HttpResponseTest.cc\
BitfieldManTest.cc\
SharedHandleTest.cc\ SharedHandleTest.cc\
ChunkedEncodingTest.cc\ ChunkedEncodingTest.cc\
FileTest.cc\ FileTest.cc\
@ -29,7 +31,6 @@ aria2c_SOURCES = AllTest.cc\
FeatureConfigTest.cc\ FeatureConfigTest.cc\
ShareRatioSeedCriteriaTest.cc\ ShareRatioSeedCriteriaTest.cc\
TimeSeedCriteriaTest.cc\ TimeSeedCriteriaTest.cc\
SegmentManTest.cc\
SpeedCalcTest.cc\ SpeedCalcTest.cc\
DefaultPeerListProcessorTest.cc\ DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc\ AnnounceListTest.cc\

View File

@ -57,10 +57,11 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT) am__EXEEXT_1 = aria2c$(EXEEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \ am_aria2c_OBJECTS = AllTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \
HttpRequestTest.$(OBJEXT) NetrcTest.$(OBJEXT) \ BitfieldManTest.$(OBJEXT) GlowFileAllocatorTest.$(OBJEXT) \
SingletonHolderTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \ RequestTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \
HttpResponseTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \ NetrcTest.$(OBJEXT) SingletonHolderTest.$(OBJEXT) \
HttpHeaderTest.$(OBJEXT) HttpResponseTest.$(OBJEXT) \
SharedHandleTest.$(OBJEXT) ChunkedEncodingTest.$(OBJEXT) \ SharedHandleTest.$(OBJEXT) ChunkedEncodingTest.$(OBJEXT) \
FileTest.$(OBJEXT) OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) \ FileTest.$(OBJEXT) OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) \
UtilTest.$(OBJEXT) CookieBoxTest.$(OBJEXT) DataTest.$(OBJEXT) \ UtilTest.$(OBJEXT) CookieBoxTest.$(OBJEXT) DataTest.$(OBJEXT) \
@ -71,8 +72,8 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
Xml2MetalinkProcessorTest.$(OBJEXT) MetalinkerTest.$(OBJEXT) \ Xml2MetalinkProcessorTest.$(OBJEXT) MetalinkerTest.$(OBJEXT) \
MetalinkEntryTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) \ MetalinkEntryTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) \
ShareRatioSeedCriteriaTest.$(OBJEXT) \ ShareRatioSeedCriteriaTest.$(OBJEXT) \
TimeSeedCriteriaTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \ TimeSeedCriteriaTest.$(OBJEXT) SpeedCalcTest.$(OBJEXT) \
SpeedCalcTest.$(OBJEXT) DefaultPeerListProcessorTest.$(OBJEXT) \ DefaultPeerListProcessorTest.$(OBJEXT) \
AnnounceListTest.$(OBJEXT) TrackerWatcherCommandTest.$(OBJEXT) \ AnnounceListTest.$(OBJEXT) TrackerWatcherCommandTest.$(OBJEXT) \
DefaultBtContextTest.$(OBJEXT) \ DefaultBtContextTest.$(OBJEXT) \
DefaultPieceStorageTest.$(OBJEXT) \ DefaultPieceStorageTest.$(OBJEXT) \
@ -258,13 +259,15 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
TESTS = aria2c TESTS = aria2c
aria2c_SOURCES = AllTest.cc\ aria2c_SOURCES = AllTest.cc\
SegmentManTest.cc\
BitfieldManTest.cc\
GlowFileAllocatorTest.cc\
RequestTest.cc\ RequestTest.cc\
HttpRequestTest.cc\ HttpRequestTest.cc\
NetrcTest.cc\ NetrcTest.cc\
SingletonHolderTest.cc\ SingletonHolderTest.cc\
HttpHeaderTest.cc\ HttpHeaderTest.cc\
HttpResponseTest.cc\ HttpResponseTest.cc\
BitfieldManTest.cc\
SharedHandleTest.cc\ SharedHandleTest.cc\
ChunkedEncodingTest.cc\ ChunkedEncodingTest.cc\
FileTest.cc\ FileTest.cc\
@ -286,7 +289,6 @@ aria2c_SOURCES = AllTest.cc\
FeatureConfigTest.cc\ FeatureConfigTest.cc\
ShareRatioSeedCriteriaTest.cc\ ShareRatioSeedCriteriaTest.cc\
TimeSeedCriteriaTest.cc\ TimeSeedCriteriaTest.cc\
SegmentManTest.cc\
SpeedCalcTest.cc\ SpeedCalcTest.cc\
DefaultPeerListProcessorTest.cc\ DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc\ AnnounceListTest.cc\
@ -423,6 +425,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DictionaryTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DictionaryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfigTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfigTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GlowFileAllocatorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseTest.Po@am__quote@

View File

@ -12,6 +12,8 @@ class SegmentManTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSaveAndLoad); CPPUNIT_TEST(testSaveAndLoad);
CPPUNIT_TEST(testNullBitfield); CPPUNIT_TEST(testNullBitfield);
CPPUNIT_TEST(testCancelSegmentOnNullBitfield); CPPUNIT_TEST(testCancelSegmentOnNullBitfield);
CPPUNIT_TEST(testMarkPieceDone);
CPPUNIT_TEST(testMarkPieceDone_usedSegment);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -22,7 +24,8 @@ public:
void testSaveAndLoad(); void testSaveAndLoad();
void testNullBitfield(); void testNullBitfield();
void testCancelSegmentOnNullBitfield(); void testCancelSegmentOnNullBitfield();
void testMarkPieceDone();
void testMarkPieceDone_usedSegment();
}; };
@ -109,3 +112,41 @@ void SegmentManTest::testCancelSegmentOnNullBitfield() {
CPPUNIT_ASSERT(!segmentMan.getSegment(1).isNull()); CPPUNIT_ASSERT(!segmentMan.getSegment(1).isNull());
} }
void SegmentManTest::testMarkPieceDone()
{
SegmentMan segmentMan;
int32_t pieceLength = 1024*1024;
int64_t totalLength = 10*pieceLength;
segmentMan.initBitfield(pieceLength, totalLength);
segmentMan.markPieceDone(5*pieceLength);
for(int32_t i = 0; i < 5; ++i) {
CPPUNIT_ASSERT(segmentMan.hasSegment(i));
}
for(int32_t i = 5; i < 10; ++i) {
CPPUNIT_ASSERT(!segmentMan.hasSegment(i));
}
}
void SegmentManTest::testMarkPieceDone_usedSegment()
{
SegmentMan segmentMan;
int32_t pieceLength = 1024*1024;
int64_t totalLength = 10*pieceLength;
segmentMan.initBitfield(pieceLength, totalLength);
segmentMan.markPieceDone(5*pieceLength+100);
for(int32_t i = 0; i < 5; ++i) {
CPPUNIT_ASSERT(segmentMan.hasSegment(i));
}
for(int32_t i = 5; i < 10; ++i) {
CPPUNIT_ASSERT(!segmentMan.hasSegment(i));
}
SegmentHandle segment = segmentMan.getSegment(0, 5);
CPPUNIT_ASSERT(!segment.isNull());
CPPUNIT_ASSERT_EQUAL(5, segment->index);
CPPUNIT_ASSERT_EQUAL(pieceLength, segment->length);
CPPUNIT_ASSERT_EQUAL(pieceLength, segment->segmentLength);
CPPUNIT_ASSERT_EQUAL(100, segment->writtenLength);
}