| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "mojo/common/data_pipe_utils.h" | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 | |
| 9 #include "base/files/file_path.h" | |
| 10 #include "base/files/file_util.h" | |
| 11 #include "base/files/scoped_file.h" | |
| 12 #include "base/message_loop/message_loop.h" | |
| 13 #include "base/task_runner_util.h" | |
| 14 | |
| 15 namespace mojo { | |
| 16 namespace common { | |
| 17 namespace { | |
| 18 | |
| 19 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, | |
| 20 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) { | |
| 21 for (;;) { | |
| 22 const void* buffer; | |
| 23 uint32_t num_bytes; | |
| 24 MojoResult result = BeginReadDataRaw( | |
| 25 source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); | |
| 26 if (result == MOJO_RESULT_OK) { | |
| 27 size_t bytes_written = write_bytes.Run(buffer, num_bytes); | |
| 28 result = EndReadDataRaw(source.get(), num_bytes); | |
| 29 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) | |
| 30 return false; | |
| 31 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | |
| 32 result = Wait(source.get(), | |
| 33 MOJO_HANDLE_SIGNAL_READABLE, | |
| 34 MOJO_DEADLINE_INDEFINITE, | |
| 35 nullptr); | |
| 36 if (result != MOJO_RESULT_OK) { | |
| 37 // If the producer handle was closed, then treat as EOF. | |
| 38 return result == MOJO_RESULT_FAILED_PRECONDITION; | |
| 39 } | |
| 40 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { | |
| 41 // If the producer handle was closed, then treat as EOF. | |
| 42 return true; | |
| 43 } else { | |
| 44 // Some other error occurred. | |
| 45 break; | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 return false; | |
| 50 } | |
| 51 | |
| 52 size_t CopyToStringHelper( | |
| 53 std::string* result, const void* buffer, uint32_t num_bytes) { | |
| 54 result->append(static_cast<const char*>(buffer), num_bytes); | |
| 55 return num_bytes; | |
| 56 } | |
| 57 | |
| 58 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { | |
| 59 return fwrite(buffer, 1, num_bytes, fp); | |
| 60 } | |
| 61 | |
| 62 } // namespace | |
| 63 | |
| 64 | |
| 65 // TODO(hansmuller): Add a max_size parameter. | |
| 66 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, | |
| 67 std::string* result) { | |
| 68 CHECK(result); | |
| 69 result->clear(); | |
| 70 return BlockingCopyHelper( | |
| 71 source.Pass(), base::Bind(&CopyToStringHelper, result)); | |
| 72 } | |
| 73 | |
| 74 bool MOJO_COMMON_EXPORT BlockingCopyFromString( | |
| 75 const std::string& source, | |
| 76 const ScopedDataPipeProducerHandle& destination) { | |
| 77 auto it = source.begin(); | |
| 78 for (;;) { | |
| 79 void* buffer = nullptr; | |
| 80 uint32_t buffer_num_bytes = 0; | |
| 81 MojoResult result = | |
| 82 BeginWriteDataRaw(destination.get(), &buffer, &buffer_num_bytes, | |
| 83 MOJO_WRITE_DATA_FLAG_NONE); | |
| 84 if (result == MOJO_RESULT_OK) { | |
| 85 char* char_buffer = static_cast<char*>(buffer); | |
| 86 uint32_t byte_index = 0; | |
| 87 while (it != source.end() && byte_index < buffer_num_bytes) { | |
| 88 char_buffer[byte_index++] = *it++; | |
| 89 } | |
| 90 EndWriteDataRaw(destination.get(), byte_index); | |
| 91 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | |
| 92 result = Wait(destination.get(), MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 93 MOJO_DEADLINE_INDEFINITE, nullptr); | |
| 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 } | |
| 104 | |
| 105 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, | |
| 106 const base::FilePath& destination) { | |
| 107 base::ScopedFILE fp(base::OpenFile(destination, "wb")); | |
| 108 if (!fp) | |
| 109 return false; | |
| 110 return BlockingCopyHelper( | |
| 111 source.Pass(), base::Bind(&CopyToFileHelper, fp.get())); | |
| 112 } | |
| 113 | |
| 114 void CopyToFile(ScopedDataPipeConsumerHandle source, | |
| 115 const base::FilePath& destination, | |
| 116 base::TaskRunner* task_runner, | |
| 117 const base::Callback<void(bool)>& callback) { | |
| 118 base::PostTaskAndReplyWithResult( | |
| 119 task_runner, | |
| 120 FROM_HERE, | |
| 121 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), | |
| 122 callback); | |
| 123 } | |
| 124 | |
| 125 } // namespace common | |
| 126 } // namespace mojo | |
| OLD | NEW |