| 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 = nullptr; | 23 const void* buffer = nullptr; |
| 24 uint32_t num_bytes = 0; | 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 if (bytes_written < num_bytes) { |
| 30 LOG(ERROR) << "write_bytes callback wrote fewer bytes (" |
| 31 << bytes_written << ") written than expected (" << num_bytes |
| 32 << ") in BlockingCopyHelper " |
| 33 << "(pipe closed? out of disk space?)" << std::endl; |
| 34 return false; |
| 35 } |
| 29 result = EndReadDataRaw(source.get(), num_bytes); | 36 result = EndReadDataRaw(source.get(), num_bytes); |
| 30 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) | 37 if (result != MOJO_RESULT_OK) { |
| 38 LOG(ERROR) << "EndReadDataRaw error (" << result |
| 39 << ") in BlockingCopyHelper" << std::endl; |
| 31 return false; | 40 return false; |
| 41 } |
| 32 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | 42 } else if (result == MOJO_RESULT_SHOULD_WAIT) { |
| 33 result = Wait(source.get(), | 43 result = Wait(source.get(), |
| 34 MOJO_HANDLE_SIGNAL_READABLE, | 44 MOJO_HANDLE_SIGNAL_READABLE, |
| 35 MOJO_DEADLINE_INDEFINITE); | 45 MOJO_DEADLINE_INDEFINITE); |
| 36 if (result != MOJO_RESULT_OK) { | 46 if (result != MOJO_RESULT_OK) { |
| 37 // If the producer handle was closed, then treat as EOF. | 47 // If the producer handle was closed, then treat as EOF. |
| 38 return result == MOJO_RESULT_FAILED_PRECONDITION; | 48 return result == MOJO_RESULT_FAILED_PRECONDITION; |
| 39 } | 49 } |
| 40 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { | 50 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { |
| 41 // If the producer handle was closed, then treat as EOF. | 51 // If the producer handle was closed, then treat as EOF. |
| 42 return true; | 52 return true; |
| 43 } else { | 53 } else { |
| 54 LOG(ERROR) << "Unhandled error " << result << " in BlockingCopyHelper" |
| 55 << std::endl; |
| 44 // Some other error occurred. | 56 // Some other error occurred. |
| 45 break; | 57 break; |
| 46 } | 58 } |
| 47 } | 59 } |
| 48 | 60 |
| 49 return false; | 61 return false; |
| 50 } | 62 } |
| 51 | 63 |
| 52 size_t CopyToStringHelper( | 64 size_t CopyToStringHelper( |
| 53 std::string* result, const void* buffer, uint32_t num_bytes) { | 65 std::string* result, const void* buffer, uint32_t num_bytes) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 std::string* result) { | 125 std::string* result) { |
| 114 CHECK(result); | 126 CHECK(result); |
| 115 result->clear(); | 127 result->clear(); |
| 116 return BlockingCopyHelper( | 128 return BlockingCopyHelper( |
| 117 source.Pass(), base::Bind(&CopyToStringHelper, result)); | 129 source.Pass(), base::Bind(&CopyToStringHelper, result)); |
| 118 } | 130 } |
| 119 | 131 |
| 120 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, | 132 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, |
| 121 const base::FilePath& destination) { | 133 const base::FilePath& destination) { |
| 122 base::ScopedFILE fp(base::OpenFile(destination, "wb")); | 134 base::ScopedFILE fp(base::OpenFile(destination, "wb")); |
| 123 if (!fp) | 135 if (!fp) { |
| 136 LOG(ERROR) << "OpenFile('" << destination.value() |
| 137 << "'failed in BlockingCopyToFile" << std::endl; |
| 124 return false; | 138 return false; |
| 139 } |
| 125 return BlockingCopyHelper( | 140 return BlockingCopyHelper( |
| 126 source.Pass(), base::Bind(&CopyToFileHelper, fp.get())); | 141 source.Pass(), base::Bind(&CopyToFileHelper, fp.get())); |
| 127 } | 142 } |
| 128 | 143 |
| 129 void CopyToFile(ScopedDataPipeConsumerHandle source, | 144 void CopyToFile(ScopedDataPipeConsumerHandle source, |
| 130 const base::FilePath& destination, | 145 const base::FilePath& destination, |
| 131 base::TaskRunner* task_runner, | 146 base::TaskRunner* task_runner, |
| 132 const base::Callback<void(bool)>& callback) { | 147 const base::Callback<void(bool)>& callback) { |
| 133 base::PostTaskAndReplyWithResult( | 148 base::PostTaskAndReplyWithResult( |
| 134 task_runner, | 149 task_runner, |
| 135 FROM_HERE, | 150 FROM_HERE, |
| 136 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), | 151 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), |
| 137 callback); | 152 callback); |
| 138 } | 153 } |
| 139 | 154 |
| 140 void CopyFromFile(const base::FilePath& source, | 155 void CopyFromFile(const base::FilePath& source, |
| 141 ScopedDataPipeProducerHandle destination, | 156 ScopedDataPipeProducerHandle destination, |
| 142 uint32_t skip, | 157 uint32_t skip, |
| 143 base::TaskRunner* task_runner, | 158 base::TaskRunner* task_runner, |
| 144 const base::Callback<void(bool)>& callback) { | 159 const base::Callback<void(bool)>& callback) { |
| 145 base::PostTaskAndReplyWithResult(task_runner, FROM_HERE, | 160 base::PostTaskAndReplyWithResult(task_runner, FROM_HERE, |
| 146 base::Bind(&BlockingCopyFromFile, source, | 161 base::Bind(&BlockingCopyFromFile, source, |
| 147 base::Passed(&destination), skip), | 162 base::Passed(&destination), skip), |
| 148 callback); | 163 callback); |
| 149 } | 164 } |
| 150 | 165 |
| 151 } // namespace common | 166 } // namespace common |
| 152 } // namespace mojo | 167 } // namespace mojo |
| OLD | NEW |