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: 475 625 76.0 %
Date: 2017-10-20 Functions: 91 136 66.9 %

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

Generated by: LCOV version 1.10