file_io_resource.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/file_io_resource.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/array_writer.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/enter.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/ppb_file_ref_api.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::EnterResourceNoLock; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::PPB_FileIO_API; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::PPB_FileRef_API; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An adapter to let Read() share the same implementation with ReadToArray(). 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return user_data; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace proxy { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileIOResource::FileIOResource(Connection connection, PP_Instance instance) 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : PluginResource(connection, instance) { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendCreate(RENDERER, PpapiHostMsg_FileIO_Create()); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileIOResource::~FileIOResource() { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Open(PP_Resource file_ref, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t open_flags, 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (enter.failed()) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_ERROR_BADRESOURCE; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, false); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_OpenReply>(RENDERER, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Open( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enter.resource()->host_resource().host_resource(), 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open_flags), 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Query(PP_FileInfo* info, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_QueryReply>(RENDERER, 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PpapiHostMsg_FileIO_Query(), 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgQueryComplete, this, 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback, info)); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Touch(PP_Time last_access_time, 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Time last_modified_time, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Touch(last_access_time, last_modified_time), 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Read(int64_t offset, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* buffer, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_read, 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_READ, true); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_ArrayOutput output_adapter; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_adapter.GetDataBuffer = &DummyGetDataBuffer; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_adapter.user_data = buffer; 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ReadValidated(offset, bytes_to_read, output_adapter, callback); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::ReadToArray(int64_t offset, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t max_read_length, 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_ArrayOutput* array_output, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(array_output); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_READ, true); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ReadValidated(offset, max_read_length, *array_output, callback); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Write(int64_t offset, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* buffer, 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_write, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_WRITE, true); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(brettw) it would be nice to use a shared memory buffer for large 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // writes rather than having to copy to a string (which will involve a number 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of extra copies to serialize over IPC). 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Write(offset, std::string(buffer, bytes_to_write)), 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::SetLength(int64_t length, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_SetLength(length), 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Flush(scoped_refptr<TrackedCallback> callback) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Flush(), 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::Close() { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Post(RENDERER, PpapiHostMsg_FileIO_Close()); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::GetOSFileDescriptor() { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t file_descriptor; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only available when running in process. 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncCall<PpapiPluginMsg_FileIO_GetOSFileDescriptorReply>( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RENDERER, PpapiHostMsg_FileIO_GetOSFileDescriptor(), &file_descriptor); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return file_descriptor; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::WillWrite(int64_t offset, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_write, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_WillWrite(offset, bytes_to_write), 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::WillSetLength(int64_t length, 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_WillSetLength(length), 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::ReadValidated(int64_t offset, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_read, 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PP_ArrayOutput& array_output, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_ReadReply>(RENDERER, 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PpapiHostMsg_FileIO_Read(offset, bytes_to_read), 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgReadComplete, this, 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback, array_output)); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int32_t FileIOResource::RequestOSFileHandle( 228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PP_FileHandle* handle, 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (rv != PP_OK) 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return rv; 234fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_RequestOSFileHandleReply>(RENDERER, 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PpapiHostMsg_FileIO_RequestOSFileHandle(), 237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgRequestOSFileHandleComplete, this, 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback, handle)); 239fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgGeneralComplete( 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ResourceMessageReplyParams& params) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE || 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.get_pending_operation() == 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_WRITE); 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // End the operation now. The callback may perform another file operation. 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetOperationFinished(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback->Run(params.result()); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgOpenFileComplete( 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ResourceMessageReplyParams& params) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.result() == PP_OK) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetOpenSucceed(); 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // End the operation now. The callback may perform another file operation. 264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) state_manager_.SetOperationFinished(); 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback->Run(params.result()); 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void FileIOResource::OnPluginMsgQueryComplete( 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TrackedCallback> callback, 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PP_FileInfo* output_info, 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ResourceMessageReplyParams& params, 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const PP_FileInfo& info) { 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE); 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *output_info = info; 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // End the operation now. The callback may perform another file operation. 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) state_manager_.SetOperationFinished(); 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback->Run(params.result()); 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void FileIOResource::OnPluginMsgReadComplete( 282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TrackedCallback> callback, 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PP_ArrayOutput array_output, 284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ResourceMessageReplyParams& params, 285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& data) { 286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FileIOStateManager::OPERATION_READ); 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The result code should contain the data size if it's positive. 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t result = params.result(); 291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK((result < 0 && data.size() == 0) || 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) result == static_cast<int32_t>(data.size())); 293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ArrayWriter output; 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) output.set_pp_array_output(array_output); 296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (output.is_valid()) 297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) output.StoreArray(data.data(), std::max(0, result)); 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = PP_ERROR_FAILED; 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // End the operation now. The callback may perform another file operation. 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetOperationFinished(); 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback->Run(result); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FileIOResource::OnPluginMsgRequestOSFileHandleComplete( 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<TrackedCallback> callback, 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_FileHandle* output_handle, 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceMessageReplyParams& params) { 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!TrackedCallback::IsPending(callback)) { 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_manager_.SetOperationFinished(); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32_t result = params.result(); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC::PlatformFileForTransit transit_file; 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!params.TakeFileHandleAtIndex(0, &transit_file)) 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result = PP_ERROR_FAILED; 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *output_handle = IPC::PlatformFileForTransitToPlatformFile(transit_file); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // End the operation now. The callback may perform another file operation. 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_manager_.SetOperationFinished(); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback->Run(result); 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace proxy 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace ppapi 331