Line data Source code
1 : // This file is generated.
2 :
3 : // Copyright 2016 The Chromium Authors. All rights reserved.
4 : // Use of this source code is governed by a BSD-style license that can be
5 : // found in the LICENSE file.
6 :
7 : #include "src/inspector/protocol/Protocol.h"
8 :
9 : #include <algorithm>
10 : #include <cmath>
11 :
12 : #include <cstring>
13 :
14 :
15 : // Copyright 2016 The Chromium Authors. All rights reserved.
16 : // Use of this source code is governed by a BSD-style license that can be
17 : // found in the LICENSE file.
18 :
19 : //#include "ErrorSupport.h"
20 :
21 : namespace v8_inspector {
22 : namespace protocol {
23 :
24 1380576 : ErrorSupport::ErrorSupport() { }
25 690288 : ErrorSupport::~ErrorSupport() { }
26 :
27 25327704 : void ErrorSupport::setName(const char* name)
28 : {
29 50655408 : setName(String(name));
30 25327704 : }
31 :
32 27691942 : void ErrorSupport::setName(const String& name)
33 : {
34 : DCHECK(m_path.size());
35 83075826 : m_path[m_path.size() - 1] = name;
36 27691942 : }
37 :
38 5391721 : void ErrorSupport::push()
39 : {
40 10783442 : m_path.push_back(String());
41 5391721 : }
42 :
43 5391721 : void ErrorSupport::pop()
44 : {
45 : m_path.pop_back();
46 5391721 : }
47 :
48 28 : void ErrorSupport::addError(const char* error)
49 : {
50 56 : addError(String(error));
51 28 : }
52 :
53 28 : void ErrorSupport::addError(const String& error)
54 : {
55 28 : StringBuilder builder;
56 112 : for (size_t i = 0; i < m_path.size(); ++i) {
57 28 : if (i)
58 : StringUtil::builderAppend(builder, '.');
59 84 : StringUtil::builderAppend(builder, m_path[i]);
60 : }
61 56 : StringUtil::builderAppend(builder, ": ");
62 : StringUtil::builderAppend(builder, error);
63 56 : m_errors.push_back(StringUtil::builderToString(builder));
64 28 : }
65 :
66 5458817 : bool ErrorSupport::hasErrors()
67 : {
68 10917653 : return !!m_errors.size();
69 : }
70 :
71 19 : String ErrorSupport::errors()
72 : {
73 19 : StringBuilder builder;
74 94 : for (size_t i = 0; i < m_errors.size(); ++i) {
75 28 : if (i)
76 18 : StringUtil::builderAppend(builder, "; ");
77 75 : StringUtil::builderAppend(builder, m_errors[i]);
78 : }
79 19 : return StringUtil::builderToString(builder);
80 : }
81 :
82 : } // namespace v8_inspector
83 : } // namespace protocol
84 :
85 :
86 : // Copyright 2016 The Chromium Authors. All rights reserved.
87 : // Use of this source code is governed by a BSD-style license that can be
88 : // found in the LICENSE file.
89 :
90 : //#include "Values.h"
91 :
92 : namespace v8_inspector {
93 : namespace protocol {
94 :
95 : namespace {
96 :
97 : const char* const nullValueString = "null";
98 : const char* const trueValueString = "true";
99 : const char* const falseValueString = "false";
100 :
101 1171629269 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
102 : {
103 1171629269 : switch (c) {
104 0 : case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
105 0 : case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
106 44345596 : case '\n': StringUtil::builderAppend(*dst, "\\n"); break;
107 0 : case '\r': StringUtil::builderAppend(*dst, "\\r"); break;
108 0 : case '\t': StringUtil::builderAppend(*dst, "\\t"); break;
109 28490 : case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
110 30637416 : case '"': StringUtil::builderAppend(*dst, "\\\""); break;
111 : default:
112 : return false;
113 : }
114 : return true;
115 : }
116 :
117 : const char hexDigits[17] = "0123456789ABCDEF";
118 :
119 120 : void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
120 : {
121 240 : StringUtil::builderAppend(*dst, "\\u");
122 600 : for (size_t i = 0; i < 4; ++i) {
123 480 : uint16_t c = hexDigits[(number & 0xF000) >> 12];
124 : StringUtil::builderAppend(*dst, c);
125 480 : number <<= 4;
126 : }
127 120 : }
128 :
129 : template <typename Char>
130 44224640 : void escapeStringForJSONInternal(const Char* str, unsigned len,
131 : StringBuilder* dst)
132 : {
133 1215853909 : for (unsigned i = 0; i < len; ++i) {
134 1171629269 : Char c = str[i];
135 1171629269 : if (escapeChar(c, dst))
136 : continue;
137 1134123518 : if (c < 32 || c > 126) {
138 120 : appendUnsignedAsHex(c, dst);
139 : } else {
140 : StringUtil::builderAppend(*dst, c);
141 : }
142 : }
143 44224640 : }
144 :
145 : } // anonymous namespace
146 :
147 0 : bool Value::asBoolean(bool*) const
148 : {
149 0 : return false;
150 : }
151 :
152 0 : bool Value::asDouble(double*) const
153 : {
154 0 : return false;
155 : }
156 :
157 0 : bool Value::asInteger(int*) const
158 : {
159 0 : return false;
160 : }
161 :
162 18 : bool Value::asString(String*) const
163 : {
164 18 : return false;
165 : }
166 :
167 0 : bool Value::asSerialized(String*) const
168 : {
169 0 : return false;
170 : }
171 :
172 2572 : void Value::writeJSON(StringBuilder* output) const
173 : {
174 : DCHECK(m_type == TypeNull);
175 : StringUtil::builderAppend(*output, nullValueString, 4);
176 2572 : }
177 :
178 5144 : std::unique_ptr<Value> Value::clone() const
179 : {
180 5144 : return Value::null();
181 : }
182 :
183 546958 : String Value::serialize()
184 : {
185 546958 : StringBuilder result;
186 : StringUtil::builderReserve(result, 512);
187 546958 : writeJSON(&result);
188 546958 : return StringUtil::builderToString(result);
189 : }
190 :
191 9526387 : bool FundamentalValue::asBoolean(bool* output) const
192 : {
193 9526387 : if (type() != TypeBoolean)
194 : return false;
195 9526387 : *output = m_boolValue;
196 9526387 : return true;
197 : }
198 :
199 0 : bool FundamentalValue::asDouble(double* output) const
200 : {
201 0 : if (type() == TypeDouble) {
202 0 : *output = m_doubleValue;
203 0 : return true;
204 : }
205 0 : if (type() == TypeInteger) {
206 0 : *output = m_integerValue;
207 0 : return true;
208 : }
209 : return false;
210 : }
211 :
212 321704 : bool FundamentalValue::asInteger(int* output) const
213 : {
214 321704 : if (type() != TypeInteger)
215 : return false;
216 321704 : *output = m_integerValue;
217 321704 : return true;
218 : }
219 :
220 10928285 : void FundamentalValue::writeJSON(StringBuilder* output) const
221 : {
222 : DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
223 10928285 : if (type() == TypeBoolean) {
224 9548168 : if (m_boolValue)
225 : StringUtil::builderAppend(*output, trueValueString, 4);
226 : else
227 : StringUtil::builderAppend(*output, falseValueString, 5);
228 1380117 : } else if (type() == TypeDouble) {
229 47474 : if (!std::isfinite(m_doubleValue)) {
230 : StringUtil::builderAppend(*output, nullValueString, 4);
231 10928285 : return;
232 : }
233 23737 : StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
234 1356380 : } else if (type() == TypeInteger) {
235 2712760 : StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
236 : }
237 : }
238 :
239 324880 : std::unique_ptr<Value> FundamentalValue::clone() const
240 : {
241 324880 : switch (type()) {
242 68486 : case TypeDouble: return FundamentalValue::create(m_doubleValue);
243 498656 : case TypeInteger: return FundamentalValue::create(m_integerValue);
244 82618 : case TypeBoolean: return FundamentalValue::create(m_boolValue);
245 : default:
246 : DCHECK(false);
247 : }
248 : return nullptr;
249 : }
250 :
251 13318742 : bool StringValue::asString(String* output) const
252 : {
253 13318742 : *output = m_stringValue;
254 13318742 : return true;
255 : }
256 :
257 14751911 : void StringValue::writeJSON(StringBuilder* output) const
258 : {
259 : DCHECK(type() == TypeString);
260 14751911 : StringUtil::builderAppendQuotedString(*output, m_stringValue);
261 14751911 : }
262 :
263 142704 : std::unique_ptr<Value> StringValue::clone() const
264 : {
265 285408 : return StringValue::create(m_stringValue);
266 : }
267 :
268 0 : bool SerializedValue::asSerialized(String* output) const
269 : {
270 0 : *output = m_serializedValue;
271 0 : return true;
272 : }
273 :
274 273107 : void SerializedValue::writeJSON(StringBuilder* output) const
275 : {
276 : DCHECK(type() == TypeSerialized);
277 273107 : StringUtil::builderAppend(*output, m_serializedValue);
278 273107 : }
279 :
280 0 : std::unique_ptr<Value> SerializedValue::clone() const
281 : {
282 0 : return SerializedValue::create(m_serializedValue);
283 : }
284 :
285 24623602 : DictionaryValue::~DictionaryValue()
286 : {
287 24623602 : }
288 :
289 24157 : void DictionaryValue::setBoolean(const String& name, bool value)
290 : {
291 72471 : setValue(name, FundamentalValue::create(value));
292 24157 : }
293 :
294 151867 : void DictionaryValue::setInteger(const String& name, int value)
295 : {
296 455601 : setValue(name, FundamentalValue::create(value));
297 151867 : }
298 :
299 0 : void DictionaryValue::setDouble(const String& name, double value)
300 : {
301 0 : setValue(name, FundamentalValue::create(value));
302 0 : }
303 :
304 133945 : void DictionaryValue::setString(const String& name, const String& value)
305 : {
306 401835 : setValue(name, StringValue::create(value));
307 133945 : }
308 :
309 54189529 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
310 : {
311 55531961 : set(name, value);
312 54189529 : }
313 :
314 20486 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
315 : {
316 20909 : set(name, value);
317 20486 : }
318 :
319 10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
320 : {
321 10 : set(name, value);
322 10 : }
323 :
324 3911 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
325 : {
326 : protocol::Value* value = get(name);
327 3911 : if (!value)
328 : return false;
329 235 : return value->asBoolean(output);
330 : }
331 :
332 176286 : bool DictionaryValue::getInteger(const String& name, int* output) const
333 : {
334 : Value* value = get(name);
335 176286 : if (!value)
336 : return false;
337 176239 : return value->asInteger(output);
338 : }
339 :
340 0 : bool DictionaryValue::getDouble(const String& name, double* output) const
341 : {
342 : Value* value = get(name);
343 0 : if (!value)
344 : return false;
345 0 : return value->asDouble(output);
346 : }
347 :
348 50 : bool DictionaryValue::getString(const String& name, String* output) const
349 : {
350 : protocol::Value* value = get(name);
351 50 : if (!value)
352 : return false;
353 40 : return value->asString(output);
354 : }
355 :
356 91238 : DictionaryValue* DictionaryValue::getObject(const String& name) const
357 : {
358 91238 : return DictionaryValue::cast(get(name));
359 : }
360 :
361 0 : protocol::ListValue* DictionaryValue::getArray(const String& name) const
362 : {
363 0 : return ListValue::cast(get(name));
364 : }
365 :
366 49931142 : protocol::Value* DictionaryValue::get(const String& name) const
367 : {
368 : Dictionary::const_iterator it = m_data.find(name);
369 50483323 : if (it == m_data.end())
370 : return nullptr;
371 25420237 : return it->second.get();
372 : }
373 :
374 85 : DictionaryValue::Entry DictionaryValue::at(size_t index) const
375 : {
376 170 : const String key = m_order[index];
377 85 : return std::make_pair(key, m_data.find(key)->second.get());
378 : }
379 :
380 3911 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
381 : {
382 3911 : bool result = defaultValue;
383 3911 : getBoolean(name, &result);
384 3911 : return result;
385 : }
386 :
387 27 : int DictionaryValue::integerProperty(const String& name, int defaultValue) const
388 : {
389 27 : int result = defaultValue;
390 27 : getInteger(name, &result);
391 27 : return result;
392 : }
393 :
394 0 : double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
395 : {
396 0 : double result = defaultValue;
397 0 : getDouble(name, &result);
398 0 : return result;
399 : }
400 :
401 15700 : void DictionaryValue::remove(const String& name)
402 : {
403 : m_data.erase(name);
404 15700 : m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
405 15700 : }
406 :
407 6722368 : void DictionaryValue::writeJSON(StringBuilder* output) const
408 : {
409 : StringUtil::builderAppend(*output, '{');
410 72647172 : for (size_t i = 0; i < m_order.size(); ++i) {
411 36323586 : Dictionary::const_iterator it = m_data.find(m_order[i]);
412 29601218 : CHECK(it != m_data.end());
413 29601218 : if (i)
414 : StringUtil::builderAppend(*output, ',');
415 29601218 : StringUtil::builderAppendQuotedString(*output, it->first);
416 : StringUtil::builderAppend(*output, ':');
417 29601218 : it->second->writeJSON(output);
418 : }
419 : StringUtil::builderAppend(*output, '}');
420 6722368 : }
421 :
422 2646 : std::unique_ptr<Value> DictionaryValue::clone() const
423 : {
424 2646 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
425 20308 : for (size_t i = 0; i < m_order.size(); ++i) {
426 17662 : String key = m_order[i];
427 : Dictionary::const_iterator value = m_data.find(key);
428 : DCHECK(value != m_data.cend() && value->second);
429 15016 : result->setValue(key, value->second->clone());
430 : }
431 2646 : return std::move(result);
432 : }
433 :
434 12311801 : DictionaryValue::DictionaryValue()
435 24623602 : : Value(TypeObject)
436 : {
437 12311801 : }
438 :
439 398985 : ListValue::~ListValue()
440 : {
441 398985 : }
442 :
443 330347 : void ListValue::writeJSON(StringBuilder* output) const
444 : {
445 : StringUtil::builderAppend(*output, '[');
446 : bool first = true;
447 3521108 : for (const std::unique_ptr<protocol::Value>& value : m_data) {
448 2860414 : if (!first)
449 : StringUtil::builderAppend(*output, ',');
450 2860414 : value->writeJSON(output);
451 : first = false;
452 : }
453 : StringUtil::builderAppend(*output, ']');
454 330347 : }
455 :
456 360 : std::unique_ptr<Value> ListValue::clone() const
457 : {
458 360 : std::unique_ptr<ListValue> result = ListValue::create();
459 1550 : for (const std::unique_ptr<protocol::Value>& value : m_data)
460 1660 : result->pushValue(value->clone());
461 360 : return std::move(result);
462 : }
463 :
464 397973 : ListValue::ListValue()
465 398985 : : Value(TypeArray)
466 : {
467 397973 : }
468 :
469 5224439 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
470 : {
471 : DCHECK(value);
472 5226137 : m_data.push_back(std::move(value));
473 5224439 : }
474 :
475 2364238 : protocol::Value* ListValue::at(size_t index)
476 : {
477 : DCHECK_LT(index, m_data.size());
478 4728476 : return m_data[index].get();
479 : }
480 :
481 0 : void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
482 : {
483 0 : escapeStringForJSONInternal<uint8_t>(str, len, dst);
484 0 : }
485 :
486 44224640 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
487 : {
488 44224640 : escapeStringForJSONInternal<uint16_t>(str, len, dst);
489 44224640 : }
490 :
491 : } // namespace v8_inspector
492 : } // namespace protocol
493 :
494 :
495 : // Copyright 2016 The Chromium Authors. All rights reserved.
496 : // Use of this source code is governed by a BSD-style license that can be
497 : // found in the LICENSE file.
498 :
499 : //#include "Object.h"
500 :
501 : namespace v8_inspector {
502 : namespace protocol {
503 :
504 0 : std::unique_ptr<Object> Object::fromValue(protocol::Value* value, ErrorSupport* errors)
505 : {
506 : protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
507 0 : if (!dictionary) {
508 0 : errors->addError("object expected");
509 : return nullptr;
510 : }
511 0 : dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
512 0 : return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
513 : }
514 :
515 0 : std::unique_ptr<protocol::DictionaryValue> Object::toValue() const
516 : {
517 0 : return DictionaryValue::cast(m_object->clone());
518 : }
519 :
520 0 : std::unique_ptr<Object> Object::clone() const
521 : {
522 0 : return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
523 : }
524 :
525 0 : Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }
526 :
527 0 : Object::~Object() { }
528 :
529 : } // namespace v8_inspector
530 : } // namespace protocol
531 :
532 :
533 : // Copyright 2016 The Chromium Authors. All rights reserved.
534 : // Use of this source code is governed by a BSD-style license that can be
535 : // found in the LICENSE file.
536 :
537 : //#include "DispatcherBase.h"
538 : //#include "Parser.h"
539 :
540 : namespace v8_inspector {
541 : namespace protocol {
542 :
543 : // static
544 29989880 : DispatchResponse DispatchResponse::OK()
545 : {
546 : DispatchResponse result;
547 29989880 : result.m_status = kSuccess;
548 29989880 : result.m_errorCode = kParseError;
549 29989880 : return result;
550 : }
551 :
552 : // static
553 552 : DispatchResponse DispatchResponse::Error(const String& error)
554 : {
555 : DispatchResponse result;
556 552 : result.m_status = kError;
557 552 : result.m_errorCode = kServerError;
558 552 : result.m_errorMessage = error;
559 552 : return result;
560 : }
561 :
562 : // static
563 122 : DispatchResponse DispatchResponse::InternalError()
564 : {
565 : DispatchResponse result;
566 122 : result.m_status = kError;
567 122 : result.m_errorCode = kInternalError;
568 244 : result.m_errorMessage = "Internal error";
569 122 : return result;
570 : }
571 :
572 : // static
573 0 : DispatchResponse DispatchResponse::InvalidParams(const String& error)
574 : {
575 : DispatchResponse result;
576 0 : result.m_status = kError;
577 0 : result.m_errorCode = kInvalidParams;
578 0 : result.m_errorMessage = error;
579 0 : return result;
580 : }
581 :
582 : // static
583 0 : DispatchResponse DispatchResponse::FallThrough()
584 : {
585 : DispatchResponse result;
586 0 : result.m_status = kFallThrough;
587 0 : result.m_errorCode = kParseError;
588 0 : return result;
589 : }
590 :
591 : // static
592 : const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";
593 :
594 146568 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
595 :
596 140324 : DispatcherBase::WeakPtr::~WeakPtr()
597 : {
598 146568 : if (m_dispatcher)
599 293116 : m_dispatcher->m_weakPtrs.erase(this);
600 140324 : }
601 :
602 6244 : DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId)
603 : : m_backendImpl(std::move(backendImpl))
604 : , m_callId(callId)
605 12488 : , m_callbackId(callbackId) { }
606 :
607 : DispatcherBase::Callback::~Callback() = default;
608 :
609 0 : void DispatcherBase::Callback::dispose()
610 : {
611 : m_backendImpl = nullptr;
612 0 : }
613 :
614 6244 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
615 : {
616 12488 : if (!m_backendImpl || !m_backendImpl->get())
617 6244 : return;
618 18717 : m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
619 : m_backendImpl = nullptr;
620 : }
621 :
622 0 : void DispatcherBase::Callback::fallThroughIfActive()
623 : {
624 0 : if (!m_backendImpl || !m_backendImpl->get())
625 0 : return;
626 : m_backendImpl->get()->markFallThrough(m_callbackId);
627 : m_backendImpl = nullptr;
628 : }
629 :
630 20436 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
631 : : m_frontendChannel(frontendChannel)
632 : , m_lastCallbackId(0)
633 40872 : , m_lastCallbackFallThrough(false) { }
634 :
635 20436 : DispatcherBase::~DispatcherBase()
636 : {
637 20436 : clearFrontend();
638 20436 : }
639 :
640 6244 : int DispatcherBase::nextCallbackId()
641 : {
642 6244 : m_lastCallbackFallThrough = false;
643 6244 : return ++m_lastCallbackId;
644 : }
645 :
646 0 : void DispatcherBase::markFallThrough(int callbackId)
647 : {
648 : DCHECK(callbackId == m_lastCallbackId);
649 0 : m_lastCallbackFallThrough = true;
650 0 : }
651 :
652 : // static
653 0 : bool DispatcherBase::getCommandName(const String& message, String* result)
654 : {
655 0 : std::unique_ptr<protocol::Value> value = StringUtil::parseJSON(message);
656 0 : if (!value)
657 : return false;
658 :
659 : protocol::DictionaryValue* object = DictionaryValue::cast(value.get());
660 0 : if (!object)
661 : return false;
662 :
663 0 : if (!object->getString("method", result))
664 : return false;
665 :
666 0 : return true;
667 : }
668 :
669 281037 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
670 : {
671 140319 : if (!m_frontendChannel)
672 : return;
673 140319 : if (response.status() == DispatchResponse::kError) {
674 399 : reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
675 : return;
676 : }
677 839520 : m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
678 : }
679 :
680 53559 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
681 : {
682 107118 : sendResponse(callId, response, DictionaryValue::create());
683 53559 : }
684 :
685 : namespace {
686 :
687 : class ProtocolError : public Serializable {
688 : public:
689 423 : static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
690 : {
691 423 : std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
692 423 : protocolError->m_callId = callId;
693 423 : protocolError->m_hasCallId = true;
694 442 : if (errors && errors->hasErrors())
695 57 : protocolError->m_data = errors->errors();
696 423 : return protocolError;
697 : }
698 :
699 0 : static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
700 : {
701 0 : return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
702 : }
703 :
704 423 : String serialize() override
705 : {
706 423 : std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
707 1269 : error->setInteger("code", m_code);
708 1269 : error->setString("message", m_errorMessage);
709 423 : if (m_data.length())
710 57 : error->setString("data", m_data);
711 423 : std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
712 1269 : message->setObject("error", std::move(error));
713 423 : if (m_hasCallId)
714 1269 : message->setInteger("id", m_callId);
715 846 : return message->serialize();
716 : }
717 :
718 1269 : ~ProtocolError() override {}
719 :
720 : private:
721 423 : ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
722 : : m_code(code)
723 423 : , m_errorMessage(errorMessage)
724 : {
725 423 : }
726 :
727 : DispatchResponse::ErrorCode m_code;
728 : String m_errorMessage;
729 : String m_data;
730 : int m_callId = 0;
731 : bool m_hasCallId = false;
732 : };
733 :
734 : } // namespace
735 :
736 423 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
737 : {
738 423 : if (frontendChannel)
739 1692 : frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
740 423 : }
741 :
742 0 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
743 : {
744 0 : if (frontendChannel)
745 0 : frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
746 0 : }
747 :
748 24 : void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
749 : {
750 423 : reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
751 24 : }
752 :
753 20436 : void DispatcherBase::clearFrontend()
754 : {
755 20436 : m_frontendChannel = nullptr;
756 40882 : for (auto& weak : m_weakPtrs)
757 10 : weak->dispose();
758 : m_weakPtrs.clear();
759 20436 : }
760 :
761 146568 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
762 : {
763 146568 : std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
764 293136 : m_weakPtrs.insert(weak.get());
765 146568 : return weak;
766 : }
767 :
768 3406 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
769 : : m_frontendChannel(frontendChannel)
770 10218 : , m_fallThroughForNotFound(false) { }
771 :
772 0 : void UberDispatcher::setFallThroughForNotFound(bool fallThroughForNotFound)
773 : {
774 0 : m_fallThroughForNotFound = fallThroughForNotFound;
775 0 : }
776 :
777 20436 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
778 : {
779 : m_dispatchers[name] = std::move(dispatcher);
780 20436 : }
781 :
782 20436 : void UberDispatcher::setupRedirects(const HashMap<String, String>& redirects)
783 : {
784 40872 : for (const auto& pair : redirects)
785 0 : m_redirects[pair.first] = pair.second;
786 20436 : }
787 :
788 140348 : DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage, int* outCallId, String* outMethod)
789 : {
790 140348 : if (!parsedMessage) {
791 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
792 0 : return DispatchResponse::kError;
793 : }
794 : std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
795 140348 : if (!messageObject) {
796 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
797 0 : return DispatchResponse::kError;
798 : }
799 :
800 140348 : int callId = 0;
801 280696 : protocol::Value* callIdValue = messageObject->get("id");
802 140348 : bool success = callIdValue && callIdValue->asInteger(&callId);
803 140348 : if (outCallId)
804 0 : *outCallId = callId;
805 140348 : if (!success) {
806 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' porperty");
807 0 : return DispatchResponse::kError;
808 : }
809 :
810 280696 : protocol::Value* methodValue = messageObject->get("method");
811 140348 : String method;
812 140348 : success = methodValue && methodValue->asString(&method);
813 140348 : if (outMethod)
814 0 : *outMethod = method;
815 140348 : if (!success) {
816 0 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' porperty", nullptr);
817 0 : return DispatchResponse::kError;
818 : }
819 :
820 : HashMap<String, String>::iterator redirectIt = m_redirects.find(method);
821 140348 : if (redirectIt != m_redirects.end())
822 0 : method = redirectIt->second;
823 :
824 140348 : size_t dotIndex = StringUtil::find(method, ".");
825 140348 : if (dotIndex == StringUtil::kNotFound) {
826 0 : if (m_fallThroughForNotFound)
827 : return DispatchResponse::kFallThrough;
828 0 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
829 0 : return DispatchResponse::kError;
830 : }
831 : String domain = StringUtil::substring(method, 0, dotIndex);
832 : auto it = m_dispatchers.find(domain);
833 140348 : if (it == m_dispatchers.end()) {
834 0 : if (m_fallThroughForNotFound)
835 : return DispatchResponse::kFallThrough;
836 0 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
837 0 : return DispatchResponse::kError;
838 : }
839 421044 : return it->second->dispatch(callId, method, std::move(messageObject));
840 : }
841 :
842 : UberDispatcher::~UberDispatcher() = default;
843 :
844 : // static
845 139920 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
846 : {
847 559680 : return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
848 : }
849 :
850 : // static
851 133187 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
852 : {
853 266374 : return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
854 : }
855 :
856 273107 : String InternalResponse::serialize()
857 : {
858 273107 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
859 645642 : std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
860 273107 : if (m_notification.length()) {
861 399561 : result->setString("method", m_notification);
862 799122 : result->setValue("params", SerializedValue::create(params->serialize()));
863 : } else {
864 419760 : result->setInteger("id", m_callId);
865 839520 : result->setValue("result", SerializedValue::create(params->serialize()));
866 : }
867 546214 : return result->serialize();
868 : }
869 :
870 0 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
871 : : m_callId(callId)
872 : , m_notification(notification)
873 273107 : , m_params(params ? std::move(params) : nullptr)
874 : {
875 0 : }
876 :
877 : } // namespace v8_inspector
878 : } // namespace protocol
879 :
880 :
881 : // Copyright 2016 The Chromium Authors. All rights reserved.
882 : // Use of this source code is governed by a BSD-style license that can be
883 : // found in the LICENSE file.
884 :
885 : namespace v8_inspector {
886 : namespace protocol {
887 :
888 : namespace {
889 :
890 : const int stackLimit = 1000;
891 :
892 : enum Token {
893 : ObjectBegin,
894 : ObjectEnd,
895 : ArrayBegin,
896 : ArrayEnd,
897 : StringLiteral,
898 : Number,
899 : BoolTrue,
900 : BoolFalse,
901 : NullToken,
902 : ListSeparator,
903 : ObjectPairSeparator,
904 : InvalidToken,
905 : };
906 :
907 : const char* const nullString = "null";
908 : const char* const trueString = "true";
909 : const char* const falseString = "false";
910 :
911 : bool isASCII(uint16_t c)
912 : {
913 4747892 : return !(c & ~0x7F);
914 : }
915 :
916 : bool isSpaceOrNewLine(uint16_t c)
917 : {
918 4000735 : return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
919 : }
920 :
921 323431 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
922 : {
923 : std::vector<char> buffer;
924 323431 : buffer.reserve(length + 1);
925 1070588 : for (size_t i = 0; i < length; ++i) {
926 1494314 : if (!isASCII(characters[i])) {
927 0 : *ok = false;
928 0 : return 0;
929 : }
930 1494314 : buffer.push_back(static_cast<char>(characters[i]));
931 : }
932 646862 : buffer.push_back('\0');
933 323431 : return StringUtil::toDouble(buffer.data(), length, ok);
934 : }
935 :
936 0 : double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
937 : {
938 0 : std::string buffer(reinterpret_cast<const char*>(characters), length);
939 0 : return StringUtil::toDouble(buffer.data(), length, ok);
940 : }
941 :
942 : template<typename Char>
943 : bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
944 : {
945 397765 : while (start < end && *token != '\0' && *start++ == *token++) { }
946 78187 : if (*token != '\0')
947 : return false;
948 78187 : *tokenEnd = start;
949 : return true;
950 : }
951 :
952 : template<typename Char>
953 323436 : bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
954 : {
955 323436 : if (start == end)
956 : return false;
957 323436 : bool haveLeadingZero = '0' == *start;
958 : int length = 0;
959 1394009 : while (start < end && '0' <= *start && *start <= '9') {
960 747137 : ++start;
961 747137 : ++length;
962 : }
963 323436 : if (!length)
964 : return false;
965 323436 : if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
966 : return false;
967 323436 : *tokenEnd = start;
968 323436 : return true;
969 : }
970 :
971 : template<typename Char>
972 323431 : bool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd)
973 : {
974 : // We just grab the number here. We validate the size in DecodeNumber.
975 : // According to RFC4627, a valid number is: [minus] int [frac] [exp]
976 323431 : if (start == end)
977 : return false;
978 323431 : Char c = *start;
979 323431 : if ('-' == c)
980 15 : ++start;
981 :
982 323431 : if (!readInt(start, end, &start, false))
983 : return false;
984 323431 : if (start == end) {
985 0 : *tokenEnd = start;
986 0 : return true;
987 : }
988 :
989 : // Optional fraction part
990 323431 : c = *start;
991 323431 : if ('.' == c) {
992 5 : ++start;
993 5 : if (!readInt(start, end, &start, true))
994 : return false;
995 5 : if (start == end) {
996 0 : *tokenEnd = start;
997 0 : return true;
998 : }
999 5 : c = *start;
1000 : }
1001 :
1002 : // Optional exponent part
1003 323431 : if ('e' == c || 'E' == c) {
1004 0 : ++start;
1005 0 : if (start == end)
1006 : return false;
1007 0 : c = *start;
1008 0 : if ('-' == c || '+' == c) {
1009 0 : ++start;
1010 0 : if (start == end)
1011 : return false;
1012 : }
1013 0 : if (!readInt(start, end, &start, true))
1014 : return false;
1015 : }
1016 :
1017 323431 : *tokenEnd = start;
1018 323431 : return true;
1019 : }
1020 :
1021 : template<typename Char>
1022 45 : bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
1023 : {
1024 45 : if (end - start < digits)
1025 : return false;
1026 180 : for (int i = 0; i < digits; ++i) {
1027 180 : Char c = *start++;
1028 180 : if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
1029 : return false;
1030 : }
1031 45 : *tokenEnd = start;
1032 45 : return true;
1033 : }
1034 :
1035 : template<typename Char>
1036 996337 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
1037 : {
1038 13279573 : while (start < end) {
1039 12283236 : Char c = *start++;
1040 12283236 : if ('\\' == c) {
1041 316784 : if (start == end)
1042 : return false;
1043 316784 : c = *start++;
1044 : // Make sure the escaped char is valid.
1045 316784 : switch (c) {
1046 : case 'x':
1047 0 : if (!readHexDigits(start, end, &start, 2))
1048 : return false;
1049 : break;
1050 : case 'u':
1051 45 : if (!readHexDigits(start, end, &start, 4))
1052 : return false;
1053 : break;
1054 : case '\\':
1055 : case '/':
1056 : case 'b':
1057 : case 'f':
1058 : case 'n':
1059 : case 'r':
1060 : case 't':
1061 : case 'v':
1062 : case '"':
1063 : break;
1064 : default:
1065 : return false;
1066 : }
1067 11966452 : } else if ('"' == c) {
1068 996337 : *tokenEnd = start;
1069 996337 : return true;
1070 : }
1071 : }
1072 : return false;
1073 : }
1074 :
1075 : template<typename Char>
1076 0 : bool skipComment(const Char* start, const Char* end, const Char** commentEnd)
1077 : {
1078 0 : if (start == end)
1079 : return false;
1080 :
1081 0 : if (*start != '/' || start + 1 >= end)
1082 : return false;
1083 : ++start;
1084 :
1085 0 : if (*start == '/') {
1086 : // Single line comment, read to newline.
1087 0 : for (++start; start < end; ++start) {
1088 0 : if (*start == '\n' || *start == '\r') {
1089 0 : *commentEnd = start + 1;
1090 0 : return true;
1091 : }
1092 : }
1093 0 : *commentEnd = end;
1094 : // Comment reaches end-of-input, which is fine.
1095 0 : return true;
1096 : }
1097 :
1098 0 : if (*start == '*') {
1099 : Char previous = '\0';
1100 : // Block comment, read until end marker.
1101 0 : for (++start; start < end; previous = *start++) {
1102 0 : if (previous == '*' && *start == '/') {
1103 0 : *commentEnd = start + 1;
1104 0 : return true;
1105 : }
1106 : }
1107 : // Block comment must close before end-of-input.
1108 : return false;
1109 : }
1110 :
1111 : return false;
1112 : }
1113 :
1114 : template<typename Char>
1115 4229310 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
1116 : {
1117 8458620 : while (start < end) {
1118 8001470 : if (isSpaceOrNewLine(*start)) {
1119 0 : ++start;
1120 4000735 : } else if (*start == '/') {
1121 : const Char* commentEnd;
1122 0 : if (!skipComment(start, end, &commentEnd))
1123 : break;
1124 0 : start = commentEnd;
1125 : } else {
1126 : break;
1127 : }
1128 : }
1129 4229310 : *whitespaceEnd = start;
1130 4229310 : }
1131 :
1132 : template<typename Char>
1133 3248019 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
1134 : {
1135 3248019 : skipWhitespaceAndComments(start, end, tokenStart);
1136 3248019 : start = *tokenStart;
1137 :
1138 3248019 : if (start == end)
1139 : return InvalidToken;
1140 :
1141 3248019 : switch (*start) {
1142 : case 'n':
1143 0 : if (parseConstToken(start, end, tokenEnd, nullString))
1144 : return NullToken;
1145 : break;
1146 : case 't':
1147 71357 : if (parseConstToken(start, end, tokenEnd, trueString))
1148 : return BoolTrue;
1149 : break;
1150 : case 'f':
1151 6830 : if (parseConstToken(start, end, tokenEnd, falseString))
1152 : return BoolFalse;
1153 : break;
1154 : case '[':
1155 652 : *tokenEnd = start + 1;
1156 652 : return ArrayBegin;
1157 : case ']':
1158 652 : *tokenEnd = start + 1;
1159 652 : return ArrayEnd;
1160 : case ',':
1161 426922 : *tokenEnd = start + 1;
1162 426922 : return ListSeparator;
1163 : case '{':
1164 335400 : *tokenEnd = start + 1;
1165 335400 : return ObjectBegin;
1166 : case '}':
1167 334590 : *tokenEnd = start + 1;
1168 334590 : return ObjectEnd;
1169 : case ':':
1170 751848 : *tokenEnd = start + 1;
1171 751848 : return ObjectPairSeparator;
1172 : case '0':
1173 : case '1':
1174 : case '2':
1175 : case '3':
1176 : case '4':
1177 : case '5':
1178 : case '6':
1179 : case '7':
1180 : case '8':
1181 : case '9':
1182 : case '-':
1183 323431 : if (parseNumberToken(start, end, tokenEnd))
1184 : return Number;
1185 : break;
1186 : case '"':
1187 996337 : if (parseStringToken(start + 1, end, tokenEnd))
1188 : return StringLiteral;
1189 : break;
1190 : }
1191 : return InvalidToken;
1192 : }
1193 :
1194 : template<typename Char>
1195 : int hexToInt(Char c)
1196 : {
1197 180 : if ('0' <= c && c <= '9')
1198 170 : return c - '0';
1199 10 : if ('A' <= c && c <= 'F')
1200 10 : return c - 'A' + 10;
1201 0 : if ('a' <= c && c <= 'f')
1202 0 : return c - 'a' + 10;
1203 : DCHECK(false);
1204 : return 0;
1205 : }
1206 :
1207 : template<typename Char>
1208 996084 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
1209 : {
1210 13278455 : while (start < end) {
1211 11286287 : uint16_t c = *start++;
1212 11286287 : if ('\\' != c) {
1213 : StringUtil::builderAppend(*output, c);
1214 : continue;
1215 : }
1216 316784 : if (start == end)
1217 : return false;
1218 316784 : c = *start++;
1219 :
1220 316784 : if (c == 'x') {
1221 : // \x is not supported.
1222 : return false;
1223 : }
1224 :
1225 316784 : switch (c) {
1226 : case '"':
1227 : case '/':
1228 : case '\\':
1229 : break;
1230 : case 'b':
1231 : c = '\b';
1232 0 : break;
1233 : case 'f':
1234 : c = '\f';
1235 0 : break;
1236 : case 'n':
1237 : c = '\n';
1238 4355 : break;
1239 : case 'r':
1240 : c = '\r';
1241 0 : break;
1242 : case 't':
1243 : c = '\t';
1244 0 : break;
1245 : case 'v':
1246 : c = '\v';
1247 0 : break;
1248 : case 'u':
1249 225 : c = (hexToInt(*start) << 12) +
1250 45 : (hexToInt(*(start + 1)) << 8) +
1251 45 : (hexToInt(*(start + 2)) << 4) +
1252 45 : hexToInt(*(start + 3));
1253 45 : start += 4;
1254 45 : break;
1255 : default:
1256 : return false;
1257 : }
1258 : StringUtil::builderAppend(*output, c);
1259 : }
1260 : return true;
1261 : }
1262 :
1263 : template<typename Char>
1264 996279 : bool decodeString(const Char* start, const Char* end, String* output)
1265 : {
1266 996279 : if (start == end) {
1267 390 : *output = "";
1268 195 : return true;
1269 : }
1270 996084 : if (start > end)
1271 : return false;
1272 996084 : StringBuilder buffer;
1273 996084 : StringUtil::builderReserve(buffer, end - start);
1274 996084 : if (!decodeString(start, end, &buffer))
1275 : return false;
1276 1992168 : *output = StringUtil::builderToString(buffer);
1277 996084 : return true;
1278 : }
1279 :
1280 : template<typename Char>
1281 981291 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
1282 : {
1283 981291 : if (depth > stackLimit)
1284 : return nullptr;
1285 :
1286 : std::unique_ptr<Value> result;
1287 : const Char* tokenStart;
1288 : const Char* tokenEnd;
1289 981291 : Token token = parseToken(start, end, &tokenStart, &tokenEnd);
1290 981291 : switch (token) {
1291 : case InvalidToken:
1292 : return nullptr;
1293 : case NullToken:
1294 : result = Value::null();
1295 0 : break;
1296 : case BoolTrue:
1297 142714 : result = FundamentalValue::create(true);
1298 71357 : break;
1299 : case BoolFalse:
1300 13660 : result = FundamentalValue::create(false);
1301 6830 : break;
1302 : case Number: {
1303 : bool ok;
1304 323431 : double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
1305 323431 : if (!ok)
1306 0 : return nullptr;
1307 323431 : int number = static_cast<int>(value);
1308 323431 : if (number == value)
1309 646852 : result = FundamentalValue::create(number);
1310 : else
1311 10 : result = FundamentalValue::create(value);
1312 323431 : break;
1313 : }
1314 : case StringLiteral: {
1315 244431 : String value;
1316 244431 : bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
1317 244431 : if (!ok)
1318 : return nullptr;
1319 488862 : result = StringValue::create(value);
1320 : break;
1321 : }
1322 : case ArrayBegin: {
1323 652 : std::unique_ptr<ListValue> array = ListValue::create();
1324 652 : start = tokenEnd;
1325 652 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1326 652 : while (token != ArrayEnd) {
1327 868 : std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
1328 868 : if (!arrayNode)
1329 : return nullptr;
1330 868 : array->pushValue(std::move(arrayNode));
1331 :
1332 : // After a list value, we expect a comma or the end of the list.
1333 868 : start = tokenEnd;
1334 868 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1335 868 : if (token == ListSeparator) {
1336 296 : start = tokenEnd;
1337 296 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1338 296 : if (token == ArrayEnd)
1339 : return nullptr;
1340 572 : } else if (token != ArrayEnd) {
1341 : // Unexpected value after list value. Bail out.
1342 : return nullptr;
1343 : }
1344 : }
1345 652 : if (token != ArrayEnd)
1346 : return nullptr;
1347 : result = std::move(array);
1348 : break;
1349 : }
1350 : case ObjectBegin: {
1351 334590 : std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
1352 334590 : start = tokenEnd;
1353 334590 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1354 334590 : while (token != ObjectEnd) {
1355 751848 : if (token != StringLiteral)
1356 0 : return nullptr;
1357 751848 : String key;
1358 751848 : if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
1359 : return nullptr;
1360 751848 : start = tokenEnd;
1361 :
1362 751848 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1363 751848 : if (token != ObjectPairSeparator)
1364 : return nullptr;
1365 751848 : start = tokenEnd;
1366 :
1367 751848 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
1368 751848 : if (!value)
1369 : return nullptr;
1370 751848 : object->setValue(key, std::move(value));
1371 751848 : start = tokenEnd;
1372 :
1373 : // After a key/value pair, we expect a comma or the end of the
1374 : // object.
1375 751848 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1376 751848 : if (token == ListSeparator) {
1377 426626 : start = tokenEnd;
1378 426626 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1379 426626 : if (token == ObjectEnd)
1380 : return nullptr;
1381 325222 : } else if (token != ObjectEnd) {
1382 : // Unexpected value after last object value. Bail out.
1383 : return nullptr;
1384 : }
1385 : }
1386 334590 : if (token != ObjectEnd)
1387 : return nullptr;
1388 : result = std::move(object);
1389 : break;
1390 : }
1391 :
1392 : default:
1393 : // We got a token that's not a value.
1394 : return nullptr;
1395 : }
1396 :
1397 981291 : skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
1398 : return result;
1399 : }
1400 :
1401 : template<typename Char>
1402 228575 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
1403 : {
1404 228575 : const Char* end = start + length;
1405 : const Char *tokenEnd;
1406 228575 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
1407 228575 : if (!value || tokenEnd != end)
1408 : return nullptr;
1409 : return value;
1410 : }
1411 :
1412 : } // anonymous namespace
1413 :
1414 228575 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
1415 : {
1416 228575 : return parseJSONInternal<uint16_t>(characters, length);
1417 : }
1418 :
1419 0 : std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
1420 : {
1421 0 : return parseJSONInternal<uint8_t>(characters, length);
1422 : }
1423 :
1424 : } // namespace v8_inspector
1425 : } // namespace protocol
|