blob: 2f381217fdd365c490f6e7e77b7f65c519c173af [file] [log] [blame]
// Copyright (c) 2012 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/plugins/ppapi/ppb_directory_reader_impl.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 "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_file_ref_api.h"
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/file_callbacks.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
#include "webkit/plugins/ppapi/ppb_file_system_impl.h"
#include "webkit/plugins/ppapi/resource_helper.h"
using ::ppapi::PpapiGlobals;
using ::ppapi::thunk::EnterResourceNoLock;
using ::ppapi::thunk::PPB_DirectoryReader_API;
using ::ppapi::thunk::PPB_FileRef_API;
namespace webkit {
namespace ppapi {
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
}
} // namespace
PPB_DirectoryReader_Impl::PPB_DirectoryReader_Impl(
PPB_FileRef_Impl* directory_ref)
: Resource(::ppapi::OBJECT_IS_IMPL, directory_ref->pp_instance()),
directory_ref_(directory_ref),
has_more_(true),
entry_(NULL) {
}
PPB_DirectoryReader_Impl::~PPB_DirectoryReader_Impl() {
}
// static
PP_Resource PPB_DirectoryReader_Impl::Create(PP_Resource directory_ref) {
EnterResourceNoLock<PPB_FileRef_API> enter(directory_ref, true);
if (enter.failed())
return 0;
return (new PPB_DirectoryReader_Impl(
static_cast<PPB_FileRef_Impl*>(enter.object())))->GetReference();
}
PPB_DirectoryReader_API* PPB_DirectoryReader_Impl::AsPPB_DirectoryReader_API() {
return this;
}
int32_t PPB_DirectoryReader_Impl::GetNextEntry(
PP_DirectoryEntry_Dev* entry,
PP_CompletionCallback callback) {
if (!callback.func)
return PP_ERROR_BLOCKS_MAIN_THREAD;
if (directory_ref_->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL)
return PP_ERROR_FAILED;
entry_ = entry;
if (FillUpEntry()) {
entry_ = NULL;
return PP_OK;
}
PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this);
if (!plugin_instance)
return PP_ERROR_FAILED;
if (!plugin_instance->delegate()->ReadDirectory(
directory_ref_->GetFileSystemURL(),
new FileCallbacks(this, callback, NULL, NULL, this)))
return PP_ERROR_FAILED;
return PP_OK_COMPLETIONPENDING;
}
void PPB_DirectoryReader_Impl::AddNewEntries(
const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more) {
DCHECK(!entries.empty() || !has_more);
has_more_ = has_more;
std::string dir_path = directory_ref_->GetCreateInfo().path;
if (dir_path[dir_path.size() - 1] != '/')
dir_path += '/';
FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path);
for (std::vector<base::FileUtilProxy::Entry>::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 PPB_DirectoryReader_Impl::FillUpEntry() {
DCHECK(entry_);
if (!entries_.empty()) {
base::FileUtilProxy::Entry dir_entry = entries_.front();
entries_.pop();
if (entry_->file_ref) {
PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
entry_->file_ref);
}
PPB_FileRef_Impl* file_ref = PPB_FileRef_Impl::CreateInternal(
directory_ref_->file_system()->pp_resource(),
FilePathStringToUTF8String(dir_entry.name));
if (!file_ref)
return false;
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 ppapi
} // namespace webkit