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

Now a file is stored in the directory specified in .metalnk file
	(file[@name]).
	* src/Metalink2RequestGroup.cc

	Create the directory structure when opening the file if it 
doesn't
	exist.
	* src/AbstractDiskWriter.cc
	* src/Util.{h, cc}
	* src/File.h
	* test/UtilTest.cc
	
	Removed file name comparison
	* src/Metalink2RequestGroup.cc
	* src/HttpResponseCommand.cc

	Rewritten using Util::mkdirs()
	* src/FileEntry.cc (setupDir)
	* test/FileEntryTest.cc
	
	Updated doc
	* src/SingleFileDownloadContext.h
pull/1/head
Tatsuhiro Tsujikawa 2007-11-05 15:13:55 +00:00
parent bcbadb3b6b
commit 52b43151c6
14 changed files with 119 additions and 31 deletions

View File

@ -1,3 +1,27 @@
2007-11-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Now a file is stored in the directory specified in .metalnk file
(file[@name]).
* src/Metalink2RequestGroup.cc
Create the directory structure when opening the file if it doesn't
exist.
* src/AbstractDiskWriter.cc
* src/Util.{h, cc}
* src/File.h
* test/UtilTest.cc
Removed file name comparison
* src/Metalink2RequestGroup.cc
* src/HttpResponseCommand.cc
Rewritten using Util::mkdirs()
* src/FileEntry.cc (setupDir)
* test/FileEntryTest.cc
Updated doc
* src/SingleFileDownloadContext.h
2007-11-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Now SleepCommand dispatches nextCommand when halt is requested.

2
TODO
View File

@ -53,4 +53,4 @@
* Implement duplicate download checking in Bt
* improve --metalink-location field
* Use content-type for PostDownloadHandler
* Fix SleepCommand to catch halt signal

View File

@ -92,11 +92,8 @@ void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags)
throw(DlAbortEx*)
{
this->filename = filename;
// TODO proper filename handling needed
assert(filename.size());
// if(filename.empty()) {
// filename = "index.html";
// }
Util::mkdirs(File(filename).getDirname());
if((fd = open(filename.c_str(), O_CREAT|O_RDWR|O_TRUNC|O_BINARY|addFlags, OPEN_MODE)) < 0) {
throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno));
}

View File

@ -95,6 +95,11 @@ public:
string getDirname() const;
const string& getPath() const
{
return name;
}
static bool isDir(const string& filename);
bool renameTo(const string& dest);

View File

@ -34,7 +34,7 @@
/* copyright --> */
#include "FileEntry.h"
#include "File.h"
#include "DlAbortEx.h"
#include "Util.h"
#include <libgen.h>
FileEntry::FileEntry(const string& path,
@ -48,21 +48,7 @@ FileEntry::~FileEntry() {}
void FileEntry::setupDir(const string& parentDir)
{
string absPath = parentDir+"/"+path;
char* temp = strdup(absPath.c_str());
string dir = string(dirname(temp));
free(temp);
if(!dir.size()) {
return;
}
File f(dir);
if(f.isDir()) {
// nothing to do
} else if(f.exists()) {
throw new DlAbortEx("%s is not a directory.", dir.c_str());
} else if(!f.mkdirs()) {
throw new DlAbortEx("Failed to create directory %s.", dir.c_str());
}
Util::mkdirs(File(parentDir+"/"+path).getDirname());
}
FileEntry& FileEntry::operator=(const FileEntry& entry)

View File

@ -91,14 +91,12 @@ bool HttpResponseCommand::executeInternal()
}
if(!_requestGroup->getPieceStorage().isNull()) {
// validate totalsize
_requestGroup->validateFilename(httpResponse->determinFilename());
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
e->commands.push_back(createHttpDownloadCommand(httpResponse));
return true;
} else {
// validate totalsize against hintTotalSize if it is provided.
_requestGroup->validateFilenameByHint(httpResponse->determinFilename());
_requestGroup->validateTotalLengthByHint(httpResponse->getEntityLength());
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setFilename(httpResponse->determinFilename());

View File

@ -159,7 +159,8 @@ RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile)
SingleFileDownloadContextHandle dctx =
new SingleFileDownloadContext(pieceLength,
0,
"");
"",
entry->file->getPath());
dctx->setDir(_option->get(PREF_DIR));
if(!entry->chunkChecksum.isNull()) {
dctx->setPieceHashes(entry->chunkChecksum->getChecksums());
@ -169,7 +170,6 @@ RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile)
// * hash and hash algorithm
rg->setDownloadContext(dctx);
rg->setHintFilename(entry->file->getBasename());
rg->setHintTotalLength(entry->getLength());
rg->setNumConcurrentCommand(entry->maxConnections < 0 ?
_option->getAsInt(PREF_METALINK_SERVERS) :

View File

@ -46,6 +46,10 @@ private:
* If _ufilename is not zero-length string, then _dir + _ufilename.
*/
FileEntryHandle _fileEntry;
/**
* _filename and _ufilename may contains directory path name.
* So usr/local/aria2c is acceptable here.
*/
string _filename;
string _ufilename;

View File

@ -763,3 +763,14 @@ int32_t Util::alphaToNum(const string& alphabets)
return num;
}
void Util::mkdirs(const string& dirpath)
{
File dir(dirpath);
if(dir.isDir()) {
// do nothing
} else if(dir.exists()) {
throw new DlAbortEx(EX_MAKE_DIR, dir.getPath().c_str(), "File already exists.");
} else if(!dir.mkdirs()) {
throw new DlAbortEx(EX_MAKE_DIR, dir.getPath().c_str(), strerror(errno));
}
}

View File

@ -150,6 +150,8 @@ public:
static bool isUppercase(const string& what);
static int32_t alphaToNum(const string& alphabets);
static void mkdirs(const string& dirpath);
};
#endif // _D_UTIL_H_

34
test/FileEntryTest.cc Normal file
View File

@ -0,0 +1,34 @@
#include "FileEntry.h"
#include <cppunit/extensions/HelperMacros.h>
class FileEntryTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(FileEntryTest);
CPPUNIT_TEST(testSetupDir);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void testSetupDir();
};
CPPUNIT_TEST_SUITE_REGISTRATION( FileEntryTest );
void FileEntryTest::testSetupDir()
{
string topDir = "/tmp";
string dir = "aria2-FileEntryTest-testSetupDir";
string filename = "filename";
string path = topDir+"/"+dir+"/"+filename;
File d(topDir+"/"+dir);
if(d.exists()) {
CPPUNIT_ASSERT(d.remove());
}
CPPUNIT_ASSERT(!d.exists());
FileEntry fileEntry(dir+"/"+filename, 0, 0);
fileEntry.setupDir(topDir);
CPPUNIT_ASSERT(d.isDir());
File f(path);
CPPUNIT_ASSERT(!f.exists());
}

View File

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

View File

@ -112,7 +112,7 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT)
am__aria2c_SOURCES_DIST = AllTest.cc PieceTest.cc \
am__aria2c_SOURCES_DIST = AllTest.cc FileEntryTest.cc PieceTest.cc \
DefaultPieceStorageTest.cc SegmentTest.cc GrowSegmentTest.cc \
SingleFileAllocationIteratorTest.cc \
DefaultBtProgressInfoFileTest.cc \
@ -203,9 +203,9 @@ am__aria2c_SOURCES_DIST = AllTest.cc PieceTest.cc \
@ENABLE_METALINK_TRUE@ Metalink2RequestGroupTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkPostDownloadHandlerTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkHelperTest.$(OBJEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) PieceTest.$(OBJEXT) \
DefaultPieceStorageTest.$(OBJEXT) SegmentTest.$(OBJEXT) \
GrowSegmentTest.$(OBJEXT) \
am_aria2c_OBJECTS = AllTest.$(OBJEXT) FileEntryTest.$(OBJEXT) \
PieceTest.$(OBJEXT) DefaultPieceStorageTest.$(OBJEXT) \
SegmentTest.$(OBJEXT) GrowSegmentTest.$(OBJEXT) \
SingleFileAllocationIteratorTest.$(OBJEXT) \
DefaultBtProgressInfoFileTest.$(OBJEXT) \
SingleFileDownloadContextTest.$(OBJEXT) \
@ -414,8 +414,8 @@ target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
TESTS = aria2c
aria2c_SOURCES = AllTest.cc PieceTest.cc DefaultPieceStorageTest.cc \
SegmentTest.cc GrowSegmentTest.cc \
aria2c_SOURCES = AllTest.cc FileEntryTest.cc PieceTest.cc \
DefaultPieceStorageTest.cc SegmentTest.cc GrowSegmentTest.cc \
SingleFileAllocationIteratorTest.cc \
DefaultBtProgressInfoFileTest.cc \
SingleFileDownloadContextTest.cc RequestGroupTest.cc \
@ -540,6 +540,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPieceStorageTest.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)/FileEntryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileUriListParserTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GrowSegmentTest.Po@am__quote@

View File

@ -28,6 +28,7 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testIsLowercase);
CPPUNIT_TEST(testIsUppercase);
CPPUNIT_TEST(testAlphaToNum);
CPPUNIT_TEST(testMkdirs);
CPPUNIT_TEST_SUITE_END();
private:
@ -55,6 +56,7 @@ public:
void testIsLowercase();
void testIsUppercase();
void testAlphaToNum();
void testMkdirs();
};
@ -364,3 +366,26 @@ void UtilTest::testAlphaToNum()
CPPUNIT_ASSERT_EQUAL((int32_t)675, Util::alphaToNum("ZZ")); // 25*26+25
CPPUNIT_ASSERT_EQUAL((int32_t)0, Util::alphaToNum(""));
}
void UtilTest::testMkdirs()
{
string dir = "/tmp/aria2-UtilTest-testMkdirs";
File d(dir);
if(d.exists()) {
CPPUNIT_ASSERT(d.remove());
}
CPPUNIT_ASSERT(!d.exists());
Util::mkdirs(dir);
CPPUNIT_ASSERT(d.isDir());
string file = "./UtilTest.cc";
File f(file);
CPPUNIT_ASSERT(f.isFile());
try {
Util::mkdirs(file);
CPPUNIT_FAIL("exception must be thrown.");
} catch(DlAbortEx* ex) {
cerr << ex->getMsg() << endl;
delete ex;
}
}