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