7 #include <packager/file/memory_file.h>
15 #include <absl/log/check.h>
16 #include <absl/log/log.h>
17 #include <absl/synchronization/mutex.h>
19 #include <packager/macros/logging.h>
29 static FileSystem* Instance() {
30 static FileSystem instance;
34 void Delete(
const std::string& file_name) {
35 absl::MutexLock auto_lock(&mutex_);
37 if (open_files_.find(file_name) != open_files_.end()) {
38 LOG(ERROR) <<
"File '" << file_name
39 <<
"' is still open. Deleting an open MemoryFile is not "
40 "allowed. Exit without deleting the file.";
44 files_.erase(file_name);
48 absl::MutexLock auto_lock(&mutex_);
49 if (!open_files_.empty()) {
50 LOG(ERROR) <<
"There are still files open. Deleting an open MemoryFile "
51 "is not allowed. Exit without deleting the file.";
57 std::vector<uint8_t>* Open(
const std::string& file_name,
58 const std::string& mode) {
59 absl::MutexLock auto_lock(&mutex_);
61 if (open_files_.find(file_name) != open_files_.end()) {
62 NOTIMPLEMENTED() <<
"File '" << file_name
63 <<
"' is already open. MemoryFile does not support "
64 "opening the same file before it is closed.";
68 auto iter = files_.find(file_name);
70 if (iter == files_.end())
72 }
else if (mode ==
"w") {
73 if (iter != files_.end())
76 NOTIMPLEMENTED() <<
"File mode '" << mode
77 <<
"' not supported by MemoryFile";
81 open_files_[file_name] = mode;
82 return &files_[file_name];
85 bool Close(
const std::string& file_name) {
86 absl::MutexLock auto_lock(&mutex_);
88 auto iter = open_files_.find(file_name);
89 if (iter == open_files_.end()) {
90 LOG(ERROR) <<
"Cannot close file '" << file_name
91 <<
"' which is not open.";
95 open_files_.erase(iter);
100 FileSystem(
const FileSystem&) =
delete;
101 FileSystem& operator=(
const FileSystem&) =
delete;
103 FileSystem() =
default;
106 std::map<std::string, std::vector<uint8_t>> files_ ABSL_GUARDED_BY(mutex_);
108 std::map<std::string, std::string> open_files_ ABSL_GUARDED_BY(mutex_);
115 MemoryFile::MemoryFile(
const std::string& file_name,
const std::string& mode)
116 : File(file_name), mode_(mode), file_(NULL), position_(0) {}
118 MemoryFile::~MemoryFile() {}
120 bool MemoryFile::Close() {
121 if (!FileSystem::Instance()->Close(file_name()))
127 int64_t MemoryFile::Read(
void* buffer, uint64_t length) {
128 const uint64_t size = Size();
129 DCHECK_LE(position_, size);
130 if (position_ >= size)
133 const uint64_t bytes_to_read = std::min(length, size - position_);
134 memcpy(buffer, &(*file_)[position_], bytes_to_read);
135 position_ += bytes_to_read;
136 return bytes_to_read;
139 int64_t MemoryFile::Write(
const void* buffer, uint64_t length) {
147 const uint64_t size = Size();
148 if (size < position_ + length) {
149 file_->resize(position_ + length);
152 memcpy(&(*file_)[position_], buffer, length);
157 void MemoryFile::CloseForWriting() {}
159 int64_t MemoryFile::Size() {
161 return file_->size();
164 bool MemoryFile::Flush() {
168 bool MemoryFile::Seek(uint64_t position) {
169 if (Size() <
static_cast<int64_t
>(position))
172 position_ = position;
176 bool MemoryFile::Tell(uint64_t* position) {
177 *position = position_;
181 bool MemoryFile::Open() {
182 file_ = FileSystem::Instance()->Open(file_name(), mode_);
190 void MemoryFile::DeleteAll() {
191 FileSystem::Instance()->DeleteAll();
194 void MemoryFile::Delete(
const std::string& file_name) {
195 FileSystem::Instance()->Delete(file_name);
All the methods that are virtual are virtual for mocking.