// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_directory_reader.h" #include "base/logging.h" #include "base/utf_string_conversions.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/dev/ppb_directory_reader_dev.h" #include "webkit/glue/plugins/pepper_file_callbacks.h" #include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_file_system.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { namespace { std::string FilePathStringToUTF8String(const FilePath::StringType& str) { #if defined(OS_WIN) return WideToUTF8(str); #elif defined(OS_POSIX) return str; #else #error "Unsupported platform." #endif } FilePath::StringType UTF8StringToFilePathString(const std::string& str) { #if defined(OS_WIN) return UTF8ToWide(str); #elif defined(OS_POSIX) return str; #else #error "Unsupported platform." #endif } PP_Resource Create(PP_Resource directory_ref_id) { scoped_refptr directory_ref( Resource::GetAs(directory_ref_id)); if (!directory_ref) return 0; DirectoryReader* reader = new DirectoryReader(directory_ref); return reader->GetReference(); } PP_Bool IsDirectoryReader(PP_Resource resource) { return BoolToPPBool(!!Resource::GetAs(resource)); } int32_t GetNextEntry(PP_Resource reader_id, PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback) { scoped_refptr reader( Resource::GetAs(reader_id)); if (!reader) return PP_ERROR_BADRESOURCE; return reader->GetNextEntry(entry, callback); } const PPB_DirectoryReader_Dev ppb_directoryreader = { &Create, &IsDirectoryReader, &GetNextEntry }; } // namespace DirectoryReader::DirectoryReader(FileRef* directory_ref) : Resource(directory_ref->module()), directory_ref_(directory_ref), has_more_(true), entry_(NULL) { } DirectoryReader::~DirectoryReader() { } const PPB_DirectoryReader_Dev* DirectoryReader::GetInterface() { return &ppb_directoryreader; } int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback) { if (directory_ref_->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) return PP_ERROR_FAILED; entry_ = entry; if (FillUpEntry()) { entry_ = NULL; return PP_OK; } PluginInstance* instance = directory_ref_->GetFileSystem()->instance(); if (!instance->delegate()->ReadDirectory( directory_ref_->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), callback, NULL, NULL, this))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; } void DirectoryReader::AddNewEntries( const std::vector& entries, bool has_more) { DCHECK(!entries.empty()); has_more_ = has_more; std::string dir_path = directory_ref_->GetPath(); if (dir_path[dir_path.size() - 1] != '/') dir_path += '/'; FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path); for (std::vector::const_iterator it = entries.begin(); it != entries.end(); it++) { base::FileUtilProxy::Entry entry; entry.name = dir_file_path + it->name; entry.is_directory = it->is_directory; entries_.push(entry); } FillUpEntry(); entry_ = NULL; } bool DirectoryReader::FillUpEntry() { DCHECK(entry_); if (!entries_.empty()) { base::FileUtilProxy::Entry dir_entry = entries_.front(); entries_.pop(); if (entry_->file_ref) ResourceTracker::Get()->UnrefResource(entry_->file_ref); FileRef* file_ref = new FileRef(module(), directory_ref_->GetFileSystem(), FilePathStringToUTF8String(dir_entry.name)); entry_->file_ref = file_ref->GetReference(); entry_->file_type = (dir_entry.is_directory ? PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR); return true; } if (!has_more_) { entry_->file_ref = 0; return true; } return false; } } // namespace pepper