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

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: Fixed compilation errors on Windows and no-DCHECKs. 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/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)
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;
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) {
dmurph 2017/05/04 22:27:07 There must be a library method for this... maybe i
pwnall 2017/05/11 23:54:24 As far as I know, there isn't. Please correct me i
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 if (end_ - current_ < length)
116 return false;
117 String output(current_, length);
118 value.swap(output);
119 current_ += length;
120 return true;
121 }
122
123 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698