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