Index: mojo/common/data_pipe_utils.cc |
diff --git a/mojo/common/data_pipe_utils.cc b/mojo/common/data_pipe_utils.cc |
index 428a5897b05074ebcae62029659adbace64314c7..34a6391e9b3ddc6a3342b4e3463003843bf59a23 100644 |
--- a/mojo/common/data_pipe_utils.cc |
+++ b/mojo/common/data_pipe_utils.cc |
@@ -58,6 +58,49 @@ size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { |
return fwrite(buffer, 1, num_bytes, fp); |
} |
+bool BlockingCopyFromFile(const base::FilePath& source, |
+ ScopedDataPipeProducerHandle destination) { |
+ base::File file(source, base::File::FLAG_OPEN | base::File::FLAG_READ); |
+ if (!file.IsValid()) |
+ return false; |
+ for (;;) { |
+ void* buffer; |
Aaron Boodman
2014/11/03 19:20:15
= nullptr; I know the code above does not do it. T
qsr
2014/11/04 11:58:34
Done. But I do not understand why you say this cod
Aaron Boodman
2014/11/04 18:05:00
Sorry, I was exaggerating for comedic effect. As i
|
+ uint32_t buffer_num_bytes; |
Aaron Boodman
2014/11/03 19:20:14
= 0;
qsr
2014/11/04 11:58:33
Done.
|
+ MojoResult result = BeginWriteDataRaw(destination.get(), |
+ &buffer, |
+ &buffer_num_bytes, |
+ MOJO_WRITE_DATA_FLAG_NONE); |
+ if (result == MOJO_RESULT_OK) { |
+ int bytes_read = |
+ file.ReadAtCurrentPos(static_cast<char*>(buffer), buffer_num_bytes); |
+ if (bytes_read >= 0) { |
+ EndWriteDataRaw(destination.get(), bytes_read); |
+ if (bytes_read == 0) { |
+ // eof |
+ return true; |
+ } |
+ } else { |
+ // error |
+ EndWriteDataRaw(destination.get(), 0); |
+ return false; |
+ } |
+ } else if (result == MOJO_RESULT_SHOULD_WAIT) { |
+ result = Wait(destination.get(), |
+ MOJO_HANDLE_SIGNAL_WRITABLE, |
+ MOJO_DEADLINE_INDEFINITE); |
+ if (result != MOJO_RESULT_OK) { |
+ // If the consumder handle was closed, then treat as EOF. |
Aaron Boodman
2014/11/03 19:20:14
typo: consumer
qsr
2014/11/04 11:58:34
Done.
|
+ return result == MOJO_RESULT_FAILED_PRECONDITION; |
+ } |
+ } else { |
+ // If the consumder handle was closed, then treat as EOF. |
+ return result == MOJO_RESULT_FAILED_PRECONDITION; |
+ } |
+ } |
+ NOTREACHED(); |
+ return false; |
+} |
+ |
} // namespace |
@@ -90,5 +133,16 @@ void CopyToFile(ScopedDataPipeConsumerHandle source, |
callback); |
} |
+void CopyFromFile(const base::FilePath& source, |
Aaron Boodman
2014/11/03 19:20:15
Can you add a unit test for this?
qsr
2014/11/04 11:58:34
Done.
|
+ ScopedDataPipeProducerHandle destination, |
+ base::TaskRunner* task_runner, |
+ const base::Callback<void(bool)>& callback) { |
+ base::PostTaskAndReplyWithResult( |
+ task_runner, |
+ FROM_HERE, |
+ base::Bind(&BlockingCopyFromFile, source, base::Passed(&destination)), |
+ callback); |
+} |
+ |
} // namespace common |
} // namespace mojo |