commit 6bcbe4baf4e033617a2b0cf7e5b8a1b1060fa4ea
parent e645038c6b02b64fcf7e5fed209323f1feda86fd
Author: cfillion <cfillion@users.noreply.github.com>
Date: Mon, 27 Feb 2017 00:11:37 -0500
finish implementation of archive import
Diffstat:
9 files changed, 77 insertions(+), 20 deletions(-)
diff --git a/src/archive.cpp b/src/archive.cpp
@@ -65,7 +65,7 @@ struct ImportArchive {
void importRemote(const string &);
void importPackage(const string &);
- std::shared_ptr<ArchiveReader> m_reader;
+ ArchiveReaderPtr m_reader;
RemoteList *m_remotes;
Transaction *m_tx;
IndexPtr m_lastIndex;
@@ -150,7 +150,7 @@ void ImportArchive::importPackage(const string &data)
% m_lastIndex->name() % categoryName % packageName % versionName);
}
- // m_tx->install(ver, pinned, m_reader);
+ m_tx->install(ver, pinned, m_reader);
}
size_t Archive::create(const auto_string &path, ReaPack *reapack)
@@ -249,6 +249,33 @@ int ArchiveReader::extractFile(const Path &path, ostream &stream)
return unzCloseCurrentFile(m_zip);
}
+FileExtractor::FileExtractor(const Path &target, const ArchiveReaderPtr &reader)
+ : m_path(target), m_reader(reader)
+{
+ setSummary("Extracting %s: " + target.join());
+}
+
+void FileExtractor::run(DownloadContext *)
+{
+ if(aborted()) {
+ finish(Aborted, {"cancelled", m_path.target().join()});
+ return;
+ }
+
+ ThreadNotifier::get()->notify({this, Running});
+
+ ofstream stream;
+ if(!FS::open(stream, m_path.temp())) {
+ finish(Failure, {FS::lastError(), m_path.temp().join()});
+ return;
+ }
+
+ if(!m_reader->extractFile(m_path.target(), stream))
+ finish(Success);
+ else
+ finish(Failure, {"Failed to extract file", m_path.target().join()});
+}
+
ArchiveWriter::ArchiveWriter(const auto_string &path)
{
zlib_filefunc64_def filefunc;
diff --git a/src/archive.hpp b/src/archive.hpp
@@ -19,12 +19,13 @@
#define REAPACK_ARCHIVE_HPP
#include "encoding.hpp"
+#include "path.hpp"
+#include "thread.hpp"
-typedef void *zipFile;
-
-class Path;
class ReaPack;
+typedef void *zipFile;
+
namespace Archive {
void import(const auto_string &path, ReaPack *);
size_t create(const auto_string &path, ReaPack *);
@@ -52,4 +53,19 @@ private:
zipFile m_zip;
};
+typedef std::shared_ptr<ArchiveReader> ArchiveReaderPtr;
+
+class FileExtractor : public ThreadTask {
+public:
+ FileExtractor(const Path &target, const ArchiveReaderPtr &);
+ const TempPath &path() const { return m_path; }
+
+ bool concurrent() const override { return false; }
+ void run(DownloadContext *) override;
+
+private:
+ TempPath m_path;
+ ArchiveReaderPtr m_reader;
+};
+
#endif
diff --git a/src/download.hpp b/src/download.hpp
@@ -44,10 +44,12 @@ public:
};
Download(const std::string &url, const NetworkOpts &, int flags = 0);
- const std::string &url() const { return m_url; }
- void start();
void setName(const std::string &);
+ const std::string &url() const { return m_url; }
+ void start();
+
+ bool concurrent() const override { return true; }
void run(DownloadContext *) override;
private:
diff --git a/src/task.cpp b/src/task.cpp
@@ -17,6 +17,7 @@
#include "task.hpp"
+#include "archive.hpp"
#include "config.hpp"
#include "download.hpp"
#include "errors.hpp"
@@ -31,9 +32,9 @@ Task::Task(Transaction *tx) : m_tx(tx)
}
InstallTask::InstallTask(const Version *ver, const bool pin,
- const Registry::Entry &re, Transaction *tx)
- : Task(tx), m_version(ver), m_pin(pin), m_oldEntry(move(re)), m_fail(false),
- m_index(ver->package()->category()->index()->shared_from_this())
+ const Registry::Entry &re, const ArchiveReaderPtr &reader, Transaction *tx)
+ : Task(tx), m_version(ver), m_pin(pin), m_oldEntry(move(re)), m_reader(reader),
+ m_fail(false), m_index(ver->package()->category()->index()->shared_from_this())
{
}
@@ -70,13 +71,15 @@ bool InstallTask::start()
if(old != m_oldFiles.end())
m_oldFiles.erase(old);
- // if(m_reader) {
- // }
- // else {
+ if(m_reader) {
+ FileExtractor *ex = new FileExtractor(targetPath, m_reader);
+ push(ex, ex->path());
+ }
+ else {
const NetworkOpts &opts = tx()->config()->network;
FileDownload *dl = new FileDownload(targetPath, src->url(), opts);
push(dl, dl->path());
- // }
+ }
}
return true;
diff --git a/src/task.hpp b/src/task.hpp
@@ -25,12 +25,14 @@
#include <unordered_set>
#include <vector>
+class ArchiveReader;
class Index;
class Source;
class ThreadTask;
class Transaction;
class Version;
+typedef std::shared_ptr<ArchiveReader> ArchiveReaderPtr;
typedef std::shared_ptr<const Index> IndexPtr;
class Task {
@@ -54,7 +56,8 @@ private:
class InstallTask : public Task {
public:
- InstallTask(const Version *ver, bool pin, const Registry::Entry &, Transaction *);
+ InstallTask(const Version *ver, bool pin, const Registry::Entry &,
+ const ArchiveReaderPtr &, Transaction *);
bool start() override;
void commit() override;
@@ -66,6 +69,8 @@ private:
const Version *m_version;
bool m_pin;
Registry::Entry m_oldEntry;
+ ArchiveReaderPtr m_reader;
+
bool m_fail;
IndexPtr m_index; // keep in memory
std::vector<Registry::File> m_oldFiles;
diff --git a/src/thread.cpp b/src/thread.cpp
@@ -140,7 +140,8 @@ void ThreadPool::push(ThreadTask *task)
task->setCleanupHandler([=] { delete task; });
- auto &thread = m_pool[m_running.size() % m_pool.size()];
+ const size_t nextThread = m_running.size() % m_pool.size();
+ auto &thread = task->concurrent() ? m_pool[nextThread] : m_pool.front();
if(!thread)
thread = make_unique<WorkerThread>();
diff --git a/src/thread.hpp b/src/thread.hpp
@@ -52,6 +52,8 @@ public:
ThreadTask();
virtual ~ThreadTask();
+
+ virtual bool concurrent() const = 0;
virtual void run(DownloadContext *) = 0;
const std::string &summary() const { return m_summary; }
diff --git a/src/transaction.cpp b/src/transaction.cpp
@@ -113,7 +113,7 @@ void Transaction::synchronize(const Package *pkg, const InstallOpts &opts)
else if(regEntry.pinned || latest->name() < regEntry.version)
return;
- m_nextQueue.push(make_shared<InstallTask>(latest, false, regEntry, this));
+ m_nextQueue.push(make_shared<InstallTask>(latest, false, regEntry, nullptr, this));
}
void Transaction::fetchIndex(const Remote &remote, const function<void()> &cb)
@@ -139,10 +139,11 @@ void Transaction::fetchIndex(const Remote &remote, const function<void()> &cb)
m_threadPool.push(dl);
}
-void Transaction::install(const Version *ver, const bool pin)
+void Transaction::install(const Version *ver,
+ const bool pin, const ArchiveReaderPtr &reader)
{
const auto &oldEntry = m_registry.getEntry(ver->package());
- m_nextQueue.push(make_shared<InstallTask>(ver, pin, oldEntry, this));
+ m_nextQueue.push(make_shared<InstallTask>(ver, pin, oldEntry, reader, this));
}
void Transaction::registerAll(const Remote &remote)
diff --git a/src/transaction.hpp b/src/transaction.hpp
@@ -54,7 +54,7 @@ public:
void synchronize(const Remote &,
boost::optional<bool> forceAutoInstall = boost::none);
- void install(const Version *, bool pin = false);
+ void install(const Version *, bool pin = false, const ArchiveReaderPtr & = nullptr);
void setPinned(const Registry::Entry &, bool pinned);
void uninstall(const Remote &);
void uninstall(const Registry::Entry &);