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

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBValueWrapper.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/IDBValueWrapper.h"
6
7 #include <utility>
8
9 #include "bindings/core/v8/ScriptValue.h"
10 #include "bindings/core/v8/serialization/SerializationTag.h"
11 #include "bindings/core/v8/serialization/SerializedScriptValue.h"
12 #include "bindings/modules/v8/V8BindingForModules.h"
13 #include "core/fileapi/Blob.h"
14 #include "modules/indexeddb/IDBRequest.h"
15 #include "platform/wtf/text/WTFString.h"
16
17 namespace blink {
18
19 IDBValueWrapper::IDBValueWrapper(v8::Isolate* isolate,
20 v8::Local<v8::Value> value,
21 bool write_wasm_to_stream,
22 ExceptionState& exception_state) {
23 SerializedScriptValue::SerializeOptions options;
24 options.blob_info = &blob_info_;
25 options.for_storage = true;
26 options.write_wasm_to_stream = write_wasm_to_stream;
27
28 serialized_value_ = SerializedScriptValue::Serialize(isolate, value, options,
29 exception_state);
30
31 #if DCHECK_IS_ON()
32 if (exception_state.HadException())
33 had_exception_ = true;
34 #endif // DCHECK_IS_ON()
35 }
36
37 void IDBValueWrapper::Clone(ScriptState* script_state, ScriptValue* clone) {
38 #if DCHECK_IS_ON()
39 DCHECK(!had_exception_)
40 << "Clone() called on wrapper with serialization exception";
41 DCHECK(!wrap_called_) << "Clone() called after WrapIfBiggerThan()";
42 #endif // DCHECK_IS_ON()
43 *clone = DeserializeScriptValue(script_state, serialized_value_.Get(),
44 &blob_info_);
45 }
46
47 void IDBValueWrapper::WriteVarint(unsigned value, Vector<char>& output) {
48 // Writes an unsigned integer as a base-128 varint.
49 // The number is written, 7 bits at a time, from the least significant to
50 // the most significant 7 bits. Each byte, except the last, has the MSB set.
51 // See also https://developers.google.com/protocol-buffers/docs/encoding
52 do {
53 output.push_back((value & 0x7F) | 0x80);
54 value >>= 7;
55 } while (value);
56 output.back() &= 0x7F;
57 }
58
59 void IDBValueWrapper::WriteAsciiString(const String& value,
60 Vector<char>& output) {
61 DCHECK(value.Is8Bit() && value.ContainsOnlyASCII());
62
63 IDBValueWrapper::WriteVarint(value.length(), output);
64 output.Append(value.Characters8(), value.length());
65 }
66
67 bool IDBValueWrapper::WrapIfBiggerThan(unsigned max_bytes) {
68 #if DCHECK_IS_ON()
69 DCHECK(!had_exception_)
70 << "WrapIfBiggerThan() called on wrapper with serialization exception";
jsbell 2017/05/08 22:08:01 tip: could use __FUNCTION__ to make this more refa
pwnall 2017/05/11 23:54:25 Done. Thank you very much for the tip!
71 DCHECK(!wrap_called_)
72 << "WrapIfBiggerThan() called twice on the same wrapper";
73 wrap_called_ = true;
74 #endif // DCHECK_IS_ON()
75
76 serialized_value_->ToWireBytes(wire_bytes_);
77 if (wire_bytes_.size() <= max_bytes)
78 return false;
79
80 // TODO(pwnall): The MIME type should probably be an atomic string.
81 String mime_type(kWrapMimeType);
82 Blob* wrapper =
83 Blob::Create(reinterpret_cast<unsigned char*>(wire_bytes_.data()),
84 wire_bytes_.size(), mime_type);
85
86 wrapper_handle_ = std::move(wrapper->GetBlobDataHandle());
87 blob_info_.emplace_back(wrapper_handle_->Uuid(), wrapper_handle_->GetType(),
88 wrapper->size());
89
90 wire_bytes_.clear();
91
92 // Version 17 of SSV always writes a V8 envelope after the Blink envelope, so
93 // its output starts with 0xFF 0x11 0xFF. Therefore, we can use 0xFF 0x11 0xvv
94 // as an escape prefix, for 0x00 <= 0xvv < 0xFF.
95 wire_bytes_.push_back(kVersionTag);
96 wire_bytes_.push_back(17);
97 wire_bytes_.push_back(1);
98 IDBValueWrapper::WriteVarint(wrapper->size(), wire_bytes_);
99 IDBValueWrapper::WriteAsciiString(wrapper->Uuid(), wire_bytes_);
100 return true;
101 }
102
103 void IDBValueWrapper::ExtractBlobDataHandles(
104 Vector<RefPtr<BlobDataHandle>>* blob_data_handles) {
105 for (const auto& kvp : serialized_value_->BlobDataHandles())
106 blob_data_handles->push_back(kvp.value);
107 if (wrapper_handle_)
108 blob_data_handles->push_back(std::move(wrapper_handle_));
109 }
110
111 PassRefPtr<SharedBuffer> IDBValueWrapper::ExtractWireBytes() {
112 #if DCHECK_IS_ON()
113 DCHECK(!had_exception_)
114 << "ExtractWireBytes() called on wrapper with serialization exception";
115 #endif // DCHECK_IS_ON()
116
117 return SharedBuffer::AdoptVector(wire_bytes_);
118 }
119
120 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698