From ada218c0897f12ccaff39dabd87bcb04214f0ae5 Mon Sep 17 00:00:00 2001 From: Thomas Inskip Date: Wed, 20 May 2015 10:14:36 -0700 Subject: [PATCH] Added File Seek and Tell functionality. Added ability to open files in direct-access mode (no buffering). Change-Id: Icca71a60f6697967e7535a030c71414de95d8044 --- packager/media/file/file.cc | 40 ++++++++++++++++++------- packager/media/file/file.h | 21 +++++++++++++ packager/media/file/local_file.cc | 14 +++++++++ packager/media/file/local_file.h | 2 ++ packager/media/file/threaded_io_file.cc | 10 +++++++ packager/media/file/threaded_io_file.h | 2 ++ packager/media/file/udp_file.h | 2 ++ packager/media/file/udp_file_posix.cc | 10 +++++++ packager/media/file/udp_file_win.cc | 10 +++++++ 9 files changed, 100 insertions(+), 11 deletions(-) diff --git a/packager/media/file/file.cc b/packager/media/file/file.cc index cab663244d..d61f1e4a3c 100644 --- a/packager/media/file/file.cc +++ b/packager/media/file/file.cc @@ -74,17 +74,8 @@ static const SupportedTypeInfo kSupportedTypeInfo[] = { } // namespace File* File::Create(const char* file_name, const char* mode) { - scoped_ptr internal_file; - for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) { - const SupportedTypeInfo& type_info = kSupportedTypeInfo[i]; - if (strncmp(type_info.type, file_name, type_info.type_length) == 0) { - internal_file.reset(type_info.factory_function( - file_name + type_info.type_length, mode)); - } - } - // Otherwise we assume it is a local file - if (!internal_file) - internal_file.reset(CreateLocalFile(file_name, mode)); + scoped_ptr internal_file( + CreateInternalFile(file_name, mode)); if (FLAGS_io_cache_size) { // Enable threaded I/O for "r", "w", and "a" modes only. @@ -106,6 +97,22 @@ File* File::Create(const char* file_name, const char* mode) { return internal_file.release(); } +File* File::CreateInternalFile(const char* file_name, const char* mode) { + scoped_ptr internal_file; + for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) { + const SupportedTypeInfo& type_info = kSupportedTypeInfo[i]; + if (strncmp(type_info.type, file_name, type_info.type_length) == 0) { + internal_file.reset(type_info.factory_function( + file_name + type_info.type_length, mode)); + } + } + // Otherwise we assume it is a local file + if (!internal_file) + internal_file.reset(CreateLocalFile(file_name, mode)); + + return internal_file.release(); +} + File* File::Open(const char* file_name, const char* mode) { File* file = File::Create(file_name, mode); if (!file) @@ -117,6 +124,17 @@ File* File::Open(const char* file_name, const char* mode) { return file; } +File* File::OpenWithNoBuffering(const char* file_name, const char* mode) { + File* file = File::CreateInternalFile(file_name, mode); + if (!file) + return NULL; + if (!file->Open()) { + delete file; + return NULL; + } + return file; +} + bool File::Delete(const char* file_name) { for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) { const SupportedTypeInfo& type_info = kSupportedTypeInfo[i]; diff --git a/packager/media/file/file.h b/packager/media/file/file.h index 01bfe05f8d..7d58f624ec 100644 --- a/packager/media/file/file.h +++ b/packager/media/file/file.h @@ -29,6 +29,14 @@ class File { /// @return A File pointer on success, false otherwise. static File* Open(const char* file_name, const char* mode); + /// Open the specified file in direct-access mode (no buffering). + /// This is a file factory method, it opens a proper file automatically + /// based on prefix, e.g. "file://" for LocalFile. + /// @param file_name contains the name of the file to be accessed. + /// @param mode contains file access mode. Implementation dependent. + /// @return A File pointer on success, false otherwise. + static File* OpenWithNoBuffering(const char* file_name, const char* mode); + /// Delete the specified file. /// @param file_name contains the path of the file to be deleted. /// @return true if successful, false otherwise. @@ -66,6 +74,17 @@ class File { /// @return true on success, false otherwise. virtual bool Flush() = 0; + /// Seek to the specifield position in the file. + /// @param position is the position to seek to. + /// @return true on success, false otherwise. + virtual bool Seek(uint64_t position) = 0; + + /// Get the current file position. + /// @param position is a pointer to contain the current file position upon + /// successful return. + /// @return true on succcess, false otherwise. + virtual bool Tell(uint64_t* position) = 0; + /// @return The file name. const std::string& file_name() const { return file_name_; } @@ -99,6 +118,8 @@ class File { // LocalFile, MemFile based on prefix. static File* Create(const char* file_name, const char* mode); + static File* CreateInternalFile(const char* file_name, const char* mode); + std::string file_name_; DISALLOW_COPY_AND_ASSIGN(File); }; diff --git a/packager/media/file/local_file.cc b/packager/media/file/local_file.cc index 35a1d11082..bba5168222 100644 --- a/packager/media/file/local_file.cc +++ b/packager/media/file/local_file.cc @@ -6,6 +6,8 @@ #include "packager/media/file/local_file.h" +#include + #include "packager/base/file_util.h" #include "packager/base/logging.h" @@ -59,6 +61,18 @@ bool LocalFile::Flush() { return ((fflush(internal_file_) == 0) && !ferror(internal_file_)); } +bool LocalFile::Seek(uint64_t position) { + return fseeko(internal_file_, position, SEEK_SET) >= 0; +} + +bool LocalFile::Tell(uint64_t* position) { + off_t offset = ftello(internal_file_); + if (offset < 0) + return false; + *position = offset; + return true; +} + LocalFile::~LocalFile() {} bool LocalFile::Open() { diff --git a/packager/media/file/local_file.h b/packager/media/file/local_file.h index 18bb38ac67..aacaa94df0 100644 --- a/packager/media/file/local_file.h +++ b/packager/media/file/local_file.h @@ -32,6 +32,8 @@ class LocalFile : public File { virtual int64_t Write(const void* buffer, uint64_t length) OVERRIDE; virtual int64_t Size() OVERRIDE; virtual bool Flush() OVERRIDE; + virtual bool Seek(uint64_t position) OVERRIDE; + virtual bool Tell(uint64_t* position) OVERRIDE; /// @} /// Delete a local file. diff --git a/packager/media/file/threaded_io_file.cc b/packager/media/file/threaded_io_file.cc index e2dca86ec5..b58c1f7ff0 100644 --- a/packager/media/file/threaded_io_file.cc +++ b/packager/media/file/threaded_io_file.cc @@ -123,6 +123,16 @@ void ThreadedIoFile::RunInInputMode() { } } +bool ThreadedIoFile::Seek(uint64_t position) { + NOTIMPLEMENTED(); + return false; +} + +bool ThreadedIoFile::Tell(uint64_t* position) { + NOTIMPLEMENTED(); + return false; +} + void ThreadedIoFile::RunInOutputMode() { DCHECK(internal_file_); DCHECK(thread_); diff --git a/packager/media/file/threaded_io_file.h b/packager/media/file/threaded_io_file.h index 0f5be3285e..ba3611562a 100644 --- a/packager/media/file/threaded_io_file.h +++ b/packager/media/file/threaded_io_file.h @@ -38,6 +38,8 @@ class ThreadedIoFile : public File { virtual int64_t Write(const void* buffer, uint64_t length) OVERRIDE; virtual int64_t Size() OVERRIDE; virtual bool Flush() OVERRIDE; + virtual bool Seek(uint64_t position) OVERRIDE; + virtual bool Tell(uint64_t* position) OVERRIDE; /// @} protected: diff --git a/packager/media/file/udp_file.h b/packager/media/file/udp_file.h index 415c00ee7c..ef64f4a140 100644 --- a/packager/media/file/udp_file.h +++ b/packager/media/file/udp_file.h @@ -31,6 +31,8 @@ class UdpFile : public File { virtual int64_t Write(const void* buffer, uint64_t length) OVERRIDE; virtual int64_t Size() OVERRIDE; virtual bool Flush() OVERRIDE; + virtual bool Seek(uint64_t position) OVERRIDE; + virtual bool Tell(uint64_t* position) OVERRIDE; /// @} protected: diff --git a/packager/media/file/udp_file_posix.cc b/packager/media/file/udp_file_posix.cc index c376c4fc96..6df6fbf368 100644 --- a/packager/media/file/udp_file_posix.cc +++ b/packager/media/file/udp_file_posix.cc @@ -129,6 +129,16 @@ bool UdpFile::Flush() { return false; } +bool UdpFile::Seek(uint64_t position) { + NOTIMPLEMENTED(); + return false; +} + +bool UdpFile::Tell(uint64_t* position) { + NOTIMPLEMENTED(); + return false; +} + class ScopedSocket { public: explicit ScopedSocket(int sock_fd) diff --git a/packager/media/file/udp_file_win.cc b/packager/media/file/udp_file_win.cc index 49a48beec6..38c94b2e75 100644 --- a/packager/media/file/udp_file_win.cc +++ b/packager/media/file/udp_file_win.cc @@ -42,6 +42,16 @@ bool UdpFile::Flush() { return false; } +bool UdpFile::Seek(uint64_t position) { + NOTIMPLEMENTED(); + return false; +} + +bool UdpFile::Tell(uint64_t* position) { + NOTIMPLEMENTED(); + return false; +} + bool UdpFile::Open() { NOTIMPLEMENTED(); return false;