Rewritten SessionSerializer using BufferedFile

pull/1/head
Tatsuhiro Tsujikawa 2011-08-07 00:36:44 +09:00
parent 6034474550
commit 1f710d29c1
3 changed files with 67 additions and 32 deletions

View File

@ -34,7 +34,7 @@
/* copyright --> */ /* copyright --> */
#include "SessionSerializer.h" #include "SessionSerializer.h"
#include <fstream> #include <cstdio>
#include <iterator> #include <iterator>
#include "RequestGroupMan.h" #include "RequestGroupMan.h"
@ -48,6 +48,7 @@
#include "prefs.h" #include "prefs.h"
#include "util.h" #include "util.h"
#include "array_fun.h" #include "array_fun.h"
#include "BufferedFile.h"
namespace aria2 { namespace aria2 {
@ -62,13 +63,11 @@ bool SessionSerializer::save(const std::string& filename) const
{ {
std::string tempFilename = strconcat(filename, "__temp"); std::string tempFilename = strconcat(filename, "__temp");
{ {
std::ofstream out(tempFilename.c_str(), std::ios::binary); BufferedFile fp(tempFilename, BufferedFile::WRITE);
if(!out) { if(!fp) {
return false; return false;
} }
save(out); if(!save(fp) || fp.close() == EOF) {
out.flush();
if(!out) {
return false; return false;
} }
} }
@ -101,7 +100,7 @@ bool inCumulativeOpts(const std::string& opt)
} // namespace } // namespace
namespace { namespace {
void writeOption(std::ostream& out, const SharedHandle<Option>& op) bool writeOption(BufferedFile& fp, const SharedHandle<Option>& op)
{ {
const std::set<std::string>& requestOptions = listRequestOptions(); const std::set<std::string>& requestOptions = listRequestOptions();
for(std::set<std::string>::const_iterator itr = requestOptions.begin(), for(std::set<std::string>::const_iterator itr = requestOptions.begin(),
@ -110,7 +109,14 @@ void writeOption(std::ostream& out, const SharedHandle<Option>& op)
continue; continue;
} }
if(op->defined(*itr)) { if(op->defined(*itr)) {
out << " " << *itr << "=" << op->get(*itr) << "\n"; if(fp.write(" ", 1) != 1 ||
fp.write((*itr).data(), (*itr).size()) != (*itr).size() ||
fp.write("=", 1) != 1 ||
fp.write(op->get(*itr).data(), op->get(*itr).size()) !=
op->get(*itr).size() ||
fp.write("\n", 1) != 1) {
return false;
}
} }
} }
const std::vector<std::string>& cumopts = getCumulativeOpts(); const std::vector<std::string>& cumopts = getCumulativeOpts();
@ -122,49 +128,67 @@ void writeOption(std::ostream& out, const SharedHandle<Option>& op)
false, false); false, false);
for(std::vector<std::string>::const_iterator i = v.begin(), eoi = v.end(); for(std::vector<std::string>::const_iterator i = v.begin(), eoi = v.end();
i != eoi; ++i) { i != eoi; ++i) {
out << " " << *opitr << "=" << *i << "\n"; if(fp.write(" ", 1) != 1 ||
fp.write((*opitr).data(), (*opitr).size()) != (*opitr).size() ||
fp.write("=", 1) != 1 ||
fp.write((*i).data(), (*i).size()) != (*i).size() ||
fp.write("\n", 1) != 1) {
return false;
} }
} }
} }
}
return true;
} }
} // namespace } // namespace
namespace { namespace {
void writeDownloadResult bool writeDownloadResult
(std::ostream& out, std::set<int64_t>& metainfoCache, (BufferedFile& fp, std::set<int64_t>& metainfoCache,
const SharedHandle<DownloadResult>& dr) const SharedHandle<DownloadResult>& dr)
{ {
const SharedHandle<MetadataInfo>& mi = dr->metadataInfo; const SharedHandle<MetadataInfo>& mi = dr->metadataInfo;
if(dr->belongsTo != 0 || (mi && mi->dataOnly())) { if(dr->belongsTo != 0 || (mi && mi->dataOnly())) {
return; return true;
} }
if(!mi) { if(!mi) {
// only save first file entry // only save first file entry
if(dr->fileEntries.empty()) { if(dr->fileEntries.empty()) {
return; return true;
} }
const SharedHandle<FileEntry>& file = dr->fileEntries[0]; const SharedHandle<FileEntry>& file = dr->fileEntries[0];
std::vector<std::string> uris; std::vector<std::string> uris;
file->getUris(uris); file->getUris(uris);
if(uris.empty()) { if(uris.empty()) {
return; return true;
}
for(std::vector<std::string>::const_iterator i = uris.begin(),
eoi = uris.end(); i != eoi; ++i) {
if(fp.write((*i).data(), (*i).size()) != (*i).size() ||
fp.write("\t", 1) != 1) {
return false;
}
}
if(fp.write("\n", 1) != 1) {
return false;
} }
std::copy(uris.begin(), uris.end(),
std::ostream_iterator<std::string>(out, "\t"));
out << "\n";
} else { } else {
if(metainfoCache.count(mi->getId()) != 0) { if(metainfoCache.count(mi->getId()) != 0) {
return; return true;
} else { } else {
metainfoCache.insert(mi->getId()); metainfoCache.insert(mi->getId());
out << mi->getUri() << "\n"; if(fp.write(mi->getUri().data(), mi->getUri().size()) !=
mi->getUri().size() ||
fp.write("\n", 1) != 1) {
return false;
} }
} }
writeOption(out, dr->option); }
return writeOption(fp, dr->option);
} }
} // namespace } // namespace
void SessionSerializer::save(std::ostream& out) const bool SessionSerializer::save(BufferedFile& fp) const
{ {
std::set<int64_t> metainfoCache; std::set<int64_t> metainfoCache;
const std::deque<SharedHandle<DownloadResult> >& results = const std::deque<SharedHandle<DownloadResult> >& results =
@ -176,12 +200,16 @@ void SessionSerializer::save(std::ostream& out) const
continue; continue;
} else if((*itr)->result == error_code::IN_PROGRESS) { } else if((*itr)->result == error_code::IN_PROGRESS) {
if(saveInProgress_) { if(saveInProgress_) {
writeDownloadResult(out, metainfoCache, *itr); if(!writeDownloadResult(fp, metainfoCache, *itr)) {
return false;
}
} }
} else { } else {
// error download // error download
if(saveError_) { if(saveError_) {
writeDownloadResult(out, metainfoCache, *itr); if(!writeDownloadResult(fp, metainfoCache, *itr)) {
return false;
}
} }
} }
} }
@ -191,16 +219,22 @@ void SessionSerializer::save(std::ostream& out) const
for(std::deque<SharedHandle<RequestGroup> >::const_iterator itr = for(std::deque<SharedHandle<RequestGroup> >::const_iterator itr =
groups.begin(), eoi = groups.end(); itr != eoi; ++itr) { groups.begin(), eoi = groups.end(); itr != eoi; ++itr) {
SharedHandle<DownloadResult> result = (*itr)->createDownloadResult(); SharedHandle<DownloadResult> result = (*itr)->createDownloadResult();
writeDownloadResult(out, metainfoCache, result); if(!writeDownloadResult(fp, metainfoCache, result)) {
return false;
}
// PREF_PAUSE was removed from option, so save it here looking // PREF_PAUSE was removed from option, so save it here looking
// property separately. // property separately.
if((*itr)->isPauseRequested()) { if((*itr)->isPauseRequested()) {
out << " " << PREF_PAUSE << "=true" << "\n"; if(fp.write(" ", 1) != 1 ||
fp.write(PREF_PAUSE.data(), PREF_PAUSE.size()) !=
PREF_PAUSE.size() ||
fp.write("=true\n", 1) != 1) {
return false;
} }
} }
} }
}
return true;
} }
} // namespace aria2 } // namespace aria2

View File

@ -45,6 +45,7 @@
namespace aria2 { namespace aria2 {
class RequestGroupMan; class RequestGroupMan;
class BufferedFile;
class SessionSerializer { class SessionSerializer {
private: private:
@ -52,12 +53,11 @@ private:
bool saveError_; bool saveError_;
bool saveInProgress_; bool saveInProgress_;
bool saveWaiting_; bool saveWaiting_;
bool save(BufferedFile& fp) const;
public: public:
SessionSerializer(const SharedHandle<RequestGroupMan>& requestGroupMan); SessionSerializer(const SharedHandle<RequestGroupMan>& requestGroupMan);
bool save(const std::string& filename) const; bool save(const std::string& filename) const;
void save(std::ostream& out) const;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -1,7 +1,7 @@
#include "SessionSerializer.h" #include "SessionSerializer.h"
#include <iostream> #include <iostream>
#include <sstream> #include <fstream>
#include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/HelperMacros.h>
@ -70,8 +70,9 @@ void SessionSerializerTest::testSave()
(createDownloadResult(error_code::REMOVED, "http://removed")); (createDownloadResult(error_code::REMOVED, "http://removed"));
rgman->addDownloadResult rgman->addDownloadResult
(createDownloadResult(error_code::TIME_OUT, "http://error")); (createDownloadResult(error_code::TIME_OUT, "http://error"));
std::stringstream ss; std::string filename = A2_TEST_OUT_DIR"/aria2_SessionSerializerTest_testSave";
s.save(ss); s.save(filename);
std::ifstream ss(filename.c_str(), std::ios::binary);
std::string line; std::string line;
std::getline(ss, line); std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(std::string("http://error\t"), line); CPPUNIT_ASSERT_EQUAL(std::string("http://error\t"), line);