diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-10-21 18:42:03 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-10-21 18:42:03 +0200 |
| commit | f37e6b5a0f320d4352b87b97f78afae762512b93 (patch) | |
| tree | 354a5a8b3882f69fa3de3fed175b30576c58bf6b /src/lib/util.cc | |
| parent | 231644e75f537342c3442c03a3cd5ef34bfa25ec (diff) | |
| parent | dfd42d2a546d14c32057a34002543877ea2f99cb (diff) | |
Merge branch 'v2.15.x' of ssh://git.carlh.net/home/carl/git/dcpomatic into v2.15.xv2.15.25
Diffstat (limited to 'src/lib/util.cc')
| -rw-r--r-- | src/lib/util.cc | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/lib/util.cc b/src/lib/util.cc index fd7a95684..bbb444367 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -1015,6 +1015,58 @@ show_jobs_on_console (bool progress) return error; } +/** XXX: could use mmap? */ +void +copy_in_bits (boost::filesystem::path from, boost::filesystem::path to, boost::function<void (float)> progress) +{ + FILE* f = fopen_boost (from, "rb"); + if (!f) { + throw OpenFileError (from, errno, OpenFileError::READ); + } + FILE* t = fopen_boost (to, "wb"); + if (!t) { + fclose (f); + throw OpenFileError (to, errno, OpenFileError::WRITE); + } + + /* on the order of a second's worth of copying */ + boost::uintmax_t const chunk = 20 * 1024 * 1024; + + uint8_t* buffer = static_cast<uint8_t*> (malloc(chunk)); + if (!buffer) { + throw std::bad_alloc (); + } + + boost::uintmax_t const total = boost::filesystem::file_size (from); + boost::uintmax_t remaining = total; + + while (remaining) { + boost::uintmax_t this_time = min (chunk, remaining); + size_t N = fread (buffer, 1, chunk, f); + if (N < this_time) { + fclose (f); + fclose (t); + free (buffer); + throw ReadFileError (from, errno); + } + + N = fwrite (buffer, 1, this_time, t); + if (N < this_time) { + fclose (f); + fclose (t); + free (buffer); + throw WriteFileError (to, errno); + } + + progress (1 - float(remaining) / total); + remaining -= this_time; + } + + fclose (f); + fclose (t); + free (buffer); +} + #ifdef DCPOMATIC_VARIANT_SWAROOP /* Make up a key from the machine UUID */ |
