data_pipe_utils.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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/file_util.h" 10#include "base/files/file_path.h" 11#include "base/files/scoped_file.h" 12#include "base/message_loop/message_loop.h" 13#include "base/task_runner_util.h" 14 15namespace mojo { 16namespace common { 17 18bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, 19 const base::FilePath& destination) { 20 base::ScopedFILE fp(base::OpenFile(destination, "wb")); 21 if (!fp) 22 return false; 23 24 for (;;) { 25 const void* buffer; 26 uint32_t num_bytes; 27 MojoResult result = BeginReadDataRaw(source.get(), &buffer, &num_bytes, 28 MOJO_READ_DATA_FLAG_NONE); 29 if (result == MOJO_RESULT_OK) { 30 size_t bytes_written = fwrite(buffer, 1, num_bytes, fp.get()); 31 result = EndReadDataRaw(source.get(), num_bytes); 32 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) 33 return false; 34 } else if (result == MOJO_RESULT_SHOULD_WAIT) { 35 result = Wait(source.get(), 36 MOJO_HANDLE_SIGNAL_READABLE, 37 MOJO_DEADLINE_INDEFINITE); 38 if (result != MOJO_RESULT_OK) { 39 // If the producer handle was closed, then treat as EOF. 40 return result == MOJO_RESULT_FAILED_PRECONDITION; 41 } 42 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { 43 // If the producer handle was closed, then treat as EOF. 44 return true; 45 } else { 46 // Some other error occurred. 47 break; 48 } 49 } 50 51 return false; 52} 53 54void CompleteBlockingCopyToFile(const base::Callback<void(bool)>& callback, 55 bool result) { 56 callback.Run(result); 57} 58 59void CopyToFile(ScopedDataPipeConsumerHandle source, 60 const base::FilePath& destination, 61 base::TaskRunner* task_runner, 62 const base::Callback<void(bool)>& callback) { 63 base::PostTaskAndReplyWithResult( 64 task_runner, 65 FROM_HERE, 66 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), 67 callback); 68} 69 70} // namespace common 71} // namespace mojo 72