OLD | NEW |
(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/IDBRequestQueueItem.h" |
| 11 #include "modules/indexeddb/IDBValue.h" |
| 12 #include "modules/indexeddb/IDBValueWrapping.h" |
| 13 #include "public/platform/modules/indexeddb/WebIDBDatabaseException.h" |
| 14 |
| 15 namespace blink { |
| 16 |
| 17 IDBRequestLoader::IDBRequestLoader(IDBRequestQueueItem* queue_item, |
| 18 Vector<RefPtr<IDBValue>>* result_values) |
| 19 : queue_item_(queue_item), values_(result_values) { |
| 20 DCHECK(IDBValueUnwrapper::IsWrapped(*values_)); |
| 21 loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this); |
| 22 } |
| 23 |
| 24 IDBRequestLoader::~IDBRequestLoader() { |
| 25 // TODO(pwnall): Do we need to call loader_->Cancel() here? |
| 26 } |
| 27 |
| 28 void IDBRequestLoader::Start() { |
| 29 // TODO(pwnall): Start() / StartNextValue() unwrap large values sequentially. |
| 30 // Consider parallelizing. The main issue is that the Blob reads |
| 31 // will have to be throttled somewhere, and the extra complexity |
| 32 // only benefits applications that use getAll(). |
| 33 current_value_ = values_->begin(); |
| 34 StartNextValue(); |
| 35 } |
| 36 |
| 37 void IDBRequestLoader::Cancel() { |
| 38 loader_->Cancel(); |
| 39 } |
| 40 |
| 41 void IDBRequestLoader::StartNextValue() { |
| 42 IDBValueUnwrapper unwrapper; |
| 43 |
| 44 while (true) { |
| 45 if (current_value_ == values_->end()) { |
| 46 ReportSuccess(); |
| 47 return; |
| 48 } |
| 49 if (unwrapper.Parse(current_value_->Get())) |
| 50 break; |
| 51 ++current_value_; |
| 52 } |
| 53 |
| 54 DCHECK(current_value_ != values_->end()); |
| 55 |
| 56 ExecutionContext* context = queue_item_->Request()->GetExecutionContext(); |
| 57 if (!context) { |
| 58 ReportError(); |
| 59 return; |
| 60 } |
| 61 |
| 62 wrapped_data_.ReserveCapacity(unwrapper.WrapperBlobSize()); |
| 63 loader_->Start(context, unwrapper.WrapperBlobHandle()); |
| 64 } |
| 65 |
| 66 void IDBRequestLoader::DidStartLoading() {} |
| 67 |
| 68 void IDBRequestLoader::DidReceiveDataForClient(const char* data, |
| 69 unsigned data_length) { |
| 70 DCHECK_LE(wrapped_data_.size() + data_length, wrapped_data_.capacity()) |
| 71 << "The reader returned more data than we were prepared for"; |
| 72 |
| 73 wrapped_data_.Append(data, data_length); |
| 74 } |
| 75 |
| 76 void IDBRequestLoader::DidFinishLoading() { |
| 77 *current_value_ = IDBValueUnwrapper::Unwrap( |
| 78 current_value_->Get(), SharedBuffer::AdoptVector(wrapped_data_)); |
| 79 ++current_value_; |
| 80 |
| 81 StartNextValue(); |
| 82 } |
| 83 |
| 84 void IDBRequestLoader::DidFail(FileError::ErrorCode) { |
| 85 ReportError(); |
| 86 } |
| 87 |
| 88 void IDBRequestLoader::ReportSuccess() { |
| 89 queue_item_->OnResultLoadComplete(); |
| 90 } |
| 91 |
| 92 void IDBRequestLoader::ReportError() { |
| 93 queue_item_->OnResultLoadComplete( |
| 94 DOMException::Create(kDataError, "Failed to read large IndexedDB value")); |
| 95 } |
| 96 |
| 97 } // namespace blink |
OLD | NEW |