summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2007-03-24 14:32:49 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2007-03-24 14:32:49 +0000
commita37aaa9c0c43c1013b323f28545eb9330d56dee3 (patch)
tree0aef46aad2dee8da1dd5f95d9a9d90100caa90b7
parent5649cf6cda777cff7749b12f5286272959520a4f (diff)
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
-rw-r--r--ChangeLog28
-rw-r--r--TODO3
-rw-r--r--src/AbstractDiskWriter.cc11
-rw-r--r--src/AbstractDiskWriter.h11
-rw-r--r--src/BitfieldMan.cc8
-rw-r--r--src/BitfieldMan.h2
-rw-r--r--src/ByteArrayDiskWriter.cc3
-rw-r--r--src/ByteArrayDiskWriter.h2
-rw-r--r--src/DefaultDiskWriter.cc10
-rw-r--r--src/DefaultFileAllocator.cc (renamed from src/FileAllocator.cc)5
-rw-r--r--src/DefaultFileAllocator.h51
-rw-r--r--src/DiskAdaptorWriter.h2
-rw-r--r--src/DiskWriter.h2
-rw-r--r--src/FileAllocator.h6
-rw-r--r--src/GlowFileAllocator.cc74
-rw-r--r--src/GlowFileAllocator.h51
-rw-r--r--src/Makefile.am6
-rw-r--r--src/Makefile.in56
-rw-r--r--src/SegmentMan.cc21
-rw-r--r--src/SegmentMan.h2
-rw-r--r--src/UrlRequestInfo.cc48
-rw-r--r--src/main.cc9
-rw-r--r--src/prefs.h2
-rw-r--r--test/BitfieldManTest.cc20
-rw-r--r--test/GlowFileAllocatorTest.cc58
-rw-r--r--test/Makefile.am5
-rw-r--r--test/Makefile.in19
-rw-r--r--test/SegmentManTest.cc43
28 files changed, 497 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index 96e193aa..9e1d5182 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* src/Request.h: Use AuthResolver to get authentication information.
diff --git a/TODO b/TODO
index 74b69b9c..4c56c567 100644
--- a/TODO
+++ b/TODO
@@ -28,4 +28,5 @@
* -c command line option to continue the download of existing file assuming
that it was downloaded from the beginning.
* Continue file allocation with existing file
-* keep-alive \ No newline at end of file
+* Netrc, mode 600, enabled in ftp, http, all
+* preallocate file in MultiDiskAdaptor \ No newline at end of file
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index 476ce676..1e9bcaed 100644
--- a/src/AbstractDiskWriter.cc
+++ b/src/AbstractDiskWriter.cc
@@ -47,6 +47,7 @@
AbstractDiskWriter::AbstractDiskWriter():
fd(0),
fileAllocator(0),
+ glowFileAllocator(0),
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;
File f(filename);
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) {
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) {
diff --git a/src/AbstractDiskWriter.h b/src/AbstractDiskWriter.h
index b6807e46..2ba973df 100644
--- a/src/AbstractDiskWriter.h
+++ b/src/AbstractDiskWriter.h
@@ -44,6 +44,7 @@ protected:
string filename;
int32_t fd;
FileAllocatorHandle fileAllocator;
+ FileAllocatorHandle glowFileAllocator;
const Logger* logger;
void createFile(const string& filename, int32_t addFlags = 0);
@@ -62,7 +63,7 @@ public:
virtual void closeFile();
- virtual void openExistingFile(const string& filename);
+ virtual void openExistingFile(const string& filename, int64_t totalLength = 0);
#ifdef ENABLE_MESSAGE_DIGEST
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);
- void setFileAllocator(const FileAllocatorHandle& fileAllocator) {
+ void setFileAllocator(const FileAllocatorHandle& fileAllocator)
+ {
this->fileAllocator = fileAllocator;
}
+
+ void setGlowFileAllocator(const FileAllocatorHandle& fileAllocator)
+ {
+ this->glowFileAllocator = fileAllocator;
+ }
};
#endif // _D_ABSTRACT_DISK_WRITER_H_
diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc
index ef9a4cbe..afcf027a 100644
--- a/src/BitfieldMan.cc
+++ b/src/BitfieldMan.cc
@@ -645,6 +645,14 @@ void BitfieldMan::unsetBitRange(int32_t startIndex, int32_t endIndex)
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
{
if(length <= 0) {
diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h
index cfca8e4d..fbbf60ae 100644
--- a/src/BitfieldMan.h
+++ b/src/BitfieldMan.h
@@ -255,6 +255,8 @@ public:
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;
int64_t getMissingUnusedLength(int32_t startingIndex) const;
diff --git a/src/ByteArrayDiskWriter.cc b/src/ByteArrayDiskWriter.cc
index ca9564f7..089a6c21 100644
--- a/src/ByteArrayDiskWriter.cc
+++ b/src/ByteArrayDiskWriter.cc
@@ -68,7 +68,8 @@ void ByteArrayDiskWriter::closeFile() {
clear();
}
-void ByteArrayDiskWriter::openExistingFile(const string& filename) {
+void ByteArrayDiskWriter::openExistingFile(const string& filename,
+ int64_t totalLength) {
openFile(filename);
}
diff --git a/src/ByteArrayDiskWriter.h b/src/ByteArrayDiskWriter.h
index e11917ff..7e1b0b02 100644
--- a/src/ByteArrayDiskWriter.h
+++ b/src/ByteArrayDiskWriter.h
@@ -55,7 +55,7 @@ public:
virtual void closeFile();
- virtual void openExistingFile(const string& filename);
+ virtual void openExistingFile(const string& filename, int64_t totalLength = 0);
// position is ignored
virtual void writeData(const char* data, int32_t len, int64_t position = 0);
diff --git a/src/DefaultDiskWriter.cc b/src/DefaultDiskWriter.cc
index 1e119ea6..0fbd83f6 100644
--- a/src/DefaultDiskWriter.cc
+++ b/src/DefaultDiskWriter.cc
@@ -35,7 +35,8 @@
#include "DefaultDiskWriter.h"
#include "DlAbortEx.h"
#include "message.h"
-#include "FileAllocator.h"
+#include "DefaultFileAllocator.h"
+#include "GlowFileAllocator.h"
#include "prefs.h"
#include "Util.h"
#include <errno.h>
@@ -69,11 +70,16 @@ DefaultDiskWriter* DefaultDiskWriter::createNewDiskWriter(const Option* option)
{
DefaultDiskWriter* diskWriter = new DefaultDiskWriter();
if(option->get(PREF_FILE_ALLOCATION) == V_PREALLOC) {
- FileAllocatorHandle allocator = new FileAllocator();
+ DefaultFileAllocatorHandle allocator = new DefaultFileAllocator();
allocator->setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor());
diskWriter->setFileAllocator(allocator);
+
+ GlowFileAllocatorHandle glowAllocator = new GlowFileAllocator();
+ glowAllocator->setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor());
+ diskWriter->setGlowFileAllocator(glowAllocator);
} else {
diskWriter->setFileAllocator(0);
+ diskWriter->setGlowFileAllocator(0);
}
return diskWriter;
}
diff --git a/src/FileAllocator.cc b/src/DefaultFileAllocator.cc
index aa027649..9dbd9247 100644
--- a/src/FileAllocator.cc
+++ b/src/DefaultFileAllocator.cc
@@ -1,4 +1,3 @@
-
/* <!-- copyright */
/*
* aria2 - The high speed download utility
@@ -33,14 +32,14 @@
* files in the program, then also delete it here.
*/
/* copyright --> */
-#include "FileAllocator.h"
+#include "DefaultFileAllocator.h"
#include "DlAbortEx.h"
#include "TimeA2.h"
#include <sys/types.h>
#include <unistd.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)) {
throw new DlAbortEx("Seek failed: %s", strerror(errno));
diff --git a/src/DefaultFileAllocator.h b/src/DefaultFileAllocator.h
new file mode 100644
index 00000000..1a74939a
--- /dev/null
+++ b/src/DefaultFileAllocator.h
@@ -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_
diff --git a/src/DiskAdaptorWriter.h b/src/DiskAdaptorWriter.h
index 016f2634..ea67d2f0 100644
--- a/src/DiskAdaptorWriter.h
+++ b/src/DiskAdaptorWriter.h
@@ -62,7 +62,7 @@ public:
diskAdaptor->closeFile();
}
- virtual void openExistingFile(const string& filename)
+ virtual void openExistingFile(const string& filename, int64_t totalLength = 0)
{
diskAdaptor->openExistingFile();
}
diff --git a/src/DiskWriter.h b/src/DiskWriter.h
index e8c946c3..dc4c57a3 100644
--- a/src/DiskWriter.h
+++ b/src/DiskWriter.h
@@ -70,7 +70,7 @@ public:
*
* @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.
diff --git a/src/FileAllocator.h b/src/FileAllocator.h
index 7e8f45a1..43e68b84 100644
--- a/src/FileAllocator.h
+++ b/src/FileAllocator.h
@@ -40,14 +40,14 @@
#include "NullFileAllocationMonitor.h"
class FileAllocator {
-private:
+protected:
FileAllocationMonitorHandle fileAllocationMonitor;
public:
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)
{
diff --git a/src/GlowFileAllocator.cc b/src/GlowFileAllocator.cc
new file mode 100644
index 00000000..645c6216
--- /dev/null
+++ b/src/GlowFileAllocator.cc
@@ -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);
+}
diff --git a/src/GlowFileAllocator.h b/src/GlowFileAllocator.h
new file mode 100644
index 00000000..a16af76b
--- /dev/null
+++ b/src/GlowFileAllocator.h
@@ -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_
diff --git a/src/Makefile.am b/src/Makefile.am
index eda3018b..9017f733 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -61,7 +61,7 @@ SRCS = Socket.h\
BitfieldManFactory.cc BitfieldManFactory.h\
Randomizer.h\
SimpleRandomizer.cc SimpleRandomizer.h\
- FileAllocator.cc FileAllocator.h\
+ FileAllocator.h\
FileAllocationMonitor.cc FileAllocationMonitor.h\
ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h\
ChunkChecksumValidator.cc ChunkChecksumValidator.h\
@@ -76,7 +76,9 @@ SRCS = Socket.h\
AbstractAuthResolver.h\
DefaultAuthResolver.cc DefaultAuthResolver.h\
NetrcAuthResolver.cc NetrcAuthResolver.h\
- RequestFactory.cc RequestFactory.h
+ RequestFactory.cc RequestFactory.h\
+ DefaultFileAllocator.cc DefaultFileAllocator.h\
+ GlowFileAllocator.cc GlowFileAllocator.h
# debug_new.cpp
if ENABLE_ASYNC_DNS
diff --git a/src/Makefile.in b/src/Makefile.in
index 761e98bc..8ff9d2fd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -210,18 +210,19 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
- SimpleRandomizer.h FileAllocator.cc FileAllocator.h \
- FileAllocationMonitor.cc FileAllocationMonitor.h \
- ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h \
- ChunkChecksumValidator.cc ChunkChecksumValidator.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 RequestFactory.cc \
- RequestFactory.h NameResolver.cc NameResolver.h MetaEntry.h \
+ SimpleRandomizer.h FileAllocator.h FileAllocationMonitor.cc \
+ FileAllocationMonitor.h ConsoleFileAllocationMonitor.cc \
+ ConsoleFileAllocationMonitor.h ChunkChecksumValidator.cc \
+ ChunkChecksumValidator.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 \
+ RequestFactory.cc RequestFactory.h DefaultFileAllocator.cc \
+ DefaultFileAllocator.h GlowFileAllocator.cc \
+ GlowFileAllocator.h NameResolver.cc NameResolver.h MetaEntry.h \
Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \
MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \
@@ -384,13 +385,14 @@ am__objects_4 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
DownloadEngineFactory.$(OBJEXT) UrlRequestInfo.$(OBJEXT) \
SpeedCalc.$(OBJEXT) BitfieldMan.$(OBJEXT) \
BitfieldManFactory.$(OBJEXT) SimpleRandomizer.$(OBJEXT) \
- FileAllocator.$(OBJEXT) FileAllocationMonitor.$(OBJEXT) \
+ FileAllocationMonitor.$(OBJEXT) \
ConsoleFileAllocationMonitor.$(OBJEXT) \
ChunkChecksumValidator.$(OBJEXT) HttpResponse.$(OBJEXT) \
HttpRequest.$(OBJEXT) AbstractProxyRequestCommand.$(OBJEXT) \
AbstractProxyResponseCommand.$(OBJEXT) Netrc.$(OBJEXT) \
AuthConfig.$(OBJEXT) DefaultAuthResolver.$(OBJEXT) \
NetrcAuthResolver.$(OBJEXT) RequestFactory.$(OBJEXT) \
+ DefaultFileAllocator.$(OBJEXT) GlowFileAllocator.$(OBJEXT) \
$(am__objects_1) $(am__objects_2) $(am__objects_3)
am_libaria2c_a_OBJECTS = $(am__objects_4)
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 \
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
- SimpleRandomizer.h FileAllocator.cc FileAllocator.h \
- FileAllocationMonitor.cc FileAllocationMonitor.h \
- ConsoleFileAllocationMonitor.cc ConsoleFileAllocationMonitor.h \
- ChunkChecksumValidator.cc ChunkChecksumValidator.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 RequestFactory.cc \
- RequestFactory.h $(am__append_1) $(am__append_2) \
+ SimpleRandomizer.h FileAllocator.h FileAllocationMonitor.cc \
+ FileAllocationMonitor.h ConsoleFileAllocationMonitor.cc \
+ ConsoleFileAllocationMonitor.h ChunkChecksumValidator.cc \
+ ChunkChecksumValidator.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 \
+ RequestFactory.cc RequestFactory.h DefaultFileAllocator.cc \
+ DefaultFileAllocator.h GlowFileAllocator.cc \
+ GlowFileAllocator.h $(am__append_1) $(am__append_2) \
$(am__append_3)
noinst_LIBRARIES = libaria2c.a
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)/DefaultBtRequestFactory.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)/DefaultPeerStorage.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)/File.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)/FtpConnection.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)/FtpTunnelRequestCommand.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)/HttpConnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.Po@am__quote@
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index df055317..906be443 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -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
void SegmentMan::checkIntegrity()
{
diff --git a/src/SegmentMan.h b/src/SegmentMan.h
index 16b7a6e1..ac72994f 100644
--- a/src/SegmentMan.h
+++ b/src/SegmentMan.h
@@ -285,6 +285,8 @@ public:
void markAllPiecesDone();
+ void markPieceDone(int64_t length);
+
#ifdef ENABLE_MESSAGE_DIGEST
void checkIntegrity();
diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc
index a9c5868d..05d1fad9 100644
--- a/src/UrlRequestInfo.cc
+++ b/src/UrlRequestInfo.cc
@@ -41,6 +41,10 @@
#include "FatalException.h"
#include "message.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) {
o << "filename = " << hr.filename << ", " << "totalLength = " << hr.totalLength;
@@ -184,11 +188,41 @@ RequestInfos UrlRequestInfo::execute() {
}
#endif // ENABLE_MESSAGE_DIGEST
- if(e->segmentMan->segmentFileExists()) {
+ if(op->get(PREF_CONTINUE) == V_TRUE && e->segmentMan->fileExists()) {
+ if(e->segmentMan->totalSize == 0) {
+ logger->notice("Cannot get file length. Download aborted.");
+ 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) {
+#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->diskWriter->openExistingFile(e->segmentMan->getFilePath(),
+ e->segmentMan->totalSize);
#ifdef ENABLE_MESSAGE_DIGEST
- if(e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
+ if(op->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
+ if(!e->segmentMan->isChunkChecksumValidationReady()) {
+ throw new DlAbortEx("Chunk checksums are not provided.");
+ }
e->segmentMan->checkIntegrity();
}
#endif // ENABLE_MESSAGE_DIGEST
@@ -202,7 +236,13 @@ RequestInfos UrlRequestInfo::execute() {
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
e->segmentMan->totalSize);
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
e->segmentMan->markAllPiecesDone();
e->segmentMan->checkIntegrity();
diff --git a/src/main.cc b/src/main.cc
index e3296473..6607c58b 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -352,6 +352,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
op->put(PREF_CHECK_INTEGRITY, V_FALSE);
op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc");
+ op->put(PREF_CONTINUE, V_FALSE);
while(1) {
int optIndex = 0;
int lopt;
@@ -383,7 +384,8 @@ int main(int argc, char* argv[]) {
{ "file-allocation", required_argument, 0, 'a' },
{ "allow-overwrite", required_argument, &lopt, 202 },
{ "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
{ "torrent-file", required_argument, NULL, 'T' },
{ "listen-port", required_argument, &lopt, 15 },
@@ -411,7 +413,7 @@ int main(int argc, char* argv[]) {
{ "help", no_argument, NULL, 'h' },
{ 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) {
break;
}
@@ -717,6 +719,9 @@ int main(int argc, char* argv[]) {
}
break;
}
+ case 'c':
+ op->put(PREF_CONTINUE, V_TRUE);
+ break;
case 'v':
showVersion();
exit(EXIT_SUCCESS);
diff --git a/src/prefs.h b/src/prefs.h
index 4846f80b..0ab155c3 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -92,6 +92,8 @@
#define PREF_CHECK_INTEGRITY "check_integrity"
// value: string that your file system recognizes as a file name.
#define PREF_NETRC_PATH "netrc_path"
+// value:
+#define PREF_CONTINUE "continue"
/**
* FTP related preferences
diff --git a/test/BitfieldManTest.cc b/test/BitfieldManTest.cc
index 8091b7b4..71459743 100644
--- a/test/BitfieldManTest.cc
+++ b/test/BitfieldManTest.cc
@@ -17,6 +17,7 @@ class BitfieldManTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testGetSparceMissingUnusedIndex);
CPPUNIT_TEST(testIsBitSetOffsetRange);
CPPUNIT_TEST(testGetMissingUnusedLength);
+ CPPUNIT_TEST(testSetBitRange);
CPPUNIT_TEST_SUITE_END();
private:
RandomizerHandle fixedNumberRandomizer;
@@ -39,6 +40,7 @@ public:
void testGetSparceMissingUnusedIndex();
void testIsBitSetOffsetRange();
void testGetMissingUnusedLength();
+ void testSetBitRange();
};
@@ -303,3 +305,21 @@ void BitfieldManTest::testGetMissingUnusedLength()
// from index 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());
+}
diff --git a/test/GlowFileAllocatorTest.cc b/test/GlowFileAllocatorTest.cc
new file mode 100644
index 00000000..a02d2bdb
--- /dev/null
+++ b/test/GlowFileAllocatorTest.cc
@@ -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());
+}
diff --git a/test/Makefile.am b/test/Makefile.am
index a3937a25..b6b126d9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,13 +1,15 @@
TESTS = aria2c
check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\
+ SegmentManTest.cc\
+ BitfieldManTest.cc\
+ GlowFileAllocatorTest.cc\
RequestTest.cc\
HttpRequestTest.cc\
NetrcTest.cc\
SingletonHolderTest.cc\
HttpHeaderTest.cc\
HttpResponseTest.cc\
- BitfieldManTest.cc\
SharedHandleTest.cc\
ChunkedEncodingTest.cc\
FileTest.cc\
@@ -29,7 +31,6 @@ aria2c_SOURCES = AllTest.cc\
FeatureConfigTest.cc\
ShareRatioSeedCriteriaTest.cc\
TimeSeedCriteriaTest.cc\
- SegmentManTest.cc\
SpeedCalcTest.cc\
DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc\
diff --git a/test/Makefile.in b/test/Makefile.in
index 01f61700..a0d41d67 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -57,10 +57,11 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT)
-am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
- HttpRequestTest.$(OBJEXT) NetrcTest.$(OBJEXT) \
- SingletonHolderTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \
- HttpResponseTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
+am_aria2c_OBJECTS = AllTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \
+ BitfieldManTest.$(OBJEXT) GlowFileAllocatorTest.$(OBJEXT) \
+ RequestTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \
+ NetrcTest.$(OBJEXT) SingletonHolderTest.$(OBJEXT) \
+ HttpHeaderTest.$(OBJEXT) HttpResponseTest.$(OBJEXT) \
SharedHandleTest.$(OBJEXT) ChunkedEncodingTest.$(OBJEXT) \
FileTest.$(OBJEXT) OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) \
UtilTest.$(OBJEXT) CookieBoxTest.$(OBJEXT) DataTest.$(OBJEXT) \
@@ -71,8 +72,8 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
Xml2MetalinkProcessorTest.$(OBJEXT) MetalinkerTest.$(OBJEXT) \
MetalinkEntryTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) \
ShareRatioSeedCriteriaTest.$(OBJEXT) \
- TimeSeedCriteriaTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \
- SpeedCalcTest.$(OBJEXT) DefaultPeerListProcessorTest.$(OBJEXT) \
+ TimeSeedCriteriaTest.$(OBJEXT) SpeedCalcTest.$(OBJEXT) \
+ DefaultPeerListProcessorTest.$(OBJEXT) \
AnnounceListTest.$(OBJEXT) TrackerWatcherCommandTest.$(OBJEXT) \
DefaultBtContextTest.$(OBJEXT) \
DefaultPieceStorageTest.$(OBJEXT) \
@@ -258,13 +259,15 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
TESTS = aria2c
aria2c_SOURCES = AllTest.cc\
+ SegmentManTest.cc\
+ BitfieldManTest.cc\
+ GlowFileAllocatorTest.cc\
RequestTest.cc\
HttpRequestTest.cc\
NetrcTest.cc\
SingletonHolderTest.cc\
HttpHeaderTest.cc\
HttpResponseTest.cc\
- BitfieldManTest.cc\
SharedHandleTest.cc\
ChunkedEncodingTest.cc\
FileTest.cc\
@@ -286,7 +289,6 @@ aria2c_SOURCES = AllTest.cc\
FeatureConfigTest.cc\
ShareRatioSeedCriteriaTest.cc\
TimeSeedCriteriaTest.cc\
- SegmentManTest.cc\
SpeedCalcTest.cc\
DefaultPeerListProcessorTest.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)/FeatureConfigTest.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)/HttpRequestTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseTest.Po@am__quote@
diff --git a/test/SegmentManTest.cc b/test/SegmentManTest.cc
index 2159cf1b..dbb9f639 100644
--- a/test/SegmentManTest.cc
+++ b/test/SegmentManTest.cc
@@ -12,6 +12,8 @@ class SegmentManTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSaveAndLoad);
CPPUNIT_TEST(testNullBitfield);
CPPUNIT_TEST(testCancelSegmentOnNullBitfield);
+ CPPUNIT_TEST(testMarkPieceDone);
+ CPPUNIT_TEST(testMarkPieceDone_usedSegment);
CPPUNIT_TEST_SUITE_END();
private:
@@ -22,7 +24,8 @@ public:
void testSaveAndLoad();
void testNullBitfield();
void testCancelSegmentOnNullBitfield();
-
+ void testMarkPieceDone();
+ void testMarkPieceDone_usedSegment();
};
@@ -109,3 +112,41 @@ void SegmentManTest::testCancelSegmentOnNullBitfield() {
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);
+}