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: 454 600 75.7 %
Date: 2017-04-26 Functions: 88 130 67.7 %

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

Generated by: LCOV version 1.10