file_io_resource.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Call<PpapiPluginMsg_FileIO_QueryReply>(RENDERER,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiHostMsg_FileIO_Query(),
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&FileIOResource::OnPluginMsgQueryComplete, this,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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) {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Call<PpapiPluginMsg_FileIO_ReadReply>(RENDERER,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiHostMsg_FileIO_Read(offset, bytes_to_read),
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&FileIOResource::OnPluginMsgReadComplete, this,
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 callback, array_output));
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgGeneralComplete(
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<TrackedCallback> callback,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ResourceMessageReplyParams& params) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state_manager_.get_pending_operation() ==
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         FileIOStateManager::OPERATION_EXCLUSIVE ||
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         state_manager_.get_pending_operation() ==
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         FileIOStateManager::OPERATION_WRITE);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // End the operation now. The callback may perform another file operation.
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_manager_.SetOperationFinished();
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback->Run(params.result());
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgOpenFileComplete(
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<TrackedCallback> callback,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ResourceMessageReplyParams& params) {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state_manager_.get_pending_operation() ==
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         FileIOStateManager::OPERATION_EXCLUSIVE);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params.result() == PP_OK)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state_manager_.SetOpenSucceed();
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // End the operation now. The callback may perform another file operation.
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_manager_.SetOperationFinished();
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback->Run(params.result());
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgQueryComplete(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<TrackedCallback> callback,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_FileInfo* output_info,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ResourceMessageReplyParams& params,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_FileInfo& info) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state_manager_.get_pending_operation() ==
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         FileIOStateManager::OPERATION_EXCLUSIVE);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *output_info = info;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // End the operation now. The callback may perform another file operation.
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_manager_.SetOperationFinished();
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback->Run(params.result());
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgReadComplete(
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<TrackedCallback> callback,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_ArrayOutput array_output,
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ResourceMessageReplyParams& params,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& data) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state_manager_.get_pending_operation() ==
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         FileIOStateManager::OPERATION_READ);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The result code should contain the data size if it's positive.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32_t result = params.result();
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK((result < 0 && data.size() == 0) ||
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         result == static_cast<int32_t>(data.size()));
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ArrayWriter output;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output.set_pp_array_output(array_output);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (output.is_valid())
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output.StoreArray(data.data(), std::max(0, result));
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result = PP_ERROR_FAILED;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // End the operation now. The callback may perform another file operation.
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_manager_.SetOperationFinished();
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback->Run(result);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace proxy
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ppapi
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292