summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2022-04-16 22:20:54 +0200
committerCarl Hetherington <cth@carlh.net>2022-05-05 23:38:41 +0200
commit8a8c977c12fc65f1f50ea05099387e0fc8840e7d (patch)
tree2d2c8663652939d643779d1ab1c18a12813fcbd2 /src/lib
parentefe153ab23b54cdbf28c653f2ccb0f25ca6bd015 (diff)
Use dcp::File in DCP-o-matic (#2231).
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/config.cc15
-rw-r--r--src/lib/cross.h3
-rw-r--r--src/lib/cross_linux.cc25
-rw-r--r--src/lib/cross_osx.cc25
-rw-r--r--src/lib/cross_windows.cc64
-rw-r--r--src/lib/curl_uploader.cc15
-rw-r--r--src/lib/curl_uploader.h1
-rw-r--r--src/lib/ext.cc12
-rw-r--r--src/lib/file_group.cc33
-rw-r--r--src/lib/file_group.h5
-rw-r--r--src/lib/file_log.cc18
-rw-r--r--src/lib/film.cc31
-rw-r--r--src/lib/film.h12
-rw-r--r--src/lib/image_examiner.cc6
-rw-r--r--src/lib/internet.cc27
-rw-r--r--src/lib/kdm_with_metadata.cc3
-rw-r--r--src/lib/reel_writer.cc31
-rw-r--r--src/lib/reel_writer.h5
-rw-r--r--src/lib/scoped_temporary.cc34
-rw-r--r--src/lib/scoped_temporary.h15
-rw-r--r--src/lib/scp_uploader.cc12
-rw-r--r--src/lib/string_text_file.cc22
-rw-r--r--src/lib/util.cc73
-rw-r--r--src/lib/util.h2
-rw-r--r--src/lib/writer.cc5
25 files changed, 142 insertions, 352 deletions
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<bool>(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<std::string> 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 <iostream>
#include "i18n.h"
@@ -62,9 +63,6 @@ CurlUploader::CurlUploader (function<void (string)> set_status, function<void (f
CurlUploader::~CurlUploader ()
{
- if (_file) {
- fclose (_file);
- }
curl_easy_cleanup (_curl);
}
@@ -85,10 +83,11 @@ CurlUploader::upload_file (boost::filesystem::path from, boost::filesystem::path
String::compose ("ftp://%1/%2/%3", Config::instance()->tms_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 <dcp/file.h>
#include <curl/curl.h>
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<CopiedFile>& 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<boost::filesystem::path> const & p)
}
-/** Destroy a FileGroup, closing any open file */
-FileGroup::~FileGroup ()
-{
- if (_current_file) {
- fclose (_current_file);
- }
-}
-
-
void
FileGroup::set_paths (vector<boost::filesystem::path> 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 <dcp/file.h>
#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
#include <vector>
@@ -41,7 +43,6 @@ public:
FileGroup ();
explicit FileGroup (boost::filesystem::path);
explicit FileGroup (std::vector<boost::filesystem::path> const &);
- ~FileGroup ();
FileGroup (FileGroup const&) = delete;
FileGroup& operator= (FileGroup const&) = delete;
@@ -58,7 +59,7 @@ private:
std::vector<boost::filesystem::path> _paths;
/** Index of path that we are currently reading from */
mutable size_t _current_path = 0;
- mutable FILE* _current_file = nullptr;
+ mutable boost::optional<dcp::File> _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 <dcp/file.h>
#include <cstdio>
#include <iostream>
#include <cerrno>
@@ -51,14 +52,13 @@ FileLog::FileLog (boost::filesystem::path file, int types)
void
FileLog::do_log (shared_ptr<const LogEntry> 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<char> 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<InfoFileHandle>(_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 <dcp/encrypted_kdm.h>
+#include <dcp/file.h>
#include <dcp/key.h>
#include <dcp/language_tag.h>
#include <dcp/rating.h>
@@ -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<const Film> film, shared_ptr<const Imag
auto path = content->path(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<uint8_t> 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 <dcp/file.h>
#include <curl/curl.h>
#include <zip.h>
#include <boost/optional.hpp>
@@ -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<optional<string
if (e) {
return e;
}
- return load (temp.file(), url);
+ return load (temp.path(), url);
}
@@ -159,14 +160,14 @@ get_from_zip_url (string url, string file, bool pasv, bool skip_pasv_ip, functio
Centos 6, Centos 7, Debian 7 and Debian 8.
*/
- auto zip_file = fopen_boost (temp_zip.file (), "rb");
+ auto& zip_file = temp_zip.open("rb");
if (!zip_file) {
- return optional<string> (_("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<string> (_("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<string> (_("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 <dcp/file.h>
#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<InfoFileHandle> 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<DCPTextTrack> track,
bool
-ReelWriter::existing_picture_frame_ok (FILE* asset_file, shared_ptr<InfoFileHandle> info_file, Frame frame) const
+ReelWriter::existing_picture_frame_ok (dcp::File& asset_file, shared_ptr<InfoFileHandle> 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<InfoFileHand
bool ok = true;
/* Read the data from the asset and hash it */
- dcpomatic_fseek (asset_file, info.offset, SEEK_SET);
+ asset_file.seek(info.offset, SEEK_SET);
ArrayData data (info.size);
- size_t const read = fread (data.data(), 1, data.size(), asset_file);
+ size_t const read = asset_file.read(data.data(), 1, data.size());
LOG_GENERAL ("Read %1 bytes of asset data; wanted %2", read, info.size);
if (read != static_cast<size_t> (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 <dcp/picture_asset_writer.h>
#include <dcp/atmos_asset_writer.h>
+#include <dcp/file.h>
+#include <dcp/picture_asset_writer.h>
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<InfoFileHandle> info_file, Frame frame) const;
+ bool existing_picture_frame_ok (dcp::File& asset_file, std::shared_ptr<InfoFileHandle> info_file, Frame frame) const;
std::shared_ptr<dcp::SubtitleAsset> empty_text_asset (TextType type, boost::optional<DCPTextTrack> track, bool with_dummy) const;
std::shared_ptr<dcp::ReelPictureAsset> create_reel_picture (std::shared_ptr<dcp::Reel> reel, std::list<ReferencedReelAsset> 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 <dcp/file.h>
#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
#include <cstdio>
@@ -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<dcp::File> _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 <dcp/file.h>
+#include <dcp/warnings.h>
#include <sys/stat.h>
#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 <sub/subrip_reader.h>
+#include <dcp/file.h>
+#include <sub/collect.h>
#include <sub/ssa_reader.h>
#include <sub/stl_binary_reader.h>
-#include <sub/collect.h>
+#include <sub/subrip_reader.h>
#include <unicode/ucsdet.h>
#include <unicode/ucnv.h>
#include <iostream>
#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<const StringTextFileContent> content)
{
string ext = content->path(0).extension().string();
@@ -49,17 +53,15 @@ StringTextFile::StringTextFile (shared_ptr<const StringTextFileContent> content)
std::unique_ptr<sub::Reader> 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<boost::filesystem::path> 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<boost::filesystem::path> 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<void (float)> 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<uint8_t*> (malloc(chunk));
- if (!buffer) {
- throw std::bad_alloc ();
- }
+ std::vector<uint8_t> 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<int, int> audio_channel_types (std::list<int> mapped, int channels);
extern std::shared_ptr<AudioBuffers> remap (std::shared_ptr<const AudioBuffers> 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<TextDecoder> 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());
}