From 77bd398153240390362fea83533627e6d767ddb3 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 14 Sep 2016 23:10:24 +0200 Subject: [PATCH] implement file-[un]archive progress report --- libs/pbd/file_archive.cc | 46 ++++++++++++++++++++++++++++++++++--- libs/pbd/pbd/file_archive.h | 12 +++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/libs/pbd/file_archive.cc b/libs/pbd/file_archive.cc index f8700ce60c..4afc9abad9 100644 --- a/libs/pbd/file_archive.cc +++ b/libs/pbd/file_archive.cc @@ -55,11 +55,19 @@ get_url (void* arg) curl = curl_easy_init (); curl_easy_setopt (curl, CURLOPT_URL, r->url); + curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); + + /* get size */ + if (r->mp.progress) { + curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); + curl_easy_setopt(curl, CURLOPT_HEADER, 0L); + curl_easy_perform (curl); + curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &r->mp.length); + } + curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void*) &r->mp); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_perform (curl); curl_easy_cleanup (curl); @@ -92,7 +100,11 @@ ar_read (struct archive* a, void* d, const void** buff) memmove (p->data, &p->data[rv], p->size - rv); } p->size -= rv; + p->processed += rv; *buff = p->buf; + if (p->progress) { + p->progress->progress (p->processed, p->length); + } p->unlock (); return rv; } @@ -130,7 +142,6 @@ setup_archive () return a; } - FileArchive::FileArchive (const std::string& url) : _req (url) { @@ -138,6 +149,12 @@ FileArchive::FileArchive (const std::string& url) fprintf (stderr, "Invalid Archive URL/filename\n"); throw failed_constructor (); } + + if (_req.is_remote ()) { + _req.mp.progress = this; + } else { + _req.mp.progress = 0; + } } int @@ -175,6 +192,12 @@ std::vector FileArchive::contents_file () { struct archive* a = setup_archive (); + GStatBuf statbuf; + if (!g_stat (_req.url, &statbuf)) { + _req.mp.length = statbuf.st_size; + } else { + _req.mp.length = -1; + } if (ARCHIVE_OK != archive_read_open_filename (a, _req.url, 8192)) { fprintf (stderr, "Error opening archive: %s\n", archive_error_string(a)); return std::vector (); @@ -200,6 +223,12 @@ int FileArchive::extract_file () { struct archive* a = setup_archive (); + GStatBuf statbuf; + if (!g_stat (_req.url, &statbuf)) { + _req.mp.length = statbuf.st_size; + } else { + _req.mp.length = -1; + } if (ARCHIVE_OK != archive_read_open_filename (a, _req.url, 8192)) { fprintf (stderr, "Error opening archive: %s\n", archive_error_string(a)); return -1; @@ -228,6 +257,11 @@ FileArchive::get_contents (struct archive* a) struct archive_entry* entry; for (;;) { int r = archive_read_next_header (a, &entry); + if (!_req.mp.progress) { + // file i/o -- not URL + const uint64_t read = archive_filter_bytes (a, -1); + progress (read, _req.mp.length); + } if (r == ARCHIVE_EOF) { break; } @@ -257,6 +291,12 @@ FileArchive::do_extract (struct archive* a) for (;;) { int r = archive_read_next_header (a, &entry); + if (!_req.mp.progress) { + // file i/o -- not URL + const uint64_t read = archive_filter_bytes (a, -1); + progress (read, _req.mp.length); + } + if (r == ARCHIVE_EOF) { break; } diff --git a/libs/pbd/pbd/file_archive.h b/libs/pbd/pbd/file_archive.h index ad1f85941f..9fc11fc464 100644 --- a/libs/pbd/pbd/file_archive.h +++ b/libs/pbd/pbd/file_archive.h @@ -38,17 +38,17 @@ class LIBPBD_API FileArchive int inflate (const std::string& destdir); std::vector contents (); - //PBD::Signal2 progress; // TODO + PBD::Signal2 progress; // TODO struct MemPipe { public: MemPipe () : data (NULL) - , size (0) - , done (false) + , progress (0) { pthread_mutex_init (&_lock, NULL); pthread_cond_init (&_ready, NULL); + reset (); } ~MemPipe () @@ -68,6 +68,8 @@ class LIBPBD_API FileArchive data = 0; size = 0; done = false; + processed = 0; + length = -1; unlock (); } @@ -81,6 +83,10 @@ class LIBPBD_API FileArchive size_t size; bool done; + double processed; + double length; + FileArchive* progress; + private: pthread_mutex_t _lock; pthread_cond_t _ready; -- 2.30.2