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 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
15 | 15 |
16 namespace mojo { | 16 namespace mojo { |
17 namespace common { | 17 namespace common { |
18 namespace { | 18 namespace { |
19 | 19 |
20 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, | 20 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, |
21 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) { | 21 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) { |
22 for (;;) { | 22 for (;;) { |
23 const void* buffer; | 23 const void* buffer = nullptr; |
24 uint32_t num_bytes; | 24 uint32_t num_bytes = 0; |
25 MojoResult result = BeginReadDataRaw( | 25 MojoResult result = BeginReadDataRaw( |
26 source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); | 26 source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); |
27 if (result == MOJO_RESULT_OK) { | 27 if (result == MOJO_RESULT_OK) { |
28 size_t bytes_written = write_bytes.Run(buffer, num_bytes); | 28 size_t bytes_written = write_bytes.Run(buffer, num_bytes); |
29 result = EndReadDataRaw(source.get(), num_bytes); | 29 result = EndReadDataRaw(source.get(), num_bytes); |
30 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) | 30 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) |
31 return false; | 31 return false; |
32 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | 32 } else if (result == MOJO_RESULT_SHOULD_WAIT) { |
33 result = Wait(source.get(), | 33 result = Wait(source.get(), |
34 MOJO_HANDLE_SIGNAL_READABLE, | 34 MOJO_HANDLE_SIGNAL_READABLE, |
(...skipping 17 matching lines...) Expand all Loading... |
52 size_t CopyToStringHelper( | 52 size_t CopyToStringHelper( |
53 std::string* result, const void* buffer, uint32_t num_bytes) { | 53 std::string* result, const void* buffer, uint32_t num_bytes) { |
54 result->append(static_cast<const char*>(buffer), num_bytes); | 54 result->append(static_cast<const char*>(buffer), num_bytes); |
55 return num_bytes; | 55 return num_bytes; |
56 } | 56 } |
57 | 57 |
58 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { | 58 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { |
59 return fwrite(buffer, 1, num_bytes, fp); | 59 return fwrite(buffer, 1, num_bytes, fp); |
60 } | 60 } |
61 | 61 |
| 62 bool BlockingCopyFromFile(const base::FilePath& source, |
| 63 ScopedDataPipeProducerHandle destination, |
| 64 uint32_t skip) { |
| 65 base::File file(source, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 66 if (!file.IsValid()) |
| 67 return false; |
| 68 if (file.Seek(base::File::FROM_BEGIN, skip) != skip) { |
| 69 return false; |
| 70 } |
| 71 for (;;) { |
| 72 void* buffer = nullptr; |
| 73 uint32_t buffer_num_bytes = 0; |
| 74 MojoResult result = |
| 75 BeginWriteDataRaw(destination.get(), &buffer, &buffer_num_bytes, |
| 76 MOJO_WRITE_DATA_FLAG_NONE); |
| 77 if (result == MOJO_RESULT_OK) { |
| 78 int bytes_read = |
| 79 file.ReadAtCurrentPos(static_cast<char*>(buffer), buffer_num_bytes); |
| 80 if (bytes_read >= 0) { |
| 81 EndWriteDataRaw(destination.get(), bytes_read); |
| 82 if (bytes_read == 0) { |
| 83 // eof |
| 84 return true; |
| 85 } |
| 86 } else { |
| 87 // error |
| 88 EndWriteDataRaw(destination.get(), 0); |
| 89 return false; |
| 90 } |
| 91 } else if (result == MOJO_RESULT_SHOULD_WAIT) { |
| 92 result = Wait(destination.get(), MOJO_HANDLE_SIGNAL_WRITABLE, |
| 93 MOJO_DEADLINE_INDEFINITE); |
| 94 if (result != MOJO_RESULT_OK) { |
| 95 // If the consumer handle was closed, then treat as EOF. |
| 96 return result == MOJO_RESULT_FAILED_PRECONDITION; |
| 97 } |
| 98 } else { |
| 99 // If the consumer handle was closed, then treat as EOF. |
| 100 return result == MOJO_RESULT_FAILED_PRECONDITION; |
| 101 } |
| 102 } |
| 103 NOTREACHED(); |
| 104 return false; |
| 105 } |
| 106 |
62 } // namespace | 107 } // namespace |
63 | 108 |
64 // TODO(hansmuller): Add a max_size parameter. | 109 // TODO(hansmuller): Add a max_size parameter. |
65 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, | 110 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, |
66 std::string* result) { | 111 std::string* result) { |
67 CHECK(result); | 112 CHECK(result); |
68 result->clear(); | 113 result->clear(); |
69 return BlockingCopyHelper( | 114 return BlockingCopyHelper( |
70 source.Pass(), base::Bind(&CopyToStringHelper, result)); | 115 source.Pass(), base::Bind(&CopyToStringHelper, result)); |
71 } | 116 } |
(...skipping 11 matching lines...) Expand all Loading... |
83 const base::FilePath& destination, | 128 const base::FilePath& destination, |
84 base::TaskRunner* task_runner, | 129 base::TaskRunner* task_runner, |
85 const base::Callback<void(bool)>& callback) { | 130 const base::Callback<void(bool)>& callback) { |
86 base::PostTaskAndReplyWithResult( | 131 base::PostTaskAndReplyWithResult( |
87 task_runner, | 132 task_runner, |
88 FROM_HERE, | 133 FROM_HERE, |
89 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), | 134 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), |
90 callback); | 135 callback); |
91 } | 136 } |
92 | 137 |
| 138 void CopyFromFile(const base::FilePath& source, |
| 139 ScopedDataPipeProducerHandle destination, |
| 140 uint32_t skip, |
| 141 base::TaskRunner* task_runner, |
| 142 const base::Callback<void(bool)>& callback) { |
| 143 base::PostTaskAndReplyWithResult(task_runner, FROM_HERE, |
| 144 base::Bind(&BlockingCopyFromFile, source, |
| 145 base::Passed(&destination), skip), |
| 146 callback); |
| 147 } |
| 148 |
93 } // namespace common | 149 } // namespace common |
94 } // namespace mojo | 150 } // namespace mojo |
OLD | NEW |