#ifndef CHROME_BROWSER_ASH_FUSEBOX_FUSEBOX_READ_WRITER_H_
#define CHROME_BROWSER_ASH_FUSEBOX_FUSEBOX_READ_WRITER_H_
#include <utility>
#include "base/files/scoped_file.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/types/expected.h"
#include "chrome/browser/ash/fusebox/fusebox.pb.h"
#include "net/base/io_buffer.h"
#include "storage/browser/file_system/file_stream_reader.h"
#include "storage/browser/file_system/file_stream_writer.h"
#include "storage/browser/file_system/file_system_context.h"
namespace fusebox {
class ReadWriter {
public:
using Close2Callback =
base::OnceCallback<void(const Close2ResponseProto& response)>;
using FlushCallback =
base::OnceCallback<void(const FlushResponseProto& response)>;
using Read2Callback =
base::OnceCallback<void(const Read2ResponseProto& response)>;
using Write2Callback =
base::OnceCallback<void(const Write2ResponseProto& response)>;
ReadWriter(const storage::FileSystemURL& fs_url,
const std::string& profile_path,
bool use_temp_file,
bool temp_file_starts_with_copy);
~ReadWriter();
void Close(scoped_refptr<storage::FileSystemContext> fs_context,
Close2Callback callback);
void Flush(scoped_refptr<storage::FileSystemContext> fs_context,
FlushCallback callback);
void Read(scoped_refptr<storage::FileSystemContext> fs_context,
int64_t offset,
int64_t length,
Read2Callback callback);
void Write(scoped_refptr<storage::FileSystemContext> fs_context,
scoped_refptr<net::StringIOBuffer> buffer,
int64_t offset,
int length,
Write2Callback callback);
using WriteTempFileResult = std::pair<base::ScopedFD, int>;
private:
void Save();
static void OnDefaultFlush(
base::WeakPtr<ReadWriter> weak_ptr,
FlushCallback callback,
scoped_refptr<storage::FileSystemContext> fs_context,
int flush_posix_error_code);
static void OnEOFFlushBeforeActualClose(
base::WeakPtr<ReadWriter> weak_ptr,
Close2Callback callback,
scoped_refptr<storage::FileSystemContext> fs_context,
std::unique_ptr<storage::FileStreamWriter> fs_writer,
int flush_posix_error_code);
static void OnTempFileInitialized(base::WeakPtr<ReadWriter> weak_ptr,
scoped_refptr<net::StringIOBuffer> buffer,
int64_t offset,
int length,
Write2Callback callback,
base::expected<base::ScopedFD, int> result);
static void CallWriteTempFile(base::WeakPtr<ReadWriter> weak_ptr,
scoped_refptr<net::StringIOBuffer> buffer,
int64_t offset,
int length,
Write2Callback callback);
static void OnRead(base::WeakPtr<ReadWriter> weak_ptr,
Read2Callback callback,
scoped_refptr<storage::FileSystemContext> fs_context,
std::unique_ptr<storage::FileStreamReader> fs_reader,
scoped_refptr<net::IOBuffer> buffer,
int64_t offset,
int length);
static void OnWriteTempFile(base::WeakPtr<ReadWriter> weak_ptr,
Write2Callback callback,
WriteTempFileResult result);
static void OnEOFFlushBeforeCallWriteDirect(
base::WeakPtr<ReadWriter> weak_ptr,
Write2Callback callback,
scoped_refptr<storage::FileSystemContext> fs_context,
scoped_refptr<net::IOBuffer> buffer,
int64_t offset,
int length,
std::unique_ptr<storage::FileStreamWriter> fs_writer,
int flush_posix_error_code);
void CallWriteDirect(Write2Callback callback,
scoped_refptr<storage::FileSystemContext> fs_context,
std::unique_ptr<storage::FileStreamWriter> fs_writer,
scoped_refptr<net::IOBuffer> buffer,
int64_t offset,
int length);
static void OnWriteDirect(
base::WeakPtr<ReadWriter> weak_ptr,
Write2Callback callback,
scoped_refptr<storage::FileSystemContext> fs_context,
std::unique_ptr<storage::FileStreamWriter> fs_writer,
scoped_refptr<net::IOBuffer> buffer,
int64_t offset,
int length);
const storage::FileSystemURL fs_url_;
const std::string profile_path_;
std::unique_ptr<storage::FileStreamReader> fs_reader_;
int64_t read_offset_ = -1;
std::unique_ptr<storage::FileStreamWriter> fs_writer_;
int64_t write_offset_ = -1;
scoped_refptr<storage::FileSystemContext> close2_fs_context_;
Close2Callback close2_callback_;
base::ScopedFD temp_file_;
int write_posix_error_code_ = 0;
bool is_loaning_temp_file_scoped_fd_ = false;
bool is_in_flight_ = false;
bool closed_ = false;
bool created_temp_file_ = false;
bool fs_writer_needs_eof_flushing_ = false;
const bool use_temp_file_;
const bool temp_file_starts_with_copy_;
base::WeakPtrFactory<ReadWriter> weak_ptr_factory_{this};
};
}
#endif