Home | History | Annotate | Download | only in operations
      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 "chrome/browser/chromeos/file_system_provider/operations/read_file.h"
      6 
      7 #include <limits>
      8 #include <string>
      9 
     10 #include "base/debug/trace_event.h"
     11 #include "chrome/common/extensions/api/file_system_provider.h"
     12 #include "chrome/common/extensions/api/file_system_provider_internal.h"
     13 
     14 namespace chromeos {
     15 namespace file_system_provider {
     16 namespace operations {
     17 namespace {
     18 
     19 // Convert |value| into |output|. If parsing fails, then returns a negative
     20 // value. Otherwise returns number of bytes written to the buffer.
     21 int CopyRequestValueToBuffer(scoped_ptr<RequestValue> value,
     22                              scoped_refptr<net::IOBuffer> buffer,
     23                              int buffer_offset,
     24                              int buffer_length) {
     25   using extensions::api::file_system_provider_internal::
     26       ReadFileRequestedSuccess::Params;
     27 
     28   const Params* params = value->read_file_success_params();
     29   if (!params)
     30     return -1;
     31 
     32   const size_t chunk_size = params->data.length();
     33 
     34   // Check for overflows.
     35   if (chunk_size > static_cast<size_t>(buffer_length) - buffer_offset)
     36     return -1;
     37 
     38   memcpy(buffer->data() + buffer_offset, params->data.c_str(), chunk_size);
     39 
     40   return chunk_size;
     41 }
     42 
     43 }  // namespace
     44 
     45 ReadFile::ReadFile(
     46     extensions::EventRouter* event_router,
     47     const ProvidedFileSystemInfo& file_system_info,
     48     int file_handle,
     49     scoped_refptr<net::IOBuffer> buffer,
     50     int64 offset,
     51     int length,
     52     const ProvidedFileSystemInterface::ReadChunkReceivedCallback& callback)
     53     : Operation(event_router, file_system_info),
     54       file_handle_(file_handle),
     55       buffer_(buffer),
     56       offset_(offset),
     57       length_(length),
     58       current_offset_(0),
     59       callback_(callback) {
     60 }
     61 
     62 ReadFile::~ReadFile() {
     63 }
     64 
     65 bool ReadFile::Execute(int request_id) {
     66   using extensions::api::file_system_provider::ReadFileRequestedOptions;
     67   TRACE_EVENT0("file_system_provider", "ReadFile::Execute");
     68 
     69   ReadFileRequestedOptions options;
     70   options.file_system_id = file_system_info_.file_system_id();
     71   options.request_id = request_id;
     72   options.open_request_id = file_handle_;
     73   options.offset = offset_;
     74   options.length = length_;
     75 
     76   return SendEvent(
     77       request_id,
     78       extensions::api::file_system_provider::OnReadFileRequested::kEventName,
     79       extensions::api::file_system_provider::OnReadFileRequested::Create(
     80           options));
     81 }
     82 
     83 void ReadFile::OnSuccess(int /* request_id */,
     84                          scoped_ptr<RequestValue> result,
     85                          bool has_more) {
     86   TRACE_EVENT0("file_system_provider", "ReadFile::OnSuccess");
     87   const int copy_result = CopyRequestValueToBuffer(
     88       result.Pass(), buffer_, current_offset_, length_);
     89 
     90   if (copy_result < 0) {
     91     LOG(ERROR) << "Failed to parse a response for the read file operation.";
     92     callback_.Run(
     93         0 /* chunk_length */, false /* has_more */, base::File::FILE_ERROR_IO);
     94     return;
     95   }
     96 
     97   if (copy_result > 0)
     98     current_offset_ += copy_result;
     99   callback_.Run(copy_result, has_more, base::File::FILE_OK);
    100 }
    101 
    102 void ReadFile::OnError(int /* request_id */,
    103                        scoped_ptr<RequestValue> /* result */,
    104                        base::File::Error error) {
    105   TRACE_EVENT0("file_system_provider", "ReadFile::OnError");
    106   callback_.Run(0 /* chunk_length */, false /* has_more */, error);
    107 }
    108 
    109 }  // namespace operations
    110 }  // namespace file_system_provider
    111 }  // namespace chromeos
    112