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

Side by Side 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: Various cleanups Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include "ppapi/proxy/filesystem_provider_resource.h"
5
6 #include "base/bind.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/numerics/safe_conversions.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/proxy/dispatch_reply_message.h"
12 #include "ppapi/proxy/plugin_dispatcher.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/shared_impl/ppapi_globals.h"
15 #include "ppapi/shared_impl/proxy_lock.h"
16 #include "ppapi/shared_impl/tracked_callback.h"
17 #include "ppapi/shared_impl/var.h"
18 #include "ppapi/shared_impl/var_tracker.h"
19
20 namespace ppapi {
21 namespace proxy {
22 namespace {
23
24 const uint32_t kMaximumCachedReplies = 10;
25
26 static std::string PP_ProviderErrorToString(PP_ProviderError_Dev enum_param) {
27 switch (enum_param) {
28 case PP_ProviderError_OK:
29 return "OK";
30 case PP_ProviderError_FAILED:
31 return "FAILED";
32 case PP_ProviderError_IN_USE:
33 return "IN_USE";
34 case PP_ProviderError_EXISTS:
35 return "EXISTS";
36 case PP_ProviderError_NOT_FOUND:
37 return "NOT_FOUND";
38 case PP_ProviderError_ACCESS_DENIED:
39 return "ACCESS_DENIED";
40 case PP_ProviderError_TOO_MANY_OPENED:
41 return "TOO_MANY_OPENED";
42 case PP_ProviderError_NO_MEMORY:
43 return "NO_MEMORY";
44 case PP_ProviderError_NO_SPACE:
45 return "NO_SPACE";
46 case PP_ProviderError_NOT_A_DIRECTORY:
47 return "NOT_A_DIRECTORY";
48 case PP_ProviderError_INVALID_OPERATION:
49 return "INVALID_OPERATION";
50 case PP_ProviderError_SECURITY:
51 return "SECURITY";
52 case PP_ProviderError_ABORT:
53 return "ABORT";
54 case PP_ProviderError_NOT_A_FILE:
55 return "NOT_A_FILE";
56 case PP_ProviderError_NOT_EMPTY:
57 return "NOT_EMPTY";
58 case PP_ProviderError_INVALID_URL:
59 return "INVALID_URL";
60 case PP_ProviderError_IO:
61 return "IO";
62 case PP_ProviderError_NONE:
63 return "";
64 }
65 NOTREACHED();
66 return "";
67 }
68
69 } // namespace
70
71 FilesystemProviderResource::ShmChannelSynchronizer::ShmChannelSynchronizer(
72 uint32_t size, FlushResponseCallback callback)
73 : max_size(size),
74 ready(true),
75 callback(callback){
76 }
77 FilesystemProviderResource::ShmChannelSynchronizer::~ShmChannelSynchronizer() {
78 }
79
80 bool FilesystemProviderResource::ShmChannelSynchronizer::EnqueueResponse(
81 scoped_ptr<base::ListValue> response,
82 const char* data, uint32_t data_size) {
83 // If channel ready send it straight away
84 if (ready) {
85 // Flush Request
86 ready = !callback.Run(response.Pass(), data, data_size);
87 if(!ready)
88 return true;
89 }
90 // If channel is not ready or failed to send,
91 // cache the response
92 if( size() + 1 > max_size )
93 return false;
94
95 // TODO(sabin): Find a better way to cached data
96 scoped_ptr<base::BinaryValue> payload(
97 base::BinaryValue::CreateWithCopiedBuffer(static_cast< const char*>(data),
98 data_size));
99 if( !payload.get() )
100 return false;
101
102 response->Append(payload.release());
103 replies.push_back(response.release());
104
105 return true;
106 }
107
108 bool FilesystemProviderResource::ShmChannelSynchronizer::PushNextResponse() {
109 scoped_ptr<base::ListValue> response;
110 scoped_ptr<base::Value> payload;
111 while (size()>0 && ready ) {
112 // Try to push a response from the queue to
113 // the browser
114 response.reset(replies.front());
115 replies.weak_erase(replies.begin());
116
117 if(!response->Remove(response->GetSize()-1, &payload)||
118 !payload->IsType(base::Value::TYPE_BINARY))
119 continue;
120
121 base::BinaryValue* data = static_cast<base::BinaryValue*>(payload.get());
122 ready = !callback.Run(
123 response.Pass(),
124 data->GetBuffer(),
125 data->GetSize());
126 }
127 return !ready;
128 }
129
130 bool
131 FilesystemProviderResource::ShmChannelSynchronizer::AckLastPushedResponse() {
132 return ready = true;
133 }
134
135 uint32_t FilesystemProviderResource::ShmChannelSynchronizer::size() {
136 return replies.size();
137 }
138
139 FilesystemProviderResource::ProvidedFilesystemInfo::ProvidedFilesystemInfo()
140 :filesystem_id("none"),
141 display_name("none"),
142 writable(false),opened_files_limit(0){
143 }
144
145 FilesystemProviderResource::ProvidedFilesystemInfo::~ProvidedFilesystemInfo() {
146 }
147
148 FilesystemProviderResource::ShmBuffer::ShmBuffer(
149 uint32_t read_size, uint32_t write_size,
150 scoped_ptr<base::SharedMemory> shm)
151 : read_size(read_size),write_size(write_size), shm(shm.Pass()) {
152 DCHECK(this->shm);
153 }
154
155 FilesystemProviderResource::ShmBuffer::~ShmBuffer() {
156 }
157
158 FilesystemProviderResource::RequestManager::RequestManager() {
159
160 }
161
162 FilesystemProviderResource::RequestManager::~RequestManager() {
163
164 }
165
166 void FilesystemProviderResource::RequestManager::AddRequest(
167 int32_t request_id, PP_OperationType_Dev operation ) {
168 requests_[ request_id ] = OperationStartTimePair(
169 operation,
170 std::chrono::system_clock::now() );
171 }
172
173 bool FilesystemProviderResource::RequestManager::RemoveRequest(
174 int32_t request_id, double *out_time_span) {
175 ListOfRequestsIterator it=requests_.find(request_id);
176 if (it==requests_.end())
177 return false;
178
179 // Compute operation time span
180 std::chrono::time_point<std::chrono::system_clock> now =
181 std::chrono::system_clock::now();
182 std::chrono::duration<double> elapsed_seconds = now - it->second.second;
183 if(out_time_span)
184 *out_time_span = elapsed_seconds.count();
185 requests_.erase( it );
186 return true;
187 }
188
189 FilesystemProviderResource::FilesystemProviderResource(
190 Connection connection,
191 PP_Instance instance )
192 :PluginResource( connection , instance ),
193 mounted_(false),
194 request_manager_(new RequestManager),
195 read_channel_controller_(
196 new ShmChannelSynchronizer(
197 kMaximumCachedReplies,
198 base::Bind(&FilesystemProviderResource::FlushReadResponse,
199 this))) {
200 DCHECK(request_manager_);
201 DCHECK(read_channel_controller_);
202 SendCreate(BROWSER, PpapiHostMsg_FilesystemProvider_Create() );
203 }
204
205 FilesystemProviderResource::~FilesystemProviderResource() {
206 }
207
208
209 thunk::PPB_FilesystemProvider_API*
210 FilesystemProviderResource::AsPPB_FilesystemProvider_API() {
211 return this;
212 }
213
214 void FilesystemProviderResource::OnReplyReceived(
215 const ResourceMessageReplyParams &params, const IPC::Message &msg) {
216 if (params.sequence()) {
217 PluginResource::OnReplyReceived(params, msg);
218 return;
219 }
220 PPAPI_BEGIN_MESSAGE_MAP(FilesystemProviderResource, msg)
221 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
222 PpapiPluginMsg_FilesystemProvider_OperationRequest,
223 OnPluginMsgOperationRequest)
224 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
225 PpapiPluginMsg_FilesystemProvider_Buffers,
226 OnPluginMsgBuffersReady)
227 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_0(
228 PpapiPluginMsg_FilesystemProvider_ReadAck,
229 OnPluginMsgReadAck)
230 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED())
231 PPAPI_END_MESSAGE_MAP()
232 }
233
234 int32_t FilesystemProviderResource::Mount(
235 PP_Var filesystem_id,
236 PP_Var display_name,
237 PP_Bool writable,
238 int32_t opened_files_limit,
239 PP_ProviderError_Dev *error,
240 scoped_refptr<TrackedCallback> callback) {
241
242 if (error==nullptr)
243 return PP_ERROR_BADARGUMENT;
244 if ( mounted_ )
245 return PP_ERROR_ADDRESS_IN_USE;
246 if ( TrackedCallback::IsPending(mount_callback_) )
247 return PP_ERROR_INPROGRESS;
248
249 StringVar* string_var = nullptr;
250
251 const PP_Var *parameter_p[] = { &filesystem_id, &display_name };
252 std::string *value_p[] = {
253 &filesystem_info_.filesystem_id,
254 &filesystem_info_.display_name
255 };
256
257 for( uint32_t i = 0; i < sizeof( value_p ) / sizeof( value_p[0] ); i++ ) {
258 string_var = StringVar :: FromPPVar( *parameter_p[ i ] );
259 *value_p[ i ] = string_var ? string_var->value() : std::string();
260 }
261
262 filesystem_info_.writable = PP_ToBool( writable );
263 filesystem_info_.opened_files_limit = opened_files_limit;
264
265 // Remember the callback and the address of the return param
266 mount_callback_ = callback;
267 mount_callback_var_ = error;
268
269 // Send mount request to the browser
270 // and receive response in OnPluginMsgMountReply
271 scoped_ptr<base::ListValue> request(
272 filesystem_provider_internal::
273 PluginToBrowserTranslator::GenerateMountRequest(
274 filesystem_info_.filesystem_id, filesystem_info_.display_name,
275 filesystem_info_.writable,filesystem_info_.opened_files_limit));
276 if (!request.get())
277 return PP_ERROR_FAILED;
278
279 Call<PpapiPluginMsg_FilesystemProvider_MountReply>(
280 BROWSER,
281 PpapiHostMsg_FilesystemProvider_Mount(*request),
282 base::Bind(&FilesystemProviderResource::OnPluginMsgMountReply, this)
283 );
284 return PP_OK_COMPLETIONPENDING;
285 }
286
287 int32_t FilesystemProviderResource::Unmount(
288 PP_Var filesystemId,
289 PP_ProviderError_Dev *error,
290 scoped_refptr<TrackedCallback> callback ) {
291 if ( !mounted_ )
292 return PP_ERROR_FAILED;
293 if ( TrackedCallback::IsPending(unmount_callback_) )
294 return PP_ERROR_INPROGRESS;
295
296 StringVar* string_var = nullptr;
297
298 string_var = StringVar::FromPPVar( filesystemId );
299 std::string fs_id = string_var ? string_var->value() : std::string();
300
301 if (fs_id!=filesystem_info_.filesystem_id)
302 return PP_ERROR_FAILED;
303
304 // Remember the unmount callback and the address of the return param
305 unmount_callback_ =callback;
306 unmount_callback_var_ =error;
307
308 Call < PpapiPluginMsg_FilesystemProvider_UnmountReply >(
309 BROWSER,
310 PpapiHostMsg_FilesystemProvider_Unmount( fs_id ),
311 base::Bind( &FilesystemProviderResource::OnPluginMsgUnmountReply,
312 this )
313 );
314
315 return PP_OK_COMPLETIONPENDING;
316 }
317
318
319 int32_t FilesystemProviderResource::SendSuccessResponse(
320 PP_OperationType_Dev operation_type,
321 int32_t request_id) {
322
323 scoped_ptr<base::ListValue> response;
324
325 switch( operation_type ) {
326 case PP_OperationType_GETMETADATA:
327 case PP_OperationType_READDIRECTORY:
328 case PP_OperationType_READFILE:
329 return PP_ERROR_BADARGUMENT;
330 default: {
331 // If we can't find a matching request from the browser
332 // bail out
333 double time_span = 0;
334 if( !request_manager_->RemoveRequest(request_id, &time_span) )//
335 return PP_ERROR_BADARGUMENT;
336 response = filesystem_provider_internal::
337 PluginToBrowserTranslator::GenerateSuccessResponse(
338 operation_type, filesystem_info_.filesystem_id,
339 request_id, time_span );
340 if(!response.get())
341 return PP_ERROR_FAILED;
342 }
343 }
344 Post(
345 BROWSER,
346 PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
347 return PP_OK;
348 }
349
350 int32_t FilesystemProviderResource::SendErrorResponse(
351 PP_OperationType_Dev operation_type,
352 PP_ProviderError_Dev error,
353 int32_t request_id) {
354
355 double time_span = 0;
356 if( !request_manager_->RemoveRequest(request_id, &time_span) )
357 return PP_ERROR_BADARGUMENT;
358
359 scoped_ptr<base::ListValue> response(
360 filesystem_provider_internal::
361 PluginToBrowserTranslator::GenerateFailureResponse(
362 operation_type, error, filesystem_info_.filesystem_id, request_id,
363 time_span ));
364 if(!response.get())
365 return PP_ERROR_FAILED;
366
367 Post(
368 BROWSER,
369 PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
370 return PP_OK;
371 }
372
373 int32_t FilesystemProviderResource::SendMetadataSuccessResponse(
374 const PP_EntryMetadata_Dev *metadata,
375 int32_t request_id) {
376 if(NULL==metadata)
377 return PP_ERROR_BADARGUMENT;
378
379 double time_span = 0;
380 if( !request_manager_->RemoveRequest(request_id, &time_span) )
381 return PP_ERROR_BADARGUMENT;
382
383 scoped_ptr<base::ListValue> response(
384 filesystem_provider_internal::
385 PluginToBrowserTranslator::GenerateMetadataResponse(
386 metadata, request_id, filesystem_info_.filesystem_id, time_span));
387 if(!response.get())
388 return PP_ERROR_FAILED;
389
390 Post(
391 BROWSER,
392 PpapiHostMsg_FilesystemProvider_OperationResponse(*response)
393 );
394 return PP_OK;
395 }
396
397 int32_t FilesystemProviderResource::SendReadDirectorySuccessResponse(
398 uint32_t array_size,
399 const PP_EntryMetadata_Dev entries[],
400 PP_Bool has_more, int32_t request_id) {
401
402 double time_span = 0;
403 if( !request_manager_->RemoveRequest(request_id, &time_span) )//
404 return PP_ERROR_BADARGUMENT;
405
406 scoped_ptr<base::ListValue> response(
407 filesystem_provider_internal::
408 PluginToBrowserTranslator::GenerateReadDirectoryResponse(
409 array_size, entries, has_more, request_id,
410 filesystem_info_.filesystem_id, time_span ));
411
412 if(!response.get())
413 return PP_ERROR_FAILED;
414 Post(
415 BROWSER,
416 PpapiHostMsg_FilesystemProvider_OperationResponse(*response) );
417 return PP_OK;
418 }
419
420 int32_t FilesystemProviderResource::SendReadFileSuccessResponse(
421 uint32_t data_size,
422 const void *data,
423 PP_Bool has_more,
424 int32_t request_id) {
425
426 double time_span = 0;
427 // Check if this is an answer to a previous request
428 if( !request_manager_->RemoveRequest(request_id, &time_span) )//
429 return PP_ERROR_BADARGUMENT;
430 // check if shared memory is ready and the right size
431 if(!read_write_buffer_.get())
432 return PP_ERROR_FAILED;
433 if(data_size > read_write_buffer_->read_size )
434 return PP_ERROR_MESSAGE_TOO_BIG;
435
436 scoped_ptr<base::ListValue> response(
437 filesystem_provider_internal::
438 PluginToBrowserTranslator::GenerateReadFileSuccessResponse(
439 data_size, PP_ToBool( has_more ), request_id, time_span,
440 filesystem_info_.filesystem_id));
441
442 if(!response.get())
443 return PP_ERROR_FAILED;
444
445 // Send response or enqueue it
446 if(!read_channel_controller_->EnqueueResponse(
447 response.Pass(), static_cast<const char*>(data),data_size))
448 return PP_ERROR_FAILED;
449 return PP_OK;
450 }
451
452 int32_t FilesystemProviderResource::GetNextRequest(
453 PP_FilesystemRequest* request, scoped_refptr<TrackedCallback> callback) {
454 if(TrackedCallback::IsPending(get_next_request_callback_))
455 return PP_ERROR_INPROGRESS;
456 // Retain the container address
457 get_next_request_callback_var_ = request;
458 // If buffered requests are pending return the first one
459 if(!received_requests_.empty()) {
460 if(!WriteRequest())
461 return PP_ERROR_FAILED;
462 // By returning PP_OK the callback is run
463 return PP_OK;
464 }
465 // Retain the callback for future execution
466 get_next_request_callback_=callback;
467
468 return PP_OK_COMPLETIONPENDING;
469 }
470
471 int32_t FilesystemProviderResource::FreeWriteRequestBuffer(const void* buffer) {
472 using namespace filesystem_provider_internal;
473 WriteFileOperationTranslator* request=nullptr;
474 if(!buffer)
475 return PP_ERROR_BADARGUMENT;
476 for(ScopedVector<OperationTranslator>::iterator
477 it(received_write_requests_.begin());
478 it!=received_write_requests_.end();++it){
479 request = static_cast<WriteFileOperationTranslator*> (*it) ;
480 if(&request->data[0]==buffer){
481 received_write_requests_.erase(it);
482 return PP_OK;
483 }
484 }
485 return PP_ERROR_FAILED;
486 }
487
488 void FilesystemProviderResource::OnPluginMsgMountReply(
489 const ResourceMessageReplyParams &params,
490 PP_ProviderError_Dev error) {
491 if (TrackedCallback::IsPending(mount_callback_)) {
492 if (error==PP_ProviderError_NONE)
493 mounted_ = true;
494 *mount_callback_var_ = error;
495 mount_callback_->Run( params.result() );
496 }
497 }
498
499 void FilesystemProviderResource::OnPluginMsgUnmountReply(
500 const ResourceMessageReplyParams &params,
501 PP_ProviderError_Dev error) {
502 mounted_ = 0;
503 if (TrackedCallback::IsPending( unmount_callback_ )) {
504 *unmount_callback_var_ = error;
505 unmount_callback_->Run( params.result() );
506 }
507 }
508
509 void FilesystemProviderResource::OnPluginMsgOperationRequest(
510 const ResourceMessageParams &params,
511 const PP_OperationType_Dev &operation,
512 const base::ListValue &operationArgs) {
513 using namespace filesystem_provider_internal;
514 // We shall push the request
515 switch (operation) {
516 case PP_OperationType_ABORT: {
517 scoped_ptr<AbortOperationTranslator>
518 request = AbortOperationTranslator::PopulateFromRequest(
519 operationArgs);
520
521 if (request.get()) {
522 // Retain payload
523 request_manager_->RemoveRequest( request->operation_request_id, NULL);
524 request_manager_->AddRequest( request->request_id, operation);
525 received_requests_.push_back( request.Pass() );
526 }
527 break;
528 } // PP_OperationType_ABORT
529 case PP_OperationType_CLOSEFILE: {
530 scoped_ptr< CloseFileOperationTranslator >
531 request = CloseFileOperationTranslator::PopulateFromRequest(
532 operationArgs);
533 if (request.get()) {
534 request_manager_->AddRequest( request->request_id, operation);
535 received_requests_.push_back( request.Pass() );
536 }
537 break;
538 }//PP_OperationType_CLOSEFILE
539 case PP_OperationType_COPYENTRY: {
540 scoped_ptr< CopyEntryOperationTranslator >
541 request = CopyEntryOperationTranslator::PopulateFromRequest(
542 operationArgs);
543 if (request.get()) {
544 request_manager_->AddRequest( request->request_id, operation);
545 received_requests_.push_back( request.Pass() );
546 }
547 break;
548 }// PP_OperationType_COPYENTRY
549 case PP_OperationType_CREATEDIRECTORY: {
550 scoped_ptr< CreateDirectoryOperationTranslator >
551 request = CreateDirectoryOperationTranslator::PopulateFromRequest(
552 operationArgs);
553 if (request.get()) {
554 request_manager_->AddRequest( request->request_id, operation);
555 received_requests_.push_back( request.Pass() );
556 }
557 break;
558 }// PP_OperationType_CREATEDIRECTORY
559 case PP_OperationType_CREATEFILE: {
560 scoped_ptr< CreateFileOperationTranslator >
561 request = CreateFileOperationTranslator::PopulateFromRequest(
562 operationArgs);
563 if (request.get()) {
564 request_manager_->AddRequest( request->request_id, operation);
565 received_requests_.push_back( request.Pass() );
566 }
567 break;
568 }// PP_OperationType_CREATEFILE
569 case PP_OperationType_DELETEENTRY: {
570 scoped_ptr< DeleteEntryOperationTranslator >
571 request = DeleteEntryOperationTranslator::PopulateFromRequest(
572 operationArgs);
573 if (request.get()) {
574 request_manager_->AddRequest( request->request_id, operation);
575 received_requests_.push_back( request.Pass() );
576 }
577 break;
578 }//PP_OperationType_DELETEENTRY
579 case PP_OperationType_GETMETADATA: {
580 scoped_ptr<GetMetadataOperationTranslator>
581 request = GetMetadataOperationTranslator::PopulateFromRequest(
582 operationArgs);
583 if ( request.get() ) {
584 request_manager_->AddRequest( request->request_id, operation);
585 received_requests_.push_back( request.Pass() );
586 }
587 break;
588 } // PP_OperationType_GETMETADATA
589 case PP_OperationType_MOVEENTRY: {
590 scoped_ptr<MoveOperationTranslator>
591 request = MoveOperationTranslator::PopulateFromRequest(
592 operationArgs);
593 if (request.get()) {
594 request_manager_->AddRequest( request->request_id, operation);
595 received_requests_.push_back( request.Pass() );
596 }
597 break;
598 }// PP_OperationType_MOVEENTRY
599 case PP_OperationType_OPENFILE: {
600 scoped_ptr<OpenFileOperationTranslator>
601 request = OpenFileOperationTranslator::PopulateFromRequest(
602 operationArgs);
603 if (request.get()) {
604 request_manager_->AddRequest( request->request_id, operation);
605 received_requests_.push_back( request.Pass() );
606 }
607 break;
608 }// PP_OperationType_OpenFile
609 case PP_OperationType_READDIRECTORY: {
610 scoped_ptr<ReadDirectoryOperationTranslator>
611 request = ReadDirectoryOperationTranslator::PopulateFromRequest(
612 operationArgs);
613 if (request.get()) {
614 request_manager_->AddRequest( request->request_id, operation);
615 received_requests_.push_back( request.Pass() );
616 }
617 break;
618 }//PP_OperationType_READDIRECTORY
619 case PP_OperationType_READFILE: {
620 scoped_ptr<ReadFileOperationTranslator>
621 request = ReadFileOperationTranslator::PopulateFromRequest(
622 operationArgs);
623 if (request.get()) {
624 request_manager_->AddRequest( request->request_id, operation);
625 received_requests_.push_back( request.Pass() );
626 }
627 break;
628 }// PP_OperationType_READFILE
629 case PP_OperationType_TRUNCATEENTRY: {
630 scoped_ptr<TruncateOperationTranslator>
631 request = TruncateOperationTranslator::PopulateFromRequest(
632 operationArgs);
633 if (request.get()) {
634 request_manager_->AddRequest( request->request_id, operation);
635 received_requests_.push_back( request.Pass() );
636 }
637 break;
638 }//PP_OperationType_TRUNCATEENTRY
639 case PP_OperationType_UNMOUNT: {
640 scoped_ptr<UnmountOperationTranslator>
641 request = UnmountOperationTranslator::PopulateFromRequest(
642 operationArgs);
643 if (request.get()) {
644 request_manager_->AddRequest( request->request_id, operation);
645 received_requests_.push_back( request.Pass() );
646 }
647 break;
648 }//PP_OperationType_UNMOUNT
649 case PP_OperationType_WRITEFILE: {
650 // If shared mem inited
651 if (read_write_buffer_.get()) {
652 scoped_ptr<WriteFileOperationTranslator>
653 request = WriteFileOperationTranslator::PopulateFromRequest(
654 operationArgs,
655 (char*)read_write_buffer_->shm->memory()+
656 read_write_buffer_->read_size
657 );
658 if (request.get()) {
659 request_manager_->AddRequest( request->request_id, operation);
660 received_requests_.push_back( request.Pass() );
661 }
662 }
663 // Send Ack for the request to the browser to signal that the shm
664 // channel can be reused.
665 Post(BROWSER, PpapiHostMsg_FilesystemProvider_WriteAck());
666 break;
667 }
668 default:
669 break;
670 }
671 if (!TrackedCallback::IsPending(get_next_request_callback_) ||
672 TrackedCallback::IsScheduledToRun(get_next_request_callback_) ||
673 !WriteRequest())
674 return;
675
676 // The plugin may call GetUIMessage in its callback
677 scoped_refptr<TrackedCallback> callback;
678 callback.swap(get_next_request_callback_);
679 // Run callback
680 callback->Run(PP_OK);
681 }
682
683 void FilesystemProviderResource::OnPluginMsgBuffersReady(
684 const ResourceMessageParams& params, uint32_t read_buffer_size,
685 uint32_t write_buffer_size ) {
686
687 std::vector<base::SharedMemoryHandle> shm_handles;
688 params.TakeAllSharedMemoryHandles(&shm_handles);
689
690 scoped_ptr<base::SharedMemory> shm(
691 new base::SharedMemory(shm_handles[0],false));
692 size_t buffer_size = read_buffer_size + write_buffer_size;
693 if(!shm->Map(buffer_size) )
694 return;
695 read_write_buffer_=
696 make_scoped_ptr(new ShmBuffer( read_buffer_size, write_buffer_size,
697 shm.Pass()));
698 }
699
700 // Received when the browser part acks the read from the shm buffer
701 void FilesystemProviderResource::OnPluginMsgReadAck(
702 const ResourceMessageReplyParams& /*params*/) {
703
704 read_channel_controller_->AckLastPushedResponse();
705 read_channel_controller_->PushNextResponse();
706 }
707
708 bool FilesystemProviderResource::WriteRequest()
709 {
710 if(!get_next_request_callback_var_)
711 return false;
712 scoped_ptr<PP_FilesystemRequest > request;
713 // The first request that we can decode we put it into the designated
714 // container for the filesystem provider implementation
715 while (received_requests_.size()>0) {
716 request = received_requests_.front()->ToFilesystemRequest();
717
718 if (!request.get()) {
719 // This request cannot be decoded
720 received_requests_.erase(received_requests_.begin());
721 } else {
722 break;
723 }
724 }
725 if(!request.get())
726 return false;
727
728 // If a write request with payload, move it to the write queue until
729 // the FS implementation frees it
730 if (request->operation_type == PP_OperationType_WRITEFILE &&
731 request->value.as_write_file.data_size) {
732 received_write_requests_.push_back(received_requests_.front());
733 received_requests_.weak_erase(received_requests_.begin());
734 // Other non-write requests or write requests that have no payload.
735 } else {
736 received_requests_.erase(received_requests_.begin());
737 }
738 *get_next_request_callback_var_ = *request;
739 get_next_request_callback_var_ = NULL;
740 return true;
741 }
742
743 bool FilesystemProviderResource::FlushReadResponse(
744 scoped_ptr<base::ListValue> response, const char*data, uint32_t data_size) {
745 if (!response.get() ||
746 data==NULL)
747 return false;
748 memcpy( read_write_buffer_->shm->memory(), data, data_size);
749
750 Post(BROWSER,
751 PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
752
753 return true;
754 }
755
756 namespace filesystem_provider_internal{
757
758 scoped_ptr<PP_FilesystemRequest>
759 AbortOperationTranslator::ToFilesystemRequest() {
760 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
761 if(!out.get())
762 return scoped_ptr<PP_FilesystemRequest>();
763 out->operation_type = PP_OperationType_ABORT;
764 out->request_id = request_id;
765 return out.Pass();
766 }
767
768 // static
769 scoped_ptr<AbortOperationTranslator>
770 AbortOperationTranslator::PopulateFromRequest( const base::ListValue &request) {
771 if( request.empty() )
772 scoped_ptr<AbortOperationTranslator>();
773
774 const base::Value *dict_value = nullptr;
775 if(!request.Get(0,&dict_value))
776 scoped_ptr<AbortOperationTranslator>();
777
778 scoped_ptr<AbortOperationTranslator> out(new AbortOperationTranslator());
779 const base::DictionaryValue* dict =
780 static_cast<const base::DictionaryValue*>(dict_value);
781
782 const base::Value* file_system_id_value = NULL;
783 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
784 return scoped_ptr<AbortOperationTranslator>();
785 if (!file_system_id_value->GetAsString(&out->file_system_id))
786 return scoped_ptr<AbortOperationTranslator>();
787
788 const base::Value* request_id_value = NULL;
789 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
790 return scoped_ptr<AbortOperationTranslator>();
791 if (!request_id_value->GetAsInteger(&out->request_id))
792 return scoped_ptr<AbortOperationTranslator>();
793
794 const base::Value* operation_request_id_value = NULL;
795 if (!dict->GetWithoutPathExpansion(
796 "operationRequestId", &operation_request_id_value))
797 return scoped_ptr<AbortOperationTranslator>();
798 if (!operation_request_id_value->GetAsInteger(&out->operation_request_id))
799 return scoped_ptr<AbortOperationTranslator>();
800 return out.Pass();
801 }
802
803 scoped_ptr<PP_FilesystemRequest>
804 CloseFileOperationTranslator::ToFilesystemRequest() {
805 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
806 if(!out.get())
807 return scoped_ptr<PP_FilesystemRequest>();
808
809 out->operation_type = PP_OperationType_CLOSEFILE;
810 out->request_id = request_id;
811 out->value.as_close_file.open_request_id = open_request_id;
812
813 return out.Pass();
814 }
815
816 //static
817 scoped_ptr<CloseFileOperationTranslator>
818 CloseFileOperationTranslator::PopulateFromRequest(
819 const base::ListValue &request) {
820 if( request.empty() )
821 scoped_ptr<CloseFileOperationTranslator>();
822
823 const base::Value *dict_value = nullptr;
824 if(!request.Get(0,&dict_value))
825 scoped_ptr<CloseFileOperationTranslator>();
826
827 scoped_ptr<CloseFileOperationTranslator>
828 out(new CloseFileOperationTranslator());
829
830 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
831 return scoped_ptr<CloseFileOperationTranslator>();
832 const base::DictionaryValue* dict =
833 static_cast<const base::DictionaryValue*>(dict_value);
834 const base::Value* file_system_id_value = NULL;
835 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
836 return scoped_ptr<CloseFileOperationTranslator>();
837 if (!file_system_id_value->GetAsString(&out->file_system_id))
838 return scoped_ptr<CloseFileOperationTranslator>();
839
840 const base::Value* request_id_value = NULL;
841 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
842 return scoped_ptr<CloseFileOperationTranslator>();
843 if (!request_id_value->GetAsInteger(&out->request_id))
844 return scoped_ptr<CloseFileOperationTranslator>();
845
846 const base::Value* open_request_id_value = NULL;
847 if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
848 return scoped_ptr<CloseFileOperationTranslator>();
849 if (!open_request_id_value->GetAsInteger(&out->open_request_id))
850 return scoped_ptr<CloseFileOperationTranslator>();
851
852 return out.Pass();
853 }
854
855 //static
856 scoped_ptr<PP_FilesystemRequest>
857 GetMetadataOperationTranslator::ToFilesystemRequest() {
858 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
859 if(!out.get())
860 return scoped_ptr<PP_FilesystemRequest>();
861 out->operation_type = PP_OperationType_GETMETADATA;
862 out->request_id = request_id;
863 out->value.as_metadata.thumbnail = PP_FromBool( thumbnail );
864 snprintf(out->value.as_metadata.entry_path,
865 sizeof(out->value.as_metadata.entry_path),
866 "%s",
867 entry_path.c_str());
868 return out.Pass();
869 }
870
871 scoped_ptr<GetMetadataOperationTranslator>
872 GetMetadataOperationTranslator::PopulateFromRequest(
873 const base::ListValue &request ) {
874
875 if( request.empty() )
876 scoped_ptr<GetMetadataOperationTranslator>();
877
878 const base::Value *dict_value = nullptr;
879 if(!request.Get(0,&dict_value))
880 return scoped_ptr<GetMetadataOperationTranslator>();
881
882 scoped_ptr<GetMetadataOperationTranslator>
883 out(new GetMetadataOperationTranslator());
884
885 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
886 return scoped_ptr<GetMetadataOperationTranslator>();
887 const base::DictionaryValue* dict =
888 static_cast<const base::DictionaryValue*>(dict_value);
889 const base::Value* file_system_id_value = NULL;
890
891 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
892 scoped_ptr<GetMetadataOperationTranslator>();
893 if (!file_system_id_value->GetAsString(&out->file_system_id))
894 scoped_ptr<GetMetadataOperationTranslator>();
895
896 const base::Value* request_id_value = NULL;
897 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
898 scoped_ptr<GetMetadataOperationTranslator>();
899 if (!request_id_value->GetAsInteger(&out->request_id))
900 scoped_ptr<GetMetadataOperationTranslator>();
901
902 const base::Value* entry_path_value = NULL;
903 if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
904 scoped_ptr<GetMetadataOperationTranslator>();
905 if (!entry_path_value->GetAsString(&out->entry_path))
906 scoped_ptr<GetMetadataOperationTranslator>();
907
908 const base::Value* thumbnail_value = NULL;
909 if (!dict->GetWithoutPathExpansion("thumbnail", &thumbnail_value))
910 scoped_ptr<GetMetadataOperationTranslator>();
911 if (!thumbnail_value->GetAsBoolean(&out->thumbnail))
912 scoped_ptr<GetMetadataOperationTranslator>();
913 return out.Pass();
914 }
915
916
917 scoped_ptr<PP_FilesystemRequest>
918 CopyEntryOperationTranslator::ToFilesystemRequest() {
919 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
920 out->operation_type = PP_OperationType_COPYENTRY;
921 out->request_id = request_id;
922 snprintf( out->value.as_copy_entry.source_path,
923 sizeof(out->value.as_copy_entry.source_path),
924 "%s",
925 source_path.c_str() );
926 snprintf( out->value.as_copy_entry.target_path,
927 sizeof(out->value.as_copy_entry.target_path),
928 "%s",
929 target_path.c_str() );
930
931 return out.Pass();
932 }
933
934 // static
935 scoped_ptr<CopyEntryOperationTranslator>
936 CopyEntryOperationTranslator::PopulateFromRequest(
937 const base::ListValue &request) {
938 if( request.empty() )
939 scoped_ptr<CopyEntryOperationTranslator>();
940
941 const base::Value *dict_value = nullptr;
942 if(!request.Get(0,&dict_value))
943 return scoped_ptr<CopyEntryOperationTranslator>();
944
945 scoped_ptr<CopyEntryOperationTranslator>
946 out(new CopyEntryOperationTranslator());
947 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
948 return scoped_ptr<CopyEntryOperationTranslator>();
949
950 const base::DictionaryValue* dict =
951 static_cast<const base::DictionaryValue*>(dict_value);
952 const base::Value* file_system_id_value = NULL;
953 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
954 return scoped_ptr<CopyEntryOperationTranslator>();
955 if (!file_system_id_value->GetAsString(&out->file_system_id))
956 return scoped_ptr<CopyEntryOperationTranslator>();
957
958 const base::Value* request_id_value = NULL;
959 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
960 return scoped_ptr<CopyEntryOperationTranslator>();
961 if (!request_id_value->GetAsInteger(&out->request_id))
962 return scoped_ptr<CopyEntryOperationTranslator>();
963
964 const base::Value* source_path_value = NULL;
965 if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value))
966 return scoped_ptr<CopyEntryOperationTranslator>();
967 if (!source_path_value->GetAsString(&out->source_path))
968 return scoped_ptr<CopyEntryOperationTranslator>();
969
970 const base::Value* target_path_value = NULL;
971 if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value))
972 return scoped_ptr<CopyEntryOperationTranslator>();
973 if (!target_path_value->GetAsString(&out->target_path))
974 return scoped_ptr<CopyEntryOperationTranslator>();
975 return out.Pass();
976
977 }
978
979 scoped_ptr<PP_FilesystemRequest>
980 CreateDirectoryOperationTranslator::ToFilesystemRequest() {
981 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
982 if(!out.get())
983 return scoped_ptr<PP_FilesystemRequest>();
984 out->operation_type = PP_OperationType_CREATEDIRECTORY;
985 out->request_id = request_id;
986 snprintf(out->value.as_create_directory.directory_path,
987 sizeof(out->value.as_create_directory.directory_path),
988 "%s",
989 directory_path.c_str() );
990 out->value.as_create_directory.recursive = PP_FromBool(recursive);
991 return out.Pass();
992 }
993
994 scoped_ptr<CreateDirectoryOperationTranslator>
995 CreateDirectoryOperationTranslator::PopulateFromRequest(
996 const base::ListValue &request) {
997 if( request.empty() )
998 scoped_ptr<CreateDirectoryOperationTranslator>();
999
1000 const base::Value *dict_value = nullptr;
1001 if(!request.Get(0,&dict_value))
1002 return scoped_ptr<CreateDirectoryOperationTranslator>();
1003
1004 scoped_ptr<CreateDirectoryOperationTranslator>
1005 out(new CreateDirectoryOperationTranslator());
1006 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1007 return scoped_ptr<CreateDirectoryOperationTranslator>();
1008
1009 const base::DictionaryValue* dict =
1010 static_cast<const base::DictionaryValue*>(dict_value);
1011 const base::Value* file_system_id_value = NULL;
1012 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1013 return scoped_ptr<CreateDirectoryOperationTranslator>();
1014 if (!file_system_id_value->GetAsString(&out->file_system_id))
1015 return scoped_ptr<CreateDirectoryOperationTranslator>();
1016
1017 const base::Value* request_id_value = NULL;
1018 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1019 return scoped_ptr<CreateDirectoryOperationTranslator>();
1020 if (!request_id_value->GetAsInteger(&out->request_id))
1021 return scoped_ptr<CreateDirectoryOperationTranslator>();
1022
1023 const base::Value* directory_path_value = NULL;
1024 if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value))
1025 return scoped_ptr<CreateDirectoryOperationTranslator>();
1026 if (!directory_path_value->GetAsString(&out->directory_path))
1027 return scoped_ptr<CreateDirectoryOperationTranslator>();
1028
1029 const base::Value* recursive_value = NULL;
1030 if (!dict->GetWithoutPathExpansion("recursive", &recursive_value))
1031 return scoped_ptr<CreateDirectoryOperationTranslator>();
1032 if (!recursive_value->GetAsBoolean(&out->recursive))
1033 return scoped_ptr<CreateDirectoryOperationTranslator>();
1034
1035 return out.Pass();
1036 }
1037
1038 scoped_ptr<PP_FilesystemRequest>
1039 CreateFileOperationTranslator::ToFilesystemRequest() {
1040 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1041 if(!out.get())
1042 return scoped_ptr<PP_FilesystemRequest>();
1043 out->operation_type = PP_OperationType_CREATEFILE;
1044 out->request_id = request_id;
1045 snprintf(out->value.as_create_file.file_path,
1046 sizeof(out->value.as_create_file.file_path),
1047 "%s",
1048 file_path.c_str());
1049 return out.Pass();
1050 }
1051
1052 scoped_ptr<CreateFileOperationTranslator>
1053 CreateFileOperationTranslator::PopulateFromRequest(
1054 const base::ListValue &request) {
1055 if( request.empty() )
1056 scoped_ptr<CreateFileOperationTranslator>();
1057
1058 const base::Value *dict_value = nullptr;
1059 if(!request.Get(0,&dict_value))
1060 return scoped_ptr<CreateFileOperationTranslator>();
1061
1062 scoped_ptr<CreateFileOperationTranslator>
1063 out(new CreateFileOperationTranslator());
1064 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1065 return scoped_ptr<CreateFileOperationTranslator>();
1066
1067 const base::DictionaryValue* dict =
1068 static_cast<const base::DictionaryValue*>(dict_value);
1069 const base::Value* file_system_id_value = NULL;
1070 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1071 return scoped_ptr<CreateFileOperationTranslator>();
1072 if (!file_system_id_value->GetAsString(&out->file_system_id))
1073 return scoped_ptr<CreateFileOperationTranslator>();
1074
1075 const base::Value* request_id_value = NULL;
1076 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1077 return scoped_ptr<CreateFileOperationTranslator>();
1078 if (!request_id_value->GetAsInteger(&out->request_id))
1079 return scoped_ptr<CreateFileOperationTranslator>();
1080
1081 const base::Value* file_path_value = NULL;
1082 if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
1083 return scoped_ptr<CreateFileOperationTranslator>();
1084 if (!file_path_value->GetAsString(&out->file_path))
1085 return scoped_ptr<CreateFileOperationTranslator>();
1086 return out.Pass();
1087 }
1088
1089 scoped_ptr<PP_FilesystemRequest>
1090 DeleteEntryOperationTranslator::ToFilesystemRequest() {
1091 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1092 out->operation_type = PP_OperationType_DELETEENTRY;
1093 out->request_id = request_id;
1094 snprintf(out->value.as_delete_entry.entry_path,
1095 sizeof(out->value.as_delete_entry.entry_path),
1096 "%s",
1097 entry_path.c_str());
1098 out->value.as_delete_entry.recursive = PP_FromBool(recursive);
1099 return out.Pass();
1100 }
1101
1102 scoped_ptr<DeleteEntryOperationTranslator>
1103 DeleteEntryOperationTranslator::PopulateFromRequest(
1104 const base::ListValue &request) {
1105 if( request.empty() )
1106 scoped_ptr<DeleteEntryOperationTranslator>();
1107
1108 const base::Value *dict_value = nullptr;
1109 if(!request.Get(0,&dict_value))
1110 return scoped_ptr<DeleteEntryOperationTranslator>();
1111
1112 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1113 return scoped_ptr<DeleteEntryOperationTranslator>();
1114
1115
1116 scoped_ptr<DeleteEntryOperationTranslator>
1117 out(new DeleteEntryOperationTranslator());
1118
1119 const base::DictionaryValue* dict =
1120 static_cast<const base::DictionaryValue*>(dict_value);
1121 const base::Value* file_system_id_value = NULL;
1122
1123 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1124 return scoped_ptr<DeleteEntryOperationTranslator>();
1125 if (!file_system_id_value->GetAsString(&out->file_system_id))
1126 return scoped_ptr<DeleteEntryOperationTranslator>();
1127
1128 const base::Value* request_id_value = NULL;
1129 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1130 return scoped_ptr<DeleteEntryOperationTranslator>();
1131 if (!request_id_value->GetAsInteger(&out->request_id))
1132 return scoped_ptr<DeleteEntryOperationTranslator>();
1133
1134 const base::Value* entry_path_value = NULL;
1135 if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
1136 return scoped_ptr<DeleteEntryOperationTranslator>();
1137 if (!entry_path_value->GetAsString(&out->entry_path))
1138 return scoped_ptr<DeleteEntryOperationTranslator>();
1139
1140 const base::Value* recursive_value = NULL;
1141 if (!dict->GetWithoutPathExpansion("recursive", &recursive_value))
1142 return scoped_ptr<DeleteEntryOperationTranslator>();
1143 if (!recursive_value->GetAsBoolean(&out->recursive))
1144 return scoped_ptr<DeleteEntryOperationTranslator>();
1145 return out.Pass();
1146 }
1147
1148 scoped_ptr<PP_FilesystemRequest>
1149 MoveOperationTranslator::ToFilesystemRequest() {
1150 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1151 if(!out.get())
1152 return scoped_ptr<PP_FilesystemRequest>();
1153 out->operation_type = PP_OperationType_MOVEENTRY;
1154 out->request_id = request_id;
1155 snprintf(out->value.as_move_entry.source_path,
1156 sizeof(out->value.as_move_entry.source_path),
1157 "%s",
1158 source_path.c_str());
1159 snprintf(out->value.as_move_entry.target_path,
1160 sizeof(out->value.as_move_entry.target_path),
1161 "%s",
1162 target_path.c_str());
1163 return out.Pass();
1164 }
1165
1166 scoped_ptr<MoveOperationTranslator>
1167 MoveOperationTranslator::PopulateFromRequest(const base::ListValue &request) {
1168 if( request.empty() )
1169 scoped_ptr<DeleteEntryOperationTranslator>();
1170
1171 const base::Value *dict_value = nullptr;
1172 if(!request.Get(0,&dict_value))
1173 return scoped_ptr<MoveOperationTranslator>();
1174
1175 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1176 return scoped_ptr<MoveOperationTranslator>();
1177
1178 scoped_ptr<MoveOperationTranslator> out(new MoveOperationTranslator());
1179 const base::DictionaryValue* dict =
1180 static_cast<const base::DictionaryValue*>(dict_value);
1181 const base::Value* file_system_id_value = NULL;
1182 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1183 return scoped_ptr<MoveOperationTranslator>();
1184 if (!file_system_id_value->GetAsString(&out->file_system_id))
1185 return scoped_ptr<MoveOperationTranslator>();
1186
1187 const base::Value* request_id_value = NULL;
1188 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1189 return scoped_ptr<MoveOperationTranslator>();
1190 if (!request_id_value->GetAsInteger(&out->request_id))
1191 return scoped_ptr<MoveOperationTranslator>();
1192
1193 const base::Value* source_path_value = NULL;
1194 if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value))
1195 return scoped_ptr<MoveOperationTranslator>();
1196 if (!source_path_value->GetAsString(&out->source_path))
1197 return scoped_ptr<MoveOperationTranslator>();
1198
1199 const base::Value* target_path_value = NULL;
1200 if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value))
1201 return scoped_ptr<MoveOperationTranslator>();
1202 if (!target_path_value->GetAsString(&out->target_path))
1203 return scoped_ptr<MoveOperationTranslator>();
1204 return out.Pass();
1205 }
1206
1207 PP_OpenFileMode_Dev ParseOpenFileMode( const std::string &mode ) {
1208 if (mode=="WRITE")
1209 return PP_OpenFileMode_WRITE;
1210 else if ( mode=="READ" )//( mode=="read")
1211 return PP_OpenFileMode_READ;
1212 else
1213 return PP_OpenFileMode_NONE;
1214 }
1215
1216
1217 scoped_ptr<PP_FilesystemRequest>
1218 OpenFileOperationTranslator::ToFilesystemRequest() {
1219 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1220 if(!out.get())
1221 return scoped_ptr<PP_FilesystemRequest>();
1222 out->operation_type = PP_OperationType_OPENFILE;
1223 out->request_id = request_id;
1224 snprintf( out->value.as_open_file.file_path,
1225 sizeof(out->value.as_open_file.file_path),
1226 "%s",
1227 file_path.c_str());
1228 out->value.as_open_file.mode = mode;
1229 return out.Pass();
1230 }
1231
1232 //static
1233 scoped_ptr<OpenFileOperationTranslator>
1234 OpenFileOperationTranslator::PopulateFromRequest(
1235 const base::ListValue &request) {
1236 if( request.empty() )
1237 scoped_ptr<OpenFileOperationTranslator>();
1238
1239 const base::Value *dict_value = nullptr;
1240 if(!request.Get(0,&dict_value))
1241 return scoped_ptr<OpenFileOperationTranslator>();
1242 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1243 return scoped_ptr<OpenFileOperationTranslator>();
1244
1245 scoped_ptr<OpenFileOperationTranslator>
1246 out(new OpenFileOperationTranslator());
1247 const base::DictionaryValue* dict =
1248 static_cast<const base::DictionaryValue*>(dict_value);
1249 const base::Value* file_system_id_value = NULL;
1250 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1251 return scoped_ptr<OpenFileOperationTranslator>();
1252 if (!file_system_id_value->GetAsString(&out->file_system_id))
1253 return scoped_ptr<OpenFileOperationTranslator>();
1254
1255 const base::Value* request_id_value = NULL;
1256 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1257 return scoped_ptr<OpenFileOperationTranslator>();
1258 if (!request_id_value->GetAsInteger(&out->request_id))
1259 return scoped_ptr<OpenFileOperationTranslator>();
1260
1261 const base::Value* file_path_value = NULL;
1262 if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
1263 return scoped_ptr<OpenFileOperationTranslator>();
1264 if (!file_path_value->GetAsString(&out->file_path))
1265 return scoped_ptr<OpenFileOperationTranslator>();
1266
1267 const base::Value* mode_value = NULL;
1268 if (!dict->GetWithoutPathExpansion("mode", &mode_value))
1269 return scoped_ptr<OpenFileOperationTranslator>();
1270 std::string open_file_mode_as_string;
1271 if (!mode_value->GetAsString(&open_file_mode_as_string))
1272 return scoped_ptr<OpenFileOperationTranslator>();
1273 out->mode = ParseOpenFileMode(open_file_mode_as_string);
1274
1275 return out.Pass();
1276 }
1277
1278 scoped_ptr<PP_FilesystemRequest>
1279 ReadDirectoryOperationTranslator::ToFilesystemRequest() {
1280 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1281 if(!out.get())
1282 return scoped_ptr<PP_FilesystemRequest>();
1283 out->operation_type = PP_OperationType_READDIRECTORY;
1284 out->request_id = request_id;
1285 snprintf(out->value.as_read_directory.directory_path,
1286 sizeof(out->value.as_read_directory.directory_path),
1287 "%s",
1288 directory_path.c_str());
1289 return out.Pass();
1290 }
1291
1292 scoped_ptr<ReadDirectoryOperationTranslator>
1293 ReadDirectoryOperationTranslator::PopulateFromRequest(
1294 const base::ListValue &request) {
1295 if( request.empty() )
1296 scoped_ptr<ReadDirectoryOperationTranslator>();
1297
1298 const base::Value *dict_value = nullptr;
1299 if(!request.Get(0,&dict_value))
1300 return scoped_ptr<ReadDirectoryOperationTranslator>();
1301
1302 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1303 return scoped_ptr<ReadDirectoryOperationTranslator>();
1304
1305 scoped_ptr<ReadDirectoryOperationTranslator>
1306 out(new ReadDirectoryOperationTranslator());
1307
1308 const base::DictionaryValue* dict =
1309 static_cast<const base::DictionaryValue*>(dict_value);
1310 const base::Value* file_system_id_value = NULL;
1311 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1312 return scoped_ptr<ReadDirectoryOperationTranslator>();
1313 if (!file_system_id_value->GetAsString(&out->file_system_id))
1314 return scoped_ptr<ReadDirectoryOperationTranslator>();
1315
1316 const base::Value* request_id_value = NULL;
1317 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1318 return scoped_ptr<ReadDirectoryOperationTranslator>();
1319 if (!request_id_value->GetAsInteger(&out->request_id))
1320 return scoped_ptr<ReadDirectoryOperationTranslator>();
1321
1322 const base::Value* directory_path_value = NULL;
1323 if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value))
1324 return scoped_ptr<ReadDirectoryOperationTranslator>();
1325 if (!directory_path_value->GetAsString(&out->directory_path))
1326 return scoped_ptr<ReadDirectoryOperationTranslator>();
1327 return out.Pass();
1328 }
1329
1330 scoped_ptr<PP_FilesystemRequest>
1331 ReadFileOperationTranslator::ToFilesystemRequest() {
1332 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1333 if(!out.get())
1334 return scoped_ptr<PP_FilesystemRequest>();
1335 out->operation_type = PP_OperationType_READFILE;
1336 out->request_id = request_id;
1337 out->value.as_read_file.open_request_id = open_request_id;
1338 out->value.as_read_file.offset = offset;
1339 out->value.as_read_file.length = length;
1340 return out.Pass();
1341 }
1342
1343 scoped_ptr<ReadFileOperationTranslator>
1344 ReadFileOperationTranslator::PopulateFromRequest(
1345 const base::ListValue &request) {
1346 if( request.empty() )
1347 scoped_ptr<ReadFileOperationTranslator>();
1348
1349 const base::Value *dict_value = nullptr;
1350 if(!request.Get(0,&dict_value))
1351 return scoped_ptr<ReadFileOperationTranslator>();
1352
1353 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1354 return scoped_ptr<ReadFileOperationTranslator>();
1355 scoped_ptr<ReadFileOperationTranslator>
1356 out(new ReadFileOperationTranslator());
1357 const base::DictionaryValue* dict =
1358 static_cast<const base::DictionaryValue*>(dict_value);
1359 const base::Value* file_system_id_value = NULL;
1360 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1361 return scoped_ptr<ReadFileOperationTranslator>();
1362 if (!file_system_id_value->GetAsString(&out->file_system_id))
1363 return scoped_ptr<ReadFileOperationTranslator>();
1364
1365 const base::Value* request_id_value = NULL;
1366 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1367 return scoped_ptr<ReadFileOperationTranslator>();
1368 if (!request_id_value->GetAsInteger(&out->request_id))
1369 return scoped_ptr<ReadFileOperationTranslator>();
1370
1371 const base::Value* open_request_id_value = NULL;
1372 if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
1373 return scoped_ptr<ReadFileOperationTranslator>();
1374 if (!open_request_id_value->GetAsInteger(&out->open_request_id))
1375 return scoped_ptr<ReadFileOperationTranslator>();
1376
1377 const base::Value* offset_value = NULL;
1378 if (!dict->GetWithoutPathExpansion("offset", &offset_value))
1379 return scoped_ptr<ReadFileOperationTranslator>();
1380 if (!offset_value->GetAsDouble(&out->offset))
1381 return scoped_ptr<ReadFileOperationTranslator>();
1382
1383 const base::Value* length_value = NULL;
1384 if (!dict->GetWithoutPathExpansion("length", &length_value))
1385 return scoped_ptr<ReadFileOperationTranslator>();
1386 if (!length_value->GetAsDouble(&out->length))
1387 return scoped_ptr<ReadFileOperationTranslator>();
1388 return out.Pass();
1389 }
1390
1391 scoped_ptr<PP_FilesystemRequest>
1392 TruncateOperationTranslator::ToFilesystemRequest() {
1393 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1394 if(!out.get())
1395 return scoped_ptr<PP_FilesystemRequest>();
1396 out->operation_type = PP_OperationType_TRUNCATEENTRY;
1397 out->request_id = request_id;
1398 out->value.as_truncate.length = length;
1399 snprintf( out->value.as_truncate.file_path,
1400 sizeof(out->value.as_truncate.file_path),
1401 "%s",
1402 file_path.c_str());
1403 return out.Pass();
1404 }
1405
1406 scoped_ptr<TruncateOperationTranslator>
1407 TruncateOperationTranslator::PopulateFromRequest(
1408 const base::ListValue &request) {
1409 if( request.empty() )
1410 return scoped_ptr<TruncateOperationTranslator>();
1411
1412 const base::Value *dict_value = nullptr;
1413 if(!request.Get(0,&dict_value))
1414 return scoped_ptr<TruncateOperationTranslator>();
1415
1416 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) {
1417 return scoped_ptr<TruncateOperationTranslator>();
1418 }
1419
1420 scoped_ptr<TruncateOperationTranslator>
1421 out(new TruncateOperationTranslator());
1422
1423 const base::DictionaryValue* dict =
1424 static_cast<const base::DictionaryValue*>(dict_value);
1425 const base::Value* file_system_id_value = NULL;
1426 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1427 return scoped_ptr<TruncateOperationTranslator>();
1428 if (!file_system_id_value->GetAsString(&out->file_system_id))
1429 return scoped_ptr<TruncateOperationTranslator>();
1430
1431 const base::Value* request_id_value = NULL;
1432 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1433 return scoped_ptr<TruncateOperationTranslator>();
1434 if (!request_id_value->GetAsInteger(&out->request_id))
1435 return scoped_ptr<TruncateOperationTranslator>();
1436
1437 const base::Value* file_path_value = NULL;
1438 if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
1439 return scoped_ptr<TruncateOperationTranslator>();
1440 if (!file_path_value->GetAsString(&out->file_path))
1441 return scoped_ptr<TruncateOperationTranslator>();
1442
1443 const base::Value* length_value = NULL;
1444 if (!dict->GetWithoutPathExpansion("length", &length_value))
1445 return scoped_ptr<TruncateOperationTranslator>();
1446 if (!length_value->GetAsDouble(&out->length))
1447 return scoped_ptr<TruncateOperationTranslator>();
1448 return out.Pass();
1449 }
1450
1451 scoped_ptr<PP_FilesystemRequest>
1452 UnmountOperationTranslator::ToFilesystemRequest() {
1453 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1454 if(!out.get())
1455 return scoped_ptr<PP_FilesystemRequest>();
1456 out->operation_type = PP_OperationType_UNMOUNT;
1457 out->request_id = request_id;
1458 return out.Pass();
1459 }
1460
1461 scoped_ptr<UnmountOperationTranslator>
1462 UnmountOperationTranslator::PopulateFromRequest(
1463 const base::ListValue &request) {
1464
1465 if( request.empty() )
1466 return scoped_ptr<UnmountOperationTranslator>();
1467
1468 const base::Value *dict_value = nullptr;
1469 if(!request.Get(0,&dict_value))
1470 return scoped_ptr<UnmountOperationTranslator>();
1471
1472 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1473 return scoped_ptr<UnmountOperationTranslator>();
1474
1475 scoped_ptr<UnmountOperationTranslator> out(new UnmountOperationTranslator());
1476
1477 const base::DictionaryValue* dict =
1478 static_cast<const base::DictionaryValue*>(dict_value);
1479 const base::Value* file_system_id_value = NULL;
1480 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1481 return scoped_ptr<UnmountOperationTranslator>();
1482 if (!file_system_id_value->GetAsString(&out->file_system_id))
1483 return scoped_ptr<UnmountOperationTranslator>();
1484
1485 const base::Value* request_id_value = NULL;
1486 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1487 return scoped_ptr<UnmountOperationTranslator>();
1488 if (!request_id_value->GetAsInteger(&out->request_id))
1489 return scoped_ptr<UnmountOperationTranslator>();
1490 return out.Pass();
1491 }
1492
1493 scoped_ptr<PP_FilesystemRequest>
1494 WriteFileOperationTranslator::ToFilesystemRequest() {
1495 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1496 if(!out.get())
1497 return scoped_ptr<PP_FilesystemRequest>();
1498 out->operation_type = PP_OperationType_WRITEFILE;
1499 out->request_id = request_id;
1500 out->value.as_write_file.open_request_id = open_request_id;
1501 out->value.as_write_file.offset = offset;
1502 out->value.as_write_file.data_size = data.size();
1503 // Pass the address
1504 if(data.size())
1505 out->value.as_write_file.data = &data[0];
1506 else // or NULL if the browser sent an empty write request
1507 out->value.as_write_file.data = NULL;
1508 return out.Pass();
1509 }
1510
1511 scoped_ptr<WriteFileOperationTranslator>
1512 WriteFileOperationTranslator::PopulateFromRequest(
1513 const base::ListValue &request,
1514 char* memory_address) {
1515
1516 if( request.empty() )
1517 return scoped_ptr<WriteFileOperationTranslator>();
1518
1519 const base::Value *dict_value = nullptr;
1520 if(!request.Get(0,&dict_value))
1521 return scoped_ptr<WriteFileOperationTranslator>();
1522
1523 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1524 return scoped_ptr<WriteFileOperationTranslator>();
1525
1526 scoped_ptr<WriteFileOperationTranslator>
1527 out(new WriteFileOperationTranslator());
1528 const base::DictionaryValue* dict =
1529 static_cast<const base::DictionaryValue*>(dict_value);
1530 const base::Value* file_system_id_value = NULL;
1531 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1532 return scoped_ptr<WriteFileOperationTranslator>();
1533 if (!file_system_id_value->GetAsString(&out->file_system_id))
1534 return scoped_ptr<WriteFileOperationTranslator>();
1535
1536 const base::Value* request_id_value = NULL;
1537 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1538 return scoped_ptr<WriteFileOperationTranslator>();
1539 if (!request_id_value->GetAsInteger(&out->request_id))
1540 return scoped_ptr<WriteFileOperationTranslator>();
1541
1542 const base::Value* open_request_id_value = NULL;
1543 if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
1544 return scoped_ptr<WriteFileOperationTranslator>();
1545 if (!open_request_id_value->GetAsInteger(&out->open_request_id))
1546 return scoped_ptr<WriteFileOperationTranslator>();
1547
1548 const base::Value* offset_value = NULL;
1549 if (!dict->GetWithoutPathExpansion("offset", &offset_value))
1550 return scoped_ptr<WriteFileOperationTranslator>();
1551 if (!offset_value->GetAsDouble(&out->offset))
1552 return scoped_ptr<WriteFileOperationTranslator>();
1553
1554 const base::Value* size_value = NULL;
1555 if (!dict->GetWithoutPathExpansion("size", &size_value))
1556 return scoped_ptr<WriteFileOperationTranslator>();
1557 if (!size_value->GetAsDouble(&out->size))
1558 return scoped_ptr<WriteFileOperationTranslator>();
1559
1560 // Buffer what will be cached until released by the FS implementation
1561 out->data.assign(memory_address,
1562 memory_address+static_cast<size_t>(out->size));
1563 return out.Pass();
1564 }
1565
1566 OperationTranslator::~OperationTranslator()
1567 {
1568
1569 }
1570
1571 scoped_ptr<base::ListValue>
1572 PluginToBrowserTranslator::GenerateReadFileSuccessResponse(
1573 uint32_t data_size, bool has_more, int32_t request_id,
1574 double time_span, const std::string& filesystem_id) {
1575 size_t index = 0;
1576 scoped_ptr<base::ListValue> response(new base::ListValue);
1577 if( !response->Set(index++,
1578 new base::FundamentalValue(PP_OperationType_READFILE))||
1579 !response->Set(index++, new base::FundamentalValue(true))||// status = suc cess
1580 !response->Set(index++,
1581 new base::StringValue(filesystem_id)) ||
1582 !response->Set(index++, new base::FundamentalValue(request_id)) ||
1583 !response->Set(index++, new base::FundamentalValue((double)data_size))||
1584 !response->Set(index++, new base::FundamentalValue(has_more))||
1585 !response->Set(index++, new base::FundamentalValue((int)time_span)))
1586 return scoped_ptr<base::ListValue>();
1587 return response.Pass();
1588 }
1589
1590 scoped_ptr<base::ListValue>
1591 PluginToBrowserTranslator::GenerateMountRequest(
1592 std::string filesystem_id, std::string display_name,
1593 bool writable, int32_t opened_files_limit) {
1594
1595 scoped_ptr<base::DictionaryValue> payload(new base::DictionaryValue);
1596 if(!payload.get())
1597 return scoped_ptr<base::ListValue>();
1598 payload->Set("fileSystemId",
1599 new base::StringValue(filesystem_id));
1600 payload->Set("displayName",
1601 new base::StringValue(display_name));
1602 payload->Set("writable",
1603 new base::FundamentalValue(writable));
1604 payload->Set("openedFilesLimit",
1605 new base::FundamentalValue(opened_files_limit));
1606 scoped_ptr<base::ListValue> response(new base::ListValue);
1607 if(!response.get())
1608 return scoped_ptr<base::ListValue>();
1609 response->Set(0,payload.release());
1610 return response.Pass();
1611 }
1612
1613 scoped_ptr<base::ListValue>
1614 PluginToBrowserTranslator::GenerateSuccessResponse(
1615 PP_OperationType_Dev operation_type,
1616 const std::string &filesystem_id,
1617 int32_t request_id, double time_span) {
1618
1619 scoped_ptr<base::ListValue> response(new base::ListValue);
1620 if(!response.get())
1621 return scoped_ptr<base::ListValue>();
1622 size_t index = 0;
1623 if ( !response->Set(index++, new base::FundamentalValue(operation_type))||
1624 !response->Set(index++,
1625 new base::FundamentalValue(true)) || // status = success
1626 !response->Set(index++,
1627 new base::StringValue(filesystem_id))||
1628 !response->Set(index++, new base::FundamentalValue(request_id)) ||
1629 !response->Set(index++, new base::FundamentalValue((int)time_span))) {
1630 return scoped_ptr<base::ListValue>();
1631 }
1632 return response.Pass();
1633 }
1634
1635 scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateFailureResponse(
1636 PP_OperationType_Dev operation_type, PP_ProviderError_Dev error,
1637 const std::string &filesystem_id, int32_t request_id, double time_span) {
1638 scoped_ptr<base::ListValue> response(new base::ListValue);
1639 if(!response.get())
1640 return scoped_ptr<base::ListValue>();
1641 size_t index=0;
1642 if ( !response->Set(index++, new base::FundamentalValue(operation_type)) ||
1643 !response->Set(index++,
1644 new base::FundamentalValue(false)) || // status = failure
1645 !response->Set(index++,
1646 new base::StringValue(filesystem_id)) ||
1647 !response->Set(index++, new base::FundamentalValue(request_id)) ||
1648 !response->Set(index++,
1649 new base::StringValue(PP_ProviderErrorToString(error))) ||
1650 !response->Set(index++, new base::FundamentalValue((int)time_span) ) )
1651 return scoped_ptr<base::ListValue>();
1652 return response.Pass();
1653 }
1654
1655 scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateMetadataResponse(
1656 const PP_EntryMetadata_Dev *metadata, int32_t request_id,
1657 const std::string &filesystem_id, double time_span) {
1658
1659 scoped_ptr<base::DictionaryValue> entry_metadata(new base::DictionaryValue);
1660 if(!entry_metadata.get())
1661 return scoped_ptr<base::ListValue>();
1662
1663 entry_metadata->SetBoolean( "isDirectory", PP_ToBool(metadata->is_directory));
1664
1665 entry_metadata->SetString("name",metadata->name[0]=='\0'?
1666 "":metadata->name);
1667 entry_metadata->SetString("mimeType", metadata->mime_type[0]=='\0'?
1668 "":metadata->mime_type);
1669 if(metadata->thumbnail[0]!='\0')
1670 entry_metadata->SetString("thumbnail", metadata->thumbnail);
1671 entry_metadata->SetDouble("size", metadata->size );
1672
1673 scoped_ptr<base::DictionaryValue>
1674 modification_time(new base::DictionaryValue());
1675 if(!modification_time.get())
1676 return scoped_ptr<base::ListValue>();
1677 modification_time->SetStringWithoutPathExpansion(
1678 "value", metadata->modification_time);
1679 entry_metadata->Set("modificationTime", modification_time.release());
1680
1681
1682 scoped_ptr<base::ListValue> response(new base::ListValue);
1683 size_t index = 0;
1684 if (!response->Set(index++,
1685 new base::FundamentalValue(PP_OperationType_GETMETADATA))||
1686 !response->Set(index++, new base::FundamentalValue(true))|| //status = suc cess
1687 !response->Set(index++,
1688 new base::StringValue(filesystem_id) ) ||
1689 !response->Set(index++, new base::FundamentalValue(request_id) ) ||
1690 !response->Set(index++, entry_metadata.release() ) ||
1691 !response->Set(index++, new base::FundamentalValue((int)time_span) ) )
1692 return scoped_ptr<base::ListValue>();
1693 return response.Pass();
1694 }
1695
1696 scoped_ptr<base::ListValue>
1697 PluginToBrowserTranslator::GenerateReadDirectoryResponse(
1698 uint32_t array_size,
1699 const PP_EntryMetadata_Dev entries[],
1700 PP_Bool has_more, int32_t request_id,
1701 const std::string &filesystem_id, double time_span) {
1702
1703 scoped_ptr<base::ListValue> response(new base::ListValue);
1704 scoped_ptr<base::ListValue> list_value(new base::ListValue);
1705 if(!list_value.get()||
1706 !response.get())
1707 return scoped_ptr<base::ListValue>();
1708
1709 for (uint32_t i = 0; i<array_size;++i) {
1710 scoped_ptr<base::DictionaryValue>
1711 entry_metadata(new base::DictionaryValue);
1712 if(!entry_metadata.get())
1713 return scoped_ptr<base::ListValue>();
1714
1715 entry_metadata->SetBoolean(
1716 "isDirectory", PP_ToBool(entries[i].is_directory) );
1717
1718 entry_metadata->SetString("name",entries[i].name[0]=='\0'?
1719 "":entries[i].name);
1720 entry_metadata->SetString("mimeType", entries[i].mime_type[0]=='\0'?
1721 "":entries[i].mime_type);
1722 if(entries[i].thumbnail[0]!='\0')
1723 entry_metadata->SetString("thumbnail", entries[i].thumbnail);
1724 entry_metadata->SetDouble("size", entries[i].size );
1725
1726 scoped_ptr<base::DictionaryValue>
1727 modification_time(new base::DictionaryValue());
1728 if(!modification_time.get())
1729 return scoped_ptr<base::ListValue>();
1730
1731 modification_time->SetStringWithoutPathExpansion(
1732 "value", entries[i].modification_time);
1733 entry_metadata->Set("modificationTime", modification_time.release());
1734 list_value->Set(i,entry_metadata.release());
1735 }
1736
1737 size_t index = 0;
1738 if (!response->Set(index++,
1739 new base::FundamentalValue(PP_OperationType_READDIRECTORY))||
1740 !response->Set(index++,
1741 new base::FundamentalValue(true))|| // status = success
1742 !response->Set(index++,
1743 new base::StringValue(filesystem_id) ) ||
1744 !response->Set(index++, new base::FundamentalValue(request_id) ) ||
1745 !response->Set(index++, list_value.release() ) ||
1746 !response->Set(index++,
1747 new base::FundamentalValue( PP_ToBool( has_more ) ) ) ||
1748 !response->Set(index++, new base::FundamentalValue( (int)time_span ) ) )
1749 return scoped_ptr<base::ListValue>();
1750 return response.Pass();
1751 }
1752 } // namespace
1753 } // namespace proxy
1754 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698