7 #include "packager/media/file/file.h"
9 #include <gflags/gflags.h>
10 #include "packager/base/logging.h"
11 #include "packager/base/memory/scoped_ptr.h"
12 #include "packager/media/file/local_file.h"
13 #include "packager/media/file/threaded_io_file.h"
14 #include "packager/media/file/udp_file.h"
15 #include "packager/base/strings/string_util.h"
17 DEFINE_uint64(io_cache_size,
19 "Size of the threaded I/O cache, in bytes. Specify 0 to disable "
21 DEFINE_uint64(io_block_size,
23 "Size of the block size used for threaded I/O, in bytes.");
25 namespace edash_packager {
28 const char* kLocalFilePrefix =
"file://";
29 const char* kUdpFilePrefix =
"udp://";
33 typedef File* (*FileFactoryFunction)(
const char* file_name,
const char* mode);
34 typedef bool (*FileDeleteFunction)(
const char* file_name);
36 struct SupportedTypeInfo {
39 const FileFactoryFunction factory_function;
40 const FileDeleteFunction delete_function;
43 File* CreateLocalFile(
const char* file_name,
const char* mode) {
44 return new LocalFile(file_name, mode);
47 bool DeleteLocalFile(
const char* file_name) {
51 File* CreateUdpFile(
const char* file_name,
const char* mode) {
52 if (base::strcasecmp(mode,
"r")) {
53 NOTIMPLEMENTED() <<
"UdpFile only supports read (receive) mode.";
56 return new UdpFile(file_name);
59 static const SupportedTypeInfo kSupportedTypeInfo[] = {
62 strlen(kLocalFilePrefix),
68 strlen(kUdpFilePrefix),
76 File* File::Create(
const char* file_name,
const char* mode) {
77 scoped_ptr<File, FileCloser> internal_file(
78 CreateInternalFile(file_name, mode));
80 if (FLAGS_io_cache_size) {
82 if (!strcmp(mode,
"r")) {
83 return new ThreadedIoFile(internal_file.Pass(),
84 ThreadedIoFile::kInputMode,
87 }
else if (!strcmp(mode,
"w") || !strcmp(mode,
"a")) {
88 return new ThreadedIoFile(internal_file.Pass(),
89 ThreadedIoFile::kOutputMode,
96 DLOG(WARNING) <<
"Threaded I/O is disabled. Performance may be decreased.";
97 return internal_file.release();
100 File* File::CreateInternalFile(
const char* file_name,
const char* mode) {
101 scoped_ptr<File, FileCloser> internal_file;
102 for (
size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) {
103 const SupportedTypeInfo& type_info = kSupportedTypeInfo[i];
104 if (strncmp(type_info.type, file_name, type_info.type_length) == 0) {
105 internal_file.reset(type_info.factory_function(
106 file_name + type_info.type_length, mode));
111 internal_file.reset(CreateLocalFile(file_name, mode));
113 return internal_file.release();
117 File* file = File::Create(file_name, mode);
128 File* file = File::CreateInternalFile(file_name, mode);
139 for (
size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) {
140 const SupportedTypeInfo& type_info = kSupportedTypeInfo[i];
141 if (strncmp(type_info.type, file_name, type_info.type_length) == 0) {
142 return type_info.delete_function ?
143 type_info.delete_function(file_name + type_info.type_length) :
148 return DeleteLocalFile(file_name);
155 int64_t res = file->
Size();
167 const size_t kBufferSize = 0x40000;
168 scoped_ptr<char[]> buf(
new char[kBufferSize]);
171 while ((len = file->
Read(buf.get(), kBufferSize)) > 0)
172 contents->append(buf.get(), len);
178 bool File::Copy(
const char* from_file_name,
const char* to_file_name) {
181 LOG(ERROR) <<
"Failed to open file " << from_file_name;
185 scoped_ptr<edash_packager::media::File, edash_packager::media::FileCloser>
188 LOG(ERROR) <<
"Failed to write to " << to_file_name;
192 uint64_t bytes_left = content.size();
193 uint64_t total_bytes_written = 0;
194 const char* content_cstr = content.c_str();
195 while (bytes_left > total_bytes_written) {
196 const int64_t bytes_written =
197 output_file->Write(content_cstr + total_bytes_written, bytes_left);
198 if (bytes_written < 0) {
199 LOG(ERROR) <<
"Failure while writing to " << to_file_name;
203 total_bytes_written += bytes_written;