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

Side by Side Diff: ppapi/examples/filesystem_provider/filesystem.cc

Issue 1093383002: [WIP] Provided file system from NACL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Various cleanups Created 5 years, 6 months 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
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 <algorithm>
6 #include <chrono>
7 #include <deque>
8 #include <map>
9 #include <set>
10 #include <sstream>
11 #include <string.h>
12
13 #include "memfilesystem.h"
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/cpp/dev/filesystem_provider.h"
16 #include "ppapi/cpp/instance.h"
17 #include "ppapi/cpp/module.h"
18 #include "ppapi/cpp/var.h"
19 #include "ppapi/utility/completion_callback_factory.h"
20 #include "ppapi/cpp/input_event.h"
21
22 namespace {
23 template<class T>
24 class FilesystemHelper {
25 public:
26 FilesystemHelper()
27 : callback_fact_(this) {
28 Init();
29 }
30 virtual ~FilesystemHelper(){}
31 virtual void OnUnmountRequest(int32_t request_id)=0;
32 virtual void OnMetadataRequest(
33 const std::string& file_path, bool thumbnail, int32_t request_id)=0;
34 virtual void OnReadDirectoryRequest(
35 const std::string& directory_path, int32_t request_id)=0;
36 virtual void OnOpenFileRequest(
37 const std::string& file_path, const PP_OpenFileMode_Dev& file_mode,
38 int32_t request_id)=0;
39 virtual void OnCloseFileRequest(
40 int32_t request_id, int32_t open_request_id)=0;
41 virtual void OnReadFileRequest(
42 int32_t open_request_id,
43 uint64_t offset,
44 uint64_t length,
45 int32_t request_id)=0;
46 virtual void OnCreateDirectoryRequest(
47 const std::string& directory_path,
48 bool recursive, int32_t request_id)=0;
49 virtual void OnDeleteEntryRequest(
50 const std::string& file_entry, bool recursive, int32_t request_id)=0;
51 virtual void OnCreateFileRequest(
52 const std::string& file_path, int32_t request_id)=0;
53 virtual void OnCopyEntryRequest(
54 const std::string& source_path,
55 const std::string& target_path,
56 int32_t request_id)=0;
57 virtual void OnMoveEntryRequest(
58 const std::string& source_path,
59 const std::string& target_path, int32_t request_id)=0;
60 virtual void OnTruncateRequest(
61 const std::string& file_path, int32_t offset, int32_t request_id)=0;
62 virtual void OnWriteRequest(int32_t, uint64_t, uint64_t,
63 const char*, int32_t)=0;
64 virtual void OnAbortRequest(int32_t request_id, int32_t open_request_id)=0;
65 private:
66 bool Init(){
67 static_cast<T*>(this)->GetNextRequest(
68 callback_fact_.NewCallbackWithOutput(
69 &FilesystemHelper::OnRequestReceived));
70 return true;
71 }
72 // Dispatcher
73 void OnRequestReceived(int32_t result, PP_FilesystemRequest request){
74 if (result==PP_OK) {
75 switch (request.operation_type) {
76 case PP_OperationType_UNMOUNT:
77 static_cast<T*>(this)->OnUnmountRequest(request.request_id);
78 break;
79 case PP_OperationType_GETMETADATA:
80 static_cast<T*>(this)->OnMetadataRequest(
81 request.value.as_metadata.entry_path,
82 request.value.as_metadata.thumbnail,
83 request.request_id);
84 break;
85 case PP_OperationType_READDIRECTORY:
86 static_cast<T*>(this)->OnReadDirectoryRequest(
87 request.value.as_read_directory.directory_path,
88 request.request_id);
89 break;
90 case PP_OperationType_OPENFILE:
91 static_cast<T*>(this)->OnOpenFileRequest(
92 request.value.as_open_file.file_path,
93 request.value.as_open_file.mode, request.request_id);
94 break;
95 case PP_OperationType_CLOSEFILE:
96 static_cast<T*>(this)->OnCloseFileRequest(
97 request.value.as_close_file.open_request_id,
98 request.request_id);
99 break;
100 case PP_OperationType_READFILE:
101 static_cast<T*>(this)->OnReadFileRequest(
102 request.value.as_read_file.open_request_id,
103 request.value.as_read_file.offset,
104 request.value.as_read_file.length,
105 request.request_id);
106 break;
107 case PP_OperationType_CREATEDIRECTORY:
108 static_cast<T*>(this)->OnCreateDirectoryRequest(
109 request.value.as_create_directory.directory_path,
110 request.value.as_create_directory.recursive,
111 request.request_id);
112 break;
113 case PP_OperationType_DELETEENTRY:
114 static_cast<T*>(this)->OnDeleteEntryRequest(
115 request.value.as_delete_entry.entry_path,
116 request.value.as_delete_entry.recursive,request.request_id);
117 break;
118 case PP_OperationType_CREATEFILE:
119 static_cast<T*>(this)->OnCreateFileRequest(
120 request.value.as_create_file.file_path, request.request_id);
121 break;
122 case PP_OperationType_COPYENTRY:
123 static_cast<T*>(this)->OnCopyEntryRequest(
124 request.value.as_copy_entry.source_path,
125 request.value.as_copy_entry.target_path,
126 request.request_id);
127 break;
128 case PP_OperationType_MOVEENTRY:
129 static_cast<T*>(this)->OnMoveEntryRequest(
130 request.value.as_move_entry.source_path,
131 request.value.as_move_entry.target_path,
132 request.request_id);
133 break;
134 case PP_OperationType_TRUNCATEENTRY:
135 static_cast<T*>(this)->OnTruncateRequest(
136 request.value.as_truncate.file_path,
137 request.value.as_truncate.length,
138 request.request_id);
139 break;
140 case PP_OperationType_WRITEFILE:
141 static_cast<T*>(this)->OnWriteRequest(
142 request.value.as_write_file.open_request_id,
143 request.value.as_write_file.offset,
144 request.value.as_write_file.data_size,
145 (char*)request.value.as_write_file.data,
146 request.request_id);
147 break;
148 case PP_OperationType_ABORT:
149 static_cast<T*>(this)->OnAbortRequest(
150 request.value.as_abort.operation_request_id,
151 request.request_id);
152 break;
153 default:
154 break;
155 }
156 }
157 // Re-register the callback
158 static_cast<T*>(this)->GetNextRequest(
159 callback_fact_.NewCallbackWithOutput(
160 &FilesystemHelper::OnRequestReceived));
161 }
162 private:
163 pp::CompletionCallbackFactory< FilesystemHelper<T> > callback_fact_;
164 };
165 }// namespace
166 class MyInstance :
167 public pp::Instance,
168 public pp::Filesystem_Provider_Dev,
169 public FilesystemHelper<MyInstance> {
170 public:
171 MyInstance(PP_Instance instance)
172 :pp::Instance(instance),
173 Filesystem_Provider_Dev(this),
174 callback_factory_(this),
175 filesystem_id_("in-memory-fs"),
176 display_name_("Test-Filesystem"),
177 mounted_(false) {
178 Initialize();
179 }
180
181 virtual ~MyInstance() {
182 }
183
184 void Initialize() {
185 Mount(filesystem_id_, display_name_, true, 0,
186 callback_factory_.NewCallbackWithOutput(
187 &MyInstance::OnMountCompletion));
188 }
189 void OnMountCompletion(int32_t result, PP_ProviderError_Dev error ) {
190 if ( result!=PP_OK ||
191 error!=PP_ProviderError_OK) {
192 return;
193 }
194 mounted_ = true;
195 }
196
197 // Filesystem_Provider_Dev interfaces
198 void OnUnmountRequest(int32_t request_id) {
199 // close connections, clean caches
200 SendSuccessResponse(PP_OperationType_UNMOUNT,request_id);
201 }
202
203 void OnMetadataRequest(
204 const std::string &entry_path,
205 bool thumbnail, int32_t request_id) {
206
207 filesystem::Filesystem::NameInodePair meta;
208 if( filesystem_.GetMetadata(entry_path,meta)==
209 filesystem::Filesystem::File_System_Error_NOT_FOUND ) {
210 SendErrorResponse(
211 PP_OperationType_GETMETADATA,
212 PP_ProviderError_NOT_FOUND,
213 request_id );
214 } else {
215 PP_EntryMetadata_Dev metadata;
216 memset(&metadata, 0x0, sizeof(metadata));
217 metadata.is_directory = PP_FromBool(meta.second->file_type()==
218 filesystem::Inode::FILE_TYPE_DIR);
219 // Should check result
220 snprintf(metadata.name,
221 sizeof(metadata.name),
222 "%s", meta.first.c_str());
223 snprintf( metadata.modification_time,
224 sizeof(metadata.modification_time),
225 "%s",meta.second->file_modified().c_str());
226 metadata.size = meta.second->size();
227 SendMetadataSuccessResponse(metadata,request_id);
228 }
229 }
230
231 void OnReadDirectoryRequest(
232 const std::string &directory_path,
233 int32_t request_id) {
234 std::vector<filesystem::Filesystem::NameInodePair> metas;
235
236 if ( filesystem_.ReadDirectory(directory_path,metas)==
237 filesystem::Filesystem::File_System_Error_NONE ) {
238 std::vector<PP_EntryMetadata_Dev> metadatas;
239 PP_EntryMetadata_Dev metadata;
240 for(std::vector<filesystem::Filesystem::NameInodePair>::iterator
241 it = metas.begin();
242 it != metas.end();
243 ++it)
244 {
245 memset(&metadata, 0x0, sizeof(metadata));
246 metadata.is_directory = PP_FromBool(it->second->file_type()==
247 filesystem::Inode::FILE_TYPE_DIR);
248 snprintf(metadata.name,
249 sizeof(metadata.name),
250 "%s", it->first.c_str());
251 snprintf( metadata.modification_time,
252 sizeof(metadata.modification_time),
253 "%s",it->second->file_modified().c_str());
254 metadata.size = it->second->size();
255 metadatas.push_back(metadata);
256 }
257 SendReadDirectorySuccessResponse(metadatas,false, request_id);
258 } else {
259 SendErrorResponse(
260 PP_OperationType_READDIRECTORY,
261 PP_ProviderError_FAILED, request_id );
262 }
263 }
264 void OnOpenFileRequest(
265 const std::string &file_path,
266 const PP_OpenFileMode_Dev &mode,
267 int32_t request_id) {
268 filesystem::Filesystem::NameInodePair meta;
269 if (filesystem_.GetMetadata(file_path,meta)==
270 filesystem::Filesystem::File_System_Error_NONE) {
271 opened_files_.insert( std::pair<int,std::string>(request_id, file_path));
272 SendSuccessResponse(
273 PP_OperationType_OPENFILE,
274 request_id );
275 } else {
276 SendErrorResponse(
277 PP_OperationType_OPENFILE,
278 PP_ProviderError_FAILED,request_id);
279 }
280 }
281
282 void OnCloseFileRequest(int32_t open_request_id,int32_t request_id) {
283 ListOfOpenedFilesIterator it = opened_files_.find(open_request_id);
284 if (it==opened_files_.end()) {// no open request
285 SendErrorResponse(
286 PP_OperationType_CLOSEFILE,
287 PP_ProviderError_FAILED,
288 request_id );
289 } else {
290 SendSuccessResponse(PP_OperationType_CLOSEFILE, request_id);
291 }
292 }
293
294 void OnReadFileRequest(
295 int32_t open_request_id,
296 uint64_t offset,
297 uint64_t length,
298 int32_t request_id) {
299 ListOfOpenedFilesIterator it = opened_files_.find(open_request_id);
300 if (it==opened_files_.end()) {
301 SendErrorResponse(
302 PP_OperationType_READFILE,
303 PP_ProviderError_FAILED,
304 request_id);
305 } else {
306 size_t in_out_length=length;
307 const char *out_data = nullptr;
308 if(filesystem::Filesystem::File_System_Error_FAILED ==
309 filesystem_.ReadFromFile(
310 it->second,
311 offset,
312 &in_out_length, &out_data ) ) {
313 SendErrorResponse(
314 PP_OperationType_READFILE,
315 PP_ProviderError_FAILED,
316 request_id);
317 } else {
318 SendReadFileSuccessResponse(
319 in_out_length, out_data, false, request_id );
320 }
321 }
322 }
323 void OnCreateDirectoryRequest (
324 const std::string &directory_path,
325 bool recursive, int32_t request_id) {
326 if(filesystem::Filesystem::File_System_Error_NONE ==
327 filesystem_.CreateDirectory(directory_path,recursive))
328 SendSuccessResponse(PP_OperationType_CREATEDIRECTORY,request_id);
329 else
330 SendErrorResponse(PP_OperationType_CREATEDIRECTORY,
331 PP_ProviderError_FAILED, request_id);
332 }
333 void OnDeleteEntryRequest(
334 const std::string &entry_path,
335 bool recursive, int32_t request_id) {
336
337 if(filesystem::Filesystem::File_System_Error_NONE==
338 filesystem_.DeleteEntry(entry_path,recursive))
339 SendSuccessResponse(PP_OperationType_DELETEENTRY,request_id);
340 else
341 SendErrorResponse(
342 PP_OperationType_DELETEENTRY,
343 PP_ProviderError_NOT_FOUND,
344 request_id);
345 }
346
347 void OnCreateFileRequest(
348 const std::string &file_path, int32_t request_id) {
349 if(filesystem::Filesystem::File_System_Error_NONE==
350 filesystem_.CreateFile(file_path))
351 SendSuccessResponse(PP_OperationType_CREATEFILE,request_id);
352 else
353 SendErrorResponse(
354 PP_OperationType_CREATEFILE,
355 PP_ProviderError_FAILED,
356 request_id);
357 }
358 void OnCopyEntryRequest(
359 const std::string &source_path,
360 const std::string &target_path,
361 int32_t request_id) {
362 if(filesystem::Filesystem::File_System_Error_NONE==
363 filesystem_.CopyEntry(source_path,target_path))
364 SendSuccessResponse(PP_OperationType_COPYENTRY,request_id);
365 else
366 SendErrorResponse(PP_OperationType_COPYENTRY,
367 PP_ProviderError_FAILED, request_id );
368 }
369 void OnMoveEntryRequest(
370 const std::string &source_path,
371 const std::string &target_path,
372 int32_t request_id) {
373 if ( filesystem::Filesystem::File_System_Error_NONE==
374 filesystem_.MoveEntry(source_path,target_path))
375 SendSuccessResponse(PP_OperationType_MOVEENTRY, request_id);
376 else
377 SendErrorResponse(
378 PP_OperationType_MOVEENTRY,
379 PP_ProviderError_FAILED,
380 request_id );
381 }
382 void OnTruncateRequest(
383 const std::string &file_path,
384 int32_t length,
385 int32_t request_id) {
386 if (filesystem::Filesystem::File_System_Error_NONE==
387 filesystem_.Truncate(file_path, length))
388 SendSuccessResponse(PP_OperationType_TRUNCATEENTRY,request_id);
389 else
390 SendErrorResponse(PP_OperationType_TRUNCATEENTRY,
391 PP_ProviderError_FAILED,request_id );
392 }
393 void OnWriteRequest(int32_t open_request_id, uint64_t offset,
394 uint64_t data_size, const char *data,
395 int32_t request_id) {
396 ListOfOpenedFilesIterator it = opened_files_.find(open_request_id);
397 if (it==opened_files_.end()){
398 SendErrorResponse(
399 PP_OperationType_WRITEFILE,
400 PP_ProviderError_FAILED,
401 request_id);
402 } else {
403 if (filesystem::Filesystem::File_System_Error_NONE!=
404 filesystem_.WriteToFile(it->second, offset, data_size, data)) {
405 SendErrorResponse(
406 PP_OperationType_WRITEFILE,
407 PP_ProviderError_FAILED,
408 request_id );
409 } else {
410 SendSuccessResponse(PP_OperationType_WRITEFILE,request_id);
411 }
412 }
413 // Free buffer
414 FreeWriteRequestBuffer(data);
415 }
416 void OnAbortRequest(
417 int32_t operation_request_id, int32_t request_id) {
418 SendSuccessResponse(PP_OperationType_ABORT,request_id);
419 }
420 private:
421 typedef std::map<int,std::string> ListOfOpenedFiles;
422 typedef ListOfOpenedFiles::iterator ListOfOpenedFilesIterator;
423 ListOfOpenedFiles opened_files_;
424 pp::CompletionCallbackFactory<MyInstance> callback_factory_;
425 // Filesystem properties
426 filesystem::Filesystem filesystem_;
427 std::string filesystem_id_;
428 std::string display_name_;
429 bool mounted_;
430 };
431
432 class MyModule : public pp::Module {
433 public:
434 virtual pp::Instance* CreateInstance(PP_Instance instance) {
435 return new MyInstance(instance);
436 }
437 };
438
439 namespace pp {
440
441 // Factory function for your specialization of the Module object.
442 Module* CreateModule() {
443 return new MyModule();
444 }
445
446 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698