mirror of https://github.com/aria2/aria2
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.hpull/1/head
parent
bcbadb3b6b
commit
52b43151c6
24
ChangeLog
24
ChangeLog
|
@ -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
2
TODO
|
@ -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
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) :
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
11
src/Util.cc
11
src/Util.cc
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
TESTS = aria2c
|
||||
check_PROGRAMS = $(TESTS)
|
||||
aria2c_SOURCES = AllTest.cc\
|
||||
FileEntryTest.cc\
|
||||
PieceTest.cc\
|
||||
DefaultPieceStorageTest.cc\
|
||||
SegmentTest.cc\
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue