Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/StdIOCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ uint32 StdIOCallback::read(void*Buffer,size_t Size)
assert(File!=nullptr);

size_t result = fread(Buffer, 1, Size, File);
if (feof(File) || ferror(File))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this really make sense? If you're, say, at position 500 in a file of size 1000 & request to read 2KB, the file descriptor will have its EOF flag set, and you simply don't return the last 500 bytes that could & were actually read to the calling function, thereby losing data. You cannot expect a function to only request exactly as much as the file size indicates, and punishing it for it is not nice.

Or am I missing something here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right we should not punish for not knowing the size, but:

  • this is how the read() method has been defined from the beginning (or since we moved to git)
  • in most cases we do know the size we are reading, EBML length and ID are read byte by byte, most elements have a known size
  • in Matroska only a few very large elements are allowed to have an unknown size (here we're talking libebml so maybe we shouldn't be this strict)
  • the read() method doesn't have a way to report EOF or other kinds of errors, or we need to throw errors, but that's not documented nor handled by callers

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get all that. For libEBML/libMatroska this sounds OK. I'm just worried that if any other program is using StdIOCallback this would be a grave behavior change for them. I actually don't know if there are any; MKVToolNix has its own I/O class derived from IOCallback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In VLC we have our own too, and I added the behaviour to match the documentation recently.

return 0;
mCurrentPosition += result;
return result;
}
Expand Down Expand Up @@ -145,6 +147,8 @@ size_t StdIOCallback::write(const void*Buffer,size_t Size)
{
assert(File!=nullptr);
uint32 Result = fwrite(Buffer,1,Size,File);
if (feof(File) || ferror(File))
return 0;
mCurrentPosition += Result;
return Result;
}
Expand Down
Loading