reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/archive.cpp | 31+++++++++++++++++++++++++++++--
Msrc/archive.hpp | 22+++++++++++++++++++---
Msrc/download.hpp | 6++++--
Msrc/task.cpp | 17++++++++++-------
Msrc/task.hpp | 7++++++-
Msrc/thread.cpp | 3++-
Msrc/thread.hpp | 2++
Msrc/transaction.cpp | 7++++---
Msrc/transaction.hpp | 2+-
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 &);