Skip to content

Commit

Permalink
added Seek() function to FileReader
Browse files Browse the repository at this point in the history
Adds a new function to the FileReader implementation of the
Reader interface for seeking within a file. It additionally
adds a new Status code to represent that a request to use
the Seek() function has failed, which will happen when the
file is stdin or something similar.

Change-Id: Iae299a3b36a8440da941b182c8865429ee3515d4
  • Loading branch information
ElijahCirioli committed Mar 1, 2023
1 parent e14008c commit 9efaf8b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
# Name or Organization <email address>

Google Inc.
Elijah Cirioli <[email protected]>
13 changes: 13 additions & 0 deletions webm_parser/include/webm/file_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ class FileReader : public Reader {
Status Skip(std::uint64_t num_to_skip,
std::uint64_t* num_actually_skipped) override;

/**
Moves the reader to a new absolute byte position in the file.
It is required to call DidSeek() on the parser after successfully seeking.
Seeking will only work on actual files, not stdin or pipes.
\param seek_position The new absolute byte position in the file.
\return `Status::kOkCompleted` if reader position is now `seek_position`.
`Status::kSeekFailed` if the reader was unable to seek to `seek_position`
such as when the file is stdin.
*/
Status Seek(std::uint64_t seek_position);

std::uint64_t Position() const override;

private:
Expand Down
5 changes: 5 additions & 0 deletions webm_parser/include/webm/status.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ struct Status {
*/
kEndOfFile = -3,

/**
The reader was unable to seek to the requested location.
*/
kSeekFailed = -4,

// Parsing errors. Range: -1025 to -2048.
/**
An element's ID is malformed.
Expand Down
24 changes: 22 additions & 2 deletions webm_parser/src/file_reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@

#include "webm/status.h"

#ifdef _MSC_VER
#define FSEEK_(stream, offset, whence) _fseeki64(stream, offset, whence)
#elif defined(_WIN32)
#define FSEEK_(stream, offset, whence) \
fseeko64(stream, static_cast<off_t>(offset), whence)
#elif _POSIX_C_SOURCE >= 200112L
#define FSEEK_(stream, offset, whence) \
fseeko(stream, static_cast<off_t>(offset), whence)
#else
#define FSEEK_(stream, offset, whence) \
std::fseek(stream, static_cast<long>(offset), whence)
#endif

namespace webm {

FileReader::FileReader(FILE* file) : file_(file) { assert(file); }
Expand Down Expand Up @@ -77,8 +90,7 @@ Status FileReader::Skip(std::uint64_t num_to_skip,
if (num_to_skip < static_cast<unsigned long>(seek_offset)) { // NOLINT
seek_offset = static_cast<long>(num_to_skip); // NOLINT
}
// TODO(mjbshaw): Use fseeko64/_fseeki64 if available.
if (!std::fseek(file_.get(), seek_offset, SEEK_CUR)) {
if (!FSEEK_(file_.get(), seek_offset, SEEK_CUR)) {
*num_actually_skipped = static_cast<std::uint64_t>(seek_offset);
position_ += static_cast<std::uint64_t>(seek_offset);
if (static_cast<unsigned long>(seek_offset) == num_to_skip) { // NOLINT
Expand Down Expand Up @@ -117,6 +129,14 @@ Status FileReader::Skip(std::uint64_t num_to_skip,
}
}

Status FileReader::Seek(std::uint64_t seek_position) {
if (FSEEK_(file_.get(), seek_position, SEEK_SET)) {
return Status(Status::kSeekFailed);
}
position_ = seek_position;
return Status(Status::kOkCompleted);
}

std::uint64_t FileReader::Position() const { return position_; }

} // namespace webm

0 comments on commit 9efaf8b

Please sign in to comment.