OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/common/data_pipe_utils.h" | 5 #include "mojo/common/data_pipe_utils.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/files/scoped_file.h" | 11 #include "base/files/scoped_file.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/task_runner_util.h" | 13 #include "base/task_runner_util.h" |
14 | 14 |
15 namespace mojo { | 15 namespace mojo { |
16 namespace common { | 16 namespace common { |
| 17 namespace { |
17 | 18 |
18 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, | 19 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, |
19 const base::FilePath& destination) { | 20 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) { |
20 base::ScopedFILE fp(base::OpenFile(destination, "wb")); | |
21 if (!fp) | |
22 return false; | |
23 | |
24 for (;;) { | 21 for (;;) { |
25 const void* buffer; | 22 const void* buffer; |
26 uint32_t num_bytes; | 23 uint32_t num_bytes; |
27 MojoResult result = BeginReadDataRaw(source.get(), &buffer, &num_bytes, | 24 MojoResult result = BeginReadDataRaw( |
28 MOJO_READ_DATA_FLAG_NONE); | 25 source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); |
29 if (result == MOJO_RESULT_OK) { | 26 if (result == MOJO_RESULT_OK) { |
30 size_t bytes_written = fwrite(buffer, 1, num_bytes, fp.get()); | 27 size_t bytes_written = write_bytes.Run(buffer, num_bytes); |
31 result = EndReadDataRaw(source.get(), num_bytes); | 28 result = EndReadDataRaw(source.get(), num_bytes); |
32 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) | 29 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) |
33 return false; | 30 return false; |
34 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | 31 } else if (result == MOJO_RESULT_SHOULD_WAIT) { |
35 result = Wait(source.get(), | 32 result = Wait(source.get(), |
36 MOJO_HANDLE_SIGNAL_READABLE, | 33 MOJO_HANDLE_SIGNAL_READABLE, |
37 MOJO_DEADLINE_INDEFINITE); | 34 MOJO_DEADLINE_INDEFINITE); |
38 if (result != MOJO_RESULT_OK) { | 35 if (result != MOJO_RESULT_OK) { |
39 // If the producer handle was closed, then treat as EOF. | 36 // If the producer handle was closed, then treat as EOF. |
40 return result == MOJO_RESULT_FAILED_PRECONDITION; | 37 return result == MOJO_RESULT_FAILED_PRECONDITION; |
41 } | 38 } |
42 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { | 39 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { |
43 // If the producer handle was closed, then treat as EOF. | 40 // If the producer handle was closed, then treat as EOF. |
44 return true; | 41 return true; |
45 } else { | 42 } else { |
46 // Some other error occurred. | 43 // Some other error occurred. |
47 break; | 44 break; |
48 } | 45 } |
49 } | 46 } |
50 | 47 |
51 return false; | 48 return false; |
52 } | 49 } |
53 | 50 |
54 void CompleteBlockingCopyToFile(const base::Callback<void(bool)>& callback, | 51 size_t CopyToStringHelper( |
55 bool result) { | 52 std::string* result, const void* buffer, uint32_t num_bytes) { |
56 callback.Run(result); | 53 result->append(static_cast<const char*>(buffer), num_bytes); |
| 54 return num_bytes; |
| 55 } |
| 56 |
| 57 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { |
| 58 return fwrite(buffer, 1, num_bytes, fp); |
| 59 } |
| 60 |
| 61 } // namespace |
| 62 |
| 63 |
| 64 // TODO(hansmuller): Add a max_size parameter. |
| 65 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, |
| 66 std::string* result) { |
| 67 CHECK(result); |
| 68 result->clear(); |
| 69 return BlockingCopyHelper( |
| 70 source.Pass(), base::Bind(&CopyToStringHelper, result)); |
| 71 } |
| 72 |
| 73 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, |
| 74 const base::FilePath& destination) { |
| 75 base::ScopedFILE fp(base::OpenFile(destination, "wb")); |
| 76 if (!fp) |
| 77 return false; |
| 78 return BlockingCopyHelper( |
| 79 source.Pass(), base::Bind(&CopyToFileHelper, fp.get())); |
57 } | 80 } |
58 | 81 |
59 void CopyToFile(ScopedDataPipeConsumerHandle source, | 82 void CopyToFile(ScopedDataPipeConsumerHandle source, |
60 const base::FilePath& destination, | 83 const base::FilePath& destination, |
61 base::TaskRunner* task_runner, | 84 base::TaskRunner* task_runner, |
62 const base::Callback<void(bool)>& callback) { | 85 const base::Callback<void(bool)>& callback) { |
63 base::PostTaskAndReplyWithResult( | 86 base::PostTaskAndReplyWithResult( |
64 task_runner, | 87 task_runner, |
65 FROM_HERE, | 88 FROM_HERE, |
66 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), | 89 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), |
67 callback); | 90 callback); |
68 } | 91 } |
69 | 92 |
70 } // namespace common | 93 } // namespace common |
71 } // namespace mojo | 94 } // namespace mojo |
OLD | NEW |