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/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 | |
OLD | NEW |