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