• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 MOJO_PUBLIC_CPP_SYSTEM_FILE_DATA_PIPE_PRODUCER_H_
6 #define MOJO_PUBLIC_CPP_SYSTEM_FILE_DATA_PIPE_PRODUCER_H_
7 
8 #include <memory>
9 
10 #include "base/callback_forward.h"
11 #include "base/files/file.h"
12 #include "base/files/file_path.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "mojo/public/cpp/system/data_pipe.h"
17 #include "mojo/public/cpp/system/system_export.h"
18 
19 namespace mojo {
20 
21 // Helper class which takes ownership of a ScopedDataPipeProducerHandle and
22 // assumes responsibility for feeding it the contents of a given file. This
23 // takes care of waiting for pipe capacity as needed, and can notify callers
24 // asynchronously when the operation is complete.
25 //
26 // Note that the FileDataPipeProducer must be kept alive until notified of
27 // completion to ensure that all of the intended contents are written to the
28 // pipe. Premature destruction may result in partial or total truncation of data
29 // made available to the consumer.
30 class MOJO_CPP_SYSTEM_EXPORT FileDataPipeProducer {
31  public:
32   using CompletionCallback = base::OnceCallback<void(MojoResult result)>;
33 
34   // Interface definition of an optional object that may be supplied to the
35   // FileDataPipeProducer so that the data being read from the consumer can be
36   // observed.
37   class Observer {
38    public:
~Observer()39     virtual ~Observer() {}
40 
41     // Called once per read attempt. |data| contains the read data (if any).
42     // |num_bytes_read| is the number of read bytes, 0 indicates EOF. Both
43     // parameters may only be used when |read_result| is base::File::FILE_OK.
44     // Can be called on any sequence.
45     virtual void OnBytesRead(const void* data,
46                              size_t num_bytes_read,
47                              base::File::Error read_result) = 0;
48 
49     // Called when the FileDataPipeProducer has finished reading all data. Will
50     // be called even if there was an error opening the file or reading the
51     // data. Can be called on any sequence.
52     virtual void OnDoneReading() = 0;
53   };
54 
55   // Constructs a new FileDataPipeProducer which will write data to |producer|.
56   // Caller may supply an optional |observer| if observation of the read file
57   // data is desired.
58   FileDataPipeProducer(ScopedDataPipeProducerHandle producer,
59                        std::unique_ptr<Observer> observer);
60   ~FileDataPipeProducer();
61 
62   // Attempts to eventually write all of |file|'s contents to the pipe. Invokes
63   // |callback| asynchronously when done. Note that |callback| IS allowed to
64   // delete this FileDataPipeProducer.
65   //
66   // If the write is successful |result| will be |MOJO_RESULT_OK|. Otherwise
67   // (e.g. if the producer detects the consumer is closed and the pipe has no
68   // remaining capacity, or if file open/reads fail for any reason) |result|
69   // will be one of the following:
70   //
71   //   |MOJO_RESULT_ABORTED|
72   //   |MOJO_RESULT_NOT_FOUND|
73   //   |MOJO_RESULT_PERMISSION_DENIED|
74   //   |MOJO_RESULT_RESOURCE_EXHAUSTED|
75   //   |MOJO_RESULT_UNKNOWN|
76   //
77   // Note that if the FileDataPipeProducer is destroyed before |callback| can be
78   // invoked, |callback| is *never* invoked, and the write will be permanently
79   // interrupted (and the producer handle closed) after making potentially only
80   // partial progress.
81   //
82   // Multiple writes may be performed in sequence (each one after the last
83   // completes), but Write() must not be called before the |callback| for the
84   // previous call to Write() (if any) has returned.
85   void WriteFromFile(base::File file, CompletionCallback callback);
86 
87   // Like above, but writes at most |max_bytes| bytes from the file to the pipe.
88   void WriteFromFile(base::File file,
89                      size_t max_bytes,
90                      CompletionCallback callback);
91 
92   // Same as above but takes a FilePath instead of an opened File. Opens the
93   // file on an appropriate sequence and then proceeds as WriteFromFile() would.
94   void WriteFromPath(const base::FilePath& path, CompletionCallback callback);
95 
96  private:
97   class FileSequenceState;
98 
99   void InitializeNewRequest(CompletionCallback callback);
100   void OnWriteComplete(CompletionCallback callback,
101                        ScopedDataPipeProducerHandle producer,
102                        MojoResult result);
103 
104   ScopedDataPipeProducerHandle producer_;
105   scoped_refptr<FileSequenceState> file_sequence_state_;
106   std::unique_ptr<Observer> observer_;
107   base::WeakPtrFactory<FileDataPipeProducer> weak_factory_;
108 
109   DISALLOW_COPY_AND_ASSIGN(FileDataPipeProducer);
110 };
111 
112 }  // namespace mojo
113 
114 #endif  // MOJO_PUBLIC_CPP_SYSTEM_FILE_DATA_PIPE_PRODUCER_H_
115