1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/operations/read_file.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <limits>
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string>
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/debug/trace_event.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/api/file_system_provider.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/api/file_system_provider_internal.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chromeos {
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace file_system_provider {
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace operations {
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Convert |value| into |output|. If parsing fails, then returns a negative
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// value. Otherwise returns number of bytes written to the buffer.
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int CopyRequestValueToBuffer(scoped_ptr<RequestValue> value,
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             scoped_refptr<net::IOBuffer> buffer,
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int buffer_offset,
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int buffer_length) {
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  using extensions::api::file_system_provider_internal::
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ReadFileRequestedSuccess::Params;
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Params* params = value->read_file_success_params();
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!params)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return -1;
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const size_t chunk_size = params->data.length();
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check for overflows.
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (chunk_size > static_cast<size_t>(buffer_length) - buffer_offset)
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return -1;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  memcpy(buffer->data() + buffer_offset, params->data.c_str(), chunk_size);
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return chunk_size;
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ReadFile::ReadFile(
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    extensions::EventRouter* event_router,
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ProvidedFileSystemInfo& file_system_info,
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int file_handle,
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer,
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int64 offset,
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int length,
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ProvidedFileSystemInterface::ReadChunkReceivedCallback& callback)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : Operation(event_router, file_system_info),
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      file_handle_(file_handle),
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      buffer_(buffer),
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      offset_(offset),
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      length_(length),
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_offset_(0),
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      callback_(callback) {
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ReadFile::~ReadFile() {
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ReadFile::Execute(int request_id) {
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_system_provider::ReadFileRequestedOptions;
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TRACE_EVENT0("file_system_provider", "ReadFile::Execute");
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ReadFileRequestedOptions options;
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  options.file_system_id = file_system_info_.file_system_id();
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  options.request_id = request_id;
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  options.open_request_id = file_handle_;
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  options.offset = offset_;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  options.length = length_;
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return SendEvent(
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request_id,
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      extensions::api::file_system_provider::OnReadFileRequested::kEventName,
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extensions::api::file_system_provider::OnReadFileRequested::Create(
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          options));
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ReadFile::OnSuccess(int /* request_id */,
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         scoped_ptr<RequestValue> result,
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         bool has_more) {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TRACE_EVENT0("file_system_provider", "ReadFile::OnSuccess");
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int copy_result = CopyRequestValueToBuffer(
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      result.Pass(), buffer_, current_offset_, length_);
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (copy_result < 0) {
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(ERROR) << "Failed to parse a response for the read file operation.";
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback_.Run(
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        0 /* chunk_length */, false /* has_more */, base::File::FILE_ERROR_IO);
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (copy_result > 0)
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    current_offset_ += copy_result;
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  callback_.Run(copy_result, has_more, base::File::FILE_OK);
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ReadFile::OnError(int /* request_id */,
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       scoped_ptr<RequestValue> /* result */,
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       base::File::Error error) {
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TRACE_EVENT0("file_system_provider", "ReadFile::OnError");
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  callback_.Run(0 /* chunk_length */, false /* has_more */, error);
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace operations
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace file_system_provider
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chromeos
112