1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef REMOTING_HOST_FILE_TRANSFER_FILE_OPERATIONS_H_
6 #define REMOTING_HOST_FILE_TRANSFER_FILE_OPERATIONS_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <memory>
11 #include <vector>
12 
13 #include "base/callback.h"
14 #include "base/macros.h"
15 #include "base/optional.h"
16 #include "remoting/protocol/file_transfer_helpers.h"
17 
18 namespace base {
19 class FilePath;
20 }
21 
22 namespace remoting {
23 
24 // Interface for reading and writing file transfers.
25 
26 class FileOperations {
27  public:
28   enum State {
29     // The Reader/Writer has been newly created. No file is open, yet.
30     kCreated = 0,
31 
32     // The file has been opened. WriteChunk(), ReadChunk(), and Close() can be
33     // called.
34     kReady = 1,
35 
36     // A file operation is currently being processed. WriteChunk(), ReadChunk(),
37     // and Close() cannot be called until the state changes back to kReady.
38     kBusy = 2,
39 
40     // EOF has been reached (when reading) or Close() has been called and
41     // succeeded (when writing).
42     kComplete = 3,
43 
44     // An error has occurred.
45     kFailed = 4,
46   };
47 
48   class Reader {
49    public:
50     using OpenResult = protocol::FileTransferResult<Monostate>;
51     using OpenCallback = base::OnceCallback<void(OpenResult result)>;
52 
53     // On success, |result| will contain the read data, or an empty vector on
54     // EOF. Once EOF is reached, the state will transition to kComplete and no
55     // more operations may be performed. The reader will attempt to read as much
56     // data as requested, but there may be cases where less data is returned.
57     using ReadResult = protocol::FileTransferResult<std::vector<std::uint8_t>>;
58     using ReadCallback = base::OnceCallback<void(ReadResult result)>;
59 
60     // Once destroyed, no further callbacks will be invoked.
61     virtual ~Reader() = default;
62 
63     // Prompt the user to select a file and open it for reading.
64     virtual void Open(OpenCallback callback) = 0;
65 
66     // Reads a chunk of the given size from the file.
67     virtual void ReadChunk(std::size_t size, ReadCallback callback) = 0;
68 
69     virtual const base::FilePath& filename() const = 0;
70     virtual std::uint64_t size() const = 0;
71     virtual State state() const = 0;
72   };
73 
74   class Writer {
75    public:
76     using Result = protocol::FileTransferResult<Monostate>;
77     using Callback = base::OnceCallback<void(Result result)>;
78 
79     // Destructing before the file is completely written and closed will
80     // automatically delete the partial file. If the Writer is destroyed after
81     // calling Close but before the associated callback is invoked, the file may
82     // either be complete or deleted, depending on the exact timing. In any
83     // event, no further callbacks will be invoked once the object is destroyed.
84     virtual ~Writer() = default;
85 
86     // Starts writing a new file to the default location. This will create a
87     // temp file at the location, which will be renamed when writing is
88     // complete.
89     virtual void Open(const base::FilePath& filename, Callback callback) = 0;
90 
91     // Writes a chuck to the file. Chunks cannot be queued; the caller must
92     // wait until callback is called before calling WriteChunk again or calling
93     // Close.
94     virtual void WriteChunk(std::vector<std::uint8_t> data,
95                             Callback callback) = 0;
96 
97     // Closes the file, flushing any data still in the OS buffer and moving the
98     // the file to its final location.
99     virtual void Close(Callback callback) = 0;
100 
101     virtual State state() const = 0;
102   };
103 
104   FileOperations() = default;
105   virtual ~FileOperations() = default;
106 
107   virtual std::unique_ptr<Reader> CreateReader() = 0;
108   virtual std::unique_ptr<Writer> CreateWriter() = 0;
109 
110   DISALLOW_COPY_AND_ASSIGN(FileOperations);
111 };
112 }  // namespace remoting
113 
114 #endif  // REMOTING_HOST_FILE_TRANSFER_FILE_OPERATIONS_H_
115