Added File Seek and Tell functionality.

Added ability to open files in direct-access mode (no buffering).

Change-Id: Icca71a60f6697967e7535a030c71414de95d8044
This commit is contained in:
Thomas Inskip 2015-05-20 10:14:36 -07:00
parent 57e3e79a3d
commit ada218c089
9 changed files with 100 additions and 11 deletions

View File

@ -74,17 +74,8 @@ static const SupportedTypeInfo kSupportedTypeInfo[] = {
} // namespace
File* File::Create(const char* file_name, const char* mode) {
scoped_ptr<File, FileCloser> 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<File, FileCloser> 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<File, FileCloser> 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];

View File

@ -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);
};

View File

@ -6,6 +6,8 @@
#include "packager/media/file/local_file.h"
#include <stdio.h>
#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() {

View File

@ -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.

View File

@ -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_);

View File

@ -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:

View File

@ -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:

View File

@ -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)

View File

@ -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;