Index: ppapi/examples/filesystem_provider/filesystem.cc |
diff --git a/ppapi/examples/filesystem_provider/filesystem.cc b/ppapi/examples/filesystem_provider/filesystem.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2d7fb930d8c111956c2e881280ae0c0d8164b588 |
--- /dev/null |
+++ b/ppapi/examples/filesystem_provider/filesystem.cc |
@@ -0,0 +1,446 @@ |
+// 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 <algorithm> |
+#include <chrono> |
+#include <deque> |
+#include <map> |
+#include <set> |
+#include <sstream> |
+#include <string.h> |
+ |
+#include "memfilesystem.h" |
+#include "ppapi/c/pp_errors.h" |
+#include "ppapi/cpp/dev/filesystem_provider.h" |
+#include "ppapi/cpp/instance.h" |
+#include "ppapi/cpp/module.h" |
+#include "ppapi/cpp/var.h" |
+#include "ppapi/utility/completion_callback_factory.h" |
+#include "ppapi/cpp/input_event.h" |
+ |
+namespace { |
+template<class T> |
+class FilesystemHelper { |
+ public: |
+ FilesystemHelper() |
+ : callback_fact_(this) { |
+ Init(); |
+ } |
+ virtual ~FilesystemHelper(){} |
+ virtual void OnUnmountRequest(int32_t request_id)=0; |
+ virtual void OnMetadataRequest( |
+ const std::string& file_path, bool thumbnail, int32_t request_id)=0; |
+ virtual void OnReadDirectoryRequest( |
+ const std::string& directory_path, int32_t request_id)=0; |
+ virtual void OnOpenFileRequest( |
+ const std::string& file_path, const PP_OpenFileMode_Dev& file_mode, |
+ int32_t request_id)=0; |
+ virtual void OnCloseFileRequest( |
+ int32_t request_id, int32_t open_request_id)=0; |
+ virtual void OnReadFileRequest( |
+ int32_t open_request_id, |
+ uint64_t offset, |
+ uint64_t length, |
+ int32_t request_id)=0; |
+ virtual void OnCreateDirectoryRequest( |
+ const std::string& directory_path, |
+ bool recursive, int32_t request_id)=0; |
+ virtual void OnDeleteEntryRequest( |
+ const std::string& file_entry, bool recursive, int32_t request_id)=0; |
+ virtual void OnCreateFileRequest( |
+ const std::string& file_path, int32_t request_id)=0; |
+ virtual void OnCopyEntryRequest( |
+ const std::string& source_path, |
+ const std::string& target_path, |
+ int32_t request_id)=0; |
+ virtual void OnMoveEntryRequest( |
+ const std::string& source_path, |
+ const std::string& target_path, int32_t request_id)=0; |
+ virtual void OnTruncateRequest( |
+ const std::string& file_path, int32_t offset, int32_t request_id)=0; |
+ virtual void OnWriteRequest(int32_t, uint64_t, uint64_t, |
+ const char*, int32_t)=0; |
+ virtual void OnAbortRequest(int32_t request_id, int32_t open_request_id)=0; |
+ private: |
+ bool Init(){ |
+ static_cast<T*>(this)->GetNextRequest( |
+ callback_fact_.NewCallbackWithOutput( |
+ &FilesystemHelper::OnRequestReceived)); |
+ return true; |
+ } |
+ // Dispatcher |
+ void OnRequestReceived(int32_t result, PP_FilesystemRequest request){ |
+ if (result==PP_OK) { |
+ switch (request.operation_type) { |
+ case PP_OperationType_UNMOUNT: |
+ static_cast<T*>(this)->OnUnmountRequest(request.request_id); |
+ break; |
+ case PP_OperationType_GETMETADATA: |
+ static_cast<T*>(this)->OnMetadataRequest( |
+ request.value.as_metadata.entry_path, |
+ request.value.as_metadata.thumbnail, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_READDIRECTORY: |
+ static_cast<T*>(this)->OnReadDirectoryRequest( |
+ request.value.as_read_directory.directory_path, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_OPENFILE: |
+ static_cast<T*>(this)->OnOpenFileRequest( |
+ request.value.as_open_file.file_path, |
+ request.value.as_open_file.mode, request.request_id); |
+ break; |
+ case PP_OperationType_CLOSEFILE: |
+ static_cast<T*>(this)->OnCloseFileRequest( |
+ request.value.as_close_file.open_request_id, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_READFILE: |
+ static_cast<T*>(this)->OnReadFileRequest( |
+ request.value.as_read_file.open_request_id, |
+ request.value.as_read_file.offset, |
+ request.value.as_read_file.length, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_CREATEDIRECTORY: |
+ static_cast<T*>(this)->OnCreateDirectoryRequest( |
+ request.value.as_create_directory.directory_path, |
+ request.value.as_create_directory.recursive, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_DELETEENTRY: |
+ static_cast<T*>(this)->OnDeleteEntryRequest( |
+ request.value.as_delete_entry.entry_path, |
+ request.value.as_delete_entry.recursive,request.request_id); |
+ break; |
+ case PP_OperationType_CREATEFILE: |
+ static_cast<T*>(this)->OnCreateFileRequest( |
+ request.value.as_create_file.file_path, request.request_id); |
+ break; |
+ case PP_OperationType_COPYENTRY: |
+ static_cast<T*>(this)->OnCopyEntryRequest( |
+ request.value.as_copy_entry.source_path, |
+ request.value.as_copy_entry.target_path, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_MOVEENTRY: |
+ static_cast<T*>(this)->OnMoveEntryRequest( |
+ request.value.as_move_entry.source_path, |
+ request.value.as_move_entry.target_path, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_TRUNCATEENTRY: |
+ static_cast<T*>(this)->OnTruncateRequest( |
+ request.value.as_truncate.file_path, |
+ request.value.as_truncate.length, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_WRITEFILE: |
+ static_cast<T*>(this)->OnWriteRequest( |
+ request.value.as_write_file.open_request_id, |
+ request.value.as_write_file.offset, |
+ request.value.as_write_file.data_size, |
+ (char*)request.value.as_write_file.data, |
+ request.request_id); |
+ break; |
+ case PP_OperationType_ABORT: |
+ static_cast<T*>(this)->OnAbortRequest( |
+ request.value.as_abort.operation_request_id, |
+ request.request_id); |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ // Re-register the callback |
+ static_cast<T*>(this)->GetNextRequest( |
+ callback_fact_.NewCallbackWithOutput( |
+ &FilesystemHelper::OnRequestReceived)); |
+ } |
+ private: |
+ pp::CompletionCallbackFactory< FilesystemHelper<T> > callback_fact_; |
+}; |
+}// namespace |
+class MyInstance : |
+ public pp::Instance, |
+ public pp::Filesystem_Provider_Dev, |
+ public FilesystemHelper<MyInstance> { |
+ public: |
+ MyInstance(PP_Instance instance) |
+ :pp::Instance(instance), |
+ Filesystem_Provider_Dev(this), |
+ callback_factory_(this), |
+ filesystem_id_("in-memory-fs"), |
+ display_name_("Test-Filesystem"), |
+ mounted_(false) { |
+ Initialize(); |
+ } |
+ |
+virtual ~MyInstance() { |
+} |
+ |
+void Initialize() { |
+ Mount(filesystem_id_, display_name_, true, 0, |
+ callback_factory_.NewCallbackWithOutput( |
+ &MyInstance::OnMountCompletion)); |
+} |
+void OnMountCompletion(int32_t result, PP_ProviderError_Dev error ) { |
+ if ( result!=PP_OK || |
+ error!=PP_ProviderError_OK) { |
+ return; |
+ } |
+ mounted_ = true; |
+} |
+ |
+// Filesystem_Provider_Dev interfaces |
+void OnUnmountRequest(int32_t request_id) { |
+ // close connections, clean caches |
+ SendSuccessResponse(PP_OperationType_UNMOUNT,request_id); |
+} |
+ |
+ void OnMetadataRequest( |
+ const std::string &entry_path, |
+ bool thumbnail, int32_t request_id) { |
+ |
+ filesystem::Filesystem::NameInodePair meta; |
+ if( filesystem_.GetMetadata(entry_path,meta)== |
+ filesystem::Filesystem::File_System_Error_NOT_FOUND ) { |
+ SendErrorResponse( |
+ PP_OperationType_GETMETADATA, |
+ PP_ProviderError_NOT_FOUND, |
+ request_id ); |
+ } else { |
+ PP_EntryMetadata_Dev metadata; |
+ memset(&metadata, 0x0, sizeof(metadata)); |
+ metadata.is_directory = PP_FromBool(meta.second->file_type()== |
+ filesystem::Inode::FILE_TYPE_DIR); |
+ // Should check result |
+ snprintf(metadata.name, |
+ sizeof(metadata.name), |
+ "%s", meta.first.c_str()); |
+ snprintf( metadata.modification_time, |
+ sizeof(metadata.modification_time), |
+ "%s",meta.second->file_modified().c_str()); |
+ metadata.size = meta.second->size(); |
+ SendMetadataSuccessResponse(metadata,request_id); |
+ } |
+ } |
+ |
+ void OnReadDirectoryRequest( |
+ const std::string &directory_path, |
+ int32_t request_id) { |
+ std::vector<filesystem::Filesystem::NameInodePair> metas; |
+ |
+ if ( filesystem_.ReadDirectory(directory_path,metas)== |
+ filesystem::Filesystem::File_System_Error_NONE ) { |
+ std::vector<PP_EntryMetadata_Dev> metadatas; |
+ PP_EntryMetadata_Dev metadata; |
+ for(std::vector<filesystem::Filesystem::NameInodePair>::iterator |
+ it = metas.begin(); |
+ it != metas.end(); |
+ ++it) |
+ { |
+ memset(&metadata, 0x0, sizeof(metadata)); |
+ metadata.is_directory = PP_FromBool(it->second->file_type()== |
+ filesystem::Inode::FILE_TYPE_DIR); |
+ snprintf(metadata.name, |
+ sizeof(metadata.name), |
+ "%s", it->first.c_str()); |
+ snprintf( metadata.modification_time, |
+ sizeof(metadata.modification_time), |
+ "%s",it->second->file_modified().c_str()); |
+ metadata.size = it->second->size(); |
+ metadatas.push_back(metadata); |
+ } |
+ SendReadDirectorySuccessResponse(metadatas,false, request_id); |
+ } else { |
+ SendErrorResponse( |
+ PP_OperationType_READDIRECTORY, |
+ PP_ProviderError_FAILED, request_id ); |
+ } |
+ } |
+ void OnOpenFileRequest( |
+ const std::string &file_path, |
+ const PP_OpenFileMode_Dev &mode, |
+ int32_t request_id) { |
+ filesystem::Filesystem::NameInodePair meta; |
+ if (filesystem_.GetMetadata(file_path,meta)== |
+ filesystem::Filesystem::File_System_Error_NONE) { |
+ opened_files_.insert( std::pair<int,std::string>(request_id, file_path)); |
+ SendSuccessResponse( |
+ PP_OperationType_OPENFILE, |
+ request_id ); |
+ } else { |
+ SendErrorResponse( |
+ PP_OperationType_OPENFILE, |
+ PP_ProviderError_FAILED,request_id); |
+ } |
+ } |
+ |
+ void OnCloseFileRequest(int32_t open_request_id,int32_t request_id) { |
+ ListOfOpenedFilesIterator it = opened_files_.find(open_request_id); |
+ if (it==opened_files_.end()) {// no open request |
+ SendErrorResponse( |
+ PP_OperationType_CLOSEFILE, |
+ PP_ProviderError_FAILED, |
+ request_id ); |
+ } else { |
+ SendSuccessResponse(PP_OperationType_CLOSEFILE, request_id); |
+ } |
+ } |
+ |
+ void OnReadFileRequest( |
+ int32_t open_request_id, |
+ uint64_t offset, |
+ uint64_t length, |
+ int32_t request_id) { |
+ ListOfOpenedFilesIterator it = opened_files_.find(open_request_id); |
+ if (it==opened_files_.end()) { |
+ SendErrorResponse( |
+ PP_OperationType_READFILE, |
+ PP_ProviderError_FAILED, |
+ request_id); |
+ } else { |
+ size_t in_out_length=length; |
+ const char *out_data = nullptr; |
+ if(filesystem::Filesystem::File_System_Error_FAILED == |
+ filesystem_.ReadFromFile( |
+ it->second, |
+ offset, |
+ &in_out_length, &out_data ) ) { |
+ SendErrorResponse( |
+ PP_OperationType_READFILE, |
+ PP_ProviderError_FAILED, |
+ request_id); |
+ } else { |
+ SendReadFileSuccessResponse( |
+ in_out_length, out_data, false, request_id ); |
+ } |
+ } |
+ } |
+ void OnCreateDirectoryRequest ( |
+ const std::string &directory_path, |
+ bool recursive, int32_t request_id) { |
+ if(filesystem::Filesystem::File_System_Error_NONE == |
+ filesystem_.CreateDirectory(directory_path,recursive)) |
+ SendSuccessResponse(PP_OperationType_CREATEDIRECTORY,request_id); |
+ else |
+ SendErrorResponse(PP_OperationType_CREATEDIRECTORY, |
+ PP_ProviderError_FAILED, request_id); |
+ } |
+ void OnDeleteEntryRequest( |
+ const std::string &entry_path, |
+ bool recursive, int32_t request_id) { |
+ |
+ if(filesystem::Filesystem::File_System_Error_NONE== |
+ filesystem_.DeleteEntry(entry_path,recursive)) |
+ SendSuccessResponse(PP_OperationType_DELETEENTRY,request_id); |
+ else |
+ SendErrorResponse( |
+ PP_OperationType_DELETEENTRY, |
+ PP_ProviderError_NOT_FOUND, |
+ request_id); |
+ } |
+ |
+ void OnCreateFileRequest( |
+ const std::string &file_path, int32_t request_id) { |
+ if(filesystem::Filesystem::File_System_Error_NONE== |
+ filesystem_.CreateFile(file_path)) |
+ SendSuccessResponse(PP_OperationType_CREATEFILE,request_id); |
+ else |
+ SendErrorResponse( |
+ PP_OperationType_CREATEFILE, |
+ PP_ProviderError_FAILED, |
+ request_id); |
+ } |
+ void OnCopyEntryRequest( |
+ const std::string &source_path, |
+ const std::string &target_path, |
+ int32_t request_id) { |
+ if(filesystem::Filesystem::File_System_Error_NONE== |
+ filesystem_.CopyEntry(source_path,target_path)) |
+ SendSuccessResponse(PP_OperationType_COPYENTRY,request_id); |
+ else |
+ SendErrorResponse(PP_OperationType_COPYENTRY, |
+ PP_ProviderError_FAILED, request_id ); |
+ } |
+ void OnMoveEntryRequest( |
+ const std::string &source_path, |
+ const std::string &target_path, |
+ int32_t request_id) { |
+ if ( filesystem::Filesystem::File_System_Error_NONE== |
+ filesystem_.MoveEntry(source_path,target_path)) |
+ SendSuccessResponse(PP_OperationType_MOVEENTRY, request_id); |
+ else |
+ SendErrorResponse( |
+ PP_OperationType_MOVEENTRY, |
+ PP_ProviderError_FAILED, |
+ request_id ); |
+ } |
+ void OnTruncateRequest( |
+ const std::string &file_path, |
+ int32_t length, |
+ int32_t request_id) { |
+ if (filesystem::Filesystem::File_System_Error_NONE== |
+ filesystem_.Truncate(file_path, length)) |
+ SendSuccessResponse(PP_OperationType_TRUNCATEENTRY,request_id); |
+ else |
+ SendErrorResponse(PP_OperationType_TRUNCATEENTRY, |
+ PP_ProviderError_FAILED,request_id ); |
+ } |
+ void OnWriteRequest(int32_t open_request_id, uint64_t offset, |
+ uint64_t data_size, const char *data, |
+ int32_t request_id) { |
+ ListOfOpenedFilesIterator it = opened_files_.find(open_request_id); |
+ if (it==opened_files_.end()){ |
+ SendErrorResponse( |
+ PP_OperationType_WRITEFILE, |
+ PP_ProviderError_FAILED, |
+ request_id); |
+ } else { |
+ if (filesystem::Filesystem::File_System_Error_NONE!= |
+ filesystem_.WriteToFile(it->second, offset, data_size, data)) { |
+ SendErrorResponse( |
+ PP_OperationType_WRITEFILE, |
+ PP_ProviderError_FAILED, |
+ request_id ); |
+ } else { |
+ SendSuccessResponse(PP_OperationType_WRITEFILE,request_id); |
+ } |
+ } |
+ // Free buffer |
+ FreeWriteRequestBuffer(data); |
+ } |
+ void OnAbortRequest( |
+ int32_t operation_request_id, int32_t request_id) { |
+ SendSuccessResponse(PP_OperationType_ABORT,request_id); |
+ } |
+ private: |
+ typedef std::map<int,std::string> ListOfOpenedFiles; |
+ typedef ListOfOpenedFiles::iterator ListOfOpenedFilesIterator; |
+ ListOfOpenedFiles opened_files_; |
+ pp::CompletionCallbackFactory<MyInstance> callback_factory_; |
+ // Filesystem properties |
+ filesystem::Filesystem filesystem_; |
+ std::string filesystem_id_; |
+ std::string display_name_; |
+ bool mounted_; |
+}; |
+ |
+class MyModule : public pp::Module { |
+ public: |
+ virtual pp::Instance* CreateInstance(PP_Instance instance) { |
+ return new MyInstance(instance); |
+ } |
+}; |
+ |
+namespace pp { |
+ |
+// Factory function for your specialization of the Module object. |
+Module* CreateModule() { |
+ return new MyModule(); |
+} |
+ |
+} // namespace pp |