| 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
|
|
|