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

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBValueUnwrapper.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/IDBValueUnwrapper.h"
6
7 #include "bindings/core/v8/SerializationTag.h"
8 #include "modules/indexeddb/IDBValue.h"
9 #include "modules/indexeddb/IDBValueWrapper.h"
10 #include "platform/blob/BlobData.h"
11 #include "platform/wtf/text/WTFString.h"
12
13 namespace blink {
14
15 IDBValueUnwrapper::IDBValueUnwrapper() : data_(nullptr) {}
16
17 bool IDBValueUnwrapper::IsWrapped(IDBValue* value) {
18 uint8_t header[3];
19 value->data_->GetPartAsBytes(header, 0UL, sizeof(header));
20 return header[0] == kVersionTag && header[1] == 17 && header[2] == 1;
21 }
22
23 PassRefPtr<IDBValue> IDBValueUnwrapper::CreateUnwrapped(
24 IDBValue* wrapped_value,
25 PassRefPtr<SharedBuffer> unwrapped_data) {
26 DCHECK_GT(wrapped_value->blob_info_->size(), 0U);
27 DCHECK_EQ(wrapped_value->blob_info_->size(),
28 wrapped_value->blob_data_->size());
29
30 // Create an IDBValue with the same blob information, minus the last blob.
31 unsigned blob_count = wrapped_value->BlobInfo()->size() - 1;
32 std::unique_ptr<Vector<RefPtr<BlobDataHandle>>> blob_data;
33 blob_data->ReserveCapacity(blob_count);
34 std::unique_ptr<Vector<WebBlobInfo>> blob_info;
35 blob_info->ReserveCapacity(blob_count);
36
37 for (unsigned i = 0; i < blob_count; ++i) {
38 blob_data->push_back((*wrapped_value->blob_data_)[i]);
39 blob_info->push_back((*wrapped_value->blob_info_)[i]);
40 }
41
42 return AdoptRef(new IDBValue(std::move(unwrapped_data), std::move(blob_data),
43 std::move(blob_info)));
44 }
45
46 bool IDBValueUnwrapper::Parse(IDBValue* value) {
47 #if DCHECK_IS_ON()
48 blob_handle_.Clear();
49 #endif // DCHECK_IS_ON()
50
51 // Fast path that avoids unnecessary dynamic allocations.
52 if (!IDBValueUnwrapper::IsWrapped(value))
53 return false;
54
55 data_ = reinterpret_cast<const uint8_t*>(value->data_->Data());
56 end_ = value->data_->size();
57 position_ = 0;
58
59 String blob_uuid;
60 if (!ReadVarint(blob_size_))
61 return false;
62 if (!ReadAsciiString(blob_uuid))
63 return false;
64
65 blob_handle_ = value->blob_data_->back();
66 if (blob_handle_->size() != blob_size_ || blob_handle_->Uuid() != blob_uuid)
67 return false;
68
69 #if DCHECK_IS_ON()
70 data_ = nullptr;
71 #endif // DCHECK_IS_ON()
72
73 return true;
74 }
75
76 PassRefPtr<BlobDataHandle> IDBValueUnwrapper::WrapperBlobHandle() {
77 DCHECK(blob_handle_);
78
79 return std::move(blob_handle_);
80 }
81
82 bool IDBValueUnwrapper::ReadVarint(unsigned& value) {
83 DCHECK(data_);
84
85 value = 0;
86 unsigned shift = 0;
87 bool has_another_byte;
88 do {
89 if (position_ >= end_)
90 return false;
91
92 if (shift >= sizeof(unsigned) * 8)
93 return false;
94 value |= static_cast<unsigned>(data_[position_]) << shift;
95 shift += 7;
96
97 has_another_byte = value & 0x80;
98 } while (has_another_byte);
99 return true;
100 }
101
102 bool IDBValueUnwrapper::ReadAsciiString(String& value) {
103 unsigned length;
104 if (!ReadVarint(length))
105 return false;
106
107 if (position_ + length > end_)
108 return false;
109 String output(data_ + position_, length);
110 value.Swap(output);
111 position_ += length;
112 return true;
113 }
114
115 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698