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