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

Unified Diff: third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp

Issue 2822453003: Wrap large IndexedDB values into Blobs before writing to LevelDB. (Closed)
Patch Set: Created 3 years, 8 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
Index: third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2fb36880f1b27b0f057d04c699a383d722b24253
--- /dev/null
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp
@@ -0,0 +1,156 @@
+// Copyright 2017 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 "modules/indexeddb/IDBRequestLoader.h"
+
+#include "core/dom/DOMException.h"
+#include "core/fileapi/FileReaderLoader.h"
+#include "modules/indexeddb/IDBRequest.h"
+#include "modules/indexeddb/IDBValue.h"
+#include "modules/indexeddb/IDBValueUnwrapper.h"
+#include "public/platform/modules/indexeddb/WebIDBDatabaseException.h"
+
+namespace blink {
+
+IDBRequestLoader::IDBRequestLoader(IDBRequest* request)
+ : mode_(kUninitialized), request_(request) {
+ loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this);
+}
+
+IDBRequestLoader::~IDBRequestLoader() {
+ // TODO(pwnall): Do we need to call loader_->Cancel() here?
+}
+
+bool IDBRequestLoader::NeedsUnwrapping(IDBValue* value) {
+ return IDBValueUnwrapper::IsWrapped(value);
+}
+
+bool IDBRequestLoader::NeedUnwrapping(const Vector<RefPtr<IDBValue>>& values) {
+ for (const auto& value : values) {
+ if (IDBValueUnwrapper::IsWrapped(value.Get()))
+ return true;
+ }
+ return false;
+}
+
+void IDBRequestLoader::Start(PassRefPtr<IDBValue> value) {
+ DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
+
+ values_.push_back(value);
+ mode_ = kValue;
+ StartNextValue();
+}
+
+void IDBRequestLoader::Start(const Vector<RefPtr<IDBValue>>& values) {
+ DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
+
+ values_.AppendVector(values);
+ mode_ = kValueArray;
+ StartNextValue();
+}
+
+void IDBRequestLoader::Start(IDBKey* key,
+ IDBKey* primary_key,
+ PassRefPtr<IDBValue> value) {
+ DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
+
+ key_ = key;
+ primary_key_ = primary_key;
+ values_.push_back(value);
+ mode_ = kKeyPrimaryKeyValue;
+ StartNextValue();
+}
+
+void IDBRequestLoader::Start(std::unique_ptr<WebIDBCursor> backend,
+ IDBKey* key,
+ IDBKey* primary_key,
+ PassRefPtr<IDBValue> value) {
+ DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
+
+ backend_ = std::move(backend);
+ key_ = key;
+ primary_key_ = primary_key;
+ values_.push_back(value);
+ mode_ = kBackendKeyPrimaryKeyValue;
+ StartNextValue();
+}
+
+void IDBRequestLoader::StartNextValue() {
+ IDBValueUnwrapper unwrapper;
+
+ while (true) {
+ if (current_value_ == values_.end()) {
+ ReportSuccess();
+ return;
+ }
+ if (unwrapper.Parse(current_value_->Get()))
+ break;
+ ++current_value_;
+ }
+
+ DCHECK(current_value_ != values_.end());
+
+ ExecutionContext* context = request_->GetExecutionContext();
+ if (!context) {
+ ReportError();
+ return;
+ }
+
+ wrapped_data_.ReserveCapacity(unwrapper.WrapperBlobSize());
+ loader_->Start(context, unwrapper.WrapperBlobHandle());
+}
+
+void IDBRequestLoader::DidStartLoading() {}
+
+void IDBRequestLoader::DidReceiveDataForClient(const char* data,
+ unsigned data_length) {
+ DCHECK_LE(wrapped_data_.size() + data_length, wrapped_data_.Capacity())
+ << "The reader returned more data than we were prepared for";
+
+ wrapped_data_.Append(data, data_length);
+}
+
+void IDBRequestLoader::DidFinishLoading() {
+ *current_value_ = IDBValueUnwrapper::CreateUnwrapped(
+ current_value_->Get(), SharedBuffer::AdoptVector(wrapped_data_));
+ ++current_value_;
+
+ StartNextValue();
+}
+
+void IDBRequestLoader::DidFail(FileError::ErrorCode) {
+ ReportError();
+}
+
+void IDBRequestLoader::ReportSuccess() {
+ switch (mode_) {
+ case kUninitialized:
+ NOTREACHED() << "Start() was not called";
+
+ case kValue:
+ DCHECK_EQ(values_.size(), 1U);
+ request_->OnSuccess(values_[0]);
+ break;
+
+ case kValueArray:
+ request_->OnSuccess(values_);
+ break;
+
+ case kKeyPrimaryKeyValue:
+ DCHECK_EQ(values_.size(), 1U);
+ request_->OnSuccess(key_, primary_key_, values_[0]);
+
+ case kBackendKeyPrimaryKeyValue:
+ DCHECK_EQ(values_.size(), 1U);
+ request_->OnSuccess(std::move(backend_), key_, primary_key_, values_[0]);
+ }
+}
+
+void IDBRequestLoader::ReportError() {
+ request_->OnError(
+ DOMException::Create(kWebIDBDatabaseExceptionDataError,
+ "Failed to read large IndexedDB value"));
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698