13
0

implement file-[un]archive progress report

This commit is contained in:
Robin Gareus 2016-09-14 23:10:24 +02:00
parent 1ee63d2610
commit 77bd398153
2 changed files with 53 additions and 7 deletions

View File

@ -55,11 +55,19 @@ get_url (void* arg)
curl = curl_easy_init (); curl = curl_easy_init ();
curl_easy_setopt (curl, CURLOPT_URL, r->url); curl_easy_setopt (curl, CURLOPT_URL, r->url);
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_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_perform (curl); curl_easy_perform (curl);
curl_easy_cleanup (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); memmove (p->data, &p->data[rv], p->size - rv);
} }
p->size -= rv; p->size -= rv;
p->processed += rv;
*buff = p->buf; *buff = p->buf;
if (p->progress) {
p->progress->progress (p->processed, p->length);
}
p->unlock (); p->unlock ();
return rv; return rv;
} }
@ -130,7 +142,6 @@ setup_archive ()
return a; return a;
} }
FileArchive::FileArchive (const std::string& url) FileArchive::FileArchive (const std::string& url)
: _req (url) : _req (url)
{ {
@ -138,6 +149,12 @@ FileArchive::FileArchive (const std::string& url)
fprintf (stderr, "Invalid Archive URL/filename\n"); fprintf (stderr, "Invalid Archive URL/filename\n");
throw failed_constructor (); throw failed_constructor ();
} }
if (_req.is_remote ()) {
_req.mp.progress = this;
} else {
_req.mp.progress = 0;
}
} }
int int
@ -175,6 +192,12 @@ std::vector<std::string>
FileArchive::contents_file () FileArchive::contents_file ()
{ {
struct archive* a = setup_archive (); 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)) { if (ARCHIVE_OK != archive_read_open_filename (a, _req.url, 8192)) {
fprintf (stderr, "Error opening archive: %s\n", archive_error_string(a)); fprintf (stderr, "Error opening archive: %s\n", archive_error_string(a));
return std::vector<std::string> (); return std::vector<std::string> ();
@ -200,6 +223,12 @@ int
FileArchive::extract_file () FileArchive::extract_file ()
{ {
struct archive* a = setup_archive (); 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)) { if (ARCHIVE_OK != archive_read_open_filename (a, _req.url, 8192)) {
fprintf (stderr, "Error opening archive: %s\n", archive_error_string(a)); fprintf (stderr, "Error opening archive: %s\n", archive_error_string(a));
return -1; return -1;
@ -228,6 +257,11 @@ FileArchive::get_contents (struct archive* a)
struct archive_entry* entry; struct archive_entry* entry;
for (;;) { for (;;) {
int r = archive_read_next_header (a, &entry); 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) { if (r == ARCHIVE_EOF) {
break; break;
} }
@ -257,6 +291,12 @@ FileArchive::do_extract (struct archive* a)
for (;;) { for (;;) {
int r = archive_read_next_header (a, &entry); 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) { if (r == ARCHIVE_EOF) {
break; break;
} }

View File

@ -38,17 +38,17 @@ class LIBPBD_API FileArchive
int inflate (const std::string& destdir); int inflate (const std::string& destdir);
std::vector<std::string> contents (); std::vector<std::string> contents ();
//PBD::Signal2<void, size_t, size_t> progress; // TODO PBD::Signal2<void, size_t, size_t> progress; // TODO
struct MemPipe { struct MemPipe {
public: public:
MemPipe () MemPipe ()
: data (NULL) : data (NULL)
, size (0) , progress (0)
, done (false)
{ {
pthread_mutex_init (&_lock, NULL); pthread_mutex_init (&_lock, NULL);
pthread_cond_init (&_ready, NULL); pthread_cond_init (&_ready, NULL);
reset ();
} }
~MemPipe () ~MemPipe ()
@ -68,6 +68,8 @@ class LIBPBD_API FileArchive
data = 0; data = 0;
size = 0; size = 0;
done = false; done = false;
processed = 0;
length = -1;
unlock (); unlock ();
} }
@ -81,6 +83,10 @@ class LIBPBD_API FileArchive
size_t size; size_t size;
bool done; bool done;
double processed;
double length;
FileArchive* progress;
private: private:
pthread_mutex_t _lock; pthread_mutex_t _lock;
pthread_cond_t _ready; pthread_cond_t _ready;