7#include <packager/file/memory_file.h>
16#include <absl/base/thread_annotations.h>
17#include <absl/log/check.h>
18#include <absl/log/log.h>
19#include <absl/synchronization/mutex.h>
21#include <packager/file.h>
22#include <packager/macros/logging.h>
32 static FileSystem* Instance() {
33 static FileSystem instance;
37 bool Delete(
const std::string& file_name) {
38 absl::MutexLock auto_lock(mutex_);
40 if (open_files_.find(file_name) != open_files_.end()) {
41 LOG(ERROR) <<
"File '" << file_name
42 <<
"' is still open. Deleting an open MemoryFile is not "
43 "allowed. Exit without deleting the file.";
47 return files_.erase(file_name) > 0;
51 absl::MutexLock auto_lock(mutex_);
52 if (!open_files_.empty()) {
53 LOG(ERROR) <<
"There are still files open. Deleting an open MemoryFile "
54 "is not allowed. Exit without deleting the file.";
60 std::vector<uint8_t>* Open(
const std::string& file_name,
61 const std::string& mode) {
62 absl::MutexLock auto_lock(mutex_);
64 if (open_files_.find(file_name) != open_files_.end()) {
65 NOTIMPLEMENTED() <<
"File '" << file_name
66 <<
"' is already open. MemoryFile does not support "
67 "opening the same file before it is closed.";
71 auto iter = files_.find(file_name);
73 if (iter == files_.end())
75 }
else if (mode ==
"w") {
76 if (iter != files_.end())
79 NOTIMPLEMENTED() <<
"File mode '" << mode
80 <<
"' not supported by MemoryFile";
84 open_files_[file_name] = mode;
85 return &files_[file_name];
88 bool Close(
const std::string& file_name) {
89 absl::MutexLock auto_lock(mutex_);
91 auto iter = open_files_.find(file_name);
92 if (iter == open_files_.end()) {
93 LOG(ERROR) <<
"Cannot close file '" << file_name
94 <<
"' which is not open.";
98 open_files_.erase(iter);
103 FileSystem(
const FileSystem&) =
delete;
104 FileSystem& operator=(
const FileSystem&) =
delete;
106 FileSystem() =
default;
109 std::map<std::string, std::vector<uint8_t>> files_ ABSL_GUARDED_BY(mutex_);
111 std::map<std::string, std::string> open_files_ ABSL_GUARDED_BY(mutex_);
118MemoryFile::MemoryFile(
const std::string& file_name,
const std::string& mode)
119 : File(file_name), mode_(mode), file_(NULL), position_(0) {}
121MemoryFile::~MemoryFile() {}
123bool MemoryFile::Close() {
124 if (!FileSystem::Instance()->Close(file_name()))
130int64_t MemoryFile::Read(
void* buffer, uint64_t length) {
131 const uint64_t size = Size();
132 DCHECK_LE(position_, size);
133 if (position_ >= size)
136 const uint64_t bytes_to_read = std::min(length, size - position_);
137 memcpy(buffer, &(*file_)[position_], bytes_to_read);
138 position_ += bytes_to_read;
139 return bytes_to_read;
142int64_t MemoryFile::Write(
const void* buffer, uint64_t length) {
150 const uint64_t size = Size();
151 if (size < position_ + length) {
152 file_->resize(position_ + length);
155 memcpy(&(*file_)[position_], buffer, length);
160void MemoryFile::CloseForWriting() {}
162int64_t MemoryFile::Size() {
164 return file_->size();
167bool MemoryFile::Flush() {
171bool MemoryFile::Seek(uint64_t position) {
172 if (Size() <
static_cast<int64_t
>(position))
175 position_ = position;
179bool MemoryFile::Tell(uint64_t* position) {
180 *position = position_;
184bool MemoryFile::Open() {
185 file_ = FileSystem::Instance()->Open(file_name(), mode_);
193void MemoryFile::DeleteAll() {
194 FileSystem::Instance()->DeleteAll();
197bool MemoryFile::Delete(
const std::string& file_name) {
198 return FileSystem::Instance()->Delete(file_name);
All the methods that are virtual are virtual for mocking.