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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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
5 #include "modules/indexeddb/IDBRequestLoader.h"
6
7 #include "core/dom/DOMException.h"
8 #include "core/fileapi/FileReaderLoader.h"
9 #include "modules/indexeddb/IDBRequest.h"
10 #include "modules/indexeddb/IDBValue.h"
11 #include "modules/indexeddb/IDBValueUnwrapper.h"
12 #include "public/platform/modules/indexeddb/WebIDBDatabaseException.h"
13
14 namespace blink {
15
16 IDBRequestLoader::IDBRequestLoader(IDBRequest* request)
17 : mode_(kUninitialized), request_(request) {
18 loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this);
19 }
20
21 IDBRequestLoader::~IDBRequestLoader() {
22 // TODO(pwnall): Do we need to call loader_->Cancel() here?
23 }
24
25 bool IDBRequestLoader::NeedsUnwrapping(IDBValue* value) {
26 return IDBValueUnwrapper::IsWrapped(value);
27 }
28
29 bool IDBRequestLoader::NeedUnwrapping(const Vector<RefPtr<IDBValue>>& values) {
30 for (const auto& value : values) {
31 if (IDBValueUnwrapper::IsWrapped(value.Get()))
32 return true;
33 }
34 return false;
35 }
36
37 void IDBRequestLoader::Start(PassRefPtr<IDBValue> value) {
38 DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
39
40 values_.push_back(value);
41 mode_ = kValue;
42 StartNextValue();
43 }
44
45 void IDBRequestLoader::Start(const Vector<RefPtr<IDBValue>>& values) {
46 DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
47
48 values_.AppendVector(values);
49 mode_ = kValueArray;
50 StartNextValue();
51 }
52
53 void IDBRequestLoader::Start(IDBKey* key,
54 IDBKey* primary_key,
55 PassRefPtr<IDBValue> value) {
56 DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
57
58 key_ = key;
59 primary_key_ = primary_key;
60 values_.push_back(value);
61 mode_ = kKeyPrimaryKeyValue;
62 StartNextValue();
63 }
64
65 void IDBRequestLoader::Start(std::unique_ptr<WebIDBCursor> backend,
66 IDBKey* key,
67 IDBKey* primary_key,
68 PassRefPtr<IDBValue> value) {
69 DCHECK_EQ(mode_, kUninitialized) << "Start() has been called before";
70
71 backend_ = std::move(backend);
72 key_ = key;
73 primary_key_ = primary_key;
74 values_.push_back(value);
75 mode_ = kBackendKeyPrimaryKeyValue;
76 StartNextValue();
77 }
78
79 void IDBRequestLoader::StartNextValue() {
80 IDBValueUnwrapper unwrapper;
81
82 while (true) {
83 if (current_value_ == values_.end()) {
84 ReportSuccess();
85 return;
86 }
87 if (unwrapper.Parse(current_value_->Get()))
88 break;
89 ++current_value_;
90 }
91
92 DCHECK(current_value_ != values_.end());
93
94 ExecutionContext* context = request_->GetExecutionContext();
95 if (!context) {
96 ReportError();
97 return;
98 }
99
100 wrapped_data_.ReserveCapacity(unwrapper.WrapperBlobSize());
101 loader_->Start(context, unwrapper.WrapperBlobHandle());
102 }
103
104 void IDBRequestLoader::DidStartLoading() {}
105
106 void IDBRequestLoader::DidReceiveDataForClient(const char* data,
107 unsigned data_length) {
108 DCHECK_LE(wrapped_data_.size() + data_length, wrapped_data_.Capacity())
109 << "The reader returned more data than we were prepared for";
110
111 wrapped_data_.Append(data, data_length);
112 }
113
114 void IDBRequestLoader::DidFinishLoading() {
115 *current_value_ = IDBValueUnwrapper::CreateUnwrapped(
116 current_value_->Get(), SharedBuffer::AdoptVector(wrapped_data_));
117 ++current_value_;
118
119 StartNextValue();
120 }
121
122 void IDBRequestLoader::DidFail(FileError::ErrorCode) {
123 ReportError();
124 }
125
126 void IDBRequestLoader::ReportSuccess() {
127 switch (mode_) {
128 case kUninitialized:
129 NOTREACHED() << "Start() was not called";
130
131 case kValue:
132 DCHECK_EQ(values_.size(), 1U);
133 request_->OnSuccess(values_[0]);
134 break;
135
136 case kValueArray:
137 request_->OnSuccess(values_);
138 break;
139
140 case kKeyPrimaryKeyValue:
141 DCHECK_EQ(values_.size(), 1U);
142 request_->OnSuccess(key_, primary_key_, values_[0]);
143
144 case kBackendKeyPrimaryKeyValue:
145 DCHECK_EQ(values_.size(), 1U);
146 request_->OnSuccess(std::move(backend_), key_, primary_key_, values_[0]);
147 }
148 }
149
150 void IDBRequestLoader::ReportError() {
151 request_->OnError(
152 DOMException::Create(kWebIDBDatabaseExceptionDataError,
153 "Failed to read large IndexedDB value"));
154 }
155
156 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698