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

Side by Side 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 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ppapi/shared_impl/file_io_impl.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/shared_impl/file_type_conversion.h"
12 #include "ppapi/shared_impl/time_conversion.h"
13 #include "ppapi/thunk/enter.h"
14 #include "ppapi/thunk/ppb_file_ref_api.h"
15
16 namespace ppapi {
17
18 using thunk::EnterResourceNoLock;
19 using thunk::PPB_FileIO_API;
20 using thunk::PPB_FileRef_API;
21
22 FileIOImpl::CallbackEntry::CallbackEntry()
23 : read_buffer(NULL),
24 info(NULL) {
25 }
26
27 FileIOImpl::CallbackEntry::CallbackEntry(const CallbackEntry& entry)
28 : callback(entry.callback),
29 read_buffer(entry.read_buffer),
30 info(entry.info) {
31 }
32
33 FileIOImpl::CallbackEntry::~CallbackEntry() {
34 }
35
36 FileIOImpl::FileIOImpl(PP_Instance instance)
37 : Resource(instance),
38 file_system_type_(PP_FILESYSTEMTYPE_INVALID),
39 file_open_(false),
40 pending_op_(OPERATION_NONE) {
41 }
42
43 FileIOImpl::FileIOImpl(const HostResource& host_resource)
44 : Resource(host_resource),
45 file_system_type_(PP_FILESYSTEMTYPE_INVALID),
46 file_open_(false),
47 pending_op_(OPERATION_NONE) {
48 }
49
50 FileIOImpl::~FileIOImpl() {
51 // The callbacks list should have been cleared by LastPluginRefWasDeleted.
52 DCHECK(callbacks_.empty());
53 }
54
55 void FileIOImpl::LastPluginRefWasDeleted() {
56 // Abort all pending callbacks. Do this by posting a task to avoid reentering
57 // the plugin's Release() call that probably deleted this object.
58 for (size_t i = 0; i < callbacks_.size(); i++) {
59 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
60 callbacks_[i].callback.func, callbacks_[i].callback.user_data,
61 static_cast<int32_t>(PP_ERROR_ABORTED)));
62 }
63 callbacks_.erase(callbacks_.begin(), callbacks_.end());
64 }
65
66 thunk::PPB_FileIO_API* FileIOImpl::AsPPB_FileIO_API() {
67 return this;
68 }
69
70 int32_t FileIOImpl::Open(PP_Resource file_ref,
71 int32_t open_flags,
72 PP_CompletionCallback callback) {
73 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true);
74 if (enter.failed())
75 return PP_ERROR_BADRESOURCE;
76
77 int32_t rv = CommonCallValidation(false, OPERATION_EXCLUSIVE, callback);
78 if (rv != PP_OK)
79 return rv;
80
81 PP_FileSystemType type = enter.object()->GetFileSystemType();
82 if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
83 type != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
84 type != PP_FILESYSTEMTYPE_EXTERNAL)
85 return PP_ERROR_FAILED;
86 file_system_type_ = type;
87
88 return OpenValidated(file_ref, enter.object(), open_flags, callback);
89 }
90
91 int32_t FileIOImpl::Query(PP_FileInfo* info, PP_CompletionCallback callback) {
92 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
93 if (rv != PP_OK)
94 return rv;
95 if (!info)
96 return PP_ERROR_BADARGUMENT;
97 return QueryValidated(info, callback);
98 }
99
100 int32_t FileIOImpl::Touch(PP_Time last_access_time,
101 PP_Time last_modified_time,
102 PP_CompletionCallback callback) {
103 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
104 if (rv != PP_OK)
105 return rv;
106 return TouchValidated(last_access_time, last_modified_time, callback);
107 }
108
109 int32_t FileIOImpl::Read(int64_t offset,
110 char* buffer,
111 int32_t bytes_to_read,
112 PP_CompletionCallback callback) {
113 int32_t rv = CommonCallValidation(true, OPERATION_READ, callback);
114 if (rv != PP_OK)
115 return rv;
116 return ReadValidated(offset, buffer, bytes_to_read, callback);
117 }
118
119 int32_t FileIOImpl::Write(int64_t offset,
120 const char* buffer,
121 int32_t bytes_to_write,
122 PP_CompletionCallback callback) {
123 int32_t rv = CommonCallValidation(true, OPERATION_WRITE, callback);
124 if (rv != PP_OK)
125 return rv;
126 return WriteValidated(offset, buffer, bytes_to_write, callback);
127 }
128
129 int32_t FileIOImpl::SetLength(int64_t length,
130 PP_CompletionCallback callback) {
131 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
132 if (rv != PP_OK)
133 return rv;
134 return SetLengthValidated(length, callback);
135 }
136
137 int32_t FileIOImpl::Flush(PP_CompletionCallback callback) {
138 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
139 if (rv != PP_OK)
140 return rv;
141 return FlushValidated(callback);
142 }
143
144 void FileIOImpl::ExecuteGeneralCallback(int32_t pp_error) {
145 RunAndRemoveFirstPendingCallback(pp_error);
146 }
147
148 void FileIOImpl::ExecuteOpenFileCallback(int32_t pp_error) {
149 if (pp_error == PP_OK)
150 file_open_ = true;
151 ExecuteGeneralCallback(pp_error);
152 }
153
154 void FileIOImpl::ExecuteQueryCallback(int32_t pp_error,
155 const PP_FileInfo& info) {
156 if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty() ||
157 !callbacks_.front().info) {
158 NOTREACHED();
159 return;
160 }
161 *callbacks_.front().info = info;
162 RunAndRemoveFirstPendingCallback(pp_error);
163 }
164
165 void FileIOImpl::ExecuteReadCallback(int32_t pp_error, const char* data) {
166 if (pending_op_ != OPERATION_READ || callbacks_.empty()) {
167 NOTREACHED();
168 return;
169 }
170
171 char* read_buffer = callbacks_.front().read_buffer;
172 DCHECK(data);
173 DCHECK(read_buffer);
174
175 // The result code contains the number of bytes if it's positive.
176 if (pp_error > 0)
177 memcpy(read_buffer, data, pp_error);
viettrungluu 2011/11/30 23:44:42 include string.h
178 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
179 }
180
181 int32_t FileIOImpl::CommonCallValidation(bool should_be_open,
182 OperationType new_op,
183 PP_CompletionCallback callback) {
184 // Only asynchronous operation is supported.
185 if (!callback.func)
186 return PP_ERROR_BLOCKS_MAIN_THREAD;
187
188 if (should_be_open) {
189 if (!file_open_)
190 return PP_ERROR_FAILED;
191 } else {
192 if (file_open_)
193 return PP_ERROR_FAILED;
194 }
195
196 if (pending_op_ != OPERATION_NONE &&
197 (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE)) {
198 return PP_ERROR_INPROGRESS;
199 }
200
201 return PP_OK;
202 }
203
204 void FileIOImpl::RegisterCallback(OperationType op,
205 PP_CompletionCallback callback,
206 char* read_buffer,
207 PP_FileInfo* info) {
208 DCHECK(callback.func);
209 DCHECK(pending_op_ == OPERATION_NONE ||
210 (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == op));
211
212 CallbackEntry entry;
213 entry.callback = callback;
214 entry.read_buffer = read_buffer;
215 entry.info = info;
216 callbacks_.push_back(entry);
217
218 pending_op_ = op;
219 }
220
221 void FileIOImpl::RunAndRemoveFirstPendingCallback(int32_t result) {
222 DCHECK(!callbacks_.empty());
223
224 CallbackEntry front = callbacks_.front();
225 callbacks_.pop_front();
226 if (callbacks_.empty())
227 pending_op_ = OPERATION_NONE;
228
229 PP_RunCompletionCallback(&front.callback, result);
230 }
231
232 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698