7 #include "packager/file/memory_file.h"
16 #include "packager/base/logging.h"
17 #include "packager/base/synchronization/lock.h"
27 static FileSystem* Instance() {
28 static FileSystem instance;
32 void Delete(
const std::string& file_name) {
33 base::AutoLock auto_lock(lock_);
35 if (open_files_.find(file_name) != open_files_.end()) {
36 LOG(ERROR) <<
"File '" << file_name
37 <<
"' is still open. Deleting an open MemoryFile is not "
38 "allowed. Exit without deleting the file.";
42 files_.erase(file_name);
46 base::AutoLock auto_lock(lock_);
47 if (!open_files_.empty()) {
48 LOG(ERROR) <<
"There are still files open. Deleting an open MemoryFile "
49 "is not allowed. Exit without deleting the file.";
55 std::vector<uint8_t>* Open(
const std::string& file_name,
56 const std::string& mode) {
57 base::AutoLock auto_lock(lock_);
59 if (open_files_.find(file_name) != open_files_.end()) {
60 NOTIMPLEMENTED() <<
"File '" << file_name
61 <<
"' is already open. MemoryFile does not support "
62 "open the same file before it is closed.";
66 auto iter = files_.find(file_name);
68 if (iter == files_.end())
70 }
else if (mode ==
"w") {
71 if (iter != files_.end())
74 NOTIMPLEMENTED() <<
"File mode '" << mode
75 <<
"' not supported by MemoryFile";
79 open_files_[file_name] = mode;
80 return &files_[file_name];
83 bool Close(
const std::string& file_name) {
84 base::AutoLock auto_lock(lock_);
86 auto iter = open_files_.find(file_name);
87 if (iter == open_files_.end()) {
88 LOG(ERROR) <<
"Cannot close file '" << file_name
89 <<
"' which is not open.";
93 open_files_.erase(iter);
98 FileSystem(
const FileSystem&) =
delete;
99 FileSystem& operator=(
const FileSystem&) =
delete;
101 FileSystem() =
default;
104 std::map<std::string, std::vector<uint8_t>> files_;
106 std::map<std::string, std::string> open_files_;
113 MemoryFile::MemoryFile(
const std::string& file_name,
const std::string& mode)
114 : File(file_name), mode_(mode), file_(NULL), position_(0) {}
116 MemoryFile::~MemoryFile() {}
118 bool MemoryFile::Close() {
119 if (!FileSystem::Instance()->Close(file_name()))
125 int64_t MemoryFile::Read(
void* buffer, uint64_t length) {
126 const uint64_t size = Size();
127 DCHECK_LE(position_, size);
128 if (position_ >= size)
131 const uint64_t bytes_to_read = std::min(length, size - position_);
132 memcpy(buffer, &(*file_)[position_], bytes_to_read);
133 position_ += bytes_to_read;
134 return bytes_to_read;
137 int64_t MemoryFile::Write(
const void* buffer, uint64_t length) {
145 const uint64_t size = Size();
146 if (size < position_ + length) {
147 file_->resize(position_ + length);
150 memcpy(&(*file_)[position_], buffer, length);
155 int64_t MemoryFile::Size() {
157 return file_->size();
160 bool MemoryFile::Flush() {
164 bool MemoryFile::Seek(uint64_t position) {
165 if (Size() <
static_cast<int64_t
>(position))
168 position_ = position;
172 bool MemoryFile::Tell(uint64_t* position) {
173 *position = position_;
177 bool MemoryFile::Open() {
178 file_ = FileSystem::Instance()->Open(file_name(), mode_);
186 void MemoryFile::DeleteAll() {
187 FileSystem::Instance()->DeleteAll();
190 void MemoryFile::Delete(
const std::string& file_name) {
191 FileSystem::Instance()->Delete(file_name);
All the methods that are virtual are virtual for mocking.