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

Unified Diff: ppapi/proxy/filesystem_provider_resource.cc

Issue 1093383002: [WIP] Provided file system from NACL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved several modules to chromeos folder. Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/filesystem_provider_resource.h ('k') | ppapi/proxy/filesystem_provider_resource_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/filesystem_provider_resource.cc
diff --git a/ppapi/proxy/filesystem_provider_resource.cc b/ppapi/proxy/filesystem_provider_resource.cc
new file mode 100644
index 0000000000000000000000000000000000000000..500b2dc5de2efb7cc07452b80180bb7ffa7c6d41
--- /dev/null
+++ b/ppapi/proxy/filesystem_provider_resource.cc
@@ -0,0 +1,2052 @@
+// Copyright 2015 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 "ppapi/proxy/filesystem_provider_resource.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/dispatch_reply_message.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+using ppapi::DictionaryVar;
+using ppapi::ArrayVar;
+
+namespace ppapi {
+namespace proxy {
+namespace {
+
+const uint32_t kMaximumCachedReplies = 10;
+
+static std::string PP_ErrorToString(int32_t error) {
+ switch (error) {
+ case PP_OK:
+ return "OK";
+ case PP_ERROR_FAILED:
+ return "FAILED";
+ case PP_ERROR_INPROGRESS:
+ return "IN_USE";
+ case PP_ERROR_FILEEXISTS:
+ return "EXISTS";
+ case PP_ERROR_FILENOTFOUND:
+ return "NOT_FOUND";
+ case PP_ERROR_NOACCESS:
+ return "ACCESS_DENIED";
+ case PP_ERROR_FILE_TOO_MANY_OPENED:
+ return "TOO_MANY_OPENED";
+ case PP_ERROR_NOMEMORY:
+ return "NO_MEMORY";
+ case PP_ERROR_NOSPACE:
+ return "NO_SPACE";
+ case PP_ERROR_NOTADIRECTORY:
+ return "NOT_A_DIRECTORY";
+ case PP_ERROR_NOTSUPPORTED:
+ return "INVALID_OPERATION";
+ case PP_ERROR_SECURITY:
+ return "SECURITY";
+ case PP_ERROR_ABORTED:
+ return "ABORT";
+ case PP_ERROR_NOTAFILE:
+ return "NOT_A_FILE";
+ case PP_ERROR_FILENOTEMPTY:
+ return "NOT_EMPTY";
+ case PP_ERROR_INVALID_URL:
+ return "INVALID_URL";
+ case PP_ERROR_FILE_IO:
+ return "IO";
+ }
+ NOTREACHED();
+ return "";
+}
+
+} // namespace
+
+FilesystemProviderResource::ShmChannelController::ShmChannelController(
+ uint32_t size, FlushResponseCallback callback)
+ : max_size(size),
+ ready(true),
+ callback(callback){
+}
+FilesystemProviderResource::ShmChannelController::~ShmChannelController() {
+}
+
+bool FilesystemProviderResource::ShmChannelController::EnqueueResponse(
+ scoped_ptr<base::ListValue> response,
+ const char* data, uint32_t data_size) {
+ // If channel ready send it straight away
+ if (ready) {
+ // Flush Request
+ ready = !callback.Run(response.Pass(), data, data_size);
+ if(!ready)
+ return true;
+ }
+ // If channel is not ready or failed to send,
+ // cache the response
+ if( size() + 1 > max_size ) {
+ return false;
+ }
+
+ scoped_ptr<base::BinaryValue> payload(
+ base::BinaryValue::CreateWithCopiedBuffer(static_cast<const char*>(data),
+ data_size));
+ if( !payload.get() )
+ return false;
+
+ response->Append(payload.release());
+ replies.push_back(response.release());
+
+ return true;
+}
+
+bool FilesystemProviderResource::ShmChannelController::PushNextResponse() {
+ scoped_ptr<base::ListValue> response;
+ scoped_ptr<base::Value> payload;
+ while (size()>0 && ready ) {
+ // Try to push a response from the queue to
+ // the browser
+ response.reset(replies.front());
+ replies.weak_erase(replies.begin());
+
+ if(!response->Remove(response->GetSize()-1, &payload)||
+ !payload->IsType(base::Value::TYPE_BINARY))
+ continue;
+
+ base::BinaryValue* data = static_cast<base::BinaryValue*>(payload.get());
+ ready = !callback.Run(
+ response.Pass(),
+ data->GetBuffer(),
+ data->GetSize());
+ }
+ return !ready;
+}
+
+bool
+FilesystemProviderResource::ShmChannelController::AckLastPushedResponse() {
+ return ready = true;
+}
+
+uint32_t FilesystemProviderResource::ShmChannelController::size() {
+ return replies.size();
+}
+
+FilesystemProviderResource::ProvidedFilesystemInfo::ProvidedFilesystemInfo()
+ :filesystem_id("none"),
+ display_name("none"),
+ writable(false),opened_files_limit(0){
+}
+
+FilesystemProviderResource::ProvidedFilesystemInfo::~ProvidedFilesystemInfo(){}
+
+FilesystemProviderResource::ShmBuffer::ShmBuffer(
+ uint32_t read_size, uint32_t write_size,
+ scoped_ptr<base::SharedMemory> shm)
+ : read_size(read_size),write_size(write_size), shm(shm.Pass()) {
+ DCHECK(this->shm);
+}
+
+FilesystemProviderResource::ShmBuffer::~ShmBuffer() {}
+
+FilesystemProviderResource::RequestManager::RequestManager() {}
+
+FilesystemProviderResource::RequestManager::~RequestManager() {}
+
+void FilesystemProviderResource::RequestManager::AddRequest(
+ int32_t request_id, PP_OperationType_Dev operation ) {
+ requests_[ request_id ] = OperationStartTimePair(
+ operation,
+ std::chrono::system_clock::now() );
+}
+
+bool FilesystemProviderResource::RequestManager::HasRequest(
+ int32_t request_id) {
+ return requests_.find(request_id)!=requests_.end();
+}
+
+bool FilesystemProviderResource::RequestManager::RemoveRequest(
+ int32_t request_id, int *out_time_span) {
+ ListOfRequestsIterator it=requests_.find(request_id);
+ if (it==requests_.end())
+ return false;
+
+ // Compute operation time span
+ std::chrono::time_point<std::chrono::system_clock> now =
+ std::chrono::system_clock::now();
+
+ if(out_time_span)
+ *out_time_span = std::chrono::duration_cast<std::chrono::seconds>
+ (now - it->second.second).count();
+ requests_.erase( it );
+ return true;
+}
+
+FilesystemProviderResource::FilesystemProviderResource(
+ Connection connection,
+ PP_Instance instance )
+ :PluginResource( connection , instance ),
+ mounted_(false),
+ request_manager_(new RequestManager),
+ read_channel_controller_(
+ new ShmChannelController(
+ kMaximumCachedReplies,
+ base::Bind(&FilesystemProviderResource::FlushReadResponse,
+ this))) {
+ DCHECK(request_manager_);
+ DCHECK(read_channel_controller_);
+ SendCreate(BROWSER, PpapiHostMsg_FilesystemProvider_Create() );
+}
+
+FilesystemProviderResource::~FilesystemProviderResource() {
+}
+
+
+thunk::PPB_FilesystemProvider_API*
+FilesystemProviderResource::AsPPB_FilesystemProvider_API() {
+ return this;
+}
+
+void FilesystemProviderResource::OnReplyReceived(
+ const ResourceMessageReplyParams &params, const IPC::Message &msg) {
+ if (params.sequence()) {
+ PluginResource::OnReplyReceived(params, msg);
+ return;
+ }
+ PPAPI_BEGIN_MESSAGE_MAP(FilesystemProviderResource, msg)
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
+ PpapiPluginMsg_FilesystemProvider_OperationRequest,
+ OnPluginMsgOperationRequest)
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
+ PpapiPluginMsg_FilesystemProvider_Buffers,
+ OnPluginMsgBuffersReady)
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_0(
+ PpapiPluginMsg_FilesystemProvider_ReadAck,
+ OnPluginMsgReadAck)
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED())
+ PPAPI_END_MESSAGE_MAP()
+}
+
+int32_t FilesystemProviderResource::Mount(
+ PP_Var filesystem_id,
+ PP_Var display_name,
+ PP_Bool writable,
+ int32_t opened_files_limit,
+ scoped_refptr<TrackedCallback> callback) {
+ if ( mounted_ )
+ return PP_ERROR_ADDRESS_IN_USE;
+ if ( TrackedCallback::IsPending(mount_callback_) )
+ return PP_ERROR_INPROGRESS;
+
+ StringVar* string_var = nullptr;
+
+ const PP_Var *parameter_p[] = { &filesystem_id, &display_name };
+ std::string *value_p[] = {
+ &filesystem_info_.filesystem_id,
+ &filesystem_info_.display_name
+ };
+
+ for( uint32_t i = 0; i < sizeof( value_p ) / sizeof( value_p[0] ); i++ ) {
+ string_var = StringVar :: FromPPVar( *parameter_p[ i ] );
+ *value_p[ i ] = string_var ? string_var->value() : std::string();
+ }
+
+ filesystem_info_.writable = PP_ToBool( writable );
+ filesystem_info_.opened_files_limit = opened_files_limit;
+
+ // Remember the callback and the address of the return param
+ mount_callback_ = callback;
+
+ // Send mount request to the browser
+ // and receive response in OnPluginMsgMountReply
+ scoped_ptr<base::ListValue> request(
+ filesystem_provider_internal::
+ PluginToBrowserTranslator::GenerateMountMessage(
+ filesystem_info_.filesystem_id, filesystem_info_.display_name,
+ filesystem_info_.writable,filesystem_info_.opened_files_limit));
+ if (!request.get())
+ return PP_ERROR_FAILED;
+
+ Call<PpapiPluginMsg_FilesystemProvider_MountReply>(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_Mount(*request),
+ base::Bind(&FilesystemProviderResource::OnPluginMsgMountReply, this));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t FilesystemProviderResource::Unmount(PP_Var filesystemId,
+ scoped_refptr<TrackedCallback> callback ) {
+ if ( !mounted_ )
+ return PP_ERROR_FAILED;
+ if ( TrackedCallback::IsPending(unmount_callback_) )
+ return PP_ERROR_INPROGRESS;
+
+ StringVar* string_var = nullptr;
+
+ string_var = StringVar::FromPPVar( filesystemId );
+ std::string fs_id = string_var ? string_var->value() : std::string();
+
+ if (fs_id!=filesystem_info_.filesystem_id)
+ return PP_ERROR_FAILED;
+
+ // Remember the unmount callback and the address of the return param
+ unmount_callback_ =callback;
+
+ Call < PpapiPluginMsg_FilesystemProvider_UnmountReply >(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_Unmount( fs_id ),
+ base::Bind( &FilesystemProviderResource::OnPluginMsgUnmountReply,
+ this )
+ );
+
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t FilesystemProviderResource::Notify(PP_Var notify_options) {
+ scoped_ptr<base::ListValue> notification(
+ filesystem_provider_internal::PluginToBrowserTranslator
+ ::GenerateNotifyMessage(notify_options) );
+ if (!notification.get())
+ return PP_ERROR_MALFORMED_INPUT;
+ Post(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_Notify(*notification));
+ return PP_OK;
+}
+
+
+int32_t FilesystemProviderResource::SendSuccessResponse(
+ PP_OperationType_Dev operation_type,
+ int32_t request_id) {
+
+ scoped_ptr<base::ListValue> response;
+
+ switch( operation_type ) {
+ case PP_OperationType_GETMETADATA:
+ case PP_OperationType_READDIRECTORY:
+ case PP_OperationType_READFILE:
+ return PP_ERROR_BADARGUMENT;
+ default: {
+ // If we can't find a matching request from the browser
+ // bail out
+ int time_span = 0;
+ if( !request_manager_->RemoveRequest(request_id, &time_span) )//
+ return PP_ERROR_BADARGUMENT;
+ if (operation_type==PP_OperationType_UNMOUNT)
+ mounted_ = false;
+ response = filesystem_provider_internal::
+ PluginToBrowserTranslator::GenerateSuccessResponse(
+ operation_type, filesystem_info_.filesystem_id,
+ request_id, time_span );
+ if(!response.get())
+ return PP_ERROR_FAILED;
+ }
+ }
+ Post(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
+ return PP_OK;
+}
+
+int32_t FilesystemProviderResource::SendErrorResponse(
+ PP_OperationType_Dev operation_type,
+ int32_t error,
+ int32_t request_id) {
+
+ int time_span = 0;
+ if( !request_manager_->RemoveRequest(request_id, &time_span) )
+ return PP_ERROR_BADARGUMENT;
+
+ scoped_ptr<base::ListValue> response(
+ filesystem_provider_internal::
+ PluginToBrowserTranslator::GenerateFailureResponse(
+ operation_type, error, filesystem_info_.filesystem_id, request_id,
+ time_span ));
+ if(!response.get())
+ return PP_ERROR_FAILED;
+
+ Post(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
+ return PP_OK;
+}
+
+int32_t FilesystemProviderResource::SendMetadataSuccessResponse(
+ struct PP_Var metadata,
+ int32_t request_id) {
+
+ int time_span = 0;
+ if( !request_manager_->RemoveRequest(request_id, &time_span) )
+ return PP_ERROR_BADARGUMENT;
+
+ scoped_ptr<base::ListValue> response(
+ filesystem_provider_internal::
+ PluginToBrowserTranslator::GenerateMetadataResponse(
+ metadata, request_id, filesystem_info_.filesystem_id, time_span));
+ if(!response.get())
+ return PP_ERROR_FAILED;
+
+ Post(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response)
+ );
+ return PP_OK;
+}
+
+int32_t FilesystemProviderResource::SendReadDirectorySuccessResponse(
+ PP_Var entries,
+ PP_Bool has_more, int32_t request_id) {
+
+ int time_span = 0;
+ if (has_more) {
+ if (!request_manager_->HasRequest(request_id))
+ return PP_ERROR_BADARGUMENT;
+ } else {
+ if(!request_manager_->RemoveRequest(request_id,&time_span))
+ return PP_ERROR_BADARGUMENT;
+ }
+ scoped_ptr<base::ListValue> response(
+ filesystem_provider_internal::
+ PluginToBrowserTranslator::GenerateReadDirectoryResponse(
+ entries, has_more, request_id,
+ filesystem_info_.filesystem_id, time_span ));
+
+ if(!response.get())
+ return PP_ERROR_FAILED;
+ Post(
+ BROWSER,
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response) );
+ return PP_OK;
+}
+
+int32_t FilesystemProviderResource::SendReadFileSuccessResponse(
+ uint32_t data_size,
+ const void *data,
+ PP_Bool has_more,
+ int32_t request_id) {
+
+ int time_span = 0;
+ // Check if this is an answer to a previous request
+ if (has_more) {
+ if (!request_manager_->HasRequest(request_id))
+ return PP_ERROR_BADARGUMENT;
+ } else {
+ if(!request_manager_->RemoveRequest(request_id,&time_span))
+ return PP_ERROR_BADARGUMENT;
+ }
+ // check if shared memory is ready and the right size
+ if(!read_write_buffer_.get())
+ return PP_ERROR_FAILED;
+ if(data_size > read_write_buffer_->read_size )
+ return PP_ERROR_MESSAGE_TOO_BIG;
+
+ scoped_ptr<base::ListValue> response(
+ filesystem_provider_internal::
+ PluginToBrowserTranslator::GenerateReadFileSuccessResponse(
+ data_size, PP_ToBool( has_more ), request_id, time_span,
+ filesystem_info_.filesystem_id));
+
+ if(!response.get())
+ return PP_ERROR_FAILED;
+
+ // Send response or enqueue it
+ if(!read_channel_controller_->EnqueueResponse(
+ response.Pass(), static_cast<const char*>(data),data_size))
+ return PP_ERROR_FAILED;
+ return PP_OK;
+}
+
+int32_t FilesystemProviderResource::GetNextRequest(
+ PP_FilesystemRequest* request, scoped_refptr<TrackedCallback> callback) {
+ if(TrackedCallback::IsPending(get_next_request_callback_))
+ return PP_ERROR_INPROGRESS;
+ // Retain the container address
+ get_next_request_callback_data_ = request;
+ // If buffered requests are pending return the first one
+ if(!received_requests_.empty()) {
+ if(!WriteRequest())
+ return PP_ERROR_FAILED;
+ // By returning PP_OK the callback is run
+ return PP_OK;
+ }
+ // Retain the callback for future execution
+ get_next_request_callback_=callback;
+
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t FilesystemProviderResource::ReleaseRequestBuffer(int32_t request_id) {
+ using namespace filesystem_provider_internal;
+ ListOfRequests::iterator it = pending_process_requests_.find(request_id);
+ if(it!=pending_process_requests_.end()) {
+ pending_process_requests_.erase(it);
+ return PP_OK;
+ }
+ return PP_ERROR_FAILED;
+}
+
+void FilesystemProviderResource::OnPluginMsgMountReply(
+ const ResourceMessageReplyParams &params) {
+ if (TrackedCallback::IsPending(mount_callback_)) {
+ if (params.result()==PP_OK)
+ mounted_ = true;
+ mount_callback_->Run( params.result() );
+ }
+}
+
+void FilesystemProviderResource::OnPluginMsgUnmountReply(
+ const ResourceMessageReplyParams &params) {
+ mounted_ = false;
+ if (TrackedCallback::IsPending( unmount_callback_ )) {
+ unmount_callback_->Run( params.result() );
+ }
+}
+
+void FilesystemProviderResource::OnPluginMsgOperationRequest(
+ const ResourceMessageParams &params,
+ const PP_OperationType_Dev &operation,
+ const base::ListValue &operationArgs) {
+using namespace filesystem_provider_internal;
+// We shall push the request
+ switch (operation) {
+ case PP_OperationType_ABORT: {
+ scoped_refptr<AbortOperationTranslator>
+ request = AbortOperationTranslator::PopulateFromRequest(
+ operationArgs);
+
+ if (request.get()) {
+ // Retain payload
+ request_manager_->RemoveRequest( request->operation_request_id, NULL);
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request);
+ }
+ break;
+ } // PP_OperationType_ABORT
+ case PP_OperationType_CLOSEFILE: {
+ scoped_refptr< CloseFileOperationTranslator >
+ request = CloseFileOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }//PP_OperationType_CLOSEFILE
+ case PP_OperationType_COPYENTRY: {
+ scoped_refptr< CopyEntryOperationTranslator >
+ request = CopyEntryOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }// PP_OperationType_COPYENTRY
+ case PP_OperationType_CREATEDIRECTORY: {
+ scoped_refptr< CreateDirectoryOperationTranslator >
+ request = CreateDirectoryOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }// PP_OperationType_CREATEDIRECTORY
+ case PP_OperationType_CREATEFILE: {
+ scoped_refptr< CreateFileOperationTranslator >
+ request = CreateFileOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }// PP_OperationType_CREATEFILE
+ case PP_OperationType_DELETEENTRY: {
+ scoped_refptr< DeleteEntryOperationTranslator >
+ request = DeleteEntryOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }//PP_OperationType_DELETEENTRY
+ case PP_OperationType_GETMETADATA: {
+ scoped_refptr<GetMetadataOperationTranslator>
+ request = GetMetadataOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if ( request.get() ) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ } // PP_OperationType_GETMETADATA
+ case PP_OperationType_MOVEENTRY: {
+ scoped_refptr<MoveOperationTranslator>
+ request = MoveOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }// PP_OperationType_MOVEENTRY
+ case PP_OperationType_OPENFILE: {
+ scoped_refptr<OpenFileOperationTranslator>
+ request = OpenFileOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }// PP_OperationType_OpenFile
+ case PP_OperationType_READDIRECTORY: {
+ scoped_refptr<ReadDirectoryOperationTranslator>
+ request = ReadDirectoryOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }//PP_OperationType_READDIRECTORY
+ case PP_OperationType_READFILE: {
+ scoped_refptr<ReadFileOperationTranslator>
+ request = ReadFileOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }// PP_OperationType_READFILE
+ case PP_OperationType_TRUNCATEENTRY: {
+ scoped_refptr<TruncateOperationTranslator>
+ request = TruncateOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }//PP_OperationType_TRUNCATEENTRY
+ case PP_OperationType_UNMOUNT: {
+ scoped_refptr<UnmountOperationTranslator>
+ request = UnmountOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }//PP_OperationType_UNMOUNT
+ case PP_OperationType_WRITEFILE: {
+ // If shared mem inited
+ if (read_write_buffer_.get()) {
+ scoped_refptr<WriteFileOperationTranslator>
+ request = WriteFileOperationTranslator::PopulateFromRequest(
+ operationArgs,
+ (char*)read_write_buffer_->shm->memory()+
+ read_write_buffer_->read_size
+ );
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ }
+ SendWriteAck();
+ break;
+ }
+ case PP_OperationType_ADDWATCHER: {
+ scoped_refptr<AddWatcherOperationTranslator>
+ request = AddWatcherOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }
+ case PP_OperationType_REMOVEWATCHER: {
+ scoped_refptr<RemoveWatcherOperationTranslator>
+ request = RemoveWatcherOperationTranslator::PopulateFromRequest(
+ operationArgs);
+ if (request.get()) {
+ request_manager_->AddRequest( request->request_id, operation);
+ received_requests_.push_back( request );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (!TrackedCallback::IsPending(get_next_request_callback_) ||
+ TrackedCallback::IsScheduledToRun(get_next_request_callback_) ||
+ !WriteRequest())
+ return;
+
+ scoped_refptr<TrackedCallback> callback;
+ callback.swap(get_next_request_callback_);
+ // Run callback
+ callback->Run(PP_OK);
+}
+
+void FilesystemProviderResource::OnPluginMsgBuffersReady(
+ const ResourceMessageParams& params, uint32_t read_buffer_size,
+ uint32_t write_buffer_size ) {
+
+ std::vector<base::SharedMemoryHandle> shm_handles;
+ params.TakeAllSharedMemoryHandles(&shm_handles);
+
+ scoped_ptr<base::SharedMemory> shm(
+ new base::SharedMemory(shm_handles[0],false));
+ size_t buffer_size = read_buffer_size + write_buffer_size;
+ if (!shm->Map(buffer_size) )
+ return;
+ read_write_buffer_=
+ make_scoped_ptr(new ShmBuffer( read_buffer_size, write_buffer_size,
+ shm.Pass()));
+}
+
+// Received when the browser part acks the read from the shm buffer
+void FilesystemProviderResource::OnPluginMsgReadAck(
+ const ResourceMessageReplyParams& /*params*/) {
+
+ read_channel_controller_->AckLastPushedResponse();
+ read_channel_controller_->PushNextResponse();
+}
+
+bool FilesystemProviderResource::WriteRequest()
+{
+ if(!get_next_request_callback_data_)
+ return false;
+ scoped_ptr<PP_FilesystemRequest > request;
+ scoped_refptr<filesystem_provider_internal::OperationTranslator>
+ message;
+ // The first request that we can decode we put it into the designated
+ // container for the filesystem provider implementation
+ while (received_requests_.size()>0) {
+ message = received_requests_.front();
+ received_requests_.pop_front();
+ request = message->ToFilesystemRequest();
+
+ if(request.get())
+ break;
+ }
+ if(!request.get())
+ return false;
+
+ // Retain the request until the implementation frees it
+ pending_process_requests_.insert(std::make_pair( request->request_id,
+ message ) );
+ *get_next_request_callback_data_ = *request;
+ get_next_request_callback_data_ = NULL;
+ return true;
+}
+
+bool FilesystemProviderResource::FlushReadResponse(
+ scoped_ptr<base::ListValue> response, const char*data, uint32_t data_size) {
+ if (!response.get() ||
+ data==NULL)
+ return false;
+ memcpy( read_write_buffer_->shm->memory(), data, data_size);
+
+ Post(BROWSER,
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
+
+ return true;
+}
+
+void FilesystemProviderResource::SendWriteAck() {
+ // Send Ack for the request to the browser to signal that the shm
+ // channel can be reused.
+ Post(BROWSER, PpapiHostMsg_FilesystemProvider_WriteAck());
+}
+
+namespace filesystem_provider_internal{
+
+AbortOperationTranslator::AbortOperationTranslator(){}
+AbortOperationTranslator::~AbortOperationTranslator(){}
+
+ scoped_ptr<PP_FilesystemRequest>
+AbortOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_ABORT;
+ out->request_id = request_id;
+ return out.Pass();
+}
+
+// static
+scoped_refptr<AbortOperationTranslator>
+AbortOperationTranslator::PopulateFromRequest( const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ scoped_refptr<AbortOperationTranslator> out(new AbortOperationTranslator());
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* operation_request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion(
+ "operationRequestId", &operation_request_id_value))
+ return nullptr;
+ if (!operation_request_id_value->GetAsInteger(&out->operation_request_id))
+ return nullptr;
+ return out;
+}
+
+CloseFileOperationTranslator::~CloseFileOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+CloseFileOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+
+ out->operation_type = PP_OperationType_CLOSEFILE;
+ out->request_id = request_id;
+ out->value.as_close_file.open_request_id = open_request_id;
+
+ return out.Pass();
+}
+
+//static
+scoped_refptr<CloseFileOperationTranslator>
+CloseFileOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ scoped_refptr<CloseFileOperationTranslator>
+ out(new CloseFileOperationTranslator());
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* open_request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
+ return nullptr;
+ if (!open_request_id_value->GetAsInteger(&out->open_request_id))
+ return nullptr;
+
+ return out;
+}
+
+CloseFileOperationTranslator::CloseFileOperationTranslator(){}
+
+//static
+GetMetadataOperationTranslator::~GetMetadataOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+GetMetadataOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_GETMETADATA;
+ out->request_id = request_id;
+ out->value.as_metadata.thumbnail = PP_FromBool( thumbnail );
+ out->value.as_metadata.entry_path = entry_path.c_str();
+
+ return out.Pass();
+}
+
+scoped_refptr<GetMetadataOperationTranslator>
+GetMetadataOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request ) {
+
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ scoped_refptr<GetMetadataOperationTranslator>
+ out(new GetMetadataOperationTranslator());
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* entry_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
+ return nullptr;
+ if (!entry_path_value->GetAsString(&out->entry_path))
+ return nullptr;
+
+ const base::Value* thumbnail_value = NULL;
+ if (!dict->GetWithoutPathExpansion("thumbnail", &thumbnail_value))
+ return nullptr;
+ if (!thumbnail_value->GetAsBoolean(&out->thumbnail))
+ return nullptr;
+ return out;
+}
+
+GetMetadataOperationTranslator::GetMetadataOperationTranslator(){}
+
+
+CopyEntryOperationTranslator::~CopyEntryOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+CopyEntryOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ out->operation_type = PP_OperationType_COPYENTRY;
+ out->request_id = request_id;
+ out->value.as_copy_entry.source_path = source_path.c_str();
+ out->value.as_copy_entry.target_path = target_path.c_str();
+ return out.Pass();
+}
+
+// static
+scoped_refptr<CopyEntryOperationTranslator>
+CopyEntryOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ scoped_refptr<CopyEntryOperationTranslator>
+ out(new CopyEntryOperationTranslator());
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* source_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value))
+ return nullptr;
+ if (!source_path_value->GetAsString(&out->source_path))
+ return nullptr;
+
+ const base::Value* target_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value))
+ return nullptr;
+ if (!target_path_value->GetAsString(&out->target_path))
+ return nullptr;
+ return out;
+
+}
+
+CopyEntryOperationTranslator::CopyEntryOperationTranslator(){}
+
+CreateDirectoryOperationTranslator::~CreateDirectoryOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+CreateDirectoryOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_CREATEDIRECTORY;
+ out->request_id = request_id;
+ out->value.as_create_directory.directory_path = directory_path.c_str();
+ out->value.as_create_directory.recursive = PP_FromBool(recursive);
+ return out.Pass();
+}
+
+scoped_refptr<CreateDirectoryOperationTranslator>
+CreateDirectoryOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ scoped_refptr<CreateDirectoryOperationTranslator>
+ out(new CreateDirectoryOperationTranslator());
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* directory_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value))
+ return nullptr;
+ if (!directory_path_value->GetAsString(&out->directory_path))
+ return nullptr;
+
+ const base::Value* recursive_value = NULL;
+ if (!dict->GetWithoutPathExpansion("recursive", &recursive_value))
+ return nullptr;
+ if (!recursive_value->GetAsBoolean(&out->recursive))
+ return nullptr;
+
+ return out;
+}
+
+CreateDirectoryOperationTranslator::CreateDirectoryOperationTranslator(){}
+
+CreateFileOperationTranslator::~CreateFileOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+CreateFileOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return scoped_ptr<PP_FilesystemRequest>();
+ out->operation_type = PP_OperationType_CREATEFILE;
+ out->request_id = request_id;
+ out->value.as_create_file.file_path = file_path.c_str();
+ return out.Pass();
+}
+
+scoped_refptr<CreateFileOperationTranslator>
+CreateFileOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ scoped_refptr<CreateFileOperationTranslator>
+ out(new CreateFileOperationTranslator());
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* file_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
+ return nullptr;
+ if (!file_path_value->GetAsString(&out->file_path))
+ return nullptr;
+ return out;
+}
+
+CreateFileOperationTranslator::CreateFileOperationTranslator(){}
+
+DeleteEntryOperationTranslator::~DeleteEntryOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+DeleteEntryOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ out->operation_type = PP_OperationType_DELETEENTRY;
+ out->request_id = request_id;
+ out->value.as_delete_entry.entry_path = entry_path.c_str();
+ out->value.as_delete_entry.recursive = PP_FromBool(recursive);
+ return out.Pass();
+}
+
+scoped_refptr<DeleteEntryOperationTranslator>
+DeleteEntryOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+
+ scoped_refptr<DeleteEntryOperationTranslator>
+ out(new DeleteEntryOperationTranslator());
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* entry_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
+ return nullptr;
+ if (!entry_path_value->GetAsString(&out->entry_path))
+ return nullptr;
+
+ const base::Value* recursive_value = NULL;
+ if (!dict->GetWithoutPathExpansion("recursive", &recursive_value))
+ return nullptr;
+ if (!recursive_value->GetAsBoolean(&out->recursive))
+ return nullptr;
+ return out;
+}
+
+DeleteEntryOperationTranslator::DeleteEntryOperationTranslator(){}
+
+MoveOperationTranslator::~MoveOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+MoveOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_MOVEENTRY;
+ out->request_id = request_id;
+ out->value.as_move_entry.source_path = source_path.c_str();
+ out->value.as_move_entry.target_path = target_path.c_str();
+ return out.Pass();
+}
+
+scoped_refptr<MoveOperationTranslator>
+MoveOperationTranslator::PopulateFromRequest(const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<MoveOperationTranslator> out(new MoveOperationTranslator());
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* source_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value))
+ return nullptr;
+ if (!source_path_value->GetAsString(&out->source_path))
+ return nullptr;
+
+ const base::Value* target_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value))
+ return nullptr;
+ if (!target_path_value->GetAsString(&out->target_path))
+ return nullptr;
+ return out;
+}
+
+MoveOperationTranslator::MoveOperationTranslator(){}
+
+PP_OpenFileMode_Dev ParseOpenFileMode( const std::string &mode ) {
+ if (mode=="WRITE")
+ return PP_OpenFileMode_WRITE;
+ else if ( mode=="READ" )//( mode=="read")
+ return PP_OpenFileMode_READ;
+ else
+ return PP_OpenFileMode_NONE;
+}
+
+
+OpenFileOperationTranslator::~OpenFileOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+OpenFileOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_OPENFILE;
+ out->request_id = request_id;
+ out->value.as_open_file.file_path = file_path.c_str();
+ out->value.as_open_file.mode = mode;
+ return out.Pass();
+}
+
+//static
+scoped_refptr<OpenFileOperationTranslator>
+OpenFileOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<OpenFileOperationTranslator>
+ out(new OpenFileOperationTranslator());
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* file_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
+ return nullptr;
+ if (!file_path_value->GetAsString(&out->file_path))
+ return nullptr;
+
+ const base::Value* mode_value = NULL;
+ if (!dict->GetWithoutPathExpansion("mode", &mode_value))
+ return nullptr;
+ std::string open_file_mode_as_string;
+ if (!mode_value->GetAsString(&open_file_mode_as_string))
+ return nullptr;
+ out->mode = ParseOpenFileMode(open_file_mode_as_string);
+
+ return out;
+}
+
+OpenFileOperationTranslator::OpenFileOperationTranslator(){}
+
+ReadDirectoryOperationTranslator::~ReadDirectoryOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+ReadDirectoryOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_READDIRECTORY;
+ out->request_id = request_id;
+ out->value.as_read_directory.directory_path = directory_path.c_str();
+ return out.Pass();
+}
+
+scoped_refptr<ReadDirectoryOperationTranslator>
+ReadDirectoryOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<ReadDirectoryOperationTranslator>
+ out(new ReadDirectoryOperationTranslator());
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* directory_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value))
+ return nullptr;
+ if (!directory_path_value->GetAsString(&out->directory_path))
+ return nullptr;
+ return out;
+}
+
+ReadDirectoryOperationTranslator::ReadDirectoryOperationTranslator(){}
+
+ReadFileOperationTranslator::~ReadFileOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+ReadFileOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return scoped_ptr<PP_FilesystemRequest>();
+ out->operation_type = PP_OperationType_READFILE;
+ out->request_id = request_id;
+ out->value.as_read_file.open_request_id = open_request_id;
+ out->value.as_read_file.offset = offset;
+ out->value.as_read_file.length = length;
+ return out.Pass();
+}
+
+scoped_refptr<ReadFileOperationTranslator>
+ReadFileOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+ scoped_refptr<ReadFileOperationTranslator>
+ out(new ReadFileOperationTranslator());
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* open_request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
+ return nullptr;
+ if (!open_request_id_value->GetAsInteger(&out->open_request_id))
+ return nullptr;
+
+ const base::Value* offset_value = NULL;
+ if (!dict->GetWithoutPathExpansion("offset", &offset_value))
+ return nullptr;
+ if (!offset_value->GetAsDouble(&out->offset))
+ return nullptr;
+
+ const base::Value* length_value = NULL;
+ if (!dict->GetWithoutPathExpansion("length", &length_value))
+ return nullptr;
+ if (!length_value->GetAsDouble(&out->length))
+ return nullptr;
+ return out;
+}
+
+ReadFileOperationTranslator::ReadFileOperationTranslator(){}
+
+TruncateOperationTranslator::~TruncateOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+TruncateOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_TRUNCATEENTRY;
+ out->request_id = request_id;
+ out->value.as_truncate.length = length;
+ out->value.as_truncate.file_path = file_path.c_str();
+ return out.Pass();
+}
+
+scoped_refptr<TruncateOperationTranslator>
+TruncateOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<TruncateOperationTranslator>
+ out(new TruncateOperationTranslator());
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* file_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
+ return nullptr;
+ if (!file_path_value->GetAsString(&out->file_path))
+ return nullptr;
+
+ const base::Value* length_value = NULL;
+ if (!dict->GetWithoutPathExpansion("length", &length_value))
+ return nullptr;
+ if (!length_value->GetAsDouble(&out->length))
+ return nullptr;
+ return out;
+}
+
+TruncateOperationTranslator::TruncateOperationTranslator(){}
+
+UnmountOperationTranslator::~UnmountOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+UnmountOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return scoped_ptr<PP_FilesystemRequest>();
+ out->operation_type = PP_OperationType_UNMOUNT;
+ out->request_id = request_id;
+ return out.Pass();
+}
+
+scoped_refptr<UnmountOperationTranslator>
+UnmountOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request) {
+
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<UnmountOperationTranslator>
+ out(new UnmountOperationTranslator());
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+ return out;
+}
+
+UnmountOperationTranslator::UnmountOperationTranslator(){}
+
+WriteFileOperationTranslator::~WriteFileOperationTranslator(){}
+
+scoped_ptr<PP_FilesystemRequest>
+WriteFileOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return nullptr;
+ out->operation_type = PP_OperationType_WRITEFILE;
+ out->request_id = request_id;
+ out->value.as_write_file.open_request_id = open_request_id;
+ out->value.as_write_file.offset = offset;
+ out->value.as_write_file.data_size = data.size();
+ // Pass the address
+ if(data.size())
+ out->value.as_write_file.data = &data[0];
+ else // or NULL if the browser sent an empty write request
+ out->value.as_write_file.data = NULL;
+ return out.Pass();
+}
+
+scoped_refptr<WriteFileOperationTranslator>
+WriteFileOperationTranslator::PopulateFromRequest(
+ const base::ListValue &request,
+ char* memory_address) {
+
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<WriteFileOperationTranslator>
+ out(new WriteFileOperationTranslator());
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+
+ const base::Value* open_request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
+ return nullptr;
+ if (!open_request_id_value->GetAsInteger(&out->open_request_id))
+ return nullptr;
+
+ const base::Value* offset_value = NULL;
+ if (!dict->GetWithoutPathExpansion("offset", &offset_value))
+ return nullptr;
+ if (!offset_value->GetAsDouble(&out->offset))
+ return nullptr;
+
+ const base::Value* size_value = NULL;
+ if (!dict->GetWithoutPathExpansion("size", &size_value))
+ return nullptr;
+ if (!size_value->GetAsDouble(&out->size))
+ return nullptr;
+
+ // Buffer what will be cached until released by the FS implementation
+ out->data.assign(memory_address,
+ memory_address+static_cast<size_t>(out->size));
+ return out;
+}
+
+WriteFileOperationTranslator::WriteFileOperationTranslator(){}
+
+OperationTranslator::~OperationTranslator(){}
+
+scoped_ptr<base::ListValue>
+PluginToBrowserTranslator::GenerateReadFileSuccessResponse(
+ uint32_t data_size, bool has_more, int32_t request_id,
+ int time_span, const std::string& filesystem_id) {
+ size_t index = 0;
+ scoped_ptr<base::ListValue> response(new base::ListValue);
+ if( !response->Set(index++,
+ new base::FundamentalValue(PP_OperationType_READFILE))||
+ !response->Set(index++, new base::FundamentalValue(true))||// status = success
+ !response->Set(index++,
+ new base::StringValue(filesystem_id)) ||
+ !response->Set(index++, new base::FundamentalValue(request_id)) ||
+ !response->Set(index++, new base::FundamentalValue(
+ static_cast<double>(data_size)))||
+ !response->Set(index++, new base::FundamentalValue(has_more))||
+ !response->Set(index++, new base::FundamentalValue(time_span)))
+ return scoped_ptr<base::ListValue>();
+ return response.Pass();
+}
+
+AddWatcherOperationTranslator::~AddWatcherOperationTranslator() {}
+
+scoped_ptr<PP_FilesystemRequest>
+AddWatcherOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return scoped_ptr<PP_FilesystemRequest>();
+ out->operation_type = PP_OperationType_ADDWATCHER;
+ out->request_id = request_id;
+ out->value.as_add_watcher.entry_path = this->entry_path.c_str();
+ out->value.as_add_watcher.recursive = PP_FromBool(this->recursive);
+ return out.Pass();
+}
+
+scoped_refptr<AddWatcherOperationTranslator>
+AddWatcherOperationTranslator::PopulateFromRequest(
+ const base::ListValue& request) {
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<AddWatcherOperationTranslator>
+ out(new AddWatcherOperationTranslator());
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+ const base::Value* entry_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
+ return nullptr;
+ if (!entry_path_value->GetAsString(&out->entry_path))
+ return nullptr;
+ const base::Value* recursive_value = NULL;
+ if (!dict->GetWithoutPathExpansion("recursive",&recursive_value))
+ return nullptr;
+ if (!recursive_value->GetAsBoolean(&out->recursive))
+ return nullptr;
+
+ return out;
+}
+
+AddWatcherOperationTranslator::AddWatcherOperationTranslator() {}
+
+RemoveWatcherOperationTranslator::~RemoveWatcherOperationTranslator() {
+
+}
+
+scoped_ptr<PP_FilesystemRequest>
+RemoveWatcherOperationTranslator::ToFilesystemRequest() {
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
+ if(!out.get())
+ return scoped_ptr<PP_FilesystemRequest>();
+ out->operation_type = PP_OperationType_REMOVEWATCHER;
+ out->request_id = request_id;
+ out->value.as_add_watcher.entry_path = this->entry_path.c_str();
+ out->value.as_add_watcher.recursive = PP_FromBool(this->recursive);
+ return out.Pass();
+}
+
+scoped_refptr<RemoveWatcherOperationTranslator>
+RemoveWatcherOperationTranslator::PopulateFromRequest(
+ const base::ListValue& request){
+ if( request.empty() )
+ return nullptr;
+
+ const base::Value *dict_value = nullptr;
+ if(!request.Get(0,&dict_value))
+ return nullptr;
+
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
+ return nullptr;
+
+ scoped_refptr<RemoveWatcherOperationTranslator>
+ out(new RemoveWatcherOperationTranslator());
+
+ const base::DictionaryValue* dict =
+ static_cast<const base::DictionaryValue*>(dict_value);
+ const base::Value* file_system_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
+ return nullptr;
+ if (!file_system_id_value->GetAsString(&out->file_system_id))
+ return nullptr;
+ const base::Value* request_id_value = NULL;
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
+ return nullptr;
+ if (!request_id_value->GetAsInteger(&out->request_id))
+ return nullptr;
+ const base::Value* entry_path_value = NULL;
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
+ return nullptr;
+ if (!entry_path_value->GetAsString(&out->entry_path))
+ return nullptr;
+ const base::Value* recursive_value = NULL;
+ if (!dict->GetWithoutPathExpansion("recursive",&recursive_value))
+ return nullptr;
+ if (!recursive_value->GetAsBoolean(&out->recursive))
+ return nullptr;
+
+ return out;
+}
+
+RemoveWatcherOperationTranslator::RemoveWatcherOperationTranslator() {}
+
+scoped_ptr<base::ListValue>
+PluginToBrowserTranslator::GenerateMountMessage(
+ std::string filesystem_id, std::string display_name,
+ bool writable, int32_t opened_files_limit) {
+
+ scoped_ptr<base::DictionaryValue> payload(new base::DictionaryValue);
+ if(!payload.get())
+ return scoped_ptr<base::ListValue>();
+ payload->Set("fileSystemId",
+ new base::StringValue(filesystem_id));
+ payload->Set("displayName",
+ new base::StringValue(display_name));
+ payload->Set("writable",
+ new base::FundamentalValue(writable));
+ payload->Set("openedFilesLimit",
+ new base::FundamentalValue(opened_files_limit));
+ scoped_ptr<base::ListValue> response(new base::ListValue);
+ if(!response.get())
+ return scoped_ptr<base::ListValue>();
+ response->Set(0,payload.release());
+ return response.Pass();
+}
+
+scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateNotifyMessage(
+ PP_Var notification_options) {
+ scoped_ptr<base::DictionaryValue> notification(new base::DictionaryValue);
+
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(notification_options);
+ if(!dict_var)
+ return nullptr;
+ for (DictionaryVar::KeyValueMap::const_iterator iter =
+ dict_var->key_value_map().begin();
+ iter != dict_var->key_value_map().end();
+ ++iter) {
+ const std::string& key = iter->first;
+ const PP_Var& child_var = iter->second.get();
+ switch(child_var.type) {
+ case PP_VARTYPE_STRING: {
+ StringVar* string = StringVar::FromPPVar(child_var);
+ if(!string)
+ return nullptr;
+ const std::string& value = string->value();
+
+ if (key=="fileSystemId") {
+ notification->SetString(key,value);
+ } else if (key== "observedPath") {
+ notification->SetString(key,value);
+ } else if(key=="tag") {
+ notification->SetString(key,value);
+ } else return nullptr;
+ break;
+ }
+ case PP_VARTYPE_BOOL: {
+ if(key!="recursive")
+ return nullptr;
+ notification->SetBoolean("recursive", child_var.value.as_bool);
+ break;
+ }
+ case PP_VARTYPE_INT32: {
+ if (key!="changeType")
+ return nullptr;
+ if (child_var.value.as_int!=PP_ChangeType_CHANGED &&
+ child_var.value.as_int!=PP_ChangeType_DELETED)
+ return nullptr;
+ notification->SetString( "changeType",
+ child_var.value.as_int!=PP_ChangeType_CHANGED ?
+ "DELETED" : "CHANGED" );
+ break;
+ }
+ case PP_VARTYPE_ARRAY: {
+ if (key!="changes")
+ return nullptr;
+ scoped_ptr<base::ListValue> changes(new base::ListValue);
+ if (!changes)
+ return nullptr;
+ ArrayVar* array_var = ArrayVar::FromPPVar(child_var);
+ if(!array_var)
+ return nullptr;
+ for( size_t i = 0; i < array_var->elements().size(); ++i ) {
+ const PP_Var& c_child_var = array_var->elements()[i].get();
+ if( c_child_var.type != PP_VARTYPE_DICTIONARY )
+ return nullptr;
+ DictionaryVar* c = DictionaryVar::FromPPVar(c_child_var);
+ if (!c)
+ return nullptr;
+ scoped_ptr<base::DictionaryValue> change(new base::DictionaryValue);
+ if (!change)
+ return nullptr;
+ for (DictionaryVar::KeyValueMap::const_iterator c_iter =
+ c->key_value_map().begin();
+ c_iter != c->key_value_map().end();
+ ++c_iter) {
+ const std::string& c_key = c_iter->first;
+ const PP_Var& c_child_var = c_iter->second.get();
+ switch(c_child_var.type) {
+ case PP_VARTYPE_STRING:{
+ StringVar* string = StringVar::FromPPVar(c_child_var);
+ if(!string)
+ return nullptr;
+ const std::string& c_value = string->value();
+ if (c_key=="entryPath")
+ change->SetString(c_key, c_value);
+ else
+ return nullptr;
+ break;
+ }
+ case PP_VARTYPE_INT32: {
+ if (c_key=="changeType")
+ change->SetString(
+ c_key,
+ c_child_var.value.as_int!=PP_ChangeType_CHANGED ?
+ "DELETED" : "CHANGED");
+ else
+ return nullptr;
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ }
+ changes->Append(change.release());
+ }
+ notification->Set(key,changes.release());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ }
+
+ scoped_ptr<base::ListValue> message(new base::ListValue);
+ if (!message.get())
+ return nullptr;
+
+ message->Append(notification.release());
+ return message.Pass();
+}
+
+scoped_ptr<base::ListValue>
+PluginToBrowserTranslator::GenerateSuccessResponse(
+ PP_OperationType_Dev operation_type,
+ const std::string &filesystem_id,
+ int32_t request_id, int time_span) {
+
+ scoped_ptr<base::ListValue> response(new base::ListValue);
+ if(!response.get())
+ return scoped_ptr<base::ListValue>();
+ size_t index = 0;
+ if ( !response->Set(index++, new base::FundamentalValue(operation_type))||
+ !response->Set(index++,
+ new base::FundamentalValue(true)) || // status = success
+ !response->Set(index++,
+ new base::StringValue(filesystem_id))||
+ !response->Set(index++, new base::FundamentalValue(request_id)) ||
+ !response->Set(index++, new base::FundamentalValue(time_span))) {
+ return scoped_ptr<base::ListValue>();
+ }
+ return response.Pass();
+}
+
+scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateFailureResponse(
+ PP_OperationType_Dev operation_type, int32_t error,
+ const std::string &filesystem_id, int32_t request_id, int time_span) {
+ scoped_ptr<base::ListValue> response(new base::ListValue);
+ if(!response.get())
+ return scoped_ptr<base::ListValue>();
+ size_t index=0;
+ if ( !response->Set(index++, new base::FundamentalValue(operation_type)) ||
+ !response->Set(index++,
+ new base::FundamentalValue(false)) || // status = failure
+ !response->Set(index++,
+ new base::StringValue(filesystem_id)) ||
+ !response->Set(index++, new base::FundamentalValue(request_id)) ||
+ !response->Set(index++,
+ new base::StringValue(PP_ErrorToString(error))) ||
+ !response->Set(index++, new base::FundamentalValue(time_span) ) )
+ return scoped_ptr<base::ListValue>();
+ return response.Pass();
+}
+
+scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateMetadataResponse(
+ PP_Var metadata, int32_t request_id,
+ const std::string &filesystem_id, int time_span) {
+
+ scoped_ptr<base::DictionaryValue> entry_metadata=
+ GenerateMetadataListFromPPVar( metadata );
+ if(!entry_metadata.get())
+ return nullptr;
+ scoped_ptr<base::ListValue> response(new base::ListValue);
+ size_t index = 0;
+ if (!response->Set(index++,
+ new base::FundamentalValue(PP_OperationType_GETMETADATA))||
+ !response->Set(index++, new base::FundamentalValue(true))|| //status = success
+ !response->Set(index++,
+ new base::StringValue(filesystem_id) ) ||
+ !response->Set(index++, new base::FundamentalValue(request_id) ) ||
+ !response->Set(index++, entry_metadata.release() ) ||
+ !response->Set(index++, new base::FundamentalValue(time_span) ) )
+ return nullptr;
+ return response.Pass();
+}
+
+scoped_ptr<base::ListValue>
+PluginToBrowserTranslator::GenerateReadDirectoryResponse(
+ PP_Var entries,
+ PP_Bool has_more, int32_t request_id,
+ const std::string &filesystem_id, int time_span) {
+
+ scoped_ptr<base::ListValue> response(new base::ListValue);
+ scoped_ptr<base::ListValue> list_value(new base::ListValue);
+ if(!list_value.get()||
+ !response.get())
+ return nullptr;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(entries);
+ if(!array_var)
+ return nullptr;
+
+ scoped_ptr<base::DictionaryValue> entry_metadata;
+ for( size_t i = 0; i < array_var->elements().size(); ++i ) {
+ const PP_Var& child_var = array_var->elements()[i].get();
+ if( child_var.type != PP_VARTYPE_DICTIONARY )
+ return nullptr;
+ entry_metadata = GenerateMetadataListFromPPVar(child_var);
+ if(!entry_metadata.get())
+ return nullptr;
+ list_value->Set(i,entry_metadata.release());
+ }
+
+ size_t index = 0;
+ if (!response->Set(index++,
+ new base::FundamentalValue(PP_OperationType_READDIRECTORY))||
+ !response->Set(index++,
+ new base::FundamentalValue(true))|| // status = success
+ !response->Set(index++,
+ new base::StringValue(filesystem_id) ) ||
+ !response->Set(index++, new base::FundamentalValue(request_id) ) ||
+ !response->Set(index++, list_value.release() ) ||
+ !response->Set(index++,
+ new base::FundamentalValue( PP_ToBool( has_more ) ) ) ||
+ !response->Set(index++, new base::FundamentalValue( time_span ) ) )
+ return scoped_ptr<base::ListValue>();
+ return response.Pass();
+}
+
+scoped_ptr<base::DictionaryValue>
+PluginToBrowserTranslator::GenerateMetadataListFromPPVar(PP_Var metadata) {
+ scoped_ptr<base::DictionaryValue> entry_metadata(new base::DictionaryValue);
+ if(!entry_metadata.get())
+ return nullptr;
+
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(metadata);
+ if(!dict_var)
+ return nullptr;
+ for (DictionaryVar::KeyValueMap::const_iterator iter =
+ dict_var->key_value_map().begin();
+ iter != dict_var->key_value_map().end();
+ ++iter) {
+ const std::string& key = iter->first;
+ const PP_Var& child_var = iter->second.get();
+ switch(child_var.type) {
+ case PP_VARTYPE_STRING:{
+ StringVar* string = StringVar::FromPPVar(child_var);
+ if(!string)
+ return nullptr;
+ const std::string& value = string->value();
+
+ if (key=="modificationTime") {
+ scoped_ptr<base::DictionaryValue>
+ modification_time(new base::DictionaryValue());
+ if(!modification_time.get())
+ return nullptr;
+ modification_time->SetStringWithoutPathExpansion(
+ "value", value);
+ entry_metadata->Set(key, modification_time.release());
+ } else if (key=="name"||key=="mimeType"||key=="thumbnail") {
+ entry_metadata->SetString(key,value);
+ } else {
+ return nullptr;
+ }
+ break;
+ }
+ case PP_VARTYPE_BOOL: {
+ if(key!="isDirectory")
+ return nullptr;
+ entry_metadata->SetBoolean("isDirectory", child_var.value.as_bool);
+ break;
+ }
+ case PP_VARTYPE_DOUBLE: {
+ if (key!="size")
+ return nullptr;
+ entry_metadata->SetDouble("size", child_var.value.as_double );
+ break;
+ }
+ default:
+ return nullptr;
+ }
+ }
+ return entry_metadata.Pass();
+}
+
+
+
+} // namespace
+} // namespace proxy
+} // namespace ppapi
« no previous file with comments | « ppapi/proxy/filesystem_provider_resource.h ('k') | ppapi/proxy/filesystem_provider_resource_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698