OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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/proxy/file_io_resource.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "ipc/ipc_message.h" | |
9 #include "ppapi/c/pp_errors.h" | |
10 #include "ppapi/proxy/ppapi_messages.h" | |
11 #include "ppapi/shared_impl/array_writer.h" | |
12 #include "ppapi/shared_impl/ppapi_globals.h" | |
13 #include "ppapi/shared_impl/resource_tracker.h" | |
14 #include "ppapi/thunk/enter.h" | |
15 #include "ppapi/thunk/ppb_file_ref_api.h" | |
16 | |
17 using ppapi::thunk::EnterResourceNoLock; | |
18 using ppapi::thunk::PPB_FileIO_API; | |
19 using ppapi::thunk::PPB_FileRef_API; | |
20 | |
21 namespace { | |
22 | |
23 // An adapter to let Read() share the same implementation with ReadToArray(). | |
24 void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { | |
25 return user_data; | |
26 } | |
27 | |
28 } // namespace | |
29 | |
30 namespace ppapi { | |
31 namespace proxy { | |
32 | |
33 FileIOResource::FileIOResource(Connection connection, PP_Instance instance) | |
34 : PluginResource(connection, instance), | |
35 PPB_FileIO_Shared() { | |
36 SendCreate(RENDERER, PpapiHostMsg_FileIO_Create()); | |
37 } | |
38 | |
39 FileIOResource::~FileIOResource() { | |
40 } | |
41 | |
42 PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { | |
43 return this; | |
44 } | |
45 | |
46 int32_t FileIOResource::Open(PP_Resource file_ref, | |
47 int32_t open_flags, | |
48 scoped_refptr<TrackedCallback> callback) { | |
49 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); | |
50 if (enter.failed()) | |
51 return PP_ERROR_BADRESOURCE; | |
52 | |
53 int32_t rv = CommonPreCondition(false, OPERATION_EXCLUSIVE); | |
54 if (rv != PP_OK) | |
55 return rv; | |
56 | |
57 CommonPostCondition(OPERATION_EXCLUSIVE); | |
58 return OpenValidated(enter.resource(), enter.object(), open_flags, callback); | |
raymes
2012/11/28 18:39:35
Again, please remove the "Validated" functions and
victorhsieh
2012/11/29 06:34:55
Done.
| |
59 } | |
60 | |
61 int32_t FileIOResource::Query(PP_FileInfo* info, | |
62 scoped_refptr<TrackedCallback> callback) { | |
63 int32_t rv = CommonPreCondition(true, OPERATION_EXCLUSIVE); | |
64 if (rv != PP_OK) | |
65 return rv; | |
66 | |
67 CommonPostCondition(OPERATION_EXCLUSIVE); | |
68 return QueryValidated(info, callback); | |
69 } | |
70 | |
71 int32_t FileIOResource::Touch(PP_Time last_access_time, | |
72 PP_Time last_modified_time, | |
73 scoped_refptr<TrackedCallback> callback) { | |
74 int32_t rv = CommonPreCondition(true, OPERATION_EXCLUSIVE); | |
75 if (rv != PP_OK) | |
76 return rv; | |
77 | |
78 CommonPostCondition(OPERATION_EXCLUSIVE); | |
79 return TouchValidated(last_access_time, last_modified_time, callback); | |
80 } | |
81 | |
82 int32_t FileIOResource::Read(int64_t offset, | |
83 char* buffer, | |
84 int32_t bytes_to_read, | |
85 scoped_refptr<TrackedCallback> callback) { | |
86 int32_t rv = CommonPreCondition(true, OPERATION_READ); | |
87 if (rv != PP_OK) | |
88 return rv; | |
89 | |
90 PP_ArrayOutput output_adapter; | |
91 output_adapter.GetDataBuffer = &DummyGetDataBuffer; | |
92 output_adapter.user_data = buffer; | |
93 CommonPostCondition(OPERATION_READ); | |
94 return ReadValidated(offset, bytes_to_read, output_adapter, callback); | |
95 } | |
96 | |
97 int32_t FileIOResource::ReadToArray(int64_t offset, | |
98 int32_t max_read_length, | |
99 PP_ArrayOutput* array_output, | |
100 scoped_refptr<TrackedCallback> callback) { | |
101 DCHECK(array_output); | |
102 int32_t rv = CommonPreCondition(true, OPERATION_READ); | |
103 if (rv != PP_OK) | |
104 return rv; | |
105 | |
106 CommonPostCondition(OPERATION_READ); | |
107 return ReadValidated(offset, max_read_length, *array_output, callback); | |
108 } | |
109 | |
110 int32_t FileIOResource::Write(int64_t offset, | |
111 const char* buffer, | |
112 int32_t bytes_to_write, | |
113 scoped_refptr<TrackedCallback> callback) { | |
114 int32_t rv = CommonPreCondition(true, OPERATION_WRITE); | |
115 if (rv != PP_OK) | |
116 return rv; | |
117 | |
118 CommonPostCondition(OPERATION_WRITE); | |
119 return WriteValidated(offset, buffer, bytes_to_write, callback); | |
120 } | |
121 | |
122 int32_t FileIOResource::SetLength(int64_t length, | |
123 scoped_refptr<TrackedCallback> callback) { | |
124 int32_t rv = CommonPreCondition(true, OPERATION_EXCLUSIVE); | |
125 if (rv != PP_OK) | |
126 return rv; | |
127 | |
128 CommonPostCondition(OPERATION_EXCLUSIVE); | |
129 return SetLengthValidated(length, callback); | |
130 } | |
131 | |
132 int32_t FileIOResource::Flush(scoped_refptr<TrackedCallback> callback) { | |
133 int32_t rv = CommonPreCondition(true, OPERATION_EXCLUSIVE); | |
134 if (rv != PP_OK) | |
135 return rv; | |
136 | |
137 CommonPostCondition(OPERATION_EXCLUSIVE); | |
138 return FlushValidated(callback); | |
139 } | |
140 | |
141 void FileIOResource::Close() { | |
142 Post(RENDERER, PpapiHostMsg_FileIO_Close()); | |
143 } | |
144 | |
145 int32_t FileIOResource::GetOSFileDescriptor() { | |
146 int32_t file_descriptor; | |
147 // Only available when running in process. | |
148 SyncCall<PpapiPluginMsg_FileIO_GetOSFileDescriptorReply>( | |
149 RENDERER, PpapiHostMsg_FileIO_GetOSFileDescriptor(), &file_descriptor); | |
150 return file_descriptor; | |
151 } | |
152 | |
153 int32_t FileIOResource::WillWrite(int64_t offset, | |
154 int32_t bytes_to_write, | |
155 scoped_refptr<TrackedCallback> callback) { | |
156 Call<PpapiPluginMsg_FileIO_GeneralComplete>(RENDERER, | |
157 PpapiHostMsg_FileIO_WillWrite(offset, bytes_to_write), | |
158 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | |
159 callback)); | |
160 SetOpInProgress(OPERATION_EXCLUSIVE); | |
161 return PP_OK_COMPLETIONPENDING; | |
162 } | |
163 | |
164 int32_t FileIOResource::WillSetLength(int64_t length, | |
165 scoped_refptr<TrackedCallback> callback) { | |
166 Call<PpapiPluginMsg_FileIO_GeneralComplete>(RENDERER, | |
167 PpapiHostMsg_FileIO_WillSetLength(length), | |
168 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | |
169 callback)); | |
170 SetOpInProgress(OPERATION_EXCLUSIVE); | |
171 return PP_OK_COMPLETIONPENDING; | |
172 } | |
173 | |
174 int32_t FileIOResource::OpenValidated(Resource* file_ref_resource, | |
175 PPB_FileRef_API* file_ref_api, | |
176 int32_t open_flags, | |
177 scoped_refptr<TrackedCallback> callback) { | |
178 Call<PpapiPluginMsg_FileIO_OpenFileComplete>(RENDERER, | |
179 PpapiHostMsg_FileIO_Open( | |
180 file_ref_resource->host_resource().host_resource(), | |
181 open_flags), | |
182 base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, | |
183 callback)); | |
184 return PP_OK_COMPLETIONPENDING; | |
185 } | |
186 | |
187 int32_t FileIOResource::QueryValidated( | |
188 PP_FileInfo* info, | |
189 scoped_refptr<TrackedCallback> callback) { | |
190 Call<PpapiPluginMsg_FileIO_QueryComplete>(RENDERER, | |
191 PpapiHostMsg_FileIO_Query(), | |
192 base::Bind(&FileIOResource::OnPluginMsgQueryComplete, this, | |
193 callback, info)); | |
194 return PP_OK_COMPLETIONPENDING; | |
195 } | |
196 | |
197 int32_t FileIOResource::TouchValidated( | |
198 PP_Time last_access_time, | |
199 PP_Time last_modified_time, | |
200 scoped_refptr<TrackedCallback> callback) { | |
201 Call<PpapiPluginMsg_FileIO_GeneralComplete>(RENDERER, | |
202 PpapiHostMsg_FileIO_Touch(last_access_time, last_modified_time), | |
203 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | |
204 callback)); | |
205 return PP_OK_COMPLETIONPENDING; | |
206 } | |
207 | |
208 int32_t FileIOResource::ReadValidated(int64_t offset, | |
209 int32_t bytes_to_read, | |
210 const PP_ArrayOutput& array_output, | |
211 scoped_refptr<TrackedCallback> callback) { | |
212 Call<PpapiPluginMsg_FileIO_ReadComplete>(RENDERER, | |
213 PpapiHostMsg_FileIO_Read(offset, bytes_to_read), | |
214 base::Bind(&FileIOResource::OnPluginMsgReadComplete, this, | |
215 callback, array_output)); | |
216 return PP_OK_COMPLETIONPENDING; | |
217 } | |
218 | |
219 int32_t FileIOResource::WriteValidated( | |
220 int64_t offset, | |
221 const char* buffer, | |
222 int32_t bytes_to_write, | |
223 scoped_refptr<TrackedCallback> callback) { | |
224 // TODO(brettw) it would be nice to use a shared memory buffer for large | |
225 // writes rather than having to copy to a string (which will involve a number | |
226 // of extra copies to serialize over IPC). | |
227 Call<PpapiPluginMsg_FileIO_GeneralComplete>(RENDERER, | |
228 PpapiHostMsg_FileIO_Write(offset, std::string(buffer, bytes_to_write)), | |
229 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | |
230 callback)); | |
231 return PP_OK_COMPLETIONPENDING; | |
232 } | |
233 | |
234 int32_t FileIOResource::SetLengthValidated( | |
235 int64_t length, | |
236 scoped_refptr<TrackedCallback> callback) { | |
237 Call<PpapiPluginMsg_FileIO_GeneralComplete>(RENDERER, | |
238 PpapiHostMsg_FileIO_SetLength(length), | |
239 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | |
240 callback)); | |
241 return PP_OK_COMPLETIONPENDING; | |
242 } | |
243 | |
244 int32_t FileIOResource::FlushValidated( | |
245 scoped_refptr<TrackedCallback> callback) { | |
246 Call<PpapiPluginMsg_FileIO_GeneralComplete>(RENDERER, | |
247 PpapiHostMsg_FileIO_Flush(), | |
248 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | |
249 callback)); | |
250 return PP_OK_COMPLETIONPENDING; | |
251 } | |
252 | |
253 void FileIOResource::OnPluginMsgGeneralComplete( | |
254 scoped_refptr<TrackedCallback> callback, | |
255 const ResourceMessageReplyParams& params) { | |
256 DCHECK(pending_op_ == OPERATION_EXCLUSIVE || | |
257 pending_op_ == OPERATION_WRITE); | |
258 callback->Run(params.result()); | |
259 SetOpFinished(); | |
260 } | |
261 | |
262 void FileIOResource::OnPluginMsgOpenFileComplete( | |
263 scoped_refptr<TrackedCallback> callback, | |
264 const ResourceMessageReplyParams& params) { | |
265 DCHECK(pending_op_ == OPERATION_EXCLUSIVE); | |
266 if (params.result() == PP_OK) | |
267 SetOpenSucceed(); | |
268 callback->Run(params.result()); | |
269 SetOpFinished(); | |
270 } | |
271 | |
272 void FileIOResource::OnPluginMsgQueryComplete( | |
273 scoped_refptr<TrackedCallback> callback, | |
274 PP_FileInfo* output_info, | |
275 const ResourceMessageReplyParams& params, | |
276 const PP_FileInfo& info) { | |
277 DCHECK(pending_op_ == OPERATION_EXCLUSIVE); | |
278 *output_info = info; | |
279 callback->Run(params.result()); | |
280 SetOpFinished(); | |
281 } | |
282 | |
283 void FileIOResource::OnPluginMsgReadComplete( | |
284 scoped_refptr<TrackedCallback> callback, | |
285 PP_ArrayOutput array_output, | |
286 const ResourceMessageReplyParams& params, | |
287 const std::string& data) { | |
288 DCHECK(pending_op_ == OPERATION_READ); | |
289 | |
290 // The result code should contain the data size if it's positive. | |
291 int32_t result = params.result(); | |
292 DCHECK((result < 0 && data.size() == 0) || | |
293 result == static_cast<int32_t>(data.size())); | |
294 | |
295 ArrayWriter output; | |
296 output.set_pp_array_output(array_output); | |
297 if (output.is_valid()) | |
298 output.StoreArray(data.data(), std::max(0, result)); | |
299 else | |
300 result = PP_ERROR_FAILED; | |
301 | |
302 callback->Run(result); | |
303 SetOpFinished(); | |
304 } | |
305 | |
306 } // namespace proxy | |
307 } // namespace ppapi | |
OLD | NEW |