summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Cirioli <eli.cirioli@gmail.com>2023-02-16 00:07:43 -0800
committerElijah Cirioli <eli.cirioli@gmail.com>2023-03-01 04:25:51 +0000
commit9efaf8bf42376151fff8a233222c7ae861ba2b78 (patch)
tree065eed26416a50d2d82e3edac804b2ca41cd3bd3
parente14008c67f0b738cff49d731671abf9e7a2b942b (diff)
downloadlibwebm-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.TXT1
-rw-r--r--webm_parser/include/webm/file_reader.h13
-rw-r--r--webm_parser/include/webm/status.h5
-rw-r--r--webm_parser/src/file_reader.cc24
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