Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(530)

Unified Diff: ppapi/shared_impl/file_io_impl.cc

Issue 8764003: Implement a proxy for Pepper FileIO. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ppapi/shared_impl/file_io_impl.cc
diff --git a/ppapi/shared_impl/file_io_impl.cc b/ppapi/shared_impl/file_io_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..075349ce3b8428070ffb2b80de869de28aef8f58
--- /dev/null
+++ b/ppapi/shared_impl/file_io_impl.cc
@@ -0,0 +1,232 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/file_io_impl.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/shared_impl/file_type_conversion.h"
+#include "ppapi/shared_impl/time_conversion.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_file_ref_api.h"
+
+namespace ppapi {
+
+using thunk::EnterResourceNoLock;
+using thunk::PPB_FileIO_API;
+using thunk::PPB_FileRef_API;
+
+FileIOImpl::CallbackEntry::CallbackEntry()
+ : read_buffer(NULL),
+ info(NULL) {
+}
+
+FileIOImpl::CallbackEntry::CallbackEntry(const CallbackEntry& entry)
+ : callback(entry.callback),
+ read_buffer(entry.read_buffer),
+ info(entry.info) {
+}
+
+FileIOImpl::CallbackEntry::~CallbackEntry() {
+}
+
+FileIOImpl::FileIOImpl(PP_Instance instance)
+ : Resource(instance),
+ file_system_type_(PP_FILESYSTEMTYPE_INVALID),
+ file_open_(false),
+ pending_op_(OPERATION_NONE) {
+}
+
+FileIOImpl::FileIOImpl(const HostResource& host_resource)
+ : Resource(host_resource),
+ file_system_type_(PP_FILESYSTEMTYPE_INVALID),
+ file_open_(false),
+ pending_op_(OPERATION_NONE) {
+}
+
+FileIOImpl::~FileIOImpl() {
+ // The callbacks list should have been cleared by LastPluginRefWasDeleted.
+ DCHECK(callbacks_.empty());
+}
+
+void FileIOImpl::LastPluginRefWasDeleted() {
+ // Abort all pending callbacks. Do this by posting a task to avoid reentering
+ // the plugin's Release() call that probably deleted this object.
+ for (size_t i = 0; i < callbacks_.size(); i++) {
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ callbacks_[i].callback.func, callbacks_[i].callback.user_data,
+ static_cast<int32_t>(PP_ERROR_ABORTED)));
+ }
+ callbacks_.erase(callbacks_.begin(), callbacks_.end());
+}
+
+thunk::PPB_FileIO_API* FileIOImpl::AsPPB_FileIO_API() {
+ return this;
+}
+
+int32_t FileIOImpl::Open(PP_Resource file_ref,
+ int32_t open_flags,
+ PP_CompletionCallback callback) {
+ EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+
+ int32_t rv = CommonCallValidation(false, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ PP_FileSystemType type = enter.object()->GetFileSystemType();
+ if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
+ type != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
+ type != PP_FILESYSTEMTYPE_EXTERNAL)
+ return PP_ERROR_FAILED;
+ file_system_type_ = type;
+
+ return OpenValidated(file_ref, enter.object(), open_flags, callback);
+}
+
+int32_t FileIOImpl::Query(PP_FileInfo* info, PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+ if (!info)
+ return PP_ERROR_BADARGUMENT;
+ return QueryValidated(info, callback);
+}
+
+int32_t FileIOImpl::Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+ return TouchValidated(last_access_time, last_modified_time, callback);
+}
+
+int32_t FileIOImpl::Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_READ, callback);
+ if (rv != PP_OK)
+ return rv;
+ return ReadValidated(offset, buffer, bytes_to_read, callback);
+}
+
+int32_t FileIOImpl::Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_WRITE, callback);
+ if (rv != PP_OK)
+ return rv;
+ return WriteValidated(offset, buffer, bytes_to_write, callback);
+}
+
+int32_t FileIOImpl::SetLength(int64_t length,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+ return SetLengthValidated(length, callback);
+}
+
+int32_t FileIOImpl::Flush(PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+ return FlushValidated(callback);
+}
+
+void FileIOImpl::ExecuteGeneralCallback(int32_t pp_error) {
+ RunAndRemoveFirstPendingCallback(pp_error);
+}
+
+void FileIOImpl::ExecuteOpenFileCallback(int32_t pp_error) {
+ if (pp_error == PP_OK)
+ file_open_ = true;
+ ExecuteGeneralCallback(pp_error);
+}
+
+void FileIOImpl::ExecuteQueryCallback(int32_t pp_error,
+ const PP_FileInfo& info) {
+ if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty() ||
+ !callbacks_.front().info) {
+ NOTREACHED();
+ return;
+ }
+ *callbacks_.front().info = info;
+ RunAndRemoveFirstPendingCallback(pp_error);
+}
+
+void FileIOImpl::ExecuteReadCallback(int32_t pp_error, const char* data) {
+ if (pending_op_ != OPERATION_READ || callbacks_.empty()) {
+ NOTREACHED();
+ return;
+ }
+
+ char* read_buffer = callbacks_.front().read_buffer;
+ DCHECK(data);
+ DCHECK(read_buffer);
+
+ // The result code contains the number of bytes if it's positive.
+ if (pp_error > 0)
+ memcpy(read_buffer, data, pp_error);
viettrungluu 2011/11/30 23:44:42 include string.h
+ RunAndRemoveFirstPendingCallback(pp_error);
viettrungluu 2011/11/30 23:44:42 How do you know you're running the right callback?
brettw 2011/12/01 18:50:15 I don't know. The existing backend worked like thi
yzshen1 2011/12/01 19:01:51 When I wrote this method, I went over the logic to
+}
+
+int32_t FileIOImpl::CommonCallValidation(bool should_be_open,
+ OperationType new_op,
+ PP_CompletionCallback callback) {
+ // Only asynchronous operation is supported.
+ if (!callback.func)
+ return PP_ERROR_BLOCKS_MAIN_THREAD;
+
+ if (should_be_open) {
+ if (!file_open_)
+ return PP_ERROR_FAILED;
+ } else {
+ if (file_open_)
+ return PP_ERROR_FAILED;
+ }
+
+ if (pending_op_ != OPERATION_NONE &&
+ (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE)) {
+ return PP_ERROR_INPROGRESS;
+ }
+
+ return PP_OK;
+}
+
+void FileIOImpl::RegisterCallback(OperationType op,
+ PP_CompletionCallback callback,
+ char* read_buffer,
+ PP_FileInfo* info) {
+ DCHECK(callback.func);
+ DCHECK(pending_op_ == OPERATION_NONE ||
+ (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == op));
+
+ CallbackEntry entry;
+ entry.callback = callback;
+ entry.read_buffer = read_buffer;
+ entry.info = info;
+ callbacks_.push_back(entry);
+
+ pending_op_ = op;
+}
+
+void FileIOImpl::RunAndRemoveFirstPendingCallback(int32_t result) {
+ DCHECK(!callbacks_.empty());
+
+ CallbackEntry front = callbacks_.front();
+ callbacks_.pop_front();
+ if (callbacks_.empty())
+ pending_op_ = OPERATION_NONE;
+
+ PP_RunCompletionCallback(&front.callback, result);
+}
+
+} // namespace ppapi

Powered by Google App Engine
This is Rietveld 408576698