From 8a8c977c12fc65f1f50ea05099387e0fc8840e7d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 16 Apr 2022 22:20:54 +0200 Subject: [PATCH] Use dcp::File in DCP-o-matic (#2231). --- cscript | 4 +- src/lib/config.cc | 15 +++----- src/lib/cross.h | 3 -- src/lib/cross_linux.cc | 25 ------------ src/lib/cross_osx.cc | 25 ------------ src/lib/cross_windows.cc | 64 ++----------------------------- src/lib/curl_uploader.cc | 15 ++++---- src/lib/curl_uploader.h | 1 + src/lib/ext.cc | 12 ++---- src/lib/file_group.cc | 33 +++++----------- src/lib/file_group.h | 5 ++- src/lib/file_log.cc | 18 ++++----- src/lib/film.cc | 31 +++------------ src/lib/film.h | 12 ++---- src/lib/image_examiner.cc | 6 +-- src/lib/internet.cc | 27 ++++++------- src/lib/kdm_with_metadata.cc | 3 +- src/lib/reel_writer.cc | 31 +++++++-------- src/lib/reel_writer.h | 5 ++- src/lib/scoped_temporary.cc | 34 +++++++---------- src/lib/scoped_temporary.h | 15 ++++---- src/lib/scp_uploader.cc | 12 +++--- src/lib/string_text_file.cc | 22 ++++++----- src/lib/util.cc | 73 ++++++++--------------------------- src/lib/util.h | 2 - src/lib/writer.cc | 5 +-- src/tools/dcpomatic_cli.cc | 7 ++-- src/wx/config_dialog.cc | 48 +++++++++++------------ test/audio_merger_test.cc | 5 ++- test/cpl_hash_test.cc | 17 ++++----- test/hints_test.cc | 10 ++--- test/test.cc | 31 ++++++--------- test/windows_test.cc | 74 ------------------------------------ test/wscript | 1 - 34 files changed, 197 insertions(+), 494 deletions(-) delete mode 100644 test/windows_test.cc diff --git a/cscript b/cscript index b65a430e5..66e77e7db 100644 --- a/cscript +++ b/cscript @@ -427,8 +427,8 @@ def dependencies(target, options): # Use distro-provided FFmpeg on Arch deps = [] - deps.append(('libdcp', 'd0d456fcae355a07ac27102ae9da2680bece6454')) - deps.append(('libsub', 'a23d106d15259440ba66c15f1dca4b6ba30c075e')) + deps.append(('libdcp', 'f031667bd2769d3daf9c49115f21a099fafcee46')) + deps.append(('libsub', '210ac21fdb9d8eb37f5ecde70cd1d0e6c8719390')) deps.append(('leqm-nrt', '93ae9e6')) deps.append(('rtaudio', 'f619b76')) # We get our OpenSSL libraries from the environment, but we diff --git a/src/lib/config.cc b/src/lib/config.cc index b46093726..3661d8ba5 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -1031,12 +1031,12 @@ Config::write_config () const try { auto const s = doc.write_to_string_formatted (); boost::filesystem::path tmp (string(target.string()).append(".tmp")); - auto f = fopen_boost (tmp, "w"); + dcp::File f(tmp, "w"); if (!f) { throw FileError (_("Could not open file for writing"), tmp); } - checked_fwrite (s.c_str(), s.bytes(), f, tmp); - fclose (f); + f.checked_write(s.c_str(), s.bytes()); + f.close(); boost::filesystem::remove (target); boost::filesystem::rename (tmp, target); } catch (xmlpp::exception& e) { @@ -1416,13 +1416,8 @@ Config::copy_and_link (boost::filesystem::path new_file) const bool Config::have_write_permission () const { - auto f = fopen_boost (config_write_file(), "r+"); - if (!f) { - return false; - } - - fclose (f); - return true; + dcp::File f(config_write_file(), "r+"); + return static_cast(f); } /** @param output_channels Number of output channels in use. diff --git a/src/lib/cross.h b/src/lib/cross.h index 83cda4a04..b79f7ebdf 100644 --- a/src/lib/cross.h +++ b/src/lib/cross.h @@ -54,8 +54,6 @@ extern void maybe_open_console (); #endif extern boost::filesystem::path resources_path (); extern boost::filesystem::path libdcp_resources_path (); -extern FILE * fopen_boost (boost::filesystem::path, std::string); -extern int dcpomatic_fseek (FILE *, int64_t, int); extern void start_batch_converter (); extern void start_player (); extern uint64_t thread_id (); @@ -65,7 +63,6 @@ extern bool running_32_on_64 (); extern void unprivileged (); extern boost::filesystem::path config_path (boost::optional version); extern boost::filesystem::path directory_containing_executable (); -extern boost::filesystem::path fix_long_path (boost::filesystem::path path); extern bool show_in_file_manager (boost::filesystem::path dir, boost::filesystem::path select); namespace dcpomatic { std::string get_process_id (); diff --git a/src/lib/cross_linux.cc b/src/lib/cross_linux.cc index d7d1089fc..89a9c5bb6 100644 --- a/src/lib/cross_linux.cc +++ b/src/lib/cross_linux.cc @@ -189,24 +189,6 @@ disk_writer_path () #endif -/* Apparently there is no way to create an ofstream using a UTF-8 - filename under Windows. We are hence reduced to using fopen - with this wrapper. -*/ -FILE * -fopen_boost (boost::filesystem::path p, string t) -{ - return fopen(p.c_str(), t.c_str()); -} - - -int -dcpomatic_fseek (FILE* stream, int64_t offset, int whence) -{ - return fseek (stream, offset, whence); -} - - void Waker::nudge () { @@ -394,13 +376,6 @@ dcpomatic::get_process_id () } -boost::filesystem::path -fix_long_path (boost::filesystem::path path) -{ - return path; -} - - bool show_in_file_manager (boost::filesystem::path dir, boost::filesystem::path) { diff --git a/src/lib/cross_osx.cc b/src/lib/cross_osx.cc index 02f720fee..b214b6359 100644 --- a/src/lib/cross_osx.cc +++ b/src/lib/cross_osx.cc @@ -156,24 +156,6 @@ disk_writer_path () #endif -/* Apparently there is no way to create an ofstream using a UTF-8 - filename under Windows. We are hence reduced to using fopen - with this wrapper. -*/ -FILE * -fopen_boost (boost::filesystem::path p, string t) -{ - return fopen (p.c_str(), t.c_str()); -} - - -int -dcpomatic_fseek (FILE* stream, int64_t offset, int whence) -{ - return fseek (stream, offset, whence); -} - - void Waker::nudge () { @@ -540,13 +522,6 @@ dcpomatic::get_process_id () } -boost::filesystem::path -fix_long_path (boost::filesystem::path path) -{ - return path; -} - - bool show_in_file_manager (boost::filesystem::path, boost::filesystem::path select) { diff --git a/src/lib/cross_windows.cc b/src/lib/cross_windows.cc index f76380836..12fb5efa0 100644 --- a/src/lib/cross_windows.cc +++ b/src/lib/cross_windows.cc @@ -162,7 +162,7 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out) return; } - auto o = fopen_boost (out, "w"); + dcp::File o(out, "w"); if (!o) { LOG_ERROR_NC (N_("ffprobe call failed (could not create output file)")); return; @@ -176,10 +176,10 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out) if (!ReadFile(child_stderr_read, buffer, sizeof(buffer), &read, 0) || read == 0) { break; } - fwrite (buffer, read, 1, o); + o.write(buffer, read, 1); } - fclose (o); + o.close(); WaitForSingleObject (process_info.hProcess, INFINITE); CloseHandle (process_info.hProcess); @@ -232,64 +232,6 @@ disk_writer_path () #endif -/** Windows can't "by default" cope with paths longer than 260 characters, so if you pass such a path to - * any boost::filesystem method it will fail. There is a "fix" for this, which is to prepend - * the string \\?\ to the path. This will make it work, so long as: - * - the path is absolute. - * - the path only uses backslashes. - * - individual path components are "short enough" (probably less than 255 characters) - * - * See https://www.boost.org/doc/libs/1_57_0/libs/filesystem/doc/reference.html under - * "Warning: Long paths on Windows" for some details. - * - * Our fopen_boost uses this method to get this fix, but any other calls to boost::filesystem - * will not unless this method is explicitly called to pre-process the pathname. - */ -boost::filesystem::path -fix_long_path (boost::filesystem::path long_path) -{ - using namespace boost::filesystem; - - if (boost::algorithm::starts_with(long_path.string(), "\\\\")) { - /* This could mean it starts with \\ (i.e. a SMB path) or \\?\ (a long path) - * or a variety of other things... anyway, we'll leave it alone. - */ - return long_path; - } - - /* We have to make the path canonical but we can't call canonical() on the long path - * as it will fail. So we'll sort of do it ourselves (possibly badly). - */ - path fixed = "\\\\?\\"; - if (long_path.is_absolute()) { - fixed += long_path.make_preferred(); - } else { - fixed += boost::filesystem::current_path() / long_path.make_preferred(); - } - return fixed; -} - - -/* Apparently there is no way to create an ofstream using a UTF-8 - filename under Windows. We are hence reduced to using fopen - with this wrapper. -*/ -FILE * -fopen_boost (boost::filesystem::path p, string t) -{ - wstring w (t.begin(), t.end()); - /* c_str() on fixed here should give a UTF-16 string */ - return _wfopen (fix_long_path(p).c_str(), w.c_str()); -} - - -int -dcpomatic_fseek (FILE* stream, int64_t offset, int whence) -{ - return _fseeki64 (stream, offset, whence); -} - - void Waker::nudge () { diff --git a/src/lib/curl_uploader.cc b/src/lib/curl_uploader.cc index 60835bea7..6fe7aba14 100644 --- a/src/lib/curl_uploader.cc +++ b/src/lib/curl_uploader.cc @@ -24,6 +24,7 @@ #include "config.h" #include "cross.h" #include "compose.hpp" +#include "dcpomatic_assert.h" #include #include "i18n.h" @@ -62,9 +63,6 @@ CurlUploader::CurlUploader (function set_status, functiontms_ip(), Config::instance()->tms_path(), to.generic_string ()).c_str () ); - _file = fopen_boost (from, "rb"); - if (!_file) { + dcp::File file(from, "rb"); + if (!file) { throw NetworkError (String::compose (_("Could not open %1 to send"), from)); } + _file = file.get(); _transferred = &transferred; _total_size = total_size; @@ -97,15 +96,15 @@ CurlUploader::upload_file (boost::filesystem::path from, boost::filesystem::path throw NetworkError (String::compose (_("Could not write to remote file (%1)"), curl_easy_strerror (r))); } - fclose (_file); - _file = 0; + _file = nullptr; } size_t CurlUploader::read_callback (void* ptr, size_t size, size_t nmemb) { - size_t const r = fread (ptr, size, nmemb, _file); + DCPOMATIC_ASSERT (_file); + size_t const r = fread(ptr, size, nmemb, _file); *_transferred += size * nmemb; if (_total_size > 0) { diff --git a/src/lib/curl_uploader.h b/src/lib/curl_uploader.h index 564e77493..ea017eb83 100644 --- a/src/lib/curl_uploader.h +++ b/src/lib/curl_uploader.h @@ -20,6 +20,7 @@ #include "uploader.h" +#include #include diff --git a/src/lib/ext.cc b/src/lib/ext.cc index 1af6c137b..7853984cf 100644 --- a/src/lib/ext.cc +++ b/src/lib/ext.cc @@ -79,7 +79,7 @@ static void count (boost::filesystem::path dir, uint64_t& total_bytes) { - dir = fix_long_path (dir); + dir = dcp::fix_long_path (dir); using namespace boost::filesystem; for (auto i: directory_iterator(dir)) { @@ -113,7 +113,7 @@ write (boost::filesystem::path from, boost::filesystem::path to, uint64_t& total throw CopyError (String::compose("Failed to open file %1", to.generic_string()), r); } - FILE* in = fopen_boost (from, "rb"); + dcp::File in(from, "rb"); if (!in) { ext4_fclose (&out); throw CopyError (String::compose("Failed to open file %1", from.string()), 0); @@ -127,9 +127,8 @@ write (boost::filesystem::path from, boost::filesystem::path to, uint64_t& total uint64_t remaining = file_size (from); while (remaining > 0) { uint64_t const this_time = min(remaining, block_size); - size_t read = fread (buffer.data(), 1, this_time, in); + size_t read = in.read(buffer.data(), 1, this_time); if (read != this_time) { - fclose (in); ext4_fclose (&out); throw CopyError (String::compose("Short read; expected %1 but read %2", this_time, read), 0); } @@ -139,12 +138,10 @@ write (boost::filesystem::path from, boost::filesystem::path to, uint64_t& total size_t written; r = ext4_fwrite (&out, buffer.data(), this_time, &written); if (r != EOK) { - fclose (in); ext4_fclose (&out); throw CopyError ("Write failed", r); } if (written != this_time) { - fclose (in); ext4_fclose (&out); throw CopyError (String::compose("Short write; expected %1 but wrote %2", this_time, written), 0); } @@ -157,7 +154,6 @@ write (boost::filesystem::path from, boost::filesystem::path to, uint64_t& total } } - fclose (in); ext4_fclose (&out); set_timestamps_to_now (to); @@ -229,7 +225,7 @@ void copy (boost::filesystem::path from, boost::filesystem::path to, uint64_t& total_remaining, uint64_t total, vector& copied_files, Nanomsg* nanomsg) { LOG_DISK ("Copy %1 -> %2", from.string(), to.generic_string()); - from = fix_long_path (from); + from = dcp::fix_long_path (from); using namespace boost::filesystem; diff --git a/src/lib/file_group.cc b/src/lib/file_group.cc index 7dae1da92..71faacc4c 100644 --- a/src/lib/file_group.cc +++ b/src/lib/file_group.cc @@ -61,15 +61,6 @@ FileGroup::FileGroup (vector const & p) } -/** Destroy a FileGroup, closing any open file */ -FileGroup::~FileGroup () -{ - if (_current_file) { - fclose (_current_file); - } -} - - void FileGroup::set_paths (vector const & p) { @@ -89,11 +80,11 @@ FileGroup::ensure_open_path (size_t p) const } if (_current_file) { - fclose (_current_file); + _current_file->close(); } _current_path = p; - _current_file = fopen_boost (_paths[_current_path], "rb"); + _current_file = dcp::File(_paths[_current_path], "rb"); if (!_current_file) { throw OpenFileError (_paths[_current_path], errno, OpenFileError::READ); } @@ -130,10 +121,10 @@ FileGroup::seek (int64_t pos, int whence) const if (i < _paths.size()) { ensure_open_path (i); - dcpomatic_fseek (_current_file, sub_pos, SEEK_SET); + _current_file->seek(sub_pos, SEEK_SET); } else { ensure_open_path (_paths.size() - 1); - dcpomatic_fseek (_current_file, _current_size, SEEK_SET); + _current_file->seek(_current_size, SEEK_SET); } return _position; @@ -148,6 +139,8 @@ FileGroup::seek (int64_t pos, int whence) const int FileGroup::read (uint8_t* buffer, int amount) const { + DCPOMATIC_ASSERT (_current_file); + int read = 0; while (true) { @@ -156,8 +149,7 @@ FileGroup::read (uint8_t* buffer, int amount) const DCPOMATIC_ASSERT (_current_file); -#ifdef DCPOMATIC_WINDOWS - int64_t const current_position = _ftelli64 (_current_file); + auto const current_position = _current_file->tell(); if (current_position == -1) { to_read = 0; eof = true; @@ -165,15 +157,8 @@ FileGroup::read (uint8_t* buffer, int amount) const to_read = _current_size - current_position; eof = true; } -#else - long const current_position = ftell(_current_file); - if ((current_position + to_read) > _current_size) { - to_read = _current_size - current_position; - eof = true; - } -#endif - int const this_time = fread (buffer + read, 1, to_read, _current_file); + int const this_time = _current_file->read(buffer + read, 1, to_read); read += this_time; _position += this_time; if (read == amount) { @@ -181,7 +166,7 @@ FileGroup::read (uint8_t* buffer, int amount) const break; } - if (ferror(_current_file)) { + if (_current_file->error()) { throw FileError (String::compose("fread error %1", errno), _paths[_current_path]); } diff --git a/src/lib/file_group.h b/src/lib/file_group.h index 9521da7ec..693bf89ba 100644 --- a/src/lib/file_group.h +++ b/src/lib/file_group.h @@ -28,7 +28,9 @@ #define DCPOMATIC_FILE_GROUP_H +#include #include +#include #include @@ -41,7 +43,6 @@ public: FileGroup (); explicit FileGroup (boost::filesystem::path); explicit FileGroup (std::vector const &); - ~FileGroup (); FileGroup (FileGroup const&) = delete; FileGroup& operator= (FileGroup const&) = delete; @@ -58,7 +59,7 @@ private: std::vector _paths; /** Index of path that we are currently reading from */ mutable size_t _current_path = 0; - mutable FILE* _current_file = nullptr; + mutable boost::optional _current_file; mutable size_t _current_size = 0; mutable int64_t _position = 0; }; diff --git a/src/lib/file_log.cc b/src/lib/file_log.cc index a9522bad5..adb06b7f0 100644 --- a/src/lib/file_log.cc +++ b/src/lib/file_log.cc @@ -22,6 +22,7 @@ #include "file_log.h" #include "cross.h" #include "config.h" +#include #include #include #include @@ -51,14 +52,13 @@ FileLog::FileLog (boost::filesystem::path file, int types) void FileLog::do_log (shared_ptr entry) { - auto f = fopen_boost (_file, "a"); + dcp::File f(_file, "a"); if (!f) { cout << "(could not log to " << _file.string() << " error " << errno << "): " << entry->get() << "\n"; return; } - fprintf (f, "%s\n", entry->get().c_str()); - fclose (f); + fprintf(f.get(), "%s\n", entry->get().c_str()); } @@ -80,7 +80,7 @@ FileLog::head_and_tail (int amount) const tail_amount = 0; } - auto f = fopen_boost (_file, "r"); + dcp::File f(_file, "r"); if (!f) { return ""; } @@ -89,21 +89,19 @@ FileLog::head_and_tail (int amount) const std::vector buffer(max(head_amount, tail_amount) + 1); - int N = fread (buffer.data(), 1, head_amount, f); + int N = f.read(buffer.data(), 1, head_amount); buffer[N] = '\0'; out += string (buffer.data()); if (tail_amount > 0) { out += "\n .\n .\n .\n"; - fseek (f, - tail_amount - 1, SEEK_END); + f.seek(- tail_amount - 1, SEEK_END); - N = fread (buffer.data(), 1, tail_amount, f); + N = f.read(buffer.data(), 1, tail_amount); buffer[N] = '\0'; - out += string (buffer.data()) + "\n"; + out += string(buffer.data()) + "\n"; } - fclose (f); - return out; } diff --git a/src/lib/film.cc b/src/lib/film.cc index e49b7f78e..54267bc56 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1718,9 +1718,9 @@ Film::should_be_enough_disk_space (double& required, double& available, bool& ca boost::filesystem::path test = internal_video_asset_dir() / "test"; boost::filesystem::path test2 = internal_video_asset_dir() / "test2"; can_hard_link = true; - auto f = fopen_boost (test, "w"); + dcp::File f(test, "w"); if (f) { - fclose (f); + f.close(); boost::system::error_code ec; boost::filesystem::create_hard_link (test, test2, ec); if (ec) { @@ -2071,34 +2071,15 @@ Film::info_file_handle (DCPTimePeriod period, bool read) const return std::make_shared(_info_file_mutex, info_file(period), read); } -InfoFileHandle::InfoFileHandle (boost::mutex& mutex, boost::filesystem::path file, bool read) +InfoFileHandle::InfoFileHandle (boost::mutex& mutex, boost::filesystem::path path, bool read) : _lock (mutex) - , _file (file) + , _file (path, read ? "rb" : (boost::filesystem::exists(path) ? "r+b" : "wb")) { - if (read) { - _handle = fopen_boost (file, "rb"); - if (!_handle) { - throw OpenFileError (file, errno, OpenFileError::READ); - } - } else { - auto const exists = boost::filesystem::exists (file); - if (exists) { - _handle = fopen_boost (file, "r+b"); - } else { - _handle = fopen_boost (file, "wb"); - } - - if (!_handle) { - throw OpenFileError (file, errno, exists ? OpenFileError::READ_WRITE : OpenFileError::WRITE); - } + if (!_file) { + throw OpenFileError (path, errno, read ? OpenFileError::READ : (boost::filesystem::exists(path) ? OpenFileError::READ_WRITE : OpenFileError::WRITE)); } } -InfoFileHandle::~InfoFileHandle () -{ - fclose (_handle); -} - /** Add FFOC and LFOC markers to a list if they are not already there */ void diff --git a/src/lib/film.h b/src/lib/film.h index d42eb5626..5318d6a12 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -37,6 +37,7 @@ #include "types.h" #include "util.h" #include +#include #include #include #include @@ -75,13 +76,8 @@ class InfoFileHandle { public: InfoFileHandle (boost::mutex& mutex, boost::filesystem::path file, bool read); - ~InfoFileHandle (); - FILE* get () const { - return _handle; - } - - boost::filesystem::path file () const { + dcp::File& get () { return _file; } @@ -89,10 +85,10 @@ private: friend class Film; boost::mutex::scoped_lock _lock; - FILE* _handle; - boost::filesystem::path _file; + dcp::File _file; }; + /** @class Film * * @brief A representation of some audio, video, subtitle and closed-caption content, diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc index 5a1672204..6e4dea7b7 100644 --- a/src/lib/image_examiner.cc +++ b/src/lib/image_examiner.cc @@ -51,13 +51,13 @@ ImageExaminer::ImageExaminer (shared_ptr film, shared_ptrpath(0); if (valid_j2k_file (path)) { auto size = boost::filesystem::file_size (path); - auto f = fopen_boost (path, "rb"); + dcp::File f(path, "rb"); if (!f) { throw FileError ("Could not open file for reading", path); } std::vector buffer(size); - checked_fread (buffer.data(), size, f, path); - fclose (f); + f.checked_read(buffer.data(), size); + f.close(); try { _video_size = dcp::decompress_j2k(buffer.data(), size, 0)->size(); } catch (dcp::ReadError& e) { diff --git a/src/lib/internet.cc b/src/lib/internet.cc index c0c8232ee..a9c30611d 100644 --- a/src/lib/internet.cc +++ b/src/lib/internet.cc @@ -24,6 +24,7 @@ #include "exceptions.h" #include "scoped_temporary.h" #include "util.h" +#include #include #include #include @@ -98,9 +99,9 @@ get_from_url (string url, bool pasv, bool skip_pasv_ip, ScopedTemporary& temp) auto curl = curl_easy_init (); curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); - auto f = temp.open ("wb"); + auto& f = temp.open ("wb"); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, get_from_url_data); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, f); + curl_easy_setopt (curl, CURLOPT_WRITEDATA, f.get()); curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, 0); curl_easy_setopt (curl, CURLOPT_FTP_USE_EPRT, 0); if (skip_pasv_ip) { @@ -115,7 +116,7 @@ get_from_url (string url, bool pasv, bool skip_pasv_ip, ScopedTemporary& temp) auto const cr = curl_easy_perform (curl); - temp.close (); + f.close(); curl_easy_cleanup (curl); if (cr != CURLE_OK) { return String::compose (_("Download failed (%1 error %2)"), url, (int) cr); @@ -133,7 +134,7 @@ get_from_url (string url, bool pasv, bool skip_pasv_ip, function (_("Could not open downloaded ZIP file")); + return string(_("Could not open downloaded ZIP file")); } - auto zip_source = zip_source_filep_create (zip_file, 0, -1, 0); + auto zip_source = zip_source_filep_create (zip_file.take(), 0, -1, 0); if (!zip_source) { - return optional (_("Could not open downloaded ZIP file")); + return string(_("Could not open downloaded ZIP file")); } zip_error_t error; @@ -182,22 +183,22 @@ get_from_zip_url (string url, string file, bool pasv, bool skip_pasv_ip, functio struct zip_file* file_in_zip = zip_fopen (zip, file.c_str(), 0); if (!file_in_zip) { - return optional (_("Unexpected ZIP file contents")); + return string(_("Unexpected ZIP file contents")); } ScopedTemporary temp_cert; - auto f = temp_cert.open ("wb"); + auto& f = temp_cert.open ("wb"); char buffer[4096]; while (true) { int const N = zip_fread (file_in_zip, buffer, sizeof (buffer)); - checked_fwrite (buffer, N, f, temp_cert.file()); + f.checked_write(buffer, N); if (N < int (sizeof (buffer))) { break; } } zip_fclose (file_in_zip); zip_close (zip); - temp_cert.close (); + f.close (); - return load (temp_cert.file(), url); + return load (temp_cert.path(), url); } diff --git a/src/lib/kdm_with_metadata.cc b/src/lib/kdm_with_metadata.cc index 857fdca2c..123649d12 100644 --- a/src/lib/kdm_with_metadata.cc +++ b/src/lib/kdm_with_metadata.cc @@ -28,6 +28,7 @@ #include "screen.h" #include "util.h" #include "zipper.h" +#include #include "i18n.h" @@ -66,7 +67,7 @@ write_files ( /* Write KDMs to the specified directory */ for (auto i: kdms) { - auto out = fix_long_path(directory / careful_string_filter(name_format.get(i->name_values(), ".xml"))); + auto out = dcp::fix_long_path(directory / careful_string_filter(name_format.get(i->name_values(), ".xml"))); if (!boost::filesystem::exists (out) || confirm_overwrite (out)) { i->kdm_as_xml (out); ++written; diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index 7a2c9c670..94920b95b 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -208,10 +208,10 @@ void ReelWriter::write_frame_info (Frame frame, Eyes eyes, dcp::FrameInfo info) const { auto handle = film()->info_file_handle(_period, false); - dcpomatic_fseek (handle->get(), frame_info_position(frame, eyes), SEEK_SET); - checked_fwrite (&info.offset, sizeof(info.offset), handle->get(), handle->file()); - checked_fwrite (&info.size, sizeof (info.size), handle->get(), handle->file()); - checked_fwrite (info.hash.c_str(), info.hash.size(), handle->get(), handle->file()); + handle->get().seek(frame_info_position(frame, eyes), SEEK_SET); + handle->get().checked_write(&info.offset, sizeof(info.offset)); + handle->get().checked_write(&info.size, sizeof(info.size)); + handle->get().checked_write(info.hash.c_str(), info.hash.size()); } @@ -219,12 +219,12 @@ dcp::FrameInfo ReelWriter::read_frame_info (shared_ptr info, Frame frame, Eyes eyes) const { dcp::FrameInfo frame_info; - dcpomatic_fseek (info->get(), frame_info_position(frame, eyes), SEEK_SET); - checked_fread (&frame_info.offset, sizeof(frame_info.offset), info->get(), info->file()); - checked_fread (&frame_info.size, sizeof(frame_info.size), info->get(), info->file()); + info->get().seek(frame_info_position(frame, eyes), SEEK_SET); + info->get().checked_read(&frame_info.offset, sizeof(frame_info.offset)); + info->get().checked_read(&frame_info.size, sizeof(frame_info.size)); char hash_buffer[33]; - checked_fread (hash_buffer, 32, info->get(), info->file()); + info->get().checked_read(hash_buffer, 32); hash_buffer[32] = '\0'; frame_info.hash = hash_buffer; @@ -260,7 +260,7 @@ ReelWriter::check_existing_picture_asset (boost::filesystem::path asset) } /* Try to open the existing asset */ - auto asset_file = fopen_boost (asset, "rb"); + dcp::File asset_file(asset, "rb"); if (!asset_file) { LOG_GENERAL ("Could not open existing asset at %1 (errno=%2)", asset.string(), errno); return 0; @@ -274,13 +274,12 @@ ReelWriter::check_existing_picture_asset (boost::filesystem::path asset) info_file = film()->info_file_handle (_period, true); } catch (OpenFileError &) { LOG_GENERAL_NC ("Could not open film info file"); - fclose (asset_file); return 0; } /* Offset of the last dcp::FrameInfo in the info file */ - int const n = (boost::filesystem::file_size(info_file->file()) / _info_size) - 1; - LOG_GENERAL ("The last FI is %1; info file is %2, info size %3", n, boost::filesystem::file_size(info_file->file()), _info_size); + int const n = (boost::filesystem::file_size(info_file->get().path()) / _info_size) - 1; + LOG_GENERAL ("The last FI is %1; info file is %2, info size %3", n, boost::filesystem::file_size(info_file->get().path()), _info_size); Frame first_nonexistant_frame; if (film()->three_d()) { @@ -303,8 +302,6 @@ ReelWriter::check_existing_picture_asset (boost::filesystem::path asset) LOG_GENERAL ("Proceeding with first nonexistant frame %1", first_nonexistant_frame); - fclose (asset_file); - return first_nonexistant_frame; } @@ -921,7 +918,7 @@ ReelWriter::write (PlayerText subs, TextType type, optional track, bool -ReelWriter::existing_picture_frame_ok (FILE* asset_file, shared_ptr info_file, Frame frame) const +ReelWriter::existing_picture_frame_ok (dcp::File& asset_file, shared_ptr info_file, Frame frame) const { LOG_GENERAL ("Checking existing picture frame %1", frame); @@ -933,9 +930,9 @@ ReelWriter::existing_picture_frame_ok (FILE* asset_file, shared_ptr (data.size ())) { LOG_GENERAL ("Existing frame %1 is incomplete", frame); diff --git a/src/lib/reel_writer.h b/src/lib/reel_writer.h index 0308c64ec..bee76ded3 100644 --- a/src/lib/reel_writer.h +++ b/src/lib/reel_writer.h @@ -25,8 +25,9 @@ #include "player_text.h" #include "dcp_text_track.h" #include "weak_film.h" -#include #include +#include +#include namespace dcpomatic { class FontData; @@ -102,7 +103,7 @@ private: void write_frame_info (Frame frame, Eyes eyes, dcp::FrameInfo info) const; long frame_info_position (Frame frame, Eyes eyes) const; Frame check_existing_picture_asset (boost::filesystem::path asset); - bool existing_picture_frame_ok (FILE* asset_file, std::shared_ptr info_file, Frame frame) const; + bool existing_picture_frame_ok (dcp::File& asset_file, std::shared_ptr info_file, Frame frame) const; std::shared_ptr empty_text_asset (TextType type, boost::optional track, bool with_dummy) const; std::shared_ptr create_reel_picture (std::shared_ptr reel, std::list const & refs) const; diff --git a/src/lib/scoped_temporary.cc b/src/lib/scoped_temporary.cc index 223100ba5..0ead7b165 100644 --- a/src/lib/scoped_temporary.cc +++ b/src/lib/scoped_temporary.cc @@ -29,16 +29,18 @@ */ ScopedTemporary::ScopedTemporary () { - _file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path (); + _path = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); } /** Close and delete the temporary file */ ScopedTemporary::~ScopedTemporary () { - close (); + if (_file) { + _file->close(); + } boost::system::error_code ec; - boost::filesystem::remove (_file, ec); + boost::filesystem::remove (_path, ec); } @@ -46,31 +48,23 @@ ScopedTemporary::~ScopedTemporary () char const * ScopedTemporary::c_str () const { - return _file.string().c_str(); + return _path.string().c_str(); } /** Open the temporary file. * @return File's FILE pointer. */ -FILE* +dcp::File& ScopedTemporary::open (char const * params) { - close (); - _open = fopen_boost (_file, params); - if (!_open) { - throw FileError ("Could not open scoped temporary", _file); + if (_file) { + _file->close(); } - return _open; -} - - -/** Close the file */ -void -ScopedTemporary::close () -{ - if (_open) { - fclose (_open); - _open = nullptr; + _file = dcp::File(_path, params); + if (!*_file) { + throw FileError ("Could not open scoped temporary", _path); } + return *_file; } + diff --git a/src/lib/scoped_temporary.h b/src/lib/scoped_temporary.h index 75d9a272f..b78f60541 100644 --- a/src/lib/scoped_temporary.h +++ b/src/lib/scoped_temporary.h @@ -19,7 +19,9 @@ */ +#include #include +#include #include @@ -35,16 +37,15 @@ public: ScopedTemporary (ScopedTemporary const&) = delete; ScopedTemporary& operator= (ScopedTemporary const&) = delete; - /** @return temporary filename */ - boost::filesystem::path file () const { - return _file; + /** @return temporary pathname */ + boost::filesystem::path path () const { + return _path; } char const * c_str () const; - FILE* open (char const *); - void close (); + dcp::File& open (char const *); private: - boost::filesystem::path _file; - FILE* _open = nullptr; + boost::filesystem::path _path; + boost::optional _file; }; diff --git a/src/lib/scp_uploader.cc b/src/lib/scp_uploader.cc index 8bb41e3b1..c14c02215 100644 --- a/src/lib/scp_uploader.cc +++ b/src/lib/scp_uploader.cc @@ -25,6 +25,8 @@ #include "config.h" #include "cross.h" #include "compose.hpp" +#include +#include #include #include "i18n.h" @@ -104,8 +106,8 @@ SCPUploader::upload_file (boost::filesystem::path from, boost::filesystem::path /* Use generic_string so that we get forward-slashes in the path, even on Windows */ ssh_scp_push_file (_scp, to.generic_string().c_str(), to_do, S_IRUSR | S_IWUSR); - auto f = fopen_boost (from, "rb"); - if (f == nullptr) { + dcp::File f(from, "rb"); + if (!f) { throw NetworkError (String::compose(_("Could not open %1 to send"), from)); } @@ -114,15 +116,13 @@ SCPUploader::upload_file (boost::filesystem::path from, boost::filesystem::path while (to_do > 0) { int const t = min (to_do, buffer_size); - size_t const read = fread (buffer, 1, t, f); + size_t const read = f.read(buffer, 1, t); if (read != size_t (t)) { - fclose (f); throw ReadFileError (from); } int const r = ssh_scp_write (_scp, buffer, t); if (r != SSH_OK) { - fclose (f); throw NetworkError (String::compose(_("Could not write to remote file (%1)"), ssh_get_error(_session))); } to_do -= t; @@ -132,6 +132,4 @@ SCPUploader::upload_file (boost::filesystem::path from, boost::filesystem::path _set_progress ((double) transferred / total_size); } } - - fclose (f); } diff --git a/src/lib/string_text_file.cc b/src/lib/string_text_file.cc index 8c2c56518..b8ca27e16 100644 --- a/src/lib/string_text_file.cc +++ b/src/lib/string_text_file.cc @@ -18,29 +18,33 @@ */ -#include "string_text_file.h" + #include "cross.h" #include "exceptions.h" +#include "string_text_file.h" #include "string_text_file_content.h" -#include +#include +#include #include #include -#include +#include #include #include #include #include "i18n.h" -using std::vector; + using std::cout; -using std::string; using std::shared_ptr; +using std::string; +using std::vector; using boost::scoped_array; using boost::optional; using dcp::ArrayData; using namespace dcpomatic; + StringTextFile::StringTextFile (shared_ptr content) { string ext = content->path(0).extension().string(); @@ -49,17 +53,15 @@ StringTextFile::StringTextFile (shared_ptr content) std::unique_ptr reader; if (ext == ".stl") { - auto f = fopen_boost (content->path(0), "rb"); + dcp::File f(content->path(0), "rb"); if (!f) { - throw OpenFileError (content->path(0), errno, OpenFileError::READ); + throw OpenFileError (f.path(), errno, OpenFileError::READ); } try { - reader.reset(new sub::STLBinaryReader(f)); + reader.reset(new sub::STLBinaryReader(f.get())); } catch (...) { - fclose (f); throw; } - fclose (f); } else { /* Text-based file; sort out its character encoding before we try to parse it */ diff --git a/src/lib/util.cc b/src/lib/util.cc index 6e2a1ad64..d020ba13d 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -250,9 +250,11 @@ LIBDCP_DISABLE_WARNINGS LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS * info) { - auto f = fopen_boost (backtrace_file, "w"); - fprintf (f, "C-style exception %d\n", info->ExceptionRecord->ExceptionCode); - fclose(f); + dcp::File f(backtrace_file, "w"); + if (f) { + fprintf(f.get(), "C-style exception %d\n", info->ExceptionRecord->ExceptionCode); + f.close(); + } if (info->ExceptionRecord->ExceptionCode != EXCEPTION_STACK_OVERFLOW) { CONTEXT* context = info->ContextRecord; @@ -490,16 +492,15 @@ digest_head_tail (vector files, boost::uintmax_t size) char* p = buffer.get (); int i = 0; while (i < int64_t (files.size()) && to_do > 0) { - auto f = fopen_boost (files[i], "rb"); + dcp::File f(files[i], "rb"); if (!f) { throw OpenFileError (files[i].string(), errno, OpenFileError::READ); } boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i])); - checked_fread (p, this_time, f, files[i]); + f.checked_read(p, this_time); p += this_time; to_do -= this_time; - fclose (f); ++i; } @@ -510,17 +511,16 @@ digest_head_tail (vector files, boost::uintmax_t size) p = buffer.get (); i = files.size() - 1; while (i >= 0 && to_do > 0) { - auto f = fopen_boost (files[i], "rb"); + dcp::File f(files[i], "rb"); if (!f) { throw OpenFileError (files[i].string(), errno, OpenFileError::READ); } boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i])); - dcpomatic_fseek (f, -this_time, SEEK_END); - checked_fread (p, this_time, f, files[i]); + f.seek(-this_time, SEEK_END); + f.checked_read(p, this_time); p += this_time; to_do -= this_time; - fclose (f); --i; } @@ -864,35 +864,6 @@ increment_eyes (Eyes e) return Eyes::LEFT; } -void -checked_fwrite (void const * ptr, size_t size, FILE* stream, boost::filesystem::path path) -{ - size_t N = fwrite (ptr, 1, size, stream); - if (N != size) { - if (ferror(stream)) { - fclose (stream); - throw FileError (String::compose("fwrite error %1", errno), path); - } else { - fclose (stream); - throw FileError ("Unexpected short write", path); - } - } -} - -void -checked_fread (void* ptr, size_t size, FILE* stream, boost::filesystem::path path) -{ - size_t N = fread (ptr, 1, size, stream); - if (N != size) { - if (ferror(stream)) { - fclose (stream); - throw FileError (String::compose("fread error %1", errno), path); - } else { - fclose (stream); - throw FileError ("Unexpected short read", path); - } - } -} size_t utf8_strlen (string s) @@ -1034,52 +1005,38 @@ show_jobs_on_console (bool progress) void copy_in_bits (boost::filesystem::path from, boost::filesystem::path to, std::function progress) { - auto f = fopen_boost (from, "rb"); + dcp::File f(from, "rb"); if (!f) { throw OpenFileError (from, errno, OpenFileError::READ); } - auto t = fopen_boost (to, "wb"); + dcp::File t(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; - auto buffer = static_cast (malloc(chunk)); - if (!buffer) { - throw std::bad_alloc (); - } + std::vector buffer(chunk); 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); + size_t N = f.read(buffer.data(), 1, chunk); if (N < this_time) { - fclose (f); - fclose (t); - free (buffer); throw ReadFileError (from, errno); } - N = fwrite (buffer, 1, this_time, t); + N = t.write(buffer.data(), 1, this_time); 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); } diff --git a/src/lib/util.h b/src/lib/util.h index 706056cda..233b3cb2a 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -113,8 +113,6 @@ extern std::string careful_string_filter (std::string); extern std::pair audio_channel_types (std::list mapped, int channels); extern std::shared_ptr remap (std::shared_ptr input, int output_channels, AudioMapping map); extern Eyes increment_eyes (Eyes e); -extern void checked_fread (void* ptr, size_t size, FILE* stream, boost::filesystem::path path); -extern void checked_fwrite (void const * ptr, size_t size, FILE* stream, boost::filesystem::path path); extern size_t utf8_strlen (std::string s); extern std::string day_of_week_to_string (boost::gregorian::greg_weekday d); extern void emit_subtitle_image (dcpomatic::ContentTimePeriod period, dcp::SubtitleImage sub, dcp::Size size, std::shared_ptr decoder); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 309cfb78c..3aca2ab89 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -710,7 +710,7 @@ void Writer::write_cover_sheet (boost::filesystem::path output_dcp) { auto const cover = film()->file("COVER_SHEET.txt"); - auto f = fopen_boost (cover, "w"); + dcp::File f(cover, "w"); if (!f) { throw OpenFileError (cover, errno, OpenFileError::WRITE); } @@ -778,8 +778,7 @@ Writer::write_cover_sheet (boost::filesystem::path output_dcp) boost::algorithm::replace_all (text, "$LENGTH", length); - checked_fwrite (text.c_str(), text.length(), f, cover); - fclose (f); + f.checked_write(text.c_str(), text.length()); } diff --git a/src/tools/dcpomatic_cli.cc b/src/tools/dcpomatic_cli.cc index 71353d463..dae904eb4 100644 --- a/src/tools/dcpomatic_cli.cc +++ b/src/tools/dcpomatic_cli.cc @@ -301,19 +301,18 @@ main (int argc, char* argv[]) } if (servers) { - auto f = fopen_boost (*servers, "r"); + dcp::File f(*servers, "r"); if (!f) { cerr << "Could not open servers list file " << *servers << "\n"; exit (EXIT_FAILURE); } vector servers; - while (!feof (f)) { + while (!f.eof()) { char buffer[128]; - if (fscanf (f, "%s.127", buffer) == 1) { + if (fscanf(f.get(), "%s.127", buffer) == 1) { servers.push_back (buffer); } } - fclose (f); Config::instance()->set_servers (servers); } diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 08e2721da..ae045d636 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -18,12 +18,14 @@ */ -#include "config_dialog.h" -#include "static_text.h" + +#include "audio_mapping_view.h" #include "check_box.h" -#include "nag_dialog.h" +#include "config_dialog.h" #include "dcpomatic_button.h" -#include "audio_mapping_view.h" +#include "nag_dialog.h" +#include "static_text.h" +#include #include @@ -462,14 +464,13 @@ CertificateChainEditor::export_certificate () if (path.extension() != ".pem") { path += ".pem"; } - auto f = fopen_boost (path, "w"); + dcp::File f(path, "w"); if (!f) { throw OpenFileError (path, errno, OpenFileError::WRITE); } string const s = j->certificate (true); - checked_fwrite (s.c_str(), s.length(), f, path); - fclose (f); + f.checked_write(s.c_str(), s.length()); } d->Destroy (); } @@ -487,14 +488,13 @@ CertificateChainEditor::export_chain () if (path.extension() != ".pem") { path += ".pem"; } - auto f = fopen_boost (path, "w"); + dcp::File f(path, "w"); if (!f) { throw OpenFileError (path, errno, OpenFileError::WRITE); } auto const s = _get()->chain(); - checked_fwrite (s.c_str(), s.length(), f, path); - fclose (f); + f.checked_write (s.c_str(), s.length()); } d->Destroy (); @@ -616,14 +616,13 @@ CertificateChainEditor::export_private_key () if (path.extension() != ".pem") { path += ".pem"; } - auto f = fopen_boost (path, "w"); + dcp::File f(path, "w"); if (!f) { throw OpenFileError (path, errno, OpenFileError::WRITE); } auto const s = _get()->key().get (); - checked_fwrite (s.c_str(), s.length(), f, path); - fclose (f); + f.checked_write(s.c_str(), s.length()); } d->Destroy (); } @@ -733,17 +732,16 @@ KeysPage::export_decryption_chain_and_key () if (d->ShowModal () == wxID_OK) { boost::filesystem::path path (wx_to_std(d->GetPath())); - auto f = fopen_boost (path, "w"); + dcp::File f(path, "w"); if (!f) { throw OpenFileError (path, errno, OpenFileError::WRITE); } auto const chain = Config::instance()->decryption_chain()->chain(); - checked_fwrite (chain.c_str(), chain.length(), f, path); - optional const key = Config::instance()->decryption_chain()->key(); + f.checked_write (chain.c_str(), chain.length()); + auto const key = Config::instance()->decryption_chain()->key(); DCPOMATIC_ASSERT (key); - checked_fwrite (key->c_str(), key->length(), f, path); - fclose (f); + f.checked_write(key->c_str(), key->length()); } d->Destroy (); @@ -768,15 +766,15 @@ KeysPage::import_decryption_chain_and_key () if (d->ShowModal () == wxID_OK) { auto new_chain = make_shared(); - FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "r"); + dcp::File f(wx_to_std(d->GetPath()), "r"); if (!f) { - throw OpenFileError (wx_to_std (d->GetPath ()), errno, OpenFileError::WRITE); + throw OpenFileError (f.path(), errno, OpenFileError::WRITE); } string current; - while (!feof (f)) { + while (!f.eof()) { char buffer[128]; - if (fgets (buffer, 128, f) == 0) { + if (f.gets(buffer, 128) == 0) { break; } current += buffer; @@ -788,7 +786,6 @@ KeysPage::import_decryption_chain_and_key () current = ""; } } - fclose (f); if (new_chain->chain_valid() && new_chain->private_key_valid()) { Config::instance()->set_decryption_chain (new_chain); @@ -833,14 +830,13 @@ KeysPage::export_decryption_certificate () if (path.extension() != ".pem") { path += ".pem"; } - auto f = fopen_boost (path, "w"); + dcp::File f(path, "w"); if (!f) { throw OpenFileError (path, errno, OpenFileError::WRITE); } auto const s = Config::instance()->decryption_chain()->leaf().certificate (true); - checked_fwrite (s.c_str(), s.length(), f, path); - fclose (f); + f.checked_write(s.c_str(), s.length()); } d->Destroy (); diff --git a/test/audio_merger_test.cc b/test/audio_merger_test.cc index 3a677bf82..336dfcdf3 100644 --- a/test/audio_merger_test.cc +++ b/test/audio_merger_test.cc @@ -30,6 +30,7 @@ #include "lib/audio_buffers.h" #include "lib/dcpomatic_time.h" #include "test.h" +#include #include #include #include @@ -154,11 +155,11 @@ BOOST_AUTO_TEST_CASE (audio_merger_test3) /* Reply a sequence of calls to AudioMerger that resulted in a crash */ BOOST_AUTO_TEST_CASE (audio_merger_test4) { - auto f = fopen_boost("test/data/audio_merger_bug1.log", "r"); + dcp::File f("test/data/audio_merger_bug1.log", "r"); BOOST_REQUIRE (f); list tokens; char buf[64]; - while (fscanf(f, "%63s", buf) == 1) { + while (fscanf(f.get(), "%63s", buf) == 1) { tokens.push_back (buf); } diff --git a/test/cpl_hash_test.cc b/test/cpl_hash_test.cc index f34c29583..56dc1974c 100644 --- a/test/cpl_hash_test.cc +++ b/test/cpl_hash_test.cc @@ -53,18 +53,18 @@ BOOST_AUTO_TEST_CASE (hash_added_to_imported_dcp_test) /* Remove tags from the CPL */ for (auto i: directory_iterator(String::compose("build/test/%1/%2", ov_name, ov->dcp_name()))) { if (boost::algorithm::starts_with(i.path().filename().string(), "cpl_")) { - auto in = fopen_boost(i.path(), "r"); + dcp::File in(i.path(), "r"); BOOST_REQUIRE (in); - auto out = fopen_boost(i.path().string() + ".tmp", "w"); + dcp::File out(i.path().string() + ".tmp", "w"); BOOST_REQUIRE (out); char buffer[256]; - while (fgets(buffer, sizeof(buffer), in)) { + while (in.gets(buffer, sizeof(buffer))) { if (string(buffer).find("Hash") == string::npos) { - fputs (buffer, out); + out.puts(buffer); } } - fclose (in); - fclose (out); + in.close(); + out.close(); rename (i.path().string() + ".tmp", i.path()); } } @@ -82,15 +82,14 @@ BOOST_AUTO_TEST_CASE (hash_added_to_imported_dcp_test) int hashes = 0; for (auto i: directory_iterator(String::compose("build/test/%1/%2", vf_name, vf->dcp_name()))) { if (boost::algorithm::starts_with(i.path().filename().string(), "cpl_")) { - auto in = fopen_boost(i.path(), "r"); + dcp::File in(i.path(), "r"); BOOST_REQUIRE (in); char buffer[256]; - while (fgets (buffer, sizeof(buffer), in)) { + while (in.gets(buffer, sizeof(buffer))) { if (string(buffer).find("Hash") != string::npos) { ++hashes; } } - fclose (in); } } BOOST_CHECK_EQUAL (hashes, 2); diff --git a/test/hints_test.cc b/test/hints_test.cc index 51374b274..bc858192d 100644 --- a/test/hints_test.cc +++ b/test/hints_test.cc @@ -200,16 +200,16 @@ BOOST_AUTO_TEST_CASE (hint_closed_caption_xml_too_big) auto film = new_test_film2 (name); - auto ccap = fopen_boost (String::compose("build/test/%1.srt", name), "w"); + dcp::File ccap(String::compose("build/test/%1.srt", name), "w"); BOOST_REQUIRE (ccap); for (int i = 0; i < 2048; ++i) { - fprintf(ccap, "%d\n", i + 1); + fprintf(ccap.get(), "%d\n", i + 1); int second = i * 2; int minute = second % 60; - fprintf(ccap, "00:%02d:%02d,000 --> 00:%02d:%02d,000\n", minute, second, minute, second + 1); - fprintf(ccap, "Here are some closed captions.\n\n"); + fprintf(ccap.get(), "00:%02d:%02d,000 --> 00:%02d:%02d,000\n", minute, second, minute, second + 1); + fprintf(ccap.get(), "Here are some closed captions.\n\n"); } - fclose (ccap); + ccap.close(); auto content = content_factory("build/test/" + name + ".srt").front(); content->text.front()->set_type (TextType::CLOSED_CAPTION); diff --git a/test/test.cc b/test/test.cc index 21f27c36c..9260d568f 100644 --- a/test/test.cc +++ b/test/test.cc @@ -462,9 +462,9 @@ check_file (boost::filesystem::path ref, boost::filesystem::path check) { auto N = boost::filesystem::file_size (ref); BOOST_CHECK_EQUAL (N, boost::filesystem::file_size (check)); - auto ref_file = fopen_boost (ref, "rb"); + dcp::File ref_file(ref, "rb"); BOOST_CHECK (ref_file); - auto check_file = fopen_boost (check, "rb"); + dcp::File check_file(check, "rb"); BOOST_CHECK (check_file); int const buffer_size = 65536; @@ -475,30 +475,27 @@ check_file (boost::filesystem::path ref, boost::filesystem::path check) while (N) { uintmax_t this_time = min (uintmax_t (buffer_size), N); - size_t r = fread (ref_buffer.data(), 1, this_time, ref_file); + size_t r = ref_file.read (ref_buffer.data(), 1, this_time); BOOST_CHECK_EQUAL (r, this_time); - r = fread (check_buffer.data(), 1, this_time, check_file); + r = check_file.read(check_buffer.data(), 1, this_time); BOOST_CHECK_EQUAL (r, this_time); - BOOST_CHECK_MESSAGE (memcmp(ref_buffer.data(), check_buffer.data(), this_time) == 0, error); - if (memcmp(ref_buffer.data(), check_buffer.data(), this_time)) { + BOOST_CHECK_MESSAGE (memcmp (ref_buffer.data(), check_buffer.data(), this_time) == 0, error); + if (memcmp (ref_buffer.data(), check_buffer.data(), this_time)) { break; } N -= this_time; } - - fclose (ref_file); - fclose (check_file); } void check_text_file (boost::filesystem::path ref, boost::filesystem::path check) { - auto ref_file = fopen_boost (ref, "r"); + dcp::File ref_file(ref, "r"); BOOST_CHECK (ref_file); - auto check_file = fopen_boost (check, "r"); + dcp::File check_file(check, "r"); BOOST_CHECK (check_file); int const buffer_size = std::max( @@ -509,16 +506,13 @@ check_text_file (boost::filesystem::path ref, boost::filesystem::path check) DCPOMATIC_ASSERT (buffer_size < 1024 * 1024); std::vector ref_buffer(buffer_size); - auto ref_read = fread(ref_buffer.data(), 1, buffer_size, ref_file); + auto ref_read = ref_file.read(ref_buffer.data(), 1, buffer_size); std::vector check_buffer(buffer_size); - auto check_read = fread(check_buffer.data(), 1, buffer_size, check_file); + auto check_read = check_file.read(check_buffer.data(), 1, buffer_size); BOOST_CHECK_EQUAL (ref_read, check_read); string const error = "File " + check.string() + " differs from reference " + ref.string(); BOOST_CHECK_MESSAGE(memcmp(ref_buffer.data(), check_buffer.data(), ref_read) == 0, error); - - fclose (ref_file); - fclose (check_file); } @@ -827,13 +821,12 @@ subtitle_file (shared_ptr film) void make_random_file (boost::filesystem::path path, size_t size) { - auto t = fopen_boost(path, "wb"); + dcp::File t(path, "wb"); BOOST_REQUIRE (t); for (size_t i = 0; i < size; ++i) { uint8_t r = rand() & 0xff; - fwrite (&r, 1, 1, t); + t.write(&r, 1, 1); } - fclose (t); } diff --git a/test/windows_test.cc b/test/windows_test.cc deleted file mode 100644 index bc9520bc3..000000000 --- a/test/windows_test.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2021 Carl Hetherington - - This file is part of DCP-o-matic. - - DCP-o-matic is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DCP-o-matic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DCP-o-matic. If not, see . - -*/ - - -#include "lib/cross.h" -#include "lib/util.h" -#include -#include -#include - - -BOOST_AUTO_TEST_CASE (fix_long_path_test) -{ -#ifdef DCPOMATIC_WINDOWS - BOOST_CHECK_EQUAL (fix_long_path("c:\\foo"), "\\\\?\\c:\\foo"); - BOOST_CHECK_EQUAL (fix_long_path("c:\\foo\\bar"), "\\\\?\\c:\\foo\\bar"); - boost::filesystem::path fixed_bar = "\\\\?\\"; - fixed_bar += boost::filesystem::current_path(); - fixed_bar /= "bar"; - BOOST_CHECK_EQUAL (fix_long_path("bar"), fixed_bar); - - BOOST_CHECK_EQUAL (fix_long_path("\\\\?\\c:\\foo"), "\\\\?\\c:\\foo"); -#else - BOOST_CHECK_EQUAL (fix_long_path("foo/bar/baz"), "foo/bar/baz"); -#endif -} - - -#ifdef DCPOMATIC_WINDOWS -BOOST_AUTO_TEST_CASE (windows_long_filename_test) -{ - using namespace boost::filesystem; - - path too_long = current_path() / "build\\test\\a\\really\\very\\long\\filesystem\\path\\indeed\\that\\will\\be\\so\\long\\that\\windows\\cannot\\normally\\cope\\with\\it\\unless\\we\\add\\this\\crazy\\prefix\\and\\then\\magically\\it\\can\\do\\it\\fine\\I\\dont\\really\\know\\why\\its\\like\\that\\but\\hey\\it\\is\\so\\here\\we\\are\\what\\can\\we\\do\\other\\than\\bodge\\it"; - - BOOST_CHECK (too_long.string().length() > 260); - boost::system::error_code ec; - create_directories (too_long, ec); - BOOST_CHECK (ec); - - path fixed_path = fix_long_path(too_long); - create_directories (fixed_path, ec); - BOOST_CHECK (!ec); - - auto file = fopen_boost(too_long / "hello", "w"); - BOOST_REQUIRE (file); - fprintf (file, "Hello_world"); - fclose (file); - - file = fopen_boost(too_long / "hello", "r"); - BOOST_REQUIRE (file); - char buffer[64]; - fscanf (file, "%63s", buffer); - BOOST_CHECK_EQUAL (strcmp(buffer, "Hello_world"), 0); -} -#endif - diff --git a/test/wscript b/test/wscript index 1555f2f59..3aa803a0c 100644 --- a/test/wscript +++ b/test/wscript @@ -151,7 +151,6 @@ def build(bld): video_level_test.cc video_mxf_content_test.cc vf_kdm_test.cc - windows_test.cc writer_test.cc zipper_test.cc """ -- 2.30.2