summaryrefslogtreecommitdiff
path: root/src/lib/file_group.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-10-07 01:02:47 +0200
committerCarl Hetherington <cth@carlh.net>2020-10-13 18:51:11 +0200
commite5277d4042b896c4b50c694fba0f1afb47337f45 (patch)
tree774c47252813040503a256105466d249114c44b0 /src/lib/file_group.cc
parenta6f1c4deaf0ddbf0197b286d0d5f1a107a487deb (diff)
Fix errors when over-reading a "large" amount from FileGroups on
Windows. I haven't been able to find any conclusive explanation for why this stuff happens; https://stackoverflow.com/questions/7241168/safe-maximum-number-of-records-read-by-fread is one possible lead.
Diffstat (limited to 'src/lib/file_group.cc')
-rw-r--r--src/lib/file_group.cc13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/lib/file_group.cc b/src/lib/file_group.cc
index 3e8a7b79c..9863a21cb 100644
--- a/src/lib/file_group.cc
+++ b/src/lib/file_group.cc
@@ -37,6 +37,7 @@ using std::cout;
FileGroup::FileGroup ()
: _current_path (0)
, _current_file (0)
+ , _current_size (0)
{
}
@@ -45,6 +46,7 @@ FileGroup::FileGroup ()
FileGroup::FileGroup (boost::filesystem::path p)
: _current_path (0)
, _current_file (0)
+ , _current_size (0)
{
_paths.push_back (p);
ensure_open_path (0);
@@ -95,6 +97,7 @@ FileGroup::ensure_open_path (size_t p) const
if (_current_file == 0) {
throw OpenFileError (_paths[_current_path], errno, OpenFileError::READ);
}
+ _current_size = boost::filesystem::file_size (_paths[_current_path]);
}
int64_t
@@ -155,7 +158,15 @@ FileGroup::read (uint8_t* buffer, int amount) const
{
int read = 0;
while (true) {
- int const this_time = fread (buffer + read, 1, amount - read, _current_file);
+ int64_t to_read = amount - read;
+#ifdef DCPOMATIC_WINDOWS
+ /* If we over-read from the file by too much on Windows we get a errno=22 rather than an feof condition,
+ * for unknown reasons. So if we're going to over-read, we need to do it by a little bit, so that feof
+ * still gets triggered but there is no errno=22.
+ */
+ to_read = std::min(to_read, static_cast<int64_t>(_current_size - _ftelli64(_current_file) + 1));
+#endif
+ int const this_time = fread (buffer + read, 1, to_read, _current_file);
read += this_time;
if (read == amount) {
/* Done */