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 --> */
#include "SessionSerializer.h"
#include <fstream>
#include <cstdio>
#include <iterator>
#include "RequestGroupMan.h"
@ -48,6 +48,7 @@
#include "prefs.h"
#include "util.h"
#include "array_fun.h"
#include "BufferedFile.h"
namespace aria2 {
@ -62,13 +63,11 @@ bool SessionSerializer::save(const std::string& filename) const
{
std::string tempFilename = strconcat(filename, "__temp");
{
std::ofstream out(tempFilename.c_str(), std::ios::binary);
if(!out) {
BufferedFile fp(tempFilename, BufferedFile::WRITE);
if(!fp) {
return false;
}
save(out);
out.flush();
if(!out) {
if(!save(fp) || fp.close() == EOF) {
return false;
}
}
@ -101,7 +100,7 @@ bool inCumulativeOpts(const std::string& opt)
} // 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();
for(std::set<std::string>::const_iterator itr = requestOptions.begin(),
@ -110,7 +109,14 @@ void writeOption(std::ostream& out, const SharedHandle<Option>& op)
continue;
}
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();
@ -122,49 +128,67 @@ void writeOption(std::ostream& out, const SharedHandle<Option>& op)
false, false);
for(std::vector<std::string>::const_iterator i = v.begin(), eoi = v.end();
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 {
void writeDownloadResult
(std::ostream& out, std::set<int64_t>& metainfoCache,
bool writeDownloadResult
(BufferedFile& fp, std::set<int64_t>& metainfoCache,
const SharedHandle<DownloadResult>& dr)
{
const SharedHandle<MetadataInfo>& mi = dr->metadataInfo;
if(dr->belongsTo != 0 || (mi && mi->dataOnly())) {
return;
return true;
}
if(!mi) {
// only save first file entry
if(dr->fileEntries.empty()) {
return;
return true;
}
const SharedHandle<FileEntry>& file = dr->fileEntries[0];
std::vector<std::string> uris;
file->getUris(uris);
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 {
if(metainfoCache.count(mi->getId()) != 0) {
return;
return true;
} else {
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
void SessionSerializer::save(std::ostream& out) const
bool SessionSerializer::save(BufferedFile& fp) const
{
std::set<int64_t> metainfoCache;
const std::deque<SharedHandle<DownloadResult> >& results =
@ -176,12 +200,16 @@ void SessionSerializer::save(std::ostream& out) const
continue;
} else if((*itr)->result == error_code::IN_PROGRESS) {
if(saveInProgress_) {
writeDownloadResult(out, metainfoCache, *itr);
if(!writeDownloadResult(fp, metainfoCache, *itr)) {
return false;
}
}
} else {
// error download
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 =
groups.begin(), eoi = groups.end(); itr != eoi; ++itr) {
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
// property separately.
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

View File

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

View File

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