diff options
author | Elijah Cirioli <eli.cirioli@gmail.com> | 2023-02-16 00:07:43 -0800 |
---|---|---|
committer | Elijah Cirioli <eli.cirioli@gmail.com> | 2023-03-01 04:25:51 +0000 |
commit | 9efaf8bf42376151fff8a233222c7ae861ba2b78 (patch) | |
tree | 065eed26416a50d2d82e3edac804b2ca41cd3bd3 | |
parent | e14008c67f0b738cff49d731671abf9e7a2b942b (diff) | |
download | libwebm-9efaf8bf42376151fff8a233222c7ae861ba2b78.tar.gz |
added Seek() function to FileReader
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
-rw-r--r-- | AUTHORS.TXT | 1 | ||||
-rw-r--r-- | webm_parser/include/webm/file_reader.h | 13 | ||||
-rw-r--r-- | webm_parser/include/webm/status.h | 5 | ||||
-rw-r--r-- | webm_parser/src/file_reader.cc | 24 |
4 files changed, 41 insertions, 2 deletions
diff --git a/AUTHORS.TXT b/AUTHORS.TXT index 9686ac1..59b648c 100644 --- a/AUTHORS.TXT +++ b/AUTHORS.TXT @@ -2,3 +2,4 @@ # Name or Organization <email address> Google Inc. +Elijah Cirioli <eli.cirioli@gmail.com> diff --git a/webm_parser/include/webm/file_reader.h b/webm_parser/include/webm/file_reader.h index 6ccdc4d..69bec76 100644 --- a/webm_parser/include/webm/file_reader.h +++ b/webm_parser/include/webm/file_reader.h @@ -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: diff --git a/webm_parser/include/webm/status.h b/webm_parser/include/webm/status.h index ff3f0c6..9577ef4 100644 --- a/webm_parser/include/webm/status.h +++ b/webm_parser/include/webm/status.h @@ -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. diff --git a/webm_parser/src/file_reader.cc b/webm_parser/src/file_reader.cc index 0921abe..a2a397b 100644 --- a/webm_parser/src/file_reader.cc +++ b/webm_parser/src/file_reader.cc @@ -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); } @@ -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 @@ -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 |