blob: 0ca229bb8e8e853d96710fc5946e7a5d854c2180 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "storage/browser/file_system/memory_file_stream_reader.h"
#include <memory>
#include <utility>
#include "base/memory/ptr_util.h"
#include "base/task_runner_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
namespace storage {
std::unique_ptr<FileStreamReader> FileStreamReader::CreateForMemoryFile(
scoped_refptr<base::TaskRunner> task_runner,
base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util,
const base::FilePath& file_path,
int64_t initial_offset,
const base::Time& expected_modification_time) {
return base::WrapUnique(new MemoryFileStreamReader(
std::move(task_runner), std::move(memory_file_util), file_path,
initial_offset, expected_modification_time));
}
MemoryFileStreamReader::MemoryFileStreamReader(
scoped_refptr<base::TaskRunner> task_runner,
base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util,
const base::FilePath& file_path,
int64_t initial_offset,
const base::Time& expected_modification_time)
: memory_file_util_(std::move(memory_file_util)),
task_runner_(std::move(task_runner)),
file_path_(file_path),
expected_modification_time_(expected_modification_time),
offset_(initial_offset) {
DCHECK(memory_file_util_.MaybeValid());
}
MemoryFileStreamReader::~MemoryFileStreamReader() = default;
int MemoryFileStreamReader::Read(net::IOBuffer* buf,
int buf_len,
net::CompletionOnceCallback callback) {
task_runner_->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(
[](base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> util,
const base::FilePath& path, base::Time expected_modification_time,
int64_t offset, scoped_refptr<net::IOBuffer> buf,
int buf_len) -> int {
if (!util)
return net::ERR_FILE_NOT_FOUND;
base::File::Info file_info;
if (util->GetFileInfo(path, &file_info) != base::File::FILE_OK)
return net::ERR_FILE_NOT_FOUND;
if (!FileStreamReader::VerifySnapshotTime(
expected_modification_time, file_info)) {
return net::ERR_UPLOAD_FILE_CHANGED;
}
return util->ReadFile(path, offset, std::move(buf), buf_len);
},
memory_file_util_, file_path_, expected_modification_time_, offset_,
base::WrapRefCounted(buf), buf_len),
base::BindOnce(&MemoryFileStreamReader::OnReadCompleted,
weak_factory_.GetWeakPtr(), std::move(callback)));
return net::ERR_IO_PENDING;
}
void MemoryFileStreamReader::OnReadCompleted(
net::CompletionOnceCallback callback,
int result) {
if (result > 0)
offset_ += result;
std::move(callback).Run(result);
}
int64_t MemoryFileStreamReader::GetLength(
net::Int64CompletionOnceCallback callback) {
task_runner_->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(
[](base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> util,
const base::FilePath& path,
base::Time expected_modification_time) -> int64_t {
if (!util)
return net::ERR_FILE_NOT_FOUND;
base::File::Info file_info;
if (util->GetFileInfo(path, &file_info) != base::File::FILE_OK) {
return net::ERR_FILE_NOT_FOUND;
}
if (!FileStreamReader::VerifySnapshotTime(
expected_modification_time, file_info)) {
return net::ERR_UPLOAD_FILE_CHANGED;
}
return file_info.size;
},
memory_file_util_, file_path_, expected_modification_time_),
// |callback| is not directly used to make sure that it is not called if
// stream is deleted while this function is in flight.
base::BindOnce(&MemoryFileStreamReader::OnGetLengthCompleted,
weak_factory_.GetWeakPtr(), std::move(callback)));
return net::ERR_IO_PENDING;
}
void MemoryFileStreamReader::OnGetLengthCompleted(
net::Int64CompletionOnceCallback callback,
int64_t result) {
std::move(callback).Run(result);
}
} // namespace storage