blob: aae1d8144ff61c68ab1317cd7a41d704d68bd76c [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// TODO(horo): Write tests.
#include "base/pepper_file_util.h"
#include <ppapi/c/pp_file_info.h>
#include <ppapi/c/ppb_file_io.h>
#include <ppapi/cpp/file_io.h>
#include <ppapi/cpp/file_ref.h>
#include <ppapi/cpp/file_system.h>
#include <ppapi/utility/completion_callback_factory.h>
#include <set>
#include "base/logging.h"
#include "base/mmap.h"
#include "base/mutex.h"
#include "base/pepper_scoped_obj.h"
#include "base/scoped_ptr.h"
#include "base/singleton.h"
#include "base/unnamed_event.h"
namespace mozc {
namespace {
// Base class of Pepper FileIO operator classes.
class PepperFileOperator {
public:
PepperFileOperator(pp::Instance *instance, pp::FileSystem *file_system)
: instance_(instance),
file_system_(file_system),
result_(PP_ERROR_FAILED) {
}
virtual ~PepperFileOperator() {}
protected:
pp::Instance *instance_;
pp::FileSystem *file_system_;
int32_t result_;
UnnamedEvent event_;
};
class PepperFileReader : public PepperFileOperator {
public:
PepperFileReader(pp::Instance *instance, pp::FileSystem *file_system);
virtual ~PepperFileReader() {}
int32_t Read(const string &filename, string *buffer);
private:
// Called in Read()
void ReadImpl(int32_t result);
void OnFileOpen(int32_t result);
void OnQuery(int32_t result);
void OnRead(int32_t result);
string filename_;
string *buffer_;
int32_t bytes_to_read_;
int64_t offset_;
PP_FileInfo file_info_;
scoped_main_thread_destructed_object<pp::FileIO> file_io_;
scoped_main_thread_destructed_object<pp::FileRef> file_ref_;
pp::CompletionCallbackFactory<PepperFileReader> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperFileReader);
};
PepperFileReader::PepperFileReader(pp::Instance *instance,
pp::FileSystem *file_system)
: PepperFileOperator(instance, file_system),
buffer_(NULL),
bytes_to_read_(0),
offset_(0) {
cc_factory_.Initialize(this);
}
int32_t PepperFileReader::Read(const string &filename, string *buffer) {
VLOG(2) << "PepperFileReader::Read \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread())
<< "PepperFileReader::Read() can't be called in the main thread.";
filename_ = filename;
buffer_ = buffer;
pp::Module::Get()->core()->CallOnMainThread(
0,
cc_factory_.NewCallback(&PepperFileReader::ReadImpl));
event_.Wait(-1);
return result_;
}
void PepperFileReader::ReadImpl(int32_t result) {
VLOG(2) << "PepperFileReader::ReadImpl: " << result;
file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
file_io_.reset(new pp::FileIO(instance_));
const int32_t ret = file_io_->Open(
*file_ref_, PP_FILEOPENFLAG_READ,
cc_factory_.NewCallback(&PepperFileReader::OnFileOpen));
VLOG(2) << "file_io_->Open ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Open error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileReader::OnFileOpen(int32_t result) {
VLOG(2) << "PepperFileReader::OnFileOpen: " << result;
if (result != PP_OK) {
LOG(ERROR) << "PepperFileReader::OnFileOpen error. ret: " << result
<< " [" << filename_ << "]";
result_ = result;
event_.Notify();
return;
}
CHECK(file_io_.get());
const int32_t ret = file_io_->Query(&file_info_,
cc_factory_.NewCallback(&PepperFileReader::OnQuery));
VLOG(2) << "file_io_->Query ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Query error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileReader::OnQuery(int32_t result) {
VLOG(2) << "PepperFileReader::OnQuery: " << result;
if (result != PP_OK) {
LOG(ERROR) << "PepperFileReader::OnQuery error. ret: " << result
<< " [" << filename_ << "]";
result_ = result;
event_.Notify();
return;
}
bytes_to_read_ = file_info_.size;
VLOG(2) << " bytes_to_read_: " << bytes_to_read_;
offset_ = 0;
buffer_->resize(bytes_to_read_);
OnRead(0);
}
void PepperFileReader::OnRead(int32_t bytes_read) {
VLOG(2) << "PepperFileReader::OnRead: " << bytes_read;
if (bytes_read < 0) {
LOG(ERROR) << "OnRead error. [" << filename_ << "]";
result_ = bytes_read;
event_.Notify();
return;
}
bytes_to_read_ -= bytes_read;
VLOG(2) << " bytes_to_read_: " << bytes_to_read_;
if (bytes_to_read_ == 0) {
result_ = PP_OK;
event_.Notify();
return;
} else {
CHECK(file_io_.get());
offset_ += bytes_read;
const int32_t ret = file_io_->Read(
offset_, &(*buffer_)[offset_], bytes_to_read_,
cc_factory_.NewCallback(&PepperFileReader::OnRead));
VLOG(2) << "file_io_->Read ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Read error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
}
class PepperFileWriter : public PepperFileOperator {
public:
PepperFileWriter(pp::Instance *instance, pp::FileSystem *file_system);
virtual ~PepperFileWriter() {}
int32_t Write(const string &filename, const string &buffer);
private:
// Called in Write()
void WriteImpl(int32_t result);
void OnFileOpen(int32_t result);
void OnWrite(int32_t result);
void OnFlush(int32_t result);
void OnReset(int32_t result);
string filename_;
const string *buffer_;
int64_t offset_;
scoped_main_thread_destructed_object<pp::FileIO> file_io_;
scoped_main_thread_destructed_object<pp::FileRef> file_ref_;
pp::CompletionCallbackFactory<PepperFileWriter> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperFileWriter);
};
PepperFileWriter::PepperFileWriter(pp::Instance *instance,
pp::FileSystem *file_system)
: PepperFileOperator(instance, file_system),
buffer_(NULL),
offset_(0) {
cc_factory_.Initialize(this);
}
int32_t PepperFileWriter::Write(const string &filename, const string &buffer) {
VLOG(2) << "PepperFileWriter::Write \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread())
<< "PepperFileWriter::Write() can't be called in the main thread.";
filename_ = filename;
buffer_ = &buffer;
pp::Module::Get()->core()->CallOnMainThread(
0,
cc_factory_.NewCallback(&PepperFileWriter::WriteImpl));
event_.Wait(-1);
return result_;
}
void PepperFileWriter::WriteImpl(int32_t result) {
VLOG(2) << "PepperFileWriter::WriteImpl: " << result;
file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
file_io_.reset(new pp::FileIO(instance_));
const int32_t ret = file_io_->Open(
*file_ref_, PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE,
cc_factory_.NewCallback(&PepperFileWriter::OnFileOpen));
VLOG(2) << "file_io_->Open ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Open error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileWriter::OnFileOpen(int32_t result) {
VLOG(2) << "PepperFileWriter::OnFileOpen: " << result;
if (result != PP_OK) {
LOG(ERROR) << "PepperFileWriter::OnFileOpen error. ret: " << result
<< " [" << filename_ << "]";
result_ = result;
event_.Notify();
return;
}
CHECK(file_io_.get());
const int32_t ret = file_io_->SetLength(
0, cc_factory_.NewCallback(&PepperFileWriter::OnReset));
VLOG(2) << "file_io_->SetLength ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->SetLength error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileWriter::OnReset(int32_t result) {
VLOG(2) << "PepperFileWriter::OnReset: " << result;
if (result != PP_OK) {
LOG(ERROR) << "PepperFileWriter::OnReset error. ret: " << result
<< " [" << filename_ << "]";
result_ = result;
event_.Notify();
return;
}
CHECK(file_io_.get());
offset_ = 0;
OnWrite(0);
}
void PepperFileWriter::OnWrite(int32_t bytes_written) {
VLOG(2) << "PepperFileWriter::OnWrite: " << bytes_written;
if (bytes_written < 0) {
LOG(ERROR) << "WriteCallback error. [" << filename_ << "]";
result_ = bytes_written;
event_.Notify();
return;
}
CHECK(file_io_.get());
offset_ += bytes_written;
if (offset_ == buffer_->length()) {
const int32_t ret = file_io_->Flush(
cc_factory_.NewCallback(&PepperFileWriter::OnFlush));
VLOG(2) << "file_io_->Flush ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Flush error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
} else {
const int32_t ret = file_io_->Write(
offset_, &(*buffer_)[offset_],
buffer_->length() - offset_,
cc_factory_.NewCallback(&PepperFileWriter::OnWrite));
VLOG(2) << "file_io_->Write ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Write error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
}
void PepperFileWriter::OnFlush(int32_t result) {
VLOG(2) << "PepperFileWriter::OnFlush: " << result;
if (result < 0) {
LOG(ERROR) << "FlushCallback error. ret: " << result
<< " [" << filename_ << "]";
result_ = result;
event_.Notify();
return;
}
result_ = PP_OK;
event_.Notify();
return;
}
class PepperFileQuerer : public PepperFileOperator {
public:
PepperFileQuerer(pp::Instance *instance, pp::FileSystem *file_system);
virtual ~PepperFileQuerer() {}
int32_t Query(const string &filename, PP_FileInfo *info);
private:
// Called in Query()
void QueryImpl(int32_t result);
void OnFileOpen(int32_t result);
void OnQuery(int32_t result);
string filename_;
PP_FileInfo file_info_;
scoped_main_thread_destructed_object<pp::FileIO> file_io_;
scoped_main_thread_destructed_object<pp::FileRef> file_ref_;
pp::CompletionCallbackFactory<PepperFileQuerer> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperFileQuerer);
};
PepperFileQuerer::PepperFileQuerer(pp::Instance *instance,
pp::FileSystem *file_system)
: PepperFileOperator(instance, file_system) {
cc_factory_.Initialize(this);
}
int32_t PepperFileQuerer::Query(const string &filename, PP_FileInfo *info) {
VLOG(2) << "PepperFileQuerer::Query \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread())
<< "PepperFileQuerer::Query() can't be called in the main thread.";
filename_ = filename;
pp::Module::Get()->core()->CallOnMainThread(
0,
cc_factory_.NewCallback(&PepperFileQuerer::QueryImpl));
event_.Wait(-1);
if (result_ == PP_OK) {
*info = file_info_;
}
return result_;
}
void PepperFileQuerer::QueryImpl(int32_t result) {
VLOG(2) << "PepperFileQuerer::QueryImpl: " << result;
file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
file_io_.reset(new pp::FileIO(instance_));
const int32_t ret = file_io_->Open(
*file_ref_, PP_FILEOPENFLAG_READ,
cc_factory_.NewCallback(&PepperFileQuerer::OnFileOpen));
VLOG(2) << "file_io_->Open ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Open error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileQuerer::OnFileOpen(int32_t result) {
VLOG(2) << "PepperFileQuerer::OnFileOpen: " << result;
if (result != PP_OK) {
LOG(ERROR) << "PepperFileQuerer::OnFileOpen error. ret: " << result
<< " [" << filename_ << "]";
result_ = result;
event_.Notify();
return;
}
CHECK(file_io_.get());
const int32_t ret = file_io_->Query(&file_info_,
cc_factory_.NewCallback(&PepperFileQuerer::OnQuery));
VLOG(2) << "file_io_->Query: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
LOG(ERROR) << "file_io_->Query error. ret: " << ret
<< " [" << filename_ << "]";
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileQuerer::OnQuery(int32_t result) {
VLOG(2) << "PepperFileQuerer::OnQuery: " << result;
result_ = result;
event_.Notify();
return;
}
class PepperFileRenamer : public PepperFileOperator {
public:
PepperFileRenamer(pp::Instance *instance, pp::FileSystem *file_system);
virtual ~PepperFileRenamer() {}
int32_t Rename(const string &filename, const string &new_filename);
private:
// Called in Rename()
void RenameImpl(int32_t result);
void OnRename(int32_t result);
string filename_;
string new_filename_;
scoped_main_thread_destructed_object<pp::FileRef> file_ref_;
scoped_main_thread_destructed_object<pp::FileRef> new_file_ref_;
pp::CompletionCallbackFactory<PepperFileRenamer> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperFileRenamer);
};
PepperFileRenamer::PepperFileRenamer(pp::Instance *instance,
pp::FileSystem *file_system)
: PepperFileOperator(instance, file_system) {
cc_factory_.Initialize(this);
}
int32_t PepperFileRenamer::Rename(const string &filename,
const string &new_filename) {
VLOG(2) << "PepperFileRenamer::Rename from \"" << filename << "\""
<< " to \"" << new_filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread())
<< "PepperFileRenamer::Rename() can't be called in the main thread.";
filename_ = filename;
new_filename_ = new_filename;
pp::Module::Get()->core()->CallOnMainThread(
0,
cc_factory_.NewCallback(&PepperFileRenamer::RenameImpl));
event_.Wait(-1);
return result_;
}
void PepperFileRenamer::RenameImpl(int32_t result) {
VLOG(2) << "PepperFileRenamer::RenameImpl: " << result;
file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
new_file_ref_.reset(new pp::FileRef(*file_system_, new_filename_.c_str()));
const int32_t ret = file_ref_->Rename(
*new_file_ref_,
cc_factory_.NewCallback(&PepperFileRenamer::OnRename));
VLOG(2) << "file_ref_->Rename ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileRenamer::OnRename(int32_t result) {
VLOG(2) << "PepperFileRenamer::OnRename: " << result;
result_ = result;
event_.Notify();
return;
}
class PepperFileDeleter : public PepperFileOperator {
public:
PepperFileDeleter(pp::Instance *instance, pp::FileSystem *file_system);
virtual ~PepperFileDeleter() {}
int32_t Delete(const string &filename);
private:
// Called in Delete()
void DeleteImpl(int32_t result);
void OnDelete(int32_t result);
string filename_;
scoped_main_thread_destructed_object<pp::FileRef> file_ref_;
pp::CompletionCallbackFactory<PepperFileDeleter> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperFileDeleter);
};
PepperFileDeleter::PepperFileDeleter(pp::Instance *instance,
pp::FileSystem *file_system)
: PepperFileOperator(instance, file_system) {
cc_factory_.Initialize(this);
}
int32_t PepperFileDeleter::Delete(const string &filename) {
VLOG(2) << "PepperFileDeleter::Delete \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread())
<< "PepperFileDeleter::Delete() can't be called in the main thread.";
filename_ = filename;
pp::Module::Get()->core()->CallOnMainThread(
0,
cc_factory_.NewCallback(&PepperFileDeleter::DeleteImpl));
event_.Wait(-1);
return result_;
}
void PepperFileDeleter::DeleteImpl(int32_t result) {
VLOG(2) << "PepperFileDeleter::DeleteImpl: " << result;
file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
const int32_t ret = file_ref_->Delete(
cc_factory_.NewCallback(&PepperFileDeleter::OnDelete));
VLOG(2) << "file_ref_->Delete ret: " << ret;
if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
result_ = ret;
event_.Notify();
return;
}
}
void PepperFileDeleter::OnDelete(int32_t result) {
VLOG(2) << "PepperFileDeleter::OnDelete: " << result;
result_ = result;
event_.Notify();
return;
}
class PepperFileSystem : public PepperFileSystemInterface {
public:
PepperFileSystem();
virtual ~PepperFileSystem();
virtual bool Open(pp::Instance *instance, int64 expected_size);
virtual bool FileExists(const string &filename);
virtual bool DirectoryExists(const string &dirname);
virtual bool ReadBinaryFile(const string &filename, string *buffer);
virtual bool WriteBinaryFile(const string &filename, const string &buffer);
virtual bool DeleteFile(const string &filename);
virtual bool RenameFile(const string &from, const string &to);
virtual bool RegisterMmap(Mmap *mmap);
virtual bool UnRegisterMmap(Mmap *mmap);
virtual bool SyncMmapToFile();
private:
// Called in Open()
void OpenImpl(int32_t result, int64_t expected_size, int32_t *ret_result);
void OnOpen(int32_t result, int32_t *ret_result);
scoped_main_thread_destructed_object<pp::FileSystem> file_system_;
pp::CompletionCallbackFactory<PepperFileSystem> cc_factory_;
UnnamedEvent event_;
pp::Instance *instance_;
set<Mmap*> mmap_set_;
Mutex mutex_;
DISALLOW_COPY_AND_ASSIGN(PepperFileSystem);
};
PepperFileSystem::PepperFileSystem() {
VLOG(2) << "PepperFileSystem::PepperFileSystem";
cc_factory_.Initialize(this);
}
PepperFileSystem::~PepperFileSystem() {
VLOG(2) << "PepperFileSystem::~PepperFileSystem";
}
bool PepperFileSystem::Open(pp::Instance *instance, int64 expected_size) {
VLOG(2) << "PepperFileSystem::Open";
CHECK(!pp::Module::Get()->core()->IsMainThread())
<< "PepperFileSystem::Open() can't be called in the main thread.";
CHECK(instance);
instance_ = instance;
int32_t ret_result = PP_ERROR_FAILED;
pp::Module::Get()->core()->CallOnMainThread(
0,
cc_factory_.NewCallback(&PepperFileSystem::OpenImpl,
expected_size,
&ret_result));
event_.Wait(-1);
return ret_result == PP_OK;
}
void PepperFileSystem::OpenImpl(int32_t result,
int64_t expected_size,
int32_t *ret_result) {
VLOG(2) << "PepperFileSystem::OpenImpl";
file_system_.reset(
new pp::FileSystem(instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT));
const int32_t open_result = file_system_->Open(
expected_size,
cc_factory_.NewCallback(&PepperFileSystem::OnOpen, ret_result));
VLOG(2) << "file_system_->Open ret:" << open_result;
if ((open_result != PP_OK_COMPLETIONPENDING) && (open_result != PP_OK)) {
*ret_result = open_result;
event_.Notify();
}
}
void PepperFileSystem::OnOpen(int32_t result, int32_t *ret_result) {
VLOG(2) << "PepperFileSystem::OnOpen: " << result;
CHECK(ret_result);
*ret_result = result;
event_.Notify();
}
bool PepperFileSystem::FileExists(const string &filename) {
VLOG(2) << "PepperFileSystem::FileExists \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread());
CHECK(file_system_.get()) << "PepperFileSystem is not initialized yet";
PP_FileInfo info;
PepperFileQuerer querer(instance_, file_system_.get());
return querer.Query(filename, &info) == PP_OK;
}
bool PepperFileSystem::DirectoryExists(const string &dirname) {
VLOG(2) << "PepperFileSystem::DirectoryExists \"" << dirname << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread());
CHECK(file_system_.get()) << "PepperFileSystem is not initialized yet";
PP_FileInfo info;
PepperFileQuerer querer(instance_, file_system_.get());
const int32_t ret = querer.Query(dirname, &info);
if (ret != PP_OK) {
return false;
}
return info.type == PP_FILETYPE_DIRECTORY;
}
bool PepperFileSystem::ReadBinaryFile(const string &filename, string *buffer) {
VLOG(2) << "PepperFileSystem::ReadBinaryFile \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread());
CHECK(file_system_.get()) << "PepperFileSystem is not initialized yet";
CHECK(buffer);
PepperFileReader reader(instance_, file_system_.get());
return reader.Read(filename, buffer) == PP_OK;
}
bool PepperFileSystem::WriteBinaryFile(const string &filename,
const string &buffer) {
VLOG(2) << "PepperFileSystem::WriteBinaryFile \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread());
CHECK(file_system_.get()) << "PepperFileSystem is not initialized yet";
PepperFileWriter writer(instance_, file_system_.get());
return writer.Write(filename, buffer) == PP_OK;
}
bool PepperFileSystem::DeleteFile(const string &filename) {
VLOG(2) << "PepperFileSystem::DeleteFile \"" << filename << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread());
CHECK(file_system_.get()) << "PepperFileSystem is not initialized yet";
PepperFileDeleter deleter(instance_, file_system_.get());
return deleter.Delete(filename) == PP_OK;
}
bool PepperFileSystem::RenameFile(const string &from, const string &to) {
VLOG(2) << "PepperFileSystem::RenameFile from \"" << from << "\""
<< " to \"" << to << "\"";
CHECK(!pp::Module::Get()->core()->IsMainThread());
CHECK(file_system_.get()) << "PepperFileSystem is not initialized yet";
PepperFileRenamer renamer(instance_, file_system_.get());
return renamer.Rename(from, to) == PP_OK;
}
bool PepperFileSystem::RegisterMmap(Mmap *mmap) {
scoped_lock lock(&mutex_);
return mmap_set_.insert(mmap).second;
}
bool PepperFileSystem::UnRegisterMmap(Mmap *mmap) {
scoped_lock lock(&mutex_);
return mmap_set_.erase(mmap);
}
bool PepperFileSystem::SyncMmapToFile() {
scoped_lock lock(&mutex_);
for (set<Mmap*>::iterator it = mmap_set_.begin();
it != mmap_set_.end(); ++it) {
(*it)->SyncToFile();
}
return true;
}
PepperFileSystemInterface *g_pepper_file_system = NULL;
PepperFileSystemInterface *GetPepperFileSystem() {
if (g_pepper_file_system != NULL) {
return g_pepper_file_system;
} else {
return Singleton<PepperFileSystem>::get();
}
}
} // namespace
void PepperFileUtil::SetPepperFileSystemInterfaceForTest(
PepperFileSystemInterface *mock_interface) {
g_pepper_file_system = mock_interface;
}
bool PepperFileUtil::Initialize(pp::Instance *instance, int64 expected_size) {
const bool result = GetPepperFileSystem()->Open(instance, expected_size);
if (!result) {
VLOG(2) << "PepperFileSystem::Open error";
}
return result;
}
bool PepperFileUtil::FileExists(const string &filename) {
return GetPepperFileSystem()->FileExists(filename);
}
bool PepperFileUtil::DirectoryExists(const string &dirname) {
return GetPepperFileSystem()->DirectoryExists(dirname);
}
bool PepperFileUtil::ReadBinaryFile(const string &filename, string *buffer) {
return GetPepperFileSystem()->ReadBinaryFile(filename, buffer);
}
bool PepperFileUtil::WriteBinaryFile(const string &filename,
const string &buffer) {
DeleteFile(filename);
return GetPepperFileSystem()->WriteBinaryFile(filename, buffer);
}
bool PepperFileUtil::DeleteFile(const string &filename) {
return GetPepperFileSystem()->DeleteFile(filename);
}
bool PepperFileUtil::RenameFile(const string &from, const string &to) {
return GetPepperFileSystem()->RenameFile(from, to);
}
bool PepperFileUtil::RegisterMmap(Mmap *mmap) {
return GetPepperFileSystem()->RegisterMmap(mmap);
}
bool PepperFileUtil::UnRegisterMmap(Mmap *mmap) {
return GetPepperFileSystem()->UnRegisterMmap(mmap);
}
bool PepperFileUtil::SyncMmapToFile() {
return GetPepperFileSystem()->SyncMmapToFile();
}
} // namespace mozc