blob: 70e7e113a873656dbd4dcb97d0f91717094b60c3 [file] [log] [blame]
// Copyright 2018 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 "third_party/blink/renderer/modules/file_system_access/native_file_system_directory_iterator.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/file_system_access/native_file_system_directory_handle.h"
#include "third_party/blink/renderer/modules/file_system_access/native_file_system_error.h"
#include "third_party/blink/renderer/modules/file_system_access/native_file_system_file_handle.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
NativeFileSystemDirectoryIterator::NativeFileSystemDirectoryIterator(
NativeFileSystemDirectoryHandle* directory,
Mode mode,
ExecutionContext* execution_context)
: ExecutionContextClient(execution_context),
mode_(mode),
directory_(directory),
receiver_(this, execution_context) {
directory_->MojoHandle()->GetEntries(receiver_.BindNewPipeAndPassRemote(
execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
ScriptPromise NativeFileSystemDirectoryIterator::next(
ScriptState* script_state) {
if (error_) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
auto result = resolver->Promise();
native_file_system_error::Reject(resolver, *error_);
return result;
}
if (!entries_.IsEmpty()) {
NativeFileSystemHandle* handle = entries_.TakeFirst();
ScriptValue result;
switch (mode_) {
case Mode::kKey:
result = V8IteratorResult(script_state, handle->name());
break;
case Mode::kValue:
result = V8IteratorResult(script_state, handle);
break;
case Mode::kKeyValue:
HeapVector<ScriptValue, 2> keyvalue;
keyvalue.push_back(ScriptValue(script_state->GetIsolate(),
ToV8(handle->name(), script_state)));
keyvalue.push_back(ScriptValue(script_state->GetIsolate(),
ToV8(handle, script_state)));
result = V8IteratorResult(script_state, keyvalue);
break;
}
return ScriptPromise::Cast(script_state, result);
}
if (waiting_for_more_entries_) {
DCHECK(!pending_next_);
pending_next_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
return pending_next_->Promise();
}
return ScriptPromise::Cast(script_state, V8IteratorResultDone(script_state));
}
bool NativeFileSystemDirectoryIterator::HasPendingActivity() const {
return pending_next_;
}
void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
visitor->Trace(receiver_);
visitor->Trace(entries_);
visitor->Trace(pending_next_);
visitor->Trace(directory_);
}
void NativeFileSystemDirectoryIterator::DidReadDirectory(
mojom::blink::FileSystemAccessErrorPtr result,
Vector<mojom::blink::FileSystemAccessEntryPtr> entries,
bool has_more_entries) {
if (!GetExecutionContext())
return;
if (result->status != mojom::blink::FileSystemAccessStatus::kOk) {
error_ = std::move(result);
if (pending_next_) {
native_file_system_error::Reject(pending_next_, *error_);
pending_next_ = nullptr;
}
return;
}
for (auto& e : entries) {
entries_.push_back(NativeFileSystemHandle::CreateFromMojoEntry(
std::move(e), GetExecutionContext()));
}
waiting_for_more_entries_ = has_more_entries;
if (pending_next_) {
ScriptState::Scope scope(pending_next_->GetScriptState());
pending_next_->Resolve(
next(pending_next_->GetScriptState()).AsScriptValue());
pending_next_ = nullptr;
}
}
} // namespace blink