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 <stdint.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/location.h"
     13 #include "base/task_runner_util.h"
     14 
     15 namespace mojo {
     16 namespace common {
     17 namespace {
     18 
     19 bool BlockingCopyFromFile(const base::FilePath& source,
     20                           ScopedDataPipeProducerHandle destination,
     21                           uint32_t skip) {
     22   base::File file(source, base::File::FLAG_OPEN | base::File::FLAG_READ);
     23   if (!file.IsValid())
     24     return false;
     25   if (file.Seek(base::File::FROM_BEGIN, skip) != skip) {
     26     LOG(ERROR) << "Seek of " << skip << " in " << source.value() << " failed";
     27     return false;
     28   }
     29   for (;;) {
     30     void* buffer = nullptr;
     31     uint32_t buffer_num_bytes = 0;
     32     MojoResult result =
     33         BeginWriteDataRaw(destination.get(), &buffer, &buffer_num_bytes,
     34                           MOJO_WRITE_DATA_FLAG_NONE);
     35     if (result == MOJO_RESULT_OK) {
     36       int bytes_read =
     37           file.ReadAtCurrentPos(static_cast<char*>(buffer), buffer_num_bytes);
     38       if (bytes_read >= 0) {
     39         EndWriteDataRaw(destination.get(), bytes_read);
     40         if (bytes_read == 0) {
     41           // eof
     42           return true;
     43         }
     44       } else {
     45         // error
     46         EndWriteDataRaw(destination.get(), 0);
     47         return false;
     48       }
     49     } else if (result == MOJO_RESULT_SHOULD_WAIT) {
     50       result = Wait(destination.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
     51                     MOJO_DEADLINE_INDEFINITE, nullptr);
     52       if (result != MOJO_RESULT_OK) {
     53         // If the consumer handle was closed, then treat as EOF.
     54         return result == MOJO_RESULT_FAILED_PRECONDITION;
     55       }
     56     } else {
     57       // If the consumer handle was closed, then treat as EOF.
     58       return result == MOJO_RESULT_FAILED_PRECONDITION;
     59     }
     60   }
     61 #if !defined(OS_WIN)
     62   NOTREACHED();
     63   return false;
     64 #endif
     65 }
     66 
     67 }  // namespace
     68 
     69 void CopyFromFile(const base::FilePath& source,
     70                   ScopedDataPipeProducerHandle destination,
     71                   uint32_t skip,
     72                   base::TaskRunner* task_runner,
     73                   const base::Callback<void(bool)>& callback) {
     74   base::PostTaskAndReplyWithResult(task_runner, FROM_HERE,
     75                                    base::Bind(&BlockingCopyFromFile, source,
     76                                               base::Passed(&destination), skip),
     77                                    callback);
     78 }
     79 
     80 }  // namespace common
     81 }  // namespace mojo
     82