blob: 1750de24e08e1bf0c53a95fe19b2226230beb704 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/network/disk_cache/mojo_backend_file_operations.h"
#include "base/task/sequenced_task_runner.h"
namespace network {
namespace {
class FileEnumeratorImpl final
: public disk_cache::BackendFileOperations::FileEnumerator {
public:
using FileEnumerationEntry =
disk_cache::BackendFileOperations::FileEnumerationEntry;
explicit FileEnumeratorImpl(mojo::PendingRemote<mojom::FileEnumerator> remote)
: remote_(std::move(remote)) {}
~FileEnumeratorImpl() override = default;
std::optional<FileEnumerationEntry> Next() override {
if (has_seen_end_) {
return std::nullopt;
}
if (index_ >= entries_.size()) {
index_ = 0;
entries_.clear();
remote_->GetNext(kNumEntries, &entries_, &has_seen_end_, &has_error_);
}
if (entries_.empty()) {
if (has_seen_end_) {
return std::nullopt;
}
has_error_ = true;
has_seen_end_ = true;
return std::nullopt;
}
DCHECK_LT(index_, entries_.size());
return std::make_optional<FileEnumerationEntry>(
std::move(entries_[index_++]));
}
bool HasError() const override { return has_error_; }
private:
mojo::Remote<mojom::FileEnumerator> remote_;
std::vector<FileEnumerationEntry> entries_;
bool has_seen_end_ = false;
bool has_error_ = false;
size_t index_ = 0;
static constexpr uint32_t kNumEntries = 1000;
};
} // namespace
MojoBackendFileOperations::MojoBackendFileOperations(
mojo::PendingRemote<mojom::HttpCacheBackendFileOperations> pending_remote,
scoped_refptr<base::SequencedTaskRunner> task_runner)
: remote_(std::move(pending_remote), std::move(task_runner)) {}
MojoBackendFileOperations::~MojoBackendFileOperations() = default;
bool MojoBackendFileOperations::CreateDirectory(const base::FilePath& path) {
bool result = false;
remote_->CreateDirectory(path, &result);
return result;
}
bool MojoBackendFileOperations::PathExists(const base::FilePath& path) {
bool result = false;
remote_->PathExists(path, &result);
return result;
}
bool MojoBackendFileOperations::DirectoryExists(const base::FilePath& path) {
bool result = false;
remote_->DirectoryExists(path, &result);
return result;
}
base::File MojoBackendFileOperations::OpenFile(const base::FilePath& path,
uint32_t flags) {
base::File file;
base::File::Error error;
// The value will be checked in the message receiver side.
auto flags_to_pass = static_cast<mojom::HttpCacheBackendOpenFileFlags>(flags);
remote_->OpenFile(path, flags_to_pass, &file, &error);
if (error != base::File::FILE_OK) {
return base::File(error);
}
return file;
}
bool MojoBackendFileOperations::DeleteFile(const base::FilePath& path,
DeleteFileMode mode) {
mojom::HttpCacheBackendDeleteFileMode mode_to_pass;
switch (mode) {
case DeleteFileMode::kDefault:
mode_to_pass = mojom::HttpCacheBackendDeleteFileMode::kDefault;
break;
case DeleteFileMode::kEnsureImmediateAvailability:
mode_to_pass =
mojom::HttpCacheBackendDeleteFileMode::kEnsureImmediateAvailability;
break;
}
bool result = false;
remote_->DeleteFile(path, mode_to_pass, &result);
return result;
}
bool MojoBackendFileOperations::ReplaceFile(const base::FilePath& from_path,
const base::FilePath& to_path,
base::File::Error* error_out) {
base::File::Error error;
remote_->RenameFile(from_path, to_path, &error);
if (error_out) {
*error_out = error;
}
return error == base::File::FILE_OK;
}
std::optional<base::File::Info> MojoBackendFileOperations::GetFileInfo(
const base::FilePath& path) {
std::optional<base::File::Info> info;
remote_->GetFileInfo(path, &info);
return info;
}
std::unique_ptr<disk_cache::BackendFileOperations::FileEnumerator>
MojoBackendFileOperations::EnumerateFiles(const base::FilePath& path) {
mojo::PendingRemote<mojom::FileEnumerator> remote;
remote_->EnumerateFiles(path, remote.InitWithNewPipeAndPassReceiver());
return std::make_unique<FileEnumeratorImpl>(std::move(remote));
}
void MojoBackendFileOperations::CleanupDirectory(
const base::FilePath& path,
base::OnceCallback<void(bool)> callback) {
remote_->CleanupDirectory(path, std::move(callback));
}
std::unique_ptr<disk_cache::UnboundBackendFileOperations>
MojoBackendFileOperations::Unbind() {
return std::make_unique<UnboundMojoBackendFileOperations>(remote_.Unbind());
}
UnboundMojoBackendFileOperations::UnboundMojoBackendFileOperations(
mojo::PendingRemote<mojom::HttpCacheBackendFileOperations> pending_remote)
: pending_remote_(std::move(pending_remote)) {}
UnboundMojoBackendFileOperations::~UnboundMojoBackendFileOperations() = default;
std::unique_ptr<disk_cache::BackendFileOperations>
UnboundMojoBackendFileOperations::Bind(
scoped_refptr<base::SequencedTaskRunner> task_runner) {
return std::make_unique<MojoBackendFileOperations>(std::move(pending_remote_),
std::move(task_runner));
}
} // namespace network