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 <climits>
11 : #include <cmath>
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 338608 : ErrorSupport::ErrorSupport() { }
25 169304 : ErrorSupport::~ErrorSupport() { }
26 :
27 218280 : void ErrorSupport::setName(const char* name)
28 : {
29 436560 : setName(String(name));
30 218280 : }
31 :
32 218625 : void ErrorSupport::setName(const String& name)
33 : {
34 : DCHECK(m_path.size());
35 655875 : m_path[m_path.size() - 1] = name;
36 218625 : }
37 :
38 154650 : void ErrorSupport::push()
39 : {
40 309300 : m_path.push_back(String());
41 154650 : }
42 :
43 154650 : void ErrorSupport::pop()
44 : {
45 : m_path.pop_back();
46 154650 : }
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 154650 : bool ErrorSupport::hasErrors()
67 : {
68 309319 : 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 1226864977 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
102 : {
103 1226864977 : switch (c) {
104 0 : case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
105 0 : case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
106 43332752 : 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 145894 : case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
110 37037896 : case '"': StringUtil::builderAppend(*dst, "\\\""); break;
111 : default:
112 : return false;
113 : }
114 : return true;
115 : }
116 :
117 : const char hexDigits[17] = "0123456789ABCDEF";
118 :
119 150 : void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
120 : {
121 300 : StringUtil::builderAppend(*dst, "\\u");
122 750 : for (size_t i = 0; i < 4; ++i) {
123 600 : uint16_t c = hexDigits[(number & 0xF000) >> 12];
124 : StringUtil::builderAppend(*dst, c);
125 600 : number <<= 4;
126 : }
127 150 : }
128 :
129 : template <typename Char>
130 49370938 : void escapeStringForJSONInternal(const Char* str, unsigned len,
131 : StringBuilder* dst)
132 : {
133 1276235915 : for (unsigned i = 0; i < len; ++i) {
134 1226864977 : Char c = str[i];
135 1226864977 : if (escapeChar(c, dst))
136 : continue;
137 1186606706 : if (c < 32 || c > 126) {
138 150 : appendUnsignedAsHex(c, dst);
139 : } else {
140 : StringUtil::builderAppend(*dst, c);
141 : }
142 : }
143 49370938 : }
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 2708 : void Value::writeJSON(StringBuilder* output) const
173 : {
174 : DCHECK(m_type == TypeNull);
175 : StringUtil::builderAppend(*output, nullValueString, 4);
176 2708 : }
177 :
178 2708 : std::unique_ptr<Value> Value::clone() const
179 : {
180 2708 : return Value::null();
181 : }
182 :
183 696483 : String Value::serialize()
184 : {
185 696483 : StringBuilder result;
186 : StringUtil::builderReserve(result, 512);
187 696483 : writeJSON(&result);
188 696483 : return StringUtil::builderToString(result);
189 : }
190 :
191 82184 : bool FundamentalValue::asBoolean(bool* output) const
192 : {
193 82184 : if (type() != TypeBoolean)
194 : return false;
195 82184 : *output = m_boolValue;
196 82184 : return true;
197 : }
198 :
199 30 : bool FundamentalValue::asDouble(double* output) const
200 : {
201 30 : if (type() == TypeDouble) {
202 0 : *output = m_doubleValue;
203 0 : return true;
204 : }
205 30 : if (type() == TypeInteger) {
206 30 : *output = m_integerValue;
207 30 : return true;
208 : }
209 : return false;
210 : }
211 :
212 361345 : bool FundamentalValue::asInteger(int* output) const
213 : {
214 361345 : if (type() != TypeInteger)
215 : return false;
216 361345 : *output = m_integerValue;
217 361345 : return true;
218 : }
219 :
220 12216995 : void FundamentalValue::writeJSON(StringBuilder* output) const
221 : {
222 : DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
223 12216995 : if (type() == TypeBoolean) {
224 10172519 : if (m_boolValue)
225 : StringUtil::builderAppend(*output, trueValueString, 4);
226 : else
227 : StringUtil::builderAppend(*output, falseValueString, 5);
228 2044476 : } else if (type() == TypeDouble) {
229 302526 : if (!std::isfinite(m_doubleValue)) {
230 : StringUtil::builderAppend(*output, nullValueString, 4);
231 12216995 : return;
232 : }
233 151258 : StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
234 1893213 : } else if (type() == TypeInteger) {
235 3786426 : StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
236 : }
237 : }
238 :
239 167261 : std::unique_ptr<Value> FundamentalValue::clone() const
240 : {
241 167261 : switch (type()) {
242 288854 : case TypeDouble: return FundamentalValue::create(m_doubleValue);
243 1708 : case TypeInteger: return FundamentalValue::create(m_integerValue);
244 43960 : case TypeBoolean: return FundamentalValue::create(m_boolValue);
245 : default:
246 : DCHECK(false);
247 : }
248 : return nullptr;
249 : }
250 :
251 296877 : bool StringValue::asString(String* output) const
252 : {
253 296877 : *output = m_stringValue;
254 296877 : return true;
255 : }
256 :
257 16433234 : void StringValue::writeJSON(StringBuilder* output) const
258 : {
259 : DCHECK(type() == TypeString);
260 16433234 : StringUtil::builderAppendQuotedString(*output, m_stringValue);
261 16433234 : }
262 :
263 65979 : std::unique_ptr<Value> StringValue::clone() const
264 : {
265 131958 : 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 347507 : void SerializedValue::writeJSON(StringBuilder* output) const
275 : {
276 : DCHECK(type() == TypeSerialized);
277 347507 : StringUtil::builderAppend(*output, m_serializedValue);
278 347507 : }
279 :
280 0 : std::unique_ptr<Value> SerializedValue::clone() const
281 : {
282 0 : return SerializedValue::create(m_serializedValue);
283 : }
284 :
285 15973240 : DictionaryValue::~DictionaryValue()
286 : {
287 15973240 : }
288 :
289 26902 : void DictionaryValue::setBoolean(const String& name, bool value)
290 : {
291 80706 : setValue(name, FundamentalValue::create(value));
292 26902 : }
293 :
294 182560 : void DictionaryValue::setInteger(const String& name, int value)
295 : {
296 547680 : setValue(name, FundamentalValue::create(value));
297 182560 : }
298 :
299 5 : void DictionaryValue::setDouble(const String& name, double value)
300 : {
301 15 : setValue(name, FundamentalValue::create(value));
302 5 : }
303 :
304 181118 : void DictionaryValue::setString(const String& name, const String& value)
305 : {
306 543354 : setValue(name, StringValue::create(value));
307 181118 : }
308 :
309 32444882 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
310 : {
311 34065063 : set(name, value);
312 32444882 : }
313 :
314 23229 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
315 : {
316 24322 : set(name, value);
317 23229 : }
318 :
319 10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
320 : {
321 10 : set(name, value);
322 10 : }
323 :
324 4479 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
325 : {
326 : protocol::Value* value = get(name);
327 4479 : if (!value)
328 : return false;
329 250 : return value->asBoolean(output);
330 : }
331 :
332 186512 : bool DictionaryValue::getInteger(const String& name, int* output) const
333 : {
334 : Value* value = get(name);
335 186512 : if (!value)
336 : return false;
337 186452 : 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 110 : bool DictionaryValue::getString(const String& name, String* output) const
349 : {
350 : protocol::Value* value = get(name);
351 110 : if (!value)
352 : return false;
353 90 : return value->asString(output);
354 : }
355 :
356 171932 : DictionaryValue* DictionaryValue::getObject(const String& name) const
357 : {
358 171932 : 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 672464 : protocol::Value* DictionaryValue::get(const String& name) const
367 : {
368 : Dictionary::const_iterator it = m_data.find(name);
369 1373975 : if (it == m_data.end())
370 : return nullptr;
371 336667 : return it->second.get();
372 : }
373 :
374 120 : DictionaryValue::Entry DictionaryValue::at(size_t index) const
375 : {
376 240 : const String key = m_order[index];
377 120 : return std::make_pair(key, m_data.find(key)->second.get());
378 : }
379 :
380 4479 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
381 : {
382 4479 : bool result = defaultValue;
383 4479 : getBoolean(name, &result);
384 4479 : return result;
385 : }
386 :
387 35 : int DictionaryValue::integerProperty(const String& name, int defaultValue) const
388 : {
389 35 : int result = defaultValue;
390 35 : getInteger(name, &result);
391 35 : 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 18130 : void DictionaryValue::remove(const String& name)
402 : {
403 : m_data.erase(name);
404 18130 : m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
405 18130 : }
406 :
407 7557624 : void DictionaryValue::writeJSON(StringBuilder* output) const
408 : {
409 : StringUtil::builderAppend(*output, '{');
410 81409536 : for (size_t i = 0; i < m_order.size(); ++i) {
411 40704768 : Dictionary::const_iterator it = m_data.find(m_order[i]);
412 33147144 : CHECK(it != m_data.end());
413 33147144 : if (i)
414 : StringUtil::builderAppend(*output, ',');
415 33147144 : StringUtil::builderAppendQuotedString(*output, it->first);
416 : StringUtil::builderAppend(*output, ':');
417 33147144 : it->second->writeJSON(output);
418 : }
419 : StringUtil::builderAppend(*output, '}');
420 7557624 : }
421 :
422 3087 : std::unique_ptr<Value> DictionaryValue::clone() const
423 : {
424 3087 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
425 22958 : for (size_t i = 0; i < m_order.size(); ++i) {
426 19871 : String key = m_order[i];
427 : Dictionary::const_iterator value = m_data.find(key);
428 : DCHECK(value != m_data.cend() && value->second);
429 16784 : result->setValue(key, value->second->clone());
430 : }
431 3087 : return std::move(result);
432 : }
433 :
434 7986620 : DictionaryValue::DictionaryValue()
435 15973240 : : Value(TypeObject)
436 : {
437 7986620 : }
438 :
439 409442 : ListValue::~ListValue()
440 : {
441 409442 : }
442 :
443 408417 : void ListValue::writeJSON(StringBuilder* output) const
444 : {
445 : StringUtil::builderAppend(*output, '[');
446 : bool first = true;
447 3939692 : for (const std::unique_ptr<protocol::Value>& value : m_data) {
448 3122858 : if (!first)
449 : StringUtil::builderAppend(*output, ',');
450 3122858 : value->writeJSON(output);
451 : first = false;
452 : }
453 : StringUtil::builderAppend(*output, ']');
454 408417 : }
455 :
456 265 : std::unique_ptr<Value> ListValue::clone() const
457 : {
458 265 : std::unique_ptr<ListValue> result = ListValue::create();
459 1230 : for (const std::unique_ptr<protocol::Value>& value : m_data)
460 1400 : result->pushValue(value->clone());
461 265 : return std::move(result);
462 : }
463 :
464 408417 : ListValue::ListValue()
465 409442 : : Value(TypeArray)
466 : {
467 408417 : }
468 :
469 3122858 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
470 : {
471 : DCHECK(value);
472 3124528 : m_data.push_back(std::move(value));
473 3122858 : }
474 :
475 345 : protocol::Value* ListValue::at(size_t index)
476 : {
477 : DCHECK_LT(index, m_data.size());
478 690 : 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 49370938 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
487 : {
488 49370938 : escapeStringForJSONInternal<uint16_t>(str, len, dst);
489 49370938 : }
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 10481314 : DispatchResponse DispatchResponse::OK()
545 : {
546 : DispatchResponse result;
547 10481314 : result.m_status = kSuccess;
548 10481314 : result.m_errorCode = kParseError;
549 10481314 : return result;
550 : }
551 :
552 : // static
553 1801 : DispatchResponse DispatchResponse::Error(const String& error)
554 : {
555 : DispatchResponse result;
556 1801 : result.m_status = kError;
557 1801 : result.m_errorCode = kServerError;
558 1801 : result.m_errorMessage = error;
559 1801 : return result;
560 : }
561 :
562 : // static
563 128 : DispatchResponse DispatchResponse::InternalError()
564 : {
565 : DispatchResponse result;
566 128 : result.m_status = kError;
567 128 : result.m_errorCode = kInternalError;
568 256 : result.m_errorMessage = "Internal error";
569 128 : 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 178823 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
595 :
596 169215 : DispatcherBase::WeakPtr::~WeakPtr()
597 : {
598 178823 : if (m_dispatcher)
599 357626 : m_dispatcher->m_weakPtrs.erase(this);
600 169215 : }
601 :
602 9608 : DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const String& message)
603 : : m_backendImpl(std::move(backendImpl))
604 : , m_callId(callId)
605 : , m_method(method)
606 19216 : , m_message(message) { }
607 :
608 : DispatcherBase::Callback::~Callback() = default;
609 :
610 0 : void DispatcherBase::Callback::dispose()
611 : {
612 : m_backendImpl = nullptr;
613 0 : }
614 :
615 9608 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
616 : {
617 19216 : if (!m_backendImpl || !m_backendImpl->get())
618 9608 : return;
619 28809 : m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
620 : m_backendImpl = nullptr;
621 : }
622 :
623 0 : void DispatcherBase::Callback::fallThroughIfActive()
624 : {
625 0 : if (!m_backendImpl || !m_backendImpl->get())
626 0 : return;
627 0 : m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
628 : m_backendImpl = nullptr;
629 : }
630 :
631 23004 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
632 46008 : : m_frontendChannel(frontendChannel) { }
633 :
634 23004 : DispatcherBase::~DispatcherBase()
635 : {
636 23004 : clearFrontend();
637 23004 : }
638 :
639 339489 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
640 : {
641 169210 : if (!m_frontendChannel)
642 : return;
643 169210 : if (response.status() == DispatchResponse::kError) {
644 1069 : reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
645 : return;
646 : }
647 1008846 : m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
648 : }
649 :
650 57311 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
651 : {
652 114622 : sendResponse(callId, response, DictionaryValue::create());
653 57311 : }
654 :
655 : namespace {
656 :
657 : class ProtocolError : public Serializable {
658 : public:
659 1093 : static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
660 : {
661 1093 : std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
662 1093 : protocolError->m_callId = callId;
663 1093 : protocolError->m_hasCallId = true;
664 1112 : if (errors && errors->hasErrors())
665 57 : protocolError->m_data = errors->errors();
666 1093 : return protocolError;
667 : }
668 :
669 0 : static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
670 : {
671 0 : return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
672 : }
673 :
674 1093 : String serialize() override
675 : {
676 1093 : std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
677 3279 : error->setInteger("code", m_code);
678 3279 : error->setString("message", m_errorMessage);
679 1093 : if (m_data.length())
680 57 : error->setString("data", m_data);
681 1093 : std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
682 3279 : message->setObject("error", std::move(error));
683 1093 : if (m_hasCallId)
684 3279 : message->setInteger("id", m_callId);
685 2186 : return message->serialize();
686 : }
687 :
688 3279 : ~ProtocolError() override {}
689 :
690 : private:
691 1093 : ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
692 : : m_code(code)
693 1093 : , m_errorMessage(errorMessage)
694 : {
695 1093 : }
696 :
697 : DispatchResponse::ErrorCode m_code;
698 : String m_errorMessage;
699 : String m_data;
700 : int m_callId = 0;
701 : bool m_hasCallId = false;
702 : };
703 :
704 : } // namespace
705 :
706 1093 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
707 : {
708 1093 : if (frontendChannel)
709 4372 : frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
710 1093 : }
711 :
712 0 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
713 : {
714 0 : if (frontendChannel)
715 0 : frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
716 0 : }
717 :
718 19 : void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
719 : {
720 1088 : reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
721 19 : }
722 :
723 23004 : void DispatcherBase::clearFrontend()
724 : {
725 23004 : m_frontendChannel = nullptr;
726 46018 : for (auto& weak : m_weakPtrs)
727 10 : weak->dispose();
728 : m_weakPtrs.clear();
729 23004 : }
730 :
731 178823 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
732 : {
733 178823 : std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
734 357646 : m_weakPtrs.insert(weak.get());
735 178823 : return weak;
736 : }
737 :
738 3834 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
739 11502 : : m_frontendChannel(frontendChannel) { }
740 :
741 23004 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
742 : {
743 : m_dispatchers[name] = std::move(dispatcher);
744 23004 : }
745 :
746 23004 : void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
747 : {
748 49842 : for (const auto& pair : redirects)
749 7668 : m_redirects[pair.first] = pair.second;
750 23004 : }
751 :
752 169239 : bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
753 169239 : if (!parsedMessage) {
754 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
755 0 : return false;
756 : }
757 : protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
758 169239 : if (!messageObject) {
759 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
760 0 : return false;
761 : }
762 :
763 169239 : int callId = 0;
764 338478 : protocol::Value* callIdValue = messageObject->get("id");
765 169239 : bool success = callIdValue && callIdValue->asInteger(&callId);
766 169239 : if (!success) {
767 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
768 0 : return false;
769 : }
770 169239 : if (outCallId)
771 169239 : *outCallId = callId;
772 :
773 338478 : protocol::Value* methodValue = messageObject->get("method");
774 169239 : String method;
775 169239 : success = methodValue && methodValue->asString(&method);
776 169239 : if (!success) {
777 0 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
778 0 : return false;
779 : }
780 169239 : if (outMethod)
781 169239 : *outMethod = method;
782 : return true;
783 : }
784 :
785 169239 : protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
786 169239 : size_t dotIndex = StringUtil::find(method, ".");
787 169239 : if (dotIndex == StringUtil::kNotFound)
788 : return nullptr;
789 : String domain = StringUtil::substring(method, 0, dotIndex);
790 : auto it = m_dispatchers.find(domain);
791 169239 : if (it == m_dispatchers.end())
792 : return nullptr;
793 169239 : if (!it->second->canDispatch(method))
794 : return nullptr;
795 169234 : return it->second.get();
796 : }
797 :
798 0 : bool UberDispatcher::canDispatch(const String& in_method)
799 : {
800 0 : String method = in_method;
801 : auto redirectIt = m_redirects.find(method);
802 0 : if (redirectIt != m_redirects.end())
803 0 : method = redirectIt->second;
804 0 : return !!findDispatcher(method);
805 : }
806 :
807 169239 : void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const String& rawMessage)
808 : {
809 169239 : String method = in_method;
810 : auto redirectIt = m_redirects.find(method);
811 169239 : if (redirectIt != m_redirects.end())
812 10 : method = redirectIt->second;
813 169239 : protocol::DispatcherBase* dispatcher = findDispatcher(method);
814 169239 : if (!dispatcher) {
815 20 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
816 169239 : return;
817 : }
818 : std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
819 507702 : dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
820 : }
821 :
822 : UberDispatcher::~UberDispatcher() = default;
823 :
824 : // static
825 168141 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
826 : {
827 672564 : return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
828 : }
829 :
830 : // static
831 179366 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
832 : {
833 358732 : return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
834 : }
835 :
836 347507 : String InternalResponse::serialize()
837 : {
838 347507 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
839 805652 : std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
840 347507 : if (m_notification.length()) {
841 538098 : result->setString("method", m_notification);
842 1076196 : result->setValue("params", SerializedValue::create(params->serialize()));
843 : } else {
844 504423 : result->setInteger("id", m_callId);
845 1008846 : result->setValue("result", SerializedValue::create(params->serialize()));
846 : }
847 695014 : return result->serialize();
848 : }
849 :
850 0 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
851 : : m_callId(callId)
852 : , m_notification(notification)
853 347507 : , m_params(params ? std::move(params) : nullptr)
854 : {
855 0 : }
856 :
857 : } // namespace v8_inspector
858 : } // namespace protocol
859 :
860 :
861 : // Copyright 2016 The Chromium Authors. All rights reserved.
862 : // Use of this source code is governed by a BSD-style license that can be
863 : // found in the LICENSE file.
864 :
865 : namespace v8_inspector {
866 : namespace protocol {
867 :
868 : namespace {
869 :
870 : const int stackLimit = 1000;
871 :
872 : enum Token {
873 : ObjectBegin,
874 : ObjectEnd,
875 : ArrayBegin,
876 : ArrayEnd,
877 : StringLiteral,
878 : Number,
879 : BoolTrue,
880 : BoolFalse,
881 : NullToken,
882 : ListSeparator,
883 : ObjectPairSeparator,
884 : InvalidToken,
885 : };
886 :
887 : const char* const nullString = "null";
888 : const char* const trueString = "true";
889 : const char* const falseString = "false";
890 :
891 : bool isASCII(uint16_t c)
892 : {
893 5494968 : return !(c & ~0x7F);
894 : }
895 :
896 : bool isSpaceOrNewLine(uint16_t c)
897 : {
898 4646695 : return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
899 : }
900 :
901 363027 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
902 : {
903 : std::vector<char> buffer;
904 363027 : buffer.reserve(length + 1);
905 1211300 : for (size_t i = 0; i < length; ++i) {
906 1696546 : if (!isASCII(characters[i])) {
907 0 : *ok = false;
908 0 : return 0;
909 : }
910 1696546 : buffer.push_back(static_cast<char>(characters[i]));
911 : }
912 726054 : buffer.push_back('\0');
913 363027 : return StringUtil::toDouble(buffer.data(), length, ok);
914 : }
915 :
916 0 : double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
917 : {
918 0 : std::string buffer(reinterpret_cast<const char*>(characters), length);
919 0 : return StringUtil::toDouble(buffer.data(), length, ok);
920 : }
921 :
922 : template<typename Char>
923 : bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
924 : {
925 418278 : while (start < end && *token != '\0' && *start++ == *token++) { }
926 82259 : if (*token != '\0')
927 : return false;
928 82259 : *tokenEnd = start;
929 : return true;
930 : }
931 :
932 : template<typename Char>
933 363032 : bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
934 : {
935 363032 : if (start == end)
936 : return false;
937 363032 : bool haveLeadingZero = '0' == *start;
938 : int length = 0;
939 1574317 : while (start < end && '0' <= *start && *start <= '9') {
940 848253 : ++start;
941 848253 : ++length;
942 : }
943 363032 : if (!length)
944 : return false;
945 363032 : if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
946 : return false;
947 363032 : *tokenEnd = start;
948 363032 : return true;
949 : }
950 :
951 : template<typename Char>
952 363027 : 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 363027 : if (start == end)
957 : return false;
958 363027 : Char c = *start;
959 363027 : if ('-' == c)
960 15 : ++start;
961 :
962 363027 : if (!readInt(start, end, &start, false))
963 : return false;
964 363027 : if (start == end) {
965 0 : *tokenEnd = start;
966 0 : return true;
967 : }
968 :
969 : // Optional fraction part
970 363027 : c = *start;
971 363027 : if ('.' == c) {
972 5 : ++start;
973 5 : if (!readInt(start, end, &start, true))
974 : return false;
975 5 : if (start == end) {
976 0 : *tokenEnd = start;
977 0 : return true;
978 : }
979 5 : c = *start;
980 : }
981 :
982 : // Optional exponent part
983 363027 : 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 363027 : *tokenEnd = start;
998 363027 : return true;
999 : }
1000 :
1001 : template<typename Char>
1002 45 : bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
1003 : {
1004 45 : if (end - start < digits)
1005 : return false;
1006 180 : for (int i = 0; i < digits; ++i) {
1007 180 : Char c = *start++;
1008 180 : if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
1009 : return false;
1010 : }
1011 45 : *tokenEnd = start;
1012 45 : return true;
1013 : }
1014 :
1015 : template<typename Char>
1016 1171276 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
1017 : {
1018 15343145 : while (start < end) {
1019 14171869 : Char c = *start++;
1020 14171869 : if ('\\' == c) {
1021 332558 : if (start == end)
1022 : return false;
1023 332558 : c = *start++;
1024 : // Make sure the escaped char is valid.
1025 332558 : switch (c) {
1026 : case 'x':
1027 0 : if (!readHexDigits(start, end, &start, 2))
1028 : return false;
1029 : break;
1030 : case 'u':
1031 45 : 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 13839311 : } else if ('"' == c) {
1048 1171276 : *tokenEnd = start;
1049 1171276 : 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 4909280 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
1096 : {
1097 9818560 : while (start < end) {
1098 9293390 : if (isSpaceOrNewLine(*start)) {
1099 0 : ++start;
1100 4646695 : } 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 4909280 : *whitespaceEnd = start;
1110 4909280 : }
1111 :
1112 : template<typename Char>
1113 3772028 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
1114 : {
1115 3772028 : skipWhitespaceAndComments(start, end, tokenStart);
1116 3772028 : start = *tokenStart;
1117 :
1118 3772028 : if (start == end)
1119 : return InvalidToken;
1120 :
1121 3772028 : switch (*start) {
1122 : case 'n':
1123 0 : if (parseConstToken(start, end, tokenEnd, nullString))
1124 : return NullToken;
1125 : break;
1126 : case 't':
1127 75276 : if (parseConstToken(start, end, tokenEnd, trueString))
1128 : return BoolTrue;
1129 : break;
1130 : case 'f':
1131 6983 : if (parseConstToken(start, end, tokenEnd, falseString))
1132 : return BoolFalse;
1133 : break;
1134 : case '[':
1135 760 : *tokenEnd = start + 1;
1136 760 : return ArrayBegin;
1137 : case ']':
1138 760 : *tokenEnd = start + 1;
1139 760 : return ArrayEnd;
1140 : case ',':
1141 491915 : *tokenEnd = start + 1;
1142 491915 : return ListSeparator;
1143 : case '{':
1144 394597 : *tokenEnd = start + 1;
1145 394597 : return ObjectBegin;
1146 : case '}':
1147 393737 : *tokenEnd = start + 1;
1148 393737 : return ObjectEnd;
1149 : case ':':
1150 873697 : *tokenEnd = start + 1;
1151 873697 : 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 363027 : if (parseNumberToken(start, end, tokenEnd))
1164 : return Number;
1165 : break;
1166 : case '"':
1167 1171276 : 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 180 : if ('0' <= c && c <= '9')
1178 170 : return c - '0';
1179 10 : if ('A' <= c && c <= 'F')
1180 10 : 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 1170926 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
1189 : {
1190 15341365 : while (start < end) {
1191 12999513 : uint16_t c = *start++;
1192 12999513 : if ('\\' != c) {
1193 : StringUtil::builderAppend(*output, c);
1194 : continue;
1195 : }
1196 332558 : if (start == end)
1197 : return false;
1198 332558 : c = *start++;
1199 :
1200 332558 : if (c == 'x') {
1201 : // \x is not supported.
1202 : return false;
1203 : }
1204 :
1205 332558 : 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 7488 : 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 225 : c = (hexToInt(*start) << 12) +
1230 45 : (hexToInt(*(start + 1)) << 8) +
1231 45 : (hexToInt(*(start + 2)) << 4) +
1232 45 : hexToInt(*(start + 3));
1233 45 : start += 4;
1234 45 : break;
1235 : default:
1236 : return false;
1237 : }
1238 : StringUtil::builderAppend(*output, c);
1239 : }
1240 : return true;
1241 : }
1242 :
1243 : template<typename Char>
1244 1171166 : bool decodeString(const Char* start, const Char* end, String* output)
1245 : {
1246 1171166 : if (start == end) {
1247 480 : *output = "";
1248 240 : return true;
1249 : }
1250 1170926 : if (start > end)
1251 : return false;
1252 1170926 : StringBuilder buffer;
1253 1170926 : StringUtil::builderReserve(buffer, end - start);
1254 1170926 : if (!decodeString(start, end, &buffer))
1255 : return false;
1256 2341852 : *output = StringUtil::builderToString(buffer);
1257 1170926 : return true;
1258 : }
1259 :
1260 : template<typename Char>
1261 1137252 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
1262 : {
1263 1137252 : if (depth > stackLimit)
1264 : return nullptr;
1265 :
1266 : std::unique_ptr<Value> result;
1267 : const Char* tokenStart;
1268 : const Char* tokenEnd;
1269 1137252 : Token token = parseToken(start, end, &tokenStart, &tokenEnd);
1270 1137252 : switch (token) {
1271 : case InvalidToken:
1272 : return nullptr;
1273 : case NullToken:
1274 : result = Value::null();
1275 0 : break;
1276 : case BoolTrue:
1277 150552 : result = FundamentalValue::create(true);
1278 75276 : break;
1279 : case BoolFalse:
1280 13966 : result = FundamentalValue::create(false);
1281 6983 : break;
1282 : case Number: {
1283 : bool ok;
1284 363027 : double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
1285 363027 : if (!ok)
1286 0 : return nullptr;
1287 363027 : if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
1288 726044 : result = FundamentalValue::create(static_cast<int>(value));
1289 : else
1290 10 : result = FundamentalValue::create(value);
1291 363027 : break;
1292 : }
1293 : case StringLiteral: {
1294 297469 : String value;
1295 297469 : bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
1296 297469 : if (!ok)
1297 : return nullptr;
1298 594938 : result = StringValue::create(value);
1299 : break;
1300 : }
1301 : case ArrayBegin: {
1302 760 : std::unique_ptr<ListValue> array = ListValue::create();
1303 760 : start = tokenEnd;
1304 760 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1305 760 : while (token != ArrayEnd) {
1306 970 : std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
1307 970 : if (!arrayNode)
1308 : return nullptr;
1309 970 : array->pushValue(std::move(arrayNode));
1310 :
1311 : // After a list value, we expect a comma or the end of the list.
1312 970 : start = tokenEnd;
1313 970 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1314 970 : if (token == ListSeparator) {
1315 290 : start = tokenEnd;
1316 290 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1317 290 : if (token == ArrayEnd)
1318 : return nullptr;
1319 680 : } else if (token != ArrayEnd) {
1320 : // Unexpected value after list value. Bail out.
1321 : return nullptr;
1322 : }
1323 : }
1324 760 : if (token != ArrayEnd)
1325 : return nullptr;
1326 : result = std::move(array);
1327 : break;
1328 : }
1329 : case ObjectBegin: {
1330 393737 : std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
1331 393737 : start = tokenEnd;
1332 393737 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1333 393737 : while (token != ObjectEnd) {
1334 873697 : if (token != StringLiteral)
1335 0 : return nullptr;
1336 873697 : String key;
1337 873697 : if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
1338 : return nullptr;
1339 873697 : start = tokenEnd;
1340 :
1341 873697 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1342 873697 : if (token != ObjectPairSeparator)
1343 : return nullptr;
1344 873697 : start = tokenEnd;
1345 :
1346 873697 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
1347 873697 : if (!value)
1348 : return nullptr;
1349 873697 : object->setValue(key, std::move(value));
1350 873697 : start = tokenEnd;
1351 :
1352 : // After a key/value pair, we expect a comma or the end of the
1353 : // object.
1354 873697 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1355 873697 : if (token == ListSeparator) {
1356 491625 : start = tokenEnd;
1357 491625 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1358 491625 : if (token == ObjectEnd)
1359 : return nullptr;
1360 382072 : } else if (token != ObjectEnd) {
1361 : // Unexpected value after last object value. Bail out.
1362 : return nullptr;
1363 : }
1364 : }
1365 393737 : if (token != ObjectEnd)
1366 : return nullptr;
1367 : result = std::move(object);
1368 : break;
1369 : }
1370 :
1371 : default:
1372 : // We got a token that's not a value.
1373 : return nullptr;
1374 : }
1375 :
1376 1137252 : skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
1377 : return result;
1378 : }
1379 :
1380 : template<typename Char>
1381 262585 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
1382 : {
1383 262585 : const Char* end = start + length;
1384 : const Char *tokenEnd;
1385 262585 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
1386 262585 : if (!value || tokenEnd != end)
1387 : return nullptr;
1388 : return value;
1389 : }
1390 :
1391 : } // anonymous namespace
1392 :
1393 262585 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
1394 : {
1395 262585 : return parseJSONInternal<uint16_t>(characters, length);
1396 : }
1397 :
1398 0 : std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
1399 : {
1400 0 : return parseJSONInternal<uint8_t>(characters, length);
1401 : }
1402 :
1403 : } // namespace v8_inspector
1404 : } // namespace protocol
|