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