2006-04-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

* src/TorrentConsoleDownloadEngine.cc
	(onPartialDownloadingCompletes): Renamed as
	onSelectiveDownloadingCompletes.
	(onSelectiveDownloadingCompletes): Updated message.

	To add DiskAdaptor which abstract DiskWriter family:

	* src/PeerConnection.cc: Use diskAdaptor instead of diskWriter.
	* src/PeerInteractionCommand.cc: Use diskAdaptor instead of 
diskWriter.
	* src/BitfieldMan.cc (isAllBitSet): bug fix.
	* src/TorrentMan.cc : Included CopyDiskAdaptor.h, 
DirectDiskAdaptor.h,
	MultiDiskAdaptor.h.
	(readFileEntry): Changed its arguments.
	(setup): setupDiskWriter is merged into this function.
	(setupDiskWriter): Removed.
	(setFileFilter): New function.
	(readFileEntryFromMetaInfoFile): Updated according to the 
changes
	made in readFileEntry.
	(getFilePath): Removed.
	(getTempFilePath): Removed.
	(getSegmentFilePath): Updated due to the removal of getFilePath.
	(fixFilename): Removed.
	(copySingleFile): Removed.
	(splitMultiFile): Removed.
	(deleteTempFile): Removed.
	(setFileEntriesToDownload): Removed.
	(isPartialDownloadingMode): Renamed as 
isSelectiveDownloadingMode.
	(isSelectiveDownloadingMode): New function.
	(setAllMultiFileRequestedState): Removed.
	(finishPartialDownloadingMode): Renamed as
	finishSelectiveDownloadingMode.
	(finishSelectiveDownloadingMode): New function.
	(getPartialTotalLength): Renamed as getSelectedTotalLength.
	(getSelectedTotalLength): New function.
	(onDownloadComplete): Use diskAdaptor.
	* src/MultiDiskWriter.cc (Constructor): Added the argument 
pieceLength
	(Range): Removed.
	(setMultiFileEntries): Renamed as setFileEntries.
	(setFileEntries): New function.
	* src/MultiDiskWriter.h [DiskWriterEntry](enabled): Removed.
	(pieceLength): New variable.
	* src/main.cc (printDownloadCompeleteMessage): New function.
	(torrentHandler): Use diskAdaptor instead of diskWriter.
	(main): Renamed torrent-show-files to show-files.
	Rewritten file contents listing.
	* src/TorrentMan.h (FileEntry): Removed.
	(multiFileTopDir): Removed.
	(multiFileEntries): Removed.
	(diskWriter): Removed.
	(diskAdaptor): New variable.
	* src/DefaultDiskWriter.h (totalLength): New variable.
	* src/DefaultDiskWriter.cc (initAndOpenFile): Added ftruncate.
	* src/TorrentDownloadEngine.cc (onEndOfRun): Use diskAdaptor 
instead of
	diskWriter.
	* src/TorrentConsoleDownloadEngine.h
	(partialDownloadLengthDiff): Renamed as 
selectedDownloadLengthDiff.
	(partialTotalLength): Renamed as selectedTotalLength.
	* src/AbstractDiskWriter.cc (openFile): If file exists, call
	openExistingFile, otherwise call initAndOpenFile.
	(closeFile): fd > 0, not fd != 0.
	
	* src/prefs.h (PREF_TORRENT_SHOW_FILES): Renamed as 
PREF_SHOW_FILES
	(PREF_SHOW_FILES): New definition.
pull/1/head
Tatsuhiro Tsujikawa 2006-04-16 14:38:19 +00:00
parent 58633887e9
commit 2a84b9de43
23 changed files with 302 additions and 343 deletions

View File

@ -1,3 +1,71 @@
2006-04-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/TorrentConsoleDownloadEngine.cc
(onPartialDownloadingCompletes): Renamed as
onSelectiveDownloadingCompletes.
(onSelectiveDownloadingCompletes): Updated message.
To add DiskAdaptor which abstract DiskWriter family:
* src/PeerConnection.cc: Use diskAdaptor instead of diskWriter.
* src/PeerInteractionCommand.cc: Use diskAdaptor instead of diskWriter.
* src/BitfieldMan.cc (isAllBitSet): bug fix.
* src/TorrentMan.cc : Included CopyDiskAdaptor.h, DirectDiskAdaptor.h,
MultiDiskAdaptor.h.
(readFileEntry): Changed its arguments.
(setup): setupDiskWriter is merged into this function.
(setupDiskWriter): Removed.
(setFileFilter): New function.
(readFileEntryFromMetaInfoFile): Updated according to the changes
made in readFileEntry.
(getFilePath): Removed.
(getTempFilePath): Removed.
(getSegmentFilePath): Updated due to the removal of getFilePath.
(fixFilename): Removed.
(copySingleFile): Removed.
(splitMultiFile): Removed.
(deleteTempFile): Removed.
(setFileEntriesToDownload): Removed.
(isPartialDownloadingMode): Renamed as isSelectiveDownloadingMode.
(isSelectiveDownloadingMode): New function.
(setAllMultiFileRequestedState): Removed.
(finishPartialDownloadingMode): Renamed as
finishSelectiveDownloadingMode.
(finishSelectiveDownloadingMode): New function.
(getPartialTotalLength): Renamed as getSelectedTotalLength.
(getSelectedTotalLength): New function.
(onDownloadComplete): Use diskAdaptor.
* src/MultiDiskWriter.cc (Constructor): Added the argument pieceLength
(Range): Removed.
(setMultiFileEntries): Renamed as setFileEntries.
(setFileEntries): New function.
* src/MultiDiskWriter.h [DiskWriterEntry](enabled): Removed.
(pieceLength): New variable.
* src/main.cc (printDownloadCompeleteMessage): New function.
(torrentHandler): Use diskAdaptor instead of diskWriter.
(main): Renamed torrent-show-files to show-files.
Rewritten file contents listing.
* src/TorrentMan.h (FileEntry): Removed.
(multiFileTopDir): Removed.
(multiFileEntries): Removed.
(diskWriter): Removed.
(diskAdaptor): New variable.
* src/DefaultDiskWriter.h (totalLength): New variable.
* src/DefaultDiskWriter.cc (initAndOpenFile): Added ftruncate.
* src/TorrentDownloadEngine.cc (onEndOfRun): Use diskAdaptor instead of
diskWriter.
* src/TorrentConsoleDownloadEngine.h
(partialDownloadLengthDiff): Renamed as selectedDownloadLengthDiff.
(partialTotalLength): Renamed as selectedTotalLength.
* src/AbstractDiskWriter.cc (openFile): If file exists, call
openExistingFile, otherwise call initAndOpenFile.
(closeFile): fd > 0, not fd != 0.
* src/prefs.h (PREF_TORRENT_SHOW_FILES): Renamed as PREF_SHOW_FILES
(PREF_SHOW_FILES): New definition.
2006-04-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add the ability to download multi torrent into respective files

12
TODO
View File

@ -11,6 +11,14 @@
* Add port range command-line option
* Add max peers command-line option
* Distinguish seeder from leecher
* file selection in multi-file mode
0.4.0 release
* Add selective downloading mode
* try to use ftruncate to allocate file.
* fix TorrentMan::getFilePath()
* test all download mode
* Add loggerfactory
* Add SIGTERM signal handler
0.4.1 release
* Add port command-line option
* Add estimated remaining time to normal HTTP/FTP downloading status ouput

View File

@ -36,7 +36,7 @@ AbstractDiskWriter::AbstractDiskWriter():fd(0) {
}
AbstractDiskWriter::~AbstractDiskWriter() {
if(fd != 0) {
if(fd > 0) {
close(fd);
}
#ifdef ENABLE_SHA1DIGEST
@ -45,13 +45,16 @@ AbstractDiskWriter::~AbstractDiskWriter() {
}
void AbstractDiskWriter::openFile(const string& filename) {
if((fd = open(filename.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0) {
throw new DlAbortEx(strerror(errno));
File f(filename);
if(f.exists()) {
openExistingFile(filename);
} else {
initAndOpenFile(filename);
}
}
void AbstractDiskWriter::closeFile() {
if(fd != 0) {
if(fd > 0) {
close(fd);
fd = 0;
}

View File

@ -261,7 +261,7 @@ bool BitfieldMan::unsetBit(int index) {
bool BitfieldMan::isAllBitSet() const {
if(filterEnabled) {
for(int i = 0; i < bitfieldLength-1; i++) {
for(int i = 0; i < bitfieldLength; i++) {
if((bitfield[i]&filterBitfield[i]) != filterBitfield[i]) {
return false;
}

View File

@ -23,10 +23,15 @@
#include "DlAbortEx.h"
#include <errno.h>
DefaultDiskWriter::DefaultDiskWriter():AbstractDiskWriter() {}
DefaultDiskWriter::DefaultDiskWriter():AbstractDiskWriter(), totalLength(0) {}
DefaultDiskWriter::DefaultDiskWriter(long long int totalLength):AbstractDiskWriter(), totalLength(totalLength) {}
DefaultDiskWriter::~DefaultDiskWriter() {}
void DefaultDiskWriter::initAndOpenFile(string filename) {
createFile(filename);
if(totalLength > 0) {
ftruncate(fd, totalLength);
}
}

View File

@ -25,8 +25,11 @@
#include "AbstractDiskWriter.h"
class DefaultDiskWriter:public AbstractDiskWriter {
private:
long long int totalLength;
public:
DefaultDiskWriter();
DefaultDiskWriter(long long int totalLength);
~DefaultDiskWriter();
void initAndOpenFile(string filename);

42
src/FileEntry.h Normal file
View File

@ -0,0 +1,42 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_FILE_ENTRY_H_
#define _D_FILE_ENTRY_H_
#include "common.h"
class FileEntry {
public:
string path;
long long int length;
long long int offset;
bool extracted;
bool requested;
FileEntry(string path, long long int length, long long int offset):
path(path), length(length), offset(offset),
extracted(false), requested(true) {}
~FileEntry() {}
};
typedef deque<FileEntry> FileEntries;
#endif // _D_FILE_ENTRY_H_

View File

@ -79,7 +79,12 @@ SRCS = Socket.cc Socket.h\
TrackerWatcherCommand.cc TrackerWatcherCommand.h\
messageDigest.h\
SendMessageQueue.cc SendMessageQueue.h\
MultiDiskWriter.cc MultiDiskWriter.h
MultiDiskWriter.cc MultiDiskWriter.h\
DiskAdaptor.cc DiskAdaptor.h\
CopyDiskAdaptor.cc CopyDiskAdaptor.h\
DirectDiskAdaptor.cc DirectDiskAdaptor.h\
MultiDiskAdaptor.cc MultiDiskAdaptor.h\
FileEntry.h
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\

View File

@ -98,7 +98,9 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
PeerMessage.$(OBJEXT) Piece.$(OBJEXT) RequestSlot.$(OBJEXT) \
RequestSlotMan.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \
Directory.$(OBJEXT) TrackerWatcherCommand.$(OBJEXT) \
SendMessageQueue.$(OBJEXT) MultiDiskWriter.$(OBJEXT)
SendMessageQueue.$(OBJEXT) MultiDiskWriter.$(OBJEXT) \
DiskAdaptor.$(OBJEXT) CopyDiskAdaptor.$(OBJEXT) \
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT)
am_libaria2c_a_OBJECTS = $(am__objects_1)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@ -327,7 +329,12 @@ SRCS = Socket.cc Socket.h\
TrackerWatcherCommand.cc TrackerWatcherCommand.h\
messageDigest.h\
SendMessageQueue.cc SendMessageQueue.h\
MultiDiskWriter.cc MultiDiskWriter.h
MultiDiskWriter.cc MultiDiskWriter.h\
DiskAdaptor.cc DiskAdaptor.h\
CopyDiskAdaptor.cc CopyDiskAdaptor.h\
DirectDiskAdaptor.cc DirectDiskAdaptor.h\
MultiDiskAdaptor.cc MultiDiskAdaptor.h\
FileEntry.h
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
@ -420,10 +427,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedEncoding.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConsoleDownloadEngine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBox.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CopyDiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Data.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Dictionary.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DirectDiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Directory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DiskAdaptor.Po@am__quote@
@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)/File.Po@am__quote@
@ -444,6 +454,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitiateConnectionCommandFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Option.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Peer.Po@am__quote@

View File

@ -24,7 +24,7 @@
#include "Util.h"
#include <errno.h>
MultiDiskWriter::MultiDiskWriter() {
MultiDiskWriter::MultiDiskWriter(int pieceLength):pieceLength(pieceLength) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestInit(ctx);
#endif // ENABLE_SHA1DIGEST
@ -37,92 +37,49 @@ MultiDiskWriter::~MultiDiskWriter() {
#endif // ENABLE_SHA1DIGEST
}
typedef struct {
long long int blockOffset;
long long int length;
} Range;
typedef deque<Range> Ranges;
void MultiDiskWriter::clearEntries() {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->enabled) {
(*itr)->diskWriter->closeFile();
}
delete *itr;
}
diskWriterEntries.clear();
}
void MultiDiskWriter::setMultiFileEntries(const MultiFileEntries& multiFileEntries, int pieceLength) {
void MultiDiskWriter::setFileEntries(const FileEntries& fileEntries) {
clearEntries();
Ranges ranges;
for(MultiFileEntries::const_iterator itr = multiFileEntries.begin();
itr != multiFileEntries.end(); itr++) {
if(itr->requested) {
Range range;
range.blockOffset = (itr->offset/pieceLength)*pieceLength;
range.length = ((itr->offset+itr->length)/pieceLength+
((itr->offset+itr->length)%pieceLength ? 1 : 0))*pieceLength-range.blockOffset;
ranges.push_back(range);
}
}
Ranges::const_iterator ritr = ranges.begin();
for(MultiFileEntries::const_iterator itr = multiFileEntries.begin();
itr != multiFileEntries.end(); itr++) {
DiskWriterEntry* entry;
if(ritr != ranges.end() &&
// !(ritr->blockOffset+ritr->length-1 < itr->offset ||
// itr->offset+itr->length-1 < ritr->blockOffset)) {
itr->offset < ritr->blockOffset+ritr->length &&
ritr->blockOffset < itr->offset+itr->length) {
entry = new DiskWriterEntry(*itr, true);
for(;ritr->blockOffset+ritr->length <= itr->offset+itr->length &&
ritr != ranges.end(); ritr++);
} else {
entry = new DiskWriterEntry(*itr, false);
}
diskWriterEntries.push_back(entry);
for(FileEntries::const_iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
diskWriterEntries.push_back(new DiskWriterEntry(*itr));
}
}
void MultiDiskWriter::openFile(const string& filename) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->enabled) {
(*itr)->diskWriter->openFile(filename+"/"+(*itr)->fileEntry.path);
}
}
}
// filename is a directory which is specified by the user in the option.
void MultiDiskWriter::initAndOpenFile(string filename) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->enabled) {
(*itr)->diskWriter->initAndOpenFile(filename+"/"+(*itr)->fileEntry.path);
}
}
}
void MultiDiskWriter::closeFile() {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->enabled) {
(*itr)->diskWriter->closeFile();
}
}
}
void MultiDiskWriter::openExistingFile(string filename) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->enabled) {
(*itr)->diskWriter->openExistingFile(filename+"/"+(*itr)->fileEntry.path);
}
}
}
void MultiDiskWriter::writeData(const char* data, int len, long long int position) {
@ -133,9 +90,6 @@ void MultiDiskWriter::writeData(const char* data, int len, long long int positio
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end() && rem != 0; itr++) {
if(isInRange(*itr, offset) || writing) {
if(!(*itr)->enabled) {
throw new DlAbortEx("invalid offset or length. offset = %lld", offset);
}
int writeLength = calculateLength(*itr, fileOffset, rem);
(*itr)->diskWriter->writeData(data+(len-rem), writeLength, fileOffset);
rem -= writeLength;
@ -174,9 +128,6 @@ int MultiDiskWriter::readData(char* data, int len, long long int position) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end() && rem != 0; itr++) {
if(isInRange(*itr, offset) || reading) {
if(!(*itr)->enabled) {
throw new DlAbortEx("invalid offset or length. offset = %lld", offset);
}
int readLength = calculateLength((*itr), fileOffset, rem);
totalReadLength += (*itr)->diskWriter->readData(data+(len-rem), readLength, fileOffset);
rem -= readLength;
@ -223,9 +174,6 @@ string MultiDiskWriter::sha1Sum(long long int offset, long long int length) {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end() && rem != 0; itr++) {
if(isInRange(*itr, offset) || reading) {
if(!(*itr)->enabled) {
throw new DlAbortEx("invalid offset or length. offset = %lld", offset);
}
int readLength = calculateLength((*itr), fileOffset, rem);
hashUpdate(*itr, fileOffset, readLength);
rem -= readLength;

View File

@ -30,18 +30,13 @@ class DiskWriterEntry {
public:
FileEntry fileEntry;
DiskWriter* diskWriter;
bool enabled;
public:
DiskWriterEntry(const FileEntry& fileEntry, bool enabled):fileEntry(fileEntry), enabled(enabled) {
if(enabled) {
diskWriter = new DefaultDiskWriter();
}
DiskWriterEntry(const FileEntry& fileEntry):fileEntry(fileEntry) {
diskWriter = new DefaultDiskWriter(this->fileEntry.length);
}
~DiskWriterEntry() {
if(enabled) {
delete diskWriter;
}
}
};
typedef deque<DiskWriterEntry*> DiskWriterEntries;
@ -49,7 +44,7 @@ typedef deque<DiskWriterEntry*> DiskWriterEntries;
class MultiDiskWriter : public DiskWriter {
private:
DiskWriterEntries diskWriterEntries;
int pieceLength;
bool isInRange(const DiskWriterEntry* entry, long long int offset) const;
int calculateLength(const DiskWriterEntry* entry, long long int fileOffset, int rem) const;
void clearEntries();
@ -59,10 +54,10 @@ private:
#endif // ENABLE_SHA1DIGEST
public:
MultiDiskWriter();
MultiDiskWriter(int pieceLength);
virtual ~MultiDiskWriter();
void setMultiFileEntries(const MultiFileEntries& multiFileEntries, int pieceLength);
void setFileEntries(const FileEntries& fileEntries);
virtual void openFile(const string& filename);
virtual void initAndOpenFile(string filename);

View File

@ -216,14 +216,14 @@ void PeerConnection::sendPiece(int index, int begin, int length) const {
int iteration = length/BUF_SIZE;
long long int pieceOffset = ((long long int)index*torrentMan->pieceLength)+begin;
for(int i = 0; i < iteration; i++) {
if(torrentMan->diskWriter->readData(buf, BUF_SIZE, pieceOffset+i*BUF_SIZE) < BUF_SIZE) {
if(torrentMan->diskAdaptor->readData(buf, BUF_SIZE, pieceOffset+i*BUF_SIZE) < BUF_SIZE) {
throw new DlAbortEx("piece reading failed.");
}
socket->writeData(buf, BUF_SIZE);
}
int rem = length%BUF_SIZE;
if(rem > 0) {
if(torrentMan->diskWriter->readData(buf, rem, pieceOffset+iteration*BUF_SIZE) < rem) {
if(torrentMan->diskAdaptor->readData(buf, rem, pieceOffset+iteration*BUF_SIZE) < rem) {
throw new DlAbortEx("piece reading failed.");
}
socket->writeData(buf, rem);
@ -259,7 +259,7 @@ int PeerConnection::sendPieceData(long long int offset, int length) const {
if(!isWritable) {
return writtenLength;
}
if(torrentMan->diskWriter->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
if(torrentMan->diskAdaptor->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
throw new DlAbortEx("piece reading failed.");
}
socket->writeData(buf, BUF_SIZE);
@ -268,7 +268,7 @@ int PeerConnection::sendPieceData(long long int offset, int length) const {
if(socket->isWritable(0)) {
int rem = length%BUF_SIZE;
if(rem > 0) {
if(torrentMan->diskWriter->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
if(torrentMan->diskAdaptor->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
throw new DlAbortEx("piece reading failed.");
}
socket->writeData(buf, rem);

View File

@ -274,7 +274,7 @@ void PeerInteractionCommand::receiveMessage() {
((long long int)message->getIndex())*e->torrentMan->pieceLength+message->getBegin();
e->logger->debug("CUID#%d - write block length = %d, offset=%lld",
cuid, message->getBlockLength(), offset);
e->torrentMan->diskWriter->writeData(message->getBlock(),
e->torrentMan->diskAdaptor->writeData(message->getBlock(),
message->getBlockLength(),
offset);
piece.completeBlock(slot.getBlockIndex());
@ -444,7 +444,7 @@ void PeerInteractionCommand::beforeSocketCheck() {
bool PeerInteractionCommand::checkPieceHash(const Piece& piece) {
long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength;
return e->torrentMan->diskWriter->sha1Sum(offset, piece.getLength()) ==
return e->torrentMan->diskAdaptor->sha1Sum(offset, piece.getLength()) ==
e->torrentMan->getPieceHash(piece.getIndex());
}
@ -454,11 +454,11 @@ void PeerInteractionCommand::erasePieceOnDisk(const Piece& piece) {
memset(buf, 0, BUFSIZE);
long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength;
for(int i = 0; i < piece.getLength()/BUFSIZE; i++) {
e->torrentMan->diskWriter->writeData(buf, BUFSIZE, offset);
e->torrentMan->diskAdaptor->writeData(buf, BUFSIZE, offset);
offset += BUFSIZE;
}
int r = piece.getLength()%BUFSIZE;
if(r > 0) {
e->torrentMan->diskWriter->writeData(buf, r, offset);
e->torrentMan->diskAdaptor->writeData(buf, r, offset);
}
}

View File

@ -35,7 +35,6 @@ PreAllocationDiskWriter::~PreAllocationDiskWriter() {}
void PreAllocationDiskWriter::initAndOpenFile(string filename) {
createFile(filename);
int bufSize = 4096;
char buf[4096];

View File

@ -26,8 +26,9 @@ TorrentConsoleDownloadEngine::TorrentConsoleDownloadEngine() {}
TorrentConsoleDownloadEngine::~TorrentConsoleDownloadEngine() {}
void TorrentConsoleDownloadEngine::onPartialDownloadingCompletes() {
printf("Download of specified files has completed. Continue normal download operation.\n");
void TorrentConsoleDownloadEngine::onSelectiveDownloadingCompletes() {
printf("\nDownload of selected files has completed.\n");
fflush(stdout);
}
void TorrentConsoleDownloadEngine::printStatistics() {
@ -68,9 +69,9 @@ void TorrentConsoleDownloadEngine::initStatistics() {
sessionDownloadLength = 0;
downloadLength = 0;
totalLength = 0;
if(torrentMan->isPartialDownloadingMode()) {
partialDownloadLengthDiff = torrentMan->getDownloadLength()-torrentMan->getCompletedLength();
partialTotalLength = torrentMan->getPartialTotalLength();
if(torrentMan->isSelectiveDownloadingMode()) {
selectedDownloadLengthDiff = torrentMan->getDownloadLength()-torrentMan->getCompletedLength();
selectedTotalLength = torrentMan->getSelectedTotalLength();
}
}
@ -95,9 +96,9 @@ void TorrentConsoleDownloadEngine::calculateStatistics() {
torrentMan->resetDeltaDownloadLength();
torrentMan->resetDeltaUploadLength();
if(torrentMan->isPartialDownloadingMode()) {
downloadLength = torrentMan->getDownloadLength()-partialDownloadLengthDiff;
totalLength = partialTotalLength;
if(torrentMan->isSelectiveDownloadingMode()) {
downloadLength = torrentMan->getDownloadLength()-selectedDownloadLengthDiff;
totalLength = selectedTotalLength;
} else {
downloadLength = torrentMan->getDownloadLength();
totalLength = torrentMan->getTotalLength();

View File

@ -26,11 +26,6 @@
class TorrentConsoleDownloadEngine : public TorrentDownloadEngine {
private:
/*
struct timeval cp;
long long int sessionDownloadSize;
long long int sessionUploadSize;
*/
struct timeval cp[2];
long long int sessionDownloadLengthArray[2];
long long int sessionUploadLengthArray[2];
@ -39,11 +34,15 @@ private:
int downloadSpeed;
int uploadSpeed;
int lastElapsed;
long long int partialDownloadLengthDiff;
long long int partialTotalLength;
long long int selectedDownloadLengthDiff;
long long int selectedTotalLength;
// The time when startup
struct timeval startup;
// The number of bytes downloaded since startup
long long int sessionDownloadLength;
// The average speed(bytes per second) since startup
int avgSpeed;
// The estimated remaining time to complete the download.
int eta;
long long int downloadLength;
long long int totalLength;
@ -53,7 +52,7 @@ private:
protected:
void initStatistics();
void calculateStatistics();
void onPartialDownloadingCompletes();
void onSelectiveDownloadingCompletes();
public:
TorrentConsoleDownloadEngine();
~TorrentConsoleDownloadEngine();

View File

@ -22,7 +22,7 @@
#include "TorrentDownloadEngine.h"
void TorrentDownloadEngine::onEndOfRun() {
torrentMan->diskWriter->closeFile();
torrentMan->diskAdaptor->closeFile();
if(filenameFixed && torrentMan->downloadComplete()) {
torrentMan->remove();
} else {
@ -32,8 +32,8 @@ void TorrentDownloadEngine::onEndOfRun() {
void TorrentDownloadEngine::afterEachIteration() {
if(!filenameFixed && torrentMan->downloadComplete()) {
if(torrentMan->isPartialDownloadingMode()) {
onPartialDownloadingCompletes();
if(torrentMan->isSelectiveDownloadingMode()) {
onSelectiveDownloadingCompletes();
}
torrentMan->onDownloadComplete();
if(torrentMan->downloadComplete()) {

View File

@ -31,7 +31,7 @@ private:
protected:
void onEndOfRun();
void afterEachIteration();
virtual void onPartialDownloadingCompletes() = 0;
virtual void onSelectiveDownloadingCompletes() = 0;
public:
TorrentDownloadEngine():filenameFixed(false) {}
virtual ~TorrentDownloadEngine() {}

View File

@ -32,6 +32,9 @@
#include "DefaultDiskWriter.h"
#include "MultiDiskWriter.h"
#include "prefs.h"
#include "CopyDiskAdaptor.h"
#include "DirectDiskAdaptor.h"
#include "MultiDiskAdaptor.h"
#include <errno.h>
#include <libgen.h>
#include <string.h>
@ -42,25 +45,21 @@ TorrentMan::TorrentMan():bitfield(NULL),
preDownloadLength(0), preUploadLength(0),
deltaDownloadLength(0), deltaUploadLength(0),
storeDir("."),
multiFileTopDir(NULL),
setupComplete(false),
interval(DEFAULT_ANNOUNCE_INTERVAL),
minInterval(DEFAULT_ANNOUNCE_MIN_INTERVAL),
complete(0), incomplete(0),
connections(0), diskWriter(NULL) {}
connections(0), diskAdaptor(NULL) {}
TorrentMan::~TorrentMan() {
if(bitfield != NULL) {
delete bitfield;
}
if(multiFileTopDir != NULL) {
delete multiFileTopDir;
}
for(Peers::iterator itr = peers.begin(); itr != peers.end(); itr++) {
delete *itr;
}
if(diskWriter != NULL) {
delete diskWriter;
if(diskAdaptor != NULL) {
delete diskAdaptor;
}
}
@ -298,7 +297,7 @@ bool TorrentMan::downloadComplete() const {
return bitfield->isAllBitSet();
}
void TorrentMan::readFileEntry(const Dictionary* infoDic, const string& defaultName) {
void TorrentMan::readFileEntry(FileEntries& fileEntries, Directory** pTopDir, const Dictionary* infoDic, const string& defaultName) {
Data* topName = (Data*)infoDic->get("name");
if(topName != NULL) {
name = topName->toString();
@ -313,12 +312,14 @@ void TorrentMan::readFileEntry(const Dictionary* infoDic, const string& defaultN
setFileMode(SINGLE);
Data* length = (Data*)infoDic->get("length");
totalLength = length->toLLInt();
FileEntry fileEntry(name, totalLength, 0);
fileEntries.push_back(fileEntry);
} else {
long long int length = 0;
long long int offset = 0;
// multi-file mode
setFileMode(MULTI);
multiFileTopDir = new Directory(name);
*pTopDir = new Directory(name);
const MetaList& metaList = files->getList();
for(MetaList::const_iterator itr = metaList.begin(); itr != metaList.end();
itr++) {
@ -327,7 +328,7 @@ void TorrentMan::readFileEntry(const Dictionary* infoDic, const string& defaultN
length += lengthData->toLLInt();
List* path = (List*)fileDic->get("path");
const MetaList& paths = path->getList();
Directory* parentDir = multiFileTopDir;
Directory* parentDir = *pTopDir;
string filePath = name;
for(int i = 0; i < (int)paths.size()-1; i++) {
Data* subpath = (Data*)paths.at(i);
@ -339,14 +340,14 @@ void TorrentMan::readFileEntry(const Dictionary* infoDic, const string& defaultN
Data* lastpath = (Data*)paths.back();
filePath.append("/").append(lastpath->toString());
FileEntry fileEntry(filePath, lengthData->toLLInt(), offset);
multiFileEntries.push_back(fileEntry);
fileEntries.push_back(fileEntry);
offset += fileEntry.length;
}
totalLength = length;
}
}
void TorrentMan::setup(string metaInfoFile) {
void TorrentMan::setup(string metaInfoFile, const Strings& targetFilePaths) {
peerId = "-A2****-";
for(int i = 0; i < 12; i++) {
peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0)));
@ -363,7 +364,9 @@ void TorrentMan::setup(string metaInfoFile) {
v.getHash(md, len);
setInfoHash(md);
readFileEntry(infoDic, metaInfoFile);
FileEntries fileEntries;
Directory* topDir = NULL;
readFileEntry(fileEntries, &topDir, infoDic, metaInfoFile);
announce = ((Data*)topDic->get("announce"))->toString();
pieceLength = ((Data*)infoDic->get("piece length"))->toInt();
@ -380,45 +383,54 @@ void TorrentMan::setup(string metaInfoFile) {
initBitfield();
delete topDic;
}
void TorrentMan::setupDiskWriter() {
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
if(segmentFileExists()) {
load();
}
if(fileMode == SINGLE) {
diskWriter = new DefaultDiskWriter();
diskAdaptor = new DirectDiskAdaptor(new DefaultDiskWriter(totalLength));
} else {
diskWriter = new MultiDiskWriter();
((MultiDiskWriter*)diskWriter)->setMultiFileEntries(multiFileEntries, pieceLength);
multiFileTopDir->createDir(storeDir, true);
diskAdaptor = new MultiDiskAdaptor(new MultiDiskWriter(pieceLength));
}
diskWriter->openFile(getFilePath());
} else {
if(option->get(PREF_NO_PREALLOCATION) == V_TRUE) {
diskWriter = new DefaultDiskWriter();
} else {
diskWriter = new PreAllocationDiskWriter(totalLength);
diskAdaptor = new CopyDiskAdaptor(new DefaultDiskWriter(totalLength));
((CopyDiskAdaptor*)diskAdaptor)->setTempFilename(name+".a2tmp");
}
diskAdaptor->setStoreDir(storeDir);
diskAdaptor->setTopDir(topDir);
diskAdaptor->setFileEntries(fileEntries);
setFileFilter(targetFilePaths);
if(segmentFileExists()) {
load();
diskWriter->openExistingFile(getTempFilePath());
diskAdaptor->openExistingFile();
} else {
diskWriter->initAndOpenFile(getTempFilePath());
}
diskAdaptor->initAndOpenFile();
}
setupComplete = true;
}
const MultiFileEntries& TorrentMan::getMultiFileEntries() const {
return multiFileEntries;
void TorrentMan::setFileFilter(const Strings& filePaths) {
if(fileMode != MULTI || filePaths.empty()) {
return;
}
diskAdaptor->removeAllDownloadEntry();
for(Strings::const_iterator pitr = filePaths.begin();
pitr != filePaths.end(); pitr++) {
if(!diskAdaptor->addDownloadEntry(*pitr)) {
throw new DlAbortEx("no such file entry <%s>", (*pitr).c_str());
}
FileEntry fileEntry = diskAdaptor->getFileEntryFromPath(*pitr);
bitfield->addFilter(fileEntry.offset, fileEntry.length);
}
bitfield->enableFilter();
}
void TorrentMan::readFileEntryFromMetaInfoFile(const string& metaInfoFile) {
FileEntries TorrentMan::readFileEntryFromMetaInfoFile(const string& metaInfoFile) {
Dictionary* topDic = (Dictionary*)MetaFileUtil::parseMetaFile(metaInfoFile);
const Dictionary* infoDic = (const Dictionary*)topDic->get("info");
readFileEntry(infoDic, metaInfoFile);
FileEntries fileEntries;
Directory* topDir;
readFileEntry(fileEntries, &topDir, infoDic, metaInfoFile);
delete topDir;
return fileEntries;
}
string TorrentMan::getName() const {
@ -433,28 +445,8 @@ string TorrentMan::getPieceHash(int index) const {
return pieceHashes.at(index);
}
string TorrentMan::getFilePath() const {
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE && fileMode == MULTI) {
return storeDir;
} else {
return storeDir+"/"+name;
}
}
string TorrentMan::getTempFilePath() const {
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
return getFilePath();
} else {
return getFilePath()+".a2tmp";
}
}
string TorrentMan::getSegmentFilePath() const {
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE && fileMode == MULTI) {
return storeDir+"/"+name+".aria2";
} else {
return getFilePath()+".aria2";
}
}
bool TorrentMan::segmentFileExists() const {
@ -546,117 +538,27 @@ void TorrentMan::remove() const {
}
}
void TorrentMan::fixFilename() {
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
// nothing to do here
} else {
if(fileMode == SINGLE) {
copySingleFile();
} else {
splitMultiFile();
}
}
}
void TorrentMan::copySingleFile() const {
logger->info("writing file %s", getFilePath().c_str());
Util::fileCopy(getFilePath(), getTempFilePath());
}
void TorrentMan::splitMultiFile() {
logger->info("creating directories");
multiFileTopDir->createDir(storeDir, true);
long long int offset = 0;
for(MultiFileEntries::iterator itr = multiFileEntries.begin();
itr != multiFileEntries.end(); itr++) {
if(!itr->extracted && itr->requested) {
string dest = storeDir+"/"+itr->path;
logger->info("writing file %s", dest.c_str());
Util::rangedFileCopy(dest, getTempFilePath(), offset, itr->length);
itr->extracted = true;
}
offset += itr->length;
}
}
void TorrentMan::deleteTempFile() const {
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
// nothing to do here
} else {
unlink(getTempFilePath().c_str());
}
}
// bool TorrentMan::unextractedFileEntryExists() const {
// if(fileMode == SINGLE) {
// return false;
// }
// for(MultiFileEntries::const_iterator itr = multiFileEntries.begin();
// itr != multiFileEntries.end(); itr++) {
// if(!itr->extracted) {
// return true;
// }
// }
// }
void TorrentMan::setFileEntriesToDownload(const Strings& filePaths) {
if(fileMode != MULTI) {
throw new DlAbortEx("only multi-mode supports partial downloading mode.");
}
// clear all requested flags in multiFileEntries.
setAllMultiFileRequestedState(false);
for(Strings::const_iterator pitr = filePaths.begin();
pitr != filePaths.end(); pitr++) {
bool found = false;
for(MultiFileEntries::iterator itr = multiFileEntries.begin();
itr != multiFileEntries.end(); itr++) {
if(*pitr == itr->path) {
itr->requested = true;
found = true;
bitfield->addFilter(itr->offset, itr->length);
break;
}
}
if(!found) {
throw new DlAbortEx("no such file entry <%s>", (*pitr).c_str());
}
}
bitfield->enableFilter();
}
bool TorrentMan::isPartialDownloadingMode() const {
bool TorrentMan::isSelectiveDownloadingMode() const {
return bitfield->isFilterEnabled();
}
void TorrentMan::setAllMultiFileRequestedState(bool state) {
for(MultiFileEntries::iterator itr = multiFileEntries.begin();
itr != multiFileEntries.end(); itr++) {
itr->requested = state;
}
}
void TorrentMan::finishPartialDownloadingMode() {
void TorrentMan::finishSelectiveDownloadingMode() {
bitfield->clearFilter();
setAllMultiFileRequestedState(true);
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE && fileMode == MULTI) {
((MultiDiskWriter*)diskWriter)->setMultiFileEntries(multiFileEntries, pieceLength);
}
diskAdaptor->addAllDownloadEntry();
}
long long int TorrentMan::getCompletedLength() const {
return bitfield->getCompletedLength();
}
long long int TorrentMan::getPartialTotalLength() const {
long long int TorrentMan::getSelectedTotalLength() const {
return bitfield->getFilteredTotalLength();
}
void TorrentMan::onDownloadComplete() {
diskWriter->closeFile();
save();
fixFilename();
if(isPartialDownloadingMode()) {
finishPartialDownloadingMode();
diskAdaptor->onDownloadComplete();
if(isSelectiveDownloadingMode()) {
finishSelectiveDownloadingMode();
}
diskWriter->openFile(getTempFilePath());
}

View File

@ -28,9 +28,10 @@
#include "BitfieldMan.h"
#include "DiskWriter.h"
#include "Piece.h"
#include "Directory.h"
#include "Dictionary.h"
#include "Option.h"
#include "FileEntry.h"
#include "DiskAdaptor.h"
#include <deque>
#include <map>
#include <string>
@ -46,22 +47,8 @@ using namespace std;
#define END_GAME_PIECE_NUM 20
#define MAX_PEER_ERROR 5
class FileEntry {
public:
string path;
long long int length;
long long int offset;
bool extracted;
bool requested;
FileEntry(string path, long long int length, long long int offset):
path(path), length(length), offset(offset),
extracted(false), requested(true) {}
~FileEntry() {}
};
typedef deque<Peer*> Peers;
typedef multimap<int, int> Haves;
typedef deque<FileEntry> MultiFileEntries;
typedef deque<Piece> UsedPieces;
typedef deque<int> PieceIndexes;
@ -85,8 +72,6 @@ private:
int port;
Haves haves;
UsedPieces usedPieces;
Directory* multiFileTopDir;
MultiFileEntries multiFileEntries;
bool setupComplete;
FILE* openSegFile(string segFilename, string mode) const;
@ -97,7 +82,8 @@ private:
void deleteUsedPiece(const Piece& piece);
int deleteUsedPiecesByFillRate(int fillRate, int toDelete);
void reduceUsedPieces(int max);
void readFileEntry(const Dictionary* infoDic, const string& defaultName);
void readFileEntry(FileEntries& fileEntries, Directory** pTopDir, const Dictionary* infoDic, const string& defaultName);
void setFileFilter(const Strings& filePaths);
public:
int pieceLength;
int pieces;
@ -115,7 +101,7 @@ public:
~TorrentMan();
const Logger* logger;
DiskWriter* diskWriter;
DiskAdaptor* diskAdaptor;
const Option* option;
int getNewCuid() { return ++cuidCounter; }
@ -150,8 +136,7 @@ public:
return infoHash;
}
void setup(string metaInfoFile);
void setupDiskWriter();
void setup(string metaInfoFile, const Strings& targetFilePaths);
string getPieceHash(int index) const;
@ -213,8 +198,6 @@ public:
string getStoreDir() const { return storeDir; }
void setStoreDir(string dir) { storeDir = dir; }
string getFilePath() const;
string getTempFilePath() const;
string getSegmentFilePath() const;
bool segmentFileExists() const;
@ -233,20 +216,14 @@ public:
int countUsedPiece() const { return usedPieces.size(); }
int countAdvertisedPiece() const { return haves.size(); }
void readFileEntryFromMetaInfoFile(const string& metaInfoFile);
const MultiFileEntries& getMultiFileEntries() const;
FileEntries readFileEntryFromMetaInfoFile(const string& metaInfoFile);
string getName() const;
//bool unextractedFileEntryExists() const;
void setAllMultiFileRequestedState(bool state);
void finishPartialDownloadingMode();
bool isPartialDownloadingMode() const;
void setFileEntriesToDownload(const Strings& filePaths);
void finishSelectiveDownloadingMode();
bool isSelectiveDownloadingMode() const;
long long int getCompletedLength() const;
long long int getPartialTotalLength() const;
long long int getSelectedTotalLength() const;
void onDownloadComplete();

View File

@ -63,6 +63,10 @@ void printDownloadCompeleteMessage(string filename) {
printf(_("\nThe download was complete. <%s>\n"), filename.c_str());
}
void printDownloadCompeleteMessage() {
printf("\nThe download was complete.\n");
}
void printDownloadAbortMessage() {
printf(_("\nThe download was not complete because of errors. Check the log.\n"));
}
@ -85,13 +89,13 @@ void handler(int signal) {
void torrentHandler(int signal) {
cout << _("\nSIGINT signal received.") << endl;
if(te->torrentMan->diskWriter != NULL) {
te->torrentMan->diskWriter->closeFile();
if(te->torrentMan->diskAdaptor != NULL) {
te->torrentMan->diskAdaptor->closeFile();
}
if(te->torrentMan->downloadComplete() && te->isFilenameFixed()) {
te->torrentMan->remove();
te->torrentMan->deleteTempFile();
printDownloadCompeleteMessage(te->torrentMan->getFilePath());
//te->torrentMan->deleteTempFile();
printDownloadCompeleteMessage();
} else {
te->torrentMan->save();
}
@ -283,7 +287,7 @@ int main(int argc, char* argv[]) {
#ifdef ENABLE_BITTORRENT
{ "torrent-file", required_argument, &lopt, 15 },
{ "follow-torrent", required_argument, &lopt, 16 },
{ "torrent-show-files", no_argument, &lopt, 17 },
{ "show-files", no_argument, &lopt, 17 },
{ "no-preallocation", no_argument, &lopt, 18 },
{ "direct-file-mapping", required_argument, &lopt, 19 },
#endif // ENABLE_BITTORRENT
@ -414,7 +418,7 @@ int main(int argc, char* argv[]) {
}
break;
case 17:
op->put(PREF_TORRENT_SHOW_FILES, V_TRUE);
op->put(PREF_SHOW_FILES, V_TRUE);
break;
case 18:
op->put(PREF_NO_PREALLOCATION, V_TRUE);
@ -608,32 +612,21 @@ int main(int argc, char* argv[]) {
te->torrentMan->option = op;
string targetTorrentFile = torrentFile.empty() ?
downloadedTorrentFile : torrentFile;
if(op->get(PREF_TORRENT_SHOW_FILES) == V_TRUE) {
te->torrentMan->readFileEntryFromMetaInfoFile(targetTorrentFile);
if(op->get(PREF_SHOW_FILES) == V_TRUE) {
FileEntries fileEntries = te->torrentMan->readFileEntryFromMetaInfoFile(targetTorrentFile);
cout << "Files:" << endl;
switch(te->torrentMan->getFileMode()) {
case TorrentMan::SINGLE:
printf("%s %s Bytes\n", te->torrentMan->getName().c_str(),
Util::llitos(te->torrentMan->getTotalLength(), true).c_str());
break;
case TorrentMan::MULTI: {
const MultiFileEntries& entries = te->torrentMan->getMultiFileEntries();
for(MultiFileEntries::const_iterator itr = entries.begin();
itr != entries.end(); itr++) {
for(FileEntries::const_iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
printf("%s %s Bytes\n", itr->path.c_str(),
Util::llitos(itr->length, true).c_str());
}
break;
}
}
exit(0);
} else {
te->torrentMan->setup(targetTorrentFile);
if(!torrentFile.empty() && !args.empty() &&
te->torrentMan->getFileMode() == TorrentMan::MULTI) {
te->torrentMan->setFileEntriesToDownload(args);
Strings targetFiles;
if(!torrentFile.empty() && !args.empty()) {
targetFiles = args;
}
te->torrentMan->setupDiskWriter();
te->torrentMan->setup(targetTorrentFile, targetFiles);
}
PeerListenCommand* listenCommand =
new PeerListenCommand(te->torrentMan->getNewCuid(), te);
@ -652,7 +645,7 @@ int main(int argc, char* argv[]) {
te->run();
if(te->torrentMan->downloadComplete()) {
printDownloadCompeleteMessage(te->torrentMan->getFilePath());
printDownloadCompeleteMessage();
} else {
printDownloadAbortMessage();
}

View File

@ -89,7 +89,7 @@
// values: 1*digit
#define PREF_PEER_CONNECTION_TIMEOUT "peer_connection_timeout"
// values: true | false
#define PREF_TORRENT_SHOW_FILES "torrent_show_files"
#define PREF_SHOW_FILES "show_files"
// values: true | false
#define PREF_NO_PREALLOCATION "no_preallocation"
// values: true | false

View File

@ -25,14 +25,14 @@ public:
CPPUNIT_TEST_SUITE_REGISTRATION( MultiDiskWriterTest );
MultiFileEntries createEntries() {
FileEntries createEntries() {
FileEntry entry1("file1.txt", 15, 0);
FileEntry entry2("file2.txt", 7, 15);
FileEntry entry3("file3.txt", 3, 22);
unlink("file1.txt");
unlink("file2.txt");
unlink("file3.txt");
MultiFileEntries entries;
FileEntries entries;
entries.push_back(entry1);
entries.push_back(entry2);
entries.push_back(entry3);
@ -52,8 +52,8 @@ void readFile(const string& filename, char* buf, int bufLength) {
}
void MultiDiskWriterTest::testWriteData() {
MultiDiskWriter dw;
dw.setMultiFileEntries(createEntries(), 2);
MultiDiskWriter dw(2);
dw.setFileEntries(createEntries());
dw.openFile(".");
string msg = "12345";
@ -97,12 +97,12 @@ void MultiDiskWriterTest::testReadData() {
FileEntry entry1("file1r.txt", 15, 0);
FileEntry entry2("file2r.txt", 7, 15);
FileEntry entry3("file3r.txt", 3, 22);
MultiFileEntries entries;
FileEntries entries;
entries.push_back(entry1);
entries.push_back(entry2);
entries.push_back(entry3);
MultiDiskWriter dw;
dw.setMultiFileEntries(entries, 2);
MultiDiskWriter dw(2);
dw.setFileEntries(entries);
dw.openFile(".");
char buf[128];
@ -124,12 +124,12 @@ void MultiDiskWriterTest::testSha1Sum() {
FileEntry entry1("file1r.txt", 15, 0);
FileEntry entry2("file2r.txt", 7, 15);
FileEntry entry3("file3r.txt", 3, 22);
MultiFileEntries entries;
FileEntries entries;
entries.push_back(entry1);
entries.push_back(entry2);
entries.push_back(entry3);
MultiDiskWriter dw;
dw.setMultiFileEntries(entries, 2);
MultiDiskWriter dw(2);
dw.setFileEntries(entries);
dw.openFile(".");
string sha1sum = dw.sha1Sum(0, 25);