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

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: Rebase + start addressing feedback. Created 3 years, 7 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 <memory>
8 #include <utility>
9
10 #include "bindings/core/v8/serialization/SerializationTag.h"
11 #include "modules/indexeddb/IDBValue.h"
12 #include "modules/indexeddb/IDBValueWrapper.h"
13 #include "platform/blob/BlobData.h"
14 #include "platform/wtf/text/WTFString.h"
15
16 namespace blink {
17
18 IDBValueUnwrapper::IDBValueUnwrapper() {
19 Reset();
20 }
21
22 bool IDBValueUnwrapper::IsWrapped(IDBValue* value) {
23 DCHECK(value);
24 if (!value->data_ || value->data_->size() < 3)
jsbell 2017/05/08 22:08:01 Constants/documentation for these magic numbers.
pwnall 2017/05/11 23:54:25 Done.
25 return false;
26
27 uint8_t header[3];
28 value->data_->GetPartAsBytes(header, static_cast<size_t>(0), sizeof(header));
29 return header[0] == kVersionTag && header[1] == 17 && header[2] == 1;
jsbell 2017/05/08 22:08:01 Ditto.
pwnall 2017/05/11 23:54:25 Done.
30 }
31
32 PassRefPtr<IDBValue> IDBValueUnwrapper::CreateUnwrapped(
33 IDBValue* wrapped_value,
34 PassRefPtr<SharedBuffer> wrapper_blob_content) {
35 DCHECK(wrapped_value);
36 DCHECK(wrapped_value->data_);
37 DCHECK_GT(wrapped_value->blob_info_->size(), 0U);
38 DCHECK_EQ(wrapped_value->blob_info_->size(),
39 wrapped_value->blob_data_->size());
40
41 // Create an IDBValue with the same blob information, minus the last blob.
42 unsigned blob_count = wrapped_value->BlobInfo()->size() - 1;
43 std::unique_ptr<Vector<RefPtr<BlobDataHandle>>> blob_data =
44 WTF::MakeUnique<Vector<RefPtr<BlobDataHandle>>>();
45 blob_data->ReserveCapacity(blob_count);
46 std::unique_ptr<Vector<WebBlobInfo>> blob_info =
47 WTF::MakeUnique<Vector<WebBlobInfo>>();
48 blob_info->ReserveCapacity(blob_count);
49
50 for (unsigned i = 0; i < blob_count; ++i) {
51 blob_data->push_back((*wrapped_value->blob_data_)[i]);
52 blob_info->push_back((*wrapped_value->blob_info_)[i]);
53 }
54
55 return AdoptRef(new IDBValue(std::move(wrapper_blob_content),
56 std::move(blob_data), std::move(blob_info)));
57 }
58
59 bool IDBValueUnwrapper::Parse(IDBValue* value) {
60 // Fast path that avoids unnecessary dynamic allocations.
61 if (!IDBValueUnwrapper::IsWrapped(value))
62 return false;
63
64 const uint8_t* data = reinterpret_cast<const uint8_t*>(value->data_->Data());
65 end_ = data + value->data_->size();
66 current_ = data + 3;
67
68 String blob_uuid;
69 if (!ReadVarint(blob_size_))
70 return Reset();
71 if (!ReadAsciiString(blob_uuid))
72 return Reset();
73
74 blob_handle_ = value->blob_data_->back();
75
76 // TODO(pwnall): Blobs seem to get different UUIDs when they're resurrected?
77 // If this is true, stashing the UUID is useless.
78 if (blob_handle_->size() != blob_size_)
79 return Reset();
80
81 return true;
82 }
83
84 PassRefPtr<BlobDataHandle> IDBValueUnwrapper::WrapperBlobHandle() {
85 DCHECK(blob_handle_);
86
87 return std::move(blob_handle_);
88 }
89
90 bool IDBValueUnwrapper::ReadVarint(unsigned& value) {
91 value = 0;
92 unsigned shift = 0;
93 bool has_another_byte;
94 do {
95 if (current_ >= end_)
96 return false;
97
98 if (shift >= sizeof(unsigned) * 8)
99 return false;
100 uint8_t byte = *current_;
101 ++current_;
102 value |= static_cast<unsigned>(byte & 0x7F) << shift;
103 shift += 7;
104
105 has_another_byte = byte & 0x80;
106 } while (has_another_byte);
107 return true;
108 }
109
110 bool IDBValueUnwrapper::ReadAsciiString(String& value) {
111 unsigned length;
112 if (!ReadVarint(length))
113 return false;
114
115 DCHECK_LE(current_, end_);
116 if (end_ - current_ < static_cast<ptrdiff_t>(length))
117 return false;
118 String output(current_, length);
119 value.swap(output);
120 current_ += length;
121 return true;
122 }
123
124 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698