LCOV - code coverage report
Current view: top level - out/Release/gen/src/inspector/protocol - Protocol.cpp (source / functions) Hit Total Coverage
Test: app.info Lines: 492 618 79.6 %
Date: 2019-01-20 Functions: 94 135 69.6 %

          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

Generated by: LCOV version 1.10