1 // Copyright 2018 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 "third_party/blink/renderer/core/inspector/inspector_session_state.h"
6
7 #include "third_party/inspector_protocol/crdtp/cbor.h"
8
9 namespace blink {
10 namespace {
11 using crdtp::span;
12 using crdtp::SpanFrom;
13 using crdtp::cbor::CBORTokenizer;
14 using crdtp::cbor::CBORTokenTag;
15 using crdtp::cbor::EncodeDouble;
16 using crdtp::cbor::EncodeFalse;
17 using crdtp::cbor::EncodeFromLatin1;
18 using crdtp::cbor::EncodeFromUTF16;
19 using crdtp::cbor::EncodeInt32;
20 using crdtp::cbor::EncodeNull;
21 using crdtp::cbor::EncodeTrue;
22 } // namespace
23
24 //
25 // InspectorSessionState
26 //
InspectorSessionState(mojom::blink::DevToolsSessionStatePtr reattach)27 InspectorSessionState::InspectorSessionState(
28 mojom::blink::DevToolsSessionStatePtr reattach)
29 : reattach_state_(std::move(reattach)),
30 updates_(mojom::blink::DevToolsSessionState::New()) {}
31
ReattachState() const32 const mojom::blink::DevToolsSessionState* InspectorSessionState::ReattachState()
33 const {
34 return reattach_state_.get();
35 }
36
EnqueueUpdate(const WTF::String & key,const WebVector<uint8_t> * value)37 void InspectorSessionState::EnqueueUpdate(const WTF::String& key,
38 const WebVector<uint8_t>* value) {
39 base::Optional<WTF::Vector<uint8_t>> updated_value;
40 if (value) {
41 WTF::Vector<uint8_t> payload;
42 payload.AppendRange(value->begin(), value->end());
43 updated_value = std::move(payload);
44 }
45 updates_->entries.Set(key, std::move(updated_value));
46 }
47
TakeUpdates()48 mojom::blink::DevToolsSessionStatePtr InspectorSessionState::TakeUpdates() {
49 auto updates = std::move(updates_);
50 updates_ = mojom::blink::DevToolsSessionState::New();
51 return updates;
52 }
53
54 //
55 // Encoding / Decoding routines.
56 //
57 /*static*/
Serialize(bool v,WebVector<uint8_t> * out)58 void InspectorAgentState::Serialize(bool v, WebVector<uint8_t>* out) {
59 out->emplace_back(v ? EncodeTrue() : EncodeFalse());
60 }
61
62 /*static*/
Deserialize(span<uint8_t> in,bool * v)63 bool InspectorAgentState::Deserialize(span<uint8_t> in, bool* v) {
64 CBORTokenizer tokenizer(in);
65 if (tokenizer.TokenTag() == CBORTokenTag::TRUE_VALUE) {
66 *v = true;
67 return true;
68 }
69 if (tokenizer.TokenTag() == CBORTokenTag::FALSE_VALUE) {
70 *v = false;
71 return true;
72 }
73 return false;
74 }
75
76 /*static*/
Serialize(int32_t v,WebVector<uint8_t> * out)77 void InspectorAgentState::Serialize(int32_t v, WebVector<uint8_t>* out) {
78 auto encode = out->ReleaseVector();
79 EncodeInt32(v, &encode);
80 *out = std::move(encode);
81 }
82
83 /*static*/
Deserialize(span<uint8_t> in,int32_t * v)84 bool InspectorAgentState::Deserialize(span<uint8_t> in, int32_t* v) {
85 CBORTokenizer tokenizer(in);
86 if (tokenizer.TokenTag() == CBORTokenTag::INT32) {
87 *v = tokenizer.GetInt32();
88 return true;
89 }
90 return false;
91 }
92
93 /*static*/
Serialize(double v,WebVector<uint8_t> * out)94 void InspectorAgentState::Serialize(double v, WebVector<uint8_t>* out) {
95 auto encode = out->ReleaseVector();
96 EncodeDouble(v, &encode);
97 *out = std::move(encode);
98 }
99
100 /*static*/
Deserialize(span<uint8_t> in,double * v)101 bool InspectorAgentState::Deserialize(span<uint8_t> in, double* v) {
102 CBORTokenizer tokenizer(in);
103 if (tokenizer.TokenTag() == CBORTokenTag::DOUBLE) {
104 *v = tokenizer.GetDouble();
105 return true;
106 }
107 return false;
108 }
109
110 /*static*/
Serialize(const WTF::String & v,WebVector<uint8_t> * out)111 void InspectorAgentState::Serialize(const WTF::String& v,
112 WebVector<uint8_t>* out) {
113 auto encode = out->ReleaseVector();
114 if (v.Is8Bit()) {
115 auto span8 = v.Span8();
116 EncodeFromLatin1(span<uint8_t>(span8.data(), span8.size()), &encode);
117 } else {
118 auto span16 = v.Span16();
119 EncodeFromUTF16(
120 span<uint16_t>(reinterpret_cast<const uint16_t*>(span16.data()),
121 span16.size()),
122 &encode);
123 }
124 *out = std::move(encode);
125 }
126
127 /*static*/
Deserialize(span<uint8_t> in,WTF::String * v)128 bool InspectorAgentState::Deserialize(span<uint8_t> in, WTF::String* v) {
129 CBORTokenizer tokenizer(in);
130 if (tokenizer.TokenTag() == CBORTokenTag::STRING8) {
131 *v = WTF::String(
132 reinterpret_cast<const char*>(tokenizer.GetString8().data()),
133 static_cast<size_t>(tokenizer.GetString8().size()));
134 return true;
135 }
136 if (tokenizer.TokenTag() == CBORTokenTag::STRING16) {
137 *v = WTF::String(
138 reinterpret_cast<const UChar*>(tokenizer.GetString16WireRep().data()),
139 tokenizer.GetString16WireRep().size() / 2);
140 return true;
141 }
142 return false;
143 }
144
145 /*static*/
Serialize(const std::vector<uint8_t> & v,WebVector<uint8_t> * out)146 void InspectorAgentState::Serialize(const std::vector<uint8_t>& v,
147 WebVector<uint8_t>* out) {
148 // We could CBOR encode this, but since we never look at the contents
149 // anyway (except for decoding just below), we just cheat and use the
150 // blob directly.
151 out->Assign(v.data(), v.size());
152 }
153
154 /*static*/
Deserialize(span<uint8_t> in,std::vector<uint8_t> * v)155 bool InspectorAgentState::Deserialize(span<uint8_t> in,
156 std::vector<uint8_t>* v) {
157 v->insert(v->end(), in.begin(), in.end());
158 return true;
159 }
160
161 //
162 // InspectorAgentState
163 //
InspectorAgentState(const WTF::String & domain_name)164 InspectorAgentState::InspectorAgentState(const WTF::String& domain_name)
165 : domain_name_(domain_name) {}
166
RegisterField(Field * field)167 WTF::String InspectorAgentState::RegisterField(Field* field) {
168 WTF::String prefix_key =
169 domain_name_ + "." + WTF::String::Number(fields_.size()) + "/";
170 fields_.push_back(field);
171 return prefix_key;
172 }
173
InitFrom(InspectorSessionState * session_state)174 void InspectorAgentState::InitFrom(InspectorSessionState* session_state) {
175 for (Field* f : fields_)
176 f->InitFrom(session_state);
177 }
178
ClearAllFields()179 void InspectorAgentState::ClearAllFields() {
180 for (Field* f : fields_)
181 f->Clear();
182 }
183
184 } // namespace blink
185