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: 488 1032 47.3 %
Date: 2019-02-19 Functions: 96 204 47.1 %

          Line data    Source code
       1             : // This file is generated by Protocol_cpp.template.
       2             : 
       3             : // Copyright 2016 The Chromium Authors. All rights reserved.
       4             : // Use of this source code is governed by a BSD-style license that can be
       5             : // found in the LICENSE file.
       6             : 
       7             : #include "src/inspector/protocol/Protocol.h"
       8             : 
       9             : #include <algorithm>
      10             : #include <climits>
      11             : #include <cmath>
      12             : #include <cstring>
      13             : 
      14             : 
      15             : // This file is generated by ErrorSupport_cpp.template.
      16             : 
      17             : // Copyright 2016 The Chromium Authors. All rights reserved.
      18             : // Use of this source code is governed by a BSD-style license that can be
      19             : // found in the LICENSE file.
      20             : 
      21             : //#include "ErrorSupport.h"
      22             : 
      23             : namespace v8_inspector {
      24             : namespace protocol {
      25             : 
      26      337208 : ErrorSupport::ErrorSupport() { }
      27      168604 : ErrorSupport::~ErrorSupport() { }
      28             : 
      29      217854 : void ErrorSupport::setName(const char* name)
      30             : {
      31      435708 :     setName(String(name));
      32      217854 : }
      33             : 
      34      218199 : void ErrorSupport::setName(const String& name)
      35             : {
      36             :     DCHECK(m_path.size());
      37      436398 :     m_path[m_path.size() - 1] = name;
      38      218199 : }
      39             : 
      40      154206 : void ErrorSupport::push()
      41             : {
      42      462618 :     m_path.push_back(String());
      43      154206 : }
      44             : 
      45      154206 : void ErrorSupport::pop()
      46             : {
      47             :     m_path.pop_back();
      48      154206 : }
      49             : 
      50          28 : void ErrorSupport::addError(const char* error)
      51             : {
      52          56 :     addError(String(error));
      53          28 : }
      54             : 
      55          28 : void ErrorSupport::addError(const String& error)
      56             : {
      57          28 :     StringBuilder builder;
      58         112 :     for (size_t i = 0; i < m_path.size(); ++i) {
      59          28 :         if (i)
      60             :             StringUtil::builderAppend(builder, '.');
      61          84 :         StringUtil::builderAppend(builder, m_path[i]);
      62             :     }
      63          56 :     StringUtil::builderAppend(builder, ": ");
      64             :     StringUtil::builderAppend(builder, error);
      65          56 :     m_errors.push_back(StringUtil::builderToString(builder));
      66          28 : }
      67             : 
      68      154206 : bool ErrorSupport::hasErrors()
      69             : {
      70      308431 :     return !!m_errors.size();
      71             : }
      72             : 
      73          19 : String ErrorSupport::errors()
      74             : {
      75          19 :     StringBuilder builder;
      76          94 :     for (size_t i = 0; i < m_errors.size(); ++i) {
      77          28 :         if (i)
      78          18 :             StringUtil::builderAppend(builder, "; ");
      79          75 :         StringUtil::builderAppend(builder, m_errors[i]);
      80             :     }
      81          19 :     return StringUtil::builderToString(builder);
      82             : }
      83             : 
      84             : } // namespace v8_inspector
      85             : } // namespace protocol
      86             : 
      87             : 
      88             : // This file is generated by Values_cpp.template.
      89             : 
      90             : // Copyright 2016 The Chromium Authors. All rights reserved.
      91             : // Use of this source code is governed by a BSD-style license that can be
      92             : // found in the LICENSE file.
      93             : 
      94             : //#include "Values.h"
      95             : 
      96             : namespace v8_inspector {
      97             : namespace protocol {
      98             : 
      99             : namespace {
     100             : 
     101             : const char* const nullValueString = "null";
     102             : const char* const trueValueString = "true";
     103             : const char* const falseValueString = "false";
     104             : 
     105  1241918906 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
     106             : {
     107  1241918906 :     switch (c) {
     108           0 :     case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
     109           0 :     case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
     110    43605884 :     case '\n': StringUtil::builderAppend(*dst, "\\n"); break;
     111           0 :     case '\r': StringUtil::builderAppend(*dst, "\\r"); break;
     112           0 :     case '\t': StringUtil::builderAppend(*dst, "\\t"); break;
     113      145844 :     case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
     114    36870630 :     case '"': StringUtil::builderAppend(*dst, "\\\""); break;
     115             :     default:
     116             :         return false;
     117             :     }
     118             :     return true;
     119             : }
     120             : 
     121             : const char hexDigits[17] = "0123456789ABCDEF";
     122             : 
     123         135 : void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
     124             : {
     125         270 :     StringUtil::builderAppend(*dst, "\\u");
     126         675 :     for (size_t i = 0; i < 4; ++i) {
     127         540 :         uint16_t c = hexDigits[(number & 0xF000) >> 12];
     128             :         StringUtil::builderAppend(*dst, c);
     129         540 :         number <<= 4;
     130             :     }
     131         135 : }
     132             : 
     133             : template <typename Char>
     134    49604192 : void escapeStringForJSONInternal(const Char* str, unsigned len,
     135             :                                  StringBuilder* dst)
     136             : {
     137  1291523098 :     for (unsigned i = 0; i < len; ++i) {
     138  1241918906 :         Char c = str[i];
     139  1241918906 :         if (escapeChar(c, dst))
     140             :             continue;
     141  1201607727 :         if (c < 32 || c > 126) {
     142         135 :             appendUnsignedAsHex(c, dst);
     143             :         } else {
     144             :             StringUtil::builderAppend(*dst, c);
     145             :         }
     146             :     }
     147    49604192 : }
     148             : 
     149             : // When parsing CBOR, we limit recursion depth for objects and arrays
     150             : // to this constant.
     151             : static constexpr int kStackLimitValues = 1000;
     152             : 
     153             : // Below are three parsing routines for CBOR, which cover enough
     154             : // to roundtrip JSON messages.
     155             : std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, CBORTokenizer* tokenizer);
     156             : std::unique_ptr<ListValue> parseArray(int32_t stack_depth, CBORTokenizer* tokenizer);
     157             : std::unique_ptr<Value> parseValue(int32_t stack_depth, CBORTokenizer* tokenizer);
     158             : 
     159             : // |bytes| must start with the indefinite length array byte, so basically,
     160             : // ParseArray may only be called after an indefinite length array has been
     161             : // detected.
     162           0 : std::unique_ptr<ListValue> parseArray(int32_t stack_depth, CBORTokenizer* tokenizer) {
     163             :   DCHECK(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
     164           0 :   tokenizer->Next();
     165           0 :   auto list = ListValue::create();
     166           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
     167             :     // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY
     168           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) return nullptr;
     169           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
     170             :     // Parse value.
     171           0 :     auto value = parseValue(stack_depth, tokenizer);
     172           0 :     if (!value) return nullptr;
     173           0 :     list->pushValue(std::move(value));
     174             :   }
     175           0 :   tokenizer->Next();
     176             :   return list;
     177             : }
     178             : 
     179           0 : std::unique_ptr<Value> parseValue(
     180             :     int32_t stack_depth, CBORTokenizer* tokenizer) {
     181             :   // Error::CBOR_STACK_LIMIT_EXCEEDED
     182           0 :   if (stack_depth > kStackLimitValues) return nullptr;
     183             :   // Skip past the envelope to get to what's inside.
     184           0 :   if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
     185             :     tokenizer->EnterEnvelope();
     186           0 :   switch (tokenizer->TokenTag()) {
     187             :     case CBORTokenTag::ERROR_VALUE:
     188             :       return nullptr;
     189             :     case CBORTokenTag::DONE:
     190             :       // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE
     191             :       return nullptr;
     192             :     case CBORTokenTag::TRUE_VALUE: {
     193           0 :       std::unique_ptr<Value> value = FundamentalValue::create(true);
     194           0 :       tokenizer->Next();
     195             :       return value;
     196             :     }
     197             :     case CBORTokenTag::FALSE_VALUE: {
     198           0 :       std::unique_ptr<Value> value = FundamentalValue::create(false);
     199           0 :       tokenizer->Next();
     200             :       return value;
     201             :     }
     202             :     case CBORTokenTag::NULL_VALUE: {
     203             :       std::unique_ptr<Value> value = FundamentalValue::null();
     204           0 :       tokenizer->Next();
     205             :       return value;
     206             :     }
     207             :     case CBORTokenTag::INT32: {
     208           0 :       std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32());
     209           0 :       tokenizer->Next();
     210             :       return value;
     211             :     }
     212             :     case CBORTokenTag::DOUBLE: {
     213           0 :       std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble());
     214           0 :       tokenizer->Next();
     215             :       return value;
     216             :     }
     217             :     case CBORTokenTag::STRING8: {
     218             :       span<uint8_t> str = tokenizer->GetString8();
     219           0 :       std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
     220           0 :       tokenizer->Next();
     221             :       return value;
     222             :     }
     223             :     case CBORTokenTag::STRING16:
     224             :       // NOT SUPPORTED YET.
     225             :       return nullptr;
     226             :     case CBORTokenTag::BINARY: {
     227             :       span<uint8_t> payload = tokenizer->GetBinary();
     228           0 :       return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size()));
     229             :     }
     230             :     case CBORTokenTag::MAP_START:
     231           0 :       return parseMap(stack_depth + 1, tokenizer);
     232             :     case CBORTokenTag::ARRAY_START:
     233           0 :       return parseArray(stack_depth + 1, tokenizer);
     234             :     default:
     235             :       // Error::CBOR_UNSUPPORTED_VALUE
     236             :       return nullptr;
     237             :   }
     238             : }
     239             : 
     240             : // |bytes| must start with the indefinite length array byte, so basically,
     241             : // ParseArray may only be called after an indefinite length array has been
     242             : // detected.
     243           0 : std::unique_ptr<DictionaryValue> parseMap(
     244             :     int32_t stack_depth, CBORTokenizer* tokenizer) {
     245           0 :   auto dict = DictionaryValue::create();
     246           0 :   tokenizer->Next();
     247           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
     248           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
     249             :       // Error::CBOR_UNEXPECTED_EOF_IN_MAP
     250           0 :       return nullptr;
     251             :     }
     252           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
     253             :     // Parse key.
     254             :     String key;
     255           0 :     if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
     256             :       span<uint8_t> key_span = tokenizer->GetString8();
     257           0 :       tokenizer->Next();
     258           0 :       key = StringUtil::fromUTF8(key_span.data(), key_span.size());
     259           0 :     } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
     260             :       return nullptr;  // STRING16 not supported yet.
     261             :     } else {
     262             :       // Error::CBOR_INVALID_MAP_KEY
     263             :       return nullptr;
     264             :     }
     265             :     // Parse value.
     266           0 :     auto value = parseValue(stack_depth, tokenizer);
     267           0 :     if (!value) return nullptr;
     268           0 :     dict->setValue(key, std::move(value));
     269             :   }
     270           0 :   tokenizer->Next();
     271             :   return dict;
     272             : }
     273             : 
     274             : } // anonymous namespace
     275             : 
     276             : // static
     277           0 : std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) {
     278           0 :   span<uint8_t> bytes(data, size);
     279             : 
     280             :   // Error::CBOR_NO_INPUT
     281           0 :   if (bytes.empty()) return nullptr;
     282             : 
     283             :   // Error::CBOR_INVALID_START_BYTE
     284             :   // TODO(johannes): EncodeInitialByteForEnvelope() method.
     285           0 :   if (bytes[0] != 0xd8) return nullptr;
     286             : 
     287             :   CBORTokenizer tokenizer(bytes);
     288           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
     289             : 
     290             :   // We checked for the envelope start byte above, so the tokenizer
     291             :   // must agree here, since it's not an error.
     292             :   DCHECK(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
     293             :   tokenizer.EnterEnvelope();
     294             :   // Error::MAP_START_EXPECTED
     295           0 :   if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) return nullptr;
     296           0 :   std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer);
     297           0 :   if (!result) return nullptr;
     298           0 :   if (tokenizer.TokenTag() == CBORTokenTag::DONE) return result;
     299           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
     300             :   // Error::CBOR_TRAILING_JUNK
     301             :   return nullptr;
     302             : }
     303             : 
     304           0 : bool Value::asBoolean(bool*) const
     305             : {
     306           0 :     return false;
     307             : }
     308             : 
     309           0 : bool Value::asDouble(double*) const
     310             : {
     311           0 :     return false;
     312             : }
     313             : 
     314           0 : bool Value::asInteger(int*) const
     315             : {
     316           0 :     return false;
     317             : }
     318             : 
     319          18 : bool Value::asString(String*) const
     320             : {
     321          18 :     return false;
     322             : }
     323             : 
     324           0 : bool Value::asBinary(Binary*) const
     325             : {
     326           0 :     return false;
     327             : }
     328             : 
     329        2667 : void Value::writeJSON(StringBuilder* output) const
     330             : {
     331             :     DCHECK(m_type == TypeNull);
     332             :     StringUtil::builderAppend(*output, nullValueString, 4);
     333        2667 : }
     334             : 
     335           0 : void Value::writeBinary(std::vector<uint8_t>* bytes) const {
     336             :     DCHECK(m_type == TypeNull);
     337           0 :     bytes->push_back(EncodeNull());
     338           0 : }
     339             : 
     340        2667 : std::unique_ptr<Value> Value::clone() const
     341             : {
     342        2667 :     return Value::null();
     343             : }
     344             : 
     345      694663 : String Value::toJSONString() const
     346             : {
     347      694663 :     StringBuilder result;
     348             :     StringUtil::builderReserve(result, 512);
     349      694663 :     writeJSON(&result);
     350      694663 :     return StringUtil::builderToString(result);
     351             : }
     352             : 
     353      694287 : String Value::serializeToJSON() {
     354      694287 :     return toJSONString();
     355             : }
     356             : 
     357           0 : std::vector<uint8_t> Value::serializeToBinary() {
     358             :     std::vector<uint8_t> bytes;
     359           0 :     writeBinary(&bytes);
     360           0 :     return bytes;
     361             : }
     362             : 
     363       82188 : bool FundamentalValue::asBoolean(bool* output) const
     364             : {
     365       82188 :     if (type() != TypeBoolean)
     366             :         return false;
     367       82188 :     *output = m_boolValue;
     368       82188 :     return true;
     369             : }
     370             : 
     371          30 : bool FundamentalValue::asDouble(double* output) const
     372             : {
     373          30 :     if (type() == TypeDouble) {
     374           0 :         *output = m_doubleValue;
     375           0 :         return true;
     376             :     }
     377          30 :     if (type() == TypeInteger) {
     378          30 :         *output = m_integerValue;
     379          30 :         return true;
     380             :     }
     381             :     return false;
     382             : }
     383             : 
     384      360252 : bool FundamentalValue::asInteger(int* output) const
     385             : {
     386      360252 :     if (type() != TypeInteger)
     387             :         return false;
     388      360252 :     *output = m_integerValue;
     389      360252 :     return true;
     390             : }
     391             : 
     392    12281268 : void FundamentalValue::writeJSON(StringBuilder* output) const
     393             : {
     394             :     DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
     395    12281268 :     if (type() == TypeBoolean) {
     396    10236353 :         if (m_boolValue)
     397             :             StringUtil::builderAppend(*output, trueValueString, 4);
     398             :         else
     399             :             StringUtil::builderAppend(*output, falseValueString, 5);
     400     2044915 :     } else if (type() == TypeDouble) {
     401      302812 :         if (!std::isfinite(m_doubleValue)) {
     402             :             StringUtil::builderAppend(*output, nullValueString, 4);
     403    12281268 :             return;
     404             :         }
     405      151401 :         StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
     406     1893509 :     } else if (type() == TypeInteger) {
     407     3787018 :         StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
     408             :     }
     409             : }
     410             : 
     411           0 : void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const {
     412           0 :     switch (type()) {
     413             :     case TypeDouble:
     414           0 :         EncodeDouble(m_doubleValue, bytes);
     415             :         return;
     416             :     case TypeInteger:
     417           0 :         EncodeInt32(m_integerValue, bytes);
     418           0 :         return;
     419             :     case TypeBoolean:
     420           0 :         bytes->push_back(m_boolValue ? EncodeTrue() : EncodeFalse());
     421           0 :         return;
     422             :     default:
     423             :         DCHECK(false);
     424             :     }
     425             : }
     426             : 
     427      167371 : std::unique_ptr<Value> FundamentalValue::clone() const
     428             : {
     429      167371 :     switch (type()) {
     430      289134 :     case TypeDouble: return FundamentalValue::create(m_doubleValue);
     431        1654 :     case TypeInteger: return FundamentalValue::create(m_integerValue);
     432       43954 :     case TypeBoolean: return FundamentalValue::create(m_boolValue);
     433             :     default:
     434             :         DCHECK(false);
     435             :     }
     436             :     return nullptr;
     437             : }
     438             : 
     439      295848 : bool StringValue::asString(String* output) const
     440             : {
     441             :     *output = m_stringValue;
     442      295848 :     return true;
     443             : }
     444             : 
     445    16510483 : void StringValue::writeJSON(StringBuilder* output) const
     446             : {
     447             :     DCHECK(type() == TypeString);
     448    16510483 :     StringUtil::builderAppendQuotedString(*output, m_stringValue);
     449    16510483 : }
     450             : 
     451           0 : void StringValue::writeBinary(std::vector<uint8_t>* bytes) const {
     452           0 :     StringUTF8Adapter utf8(m_stringValue);
     453             :     EncodeString8(span<uint8_t>(reinterpret_cast<const uint8_t*>(utf8.Data()),
     454           0 :                   utf8.length()), bytes);
     455           0 : }
     456             : 
     457       65900 : std::unique_ptr<Value> StringValue::clone() const
     458             : {
     459      131800 :     return StringValue::create(m_stringValue);
     460             : }
     461             : 
     462           0 : bool BinaryValue::asBinary(Binary* output) const
     463             : {
     464             :     *output = m_binaryValue;
     465           0 :     return true;
     466             : }
     467             : 
     468           0 : void BinaryValue::writeJSON(StringBuilder* output) const
     469             : {
     470             :     DCHECK(type() == TypeBinary);
     471           0 :     StringUtil::builderAppendQuotedString(*output, m_binaryValue.toBase64());
     472             : }
     473             : 
     474           0 : void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
     475           0 :     EncodeBinary(span<uint8_t>(m_binaryValue.data(), m_binaryValue.size()), bytes);
     476             : }
     477             : 
     478           0 : std::unique_ptr<Value> BinaryValue::clone() const
     479             : {
     480           0 :     return BinaryValue::create(m_binaryValue);
     481             : }
     482             : 
     483      346600 : void SerializedValue::writeJSON(StringBuilder* output) const
     484             : {
     485             :     DCHECK(type() == TypeSerialized);
     486      346600 :     StringUtil::builderAppend(*output, m_serializedJSON);
     487      346600 : }
     488             : 
     489           0 : void SerializedValue::writeBinary(std::vector<uint8_t>* output) const
     490             : {
     491             :     DCHECK(type() == TypeSerialized);
     492           0 :     output->insert(output->end(), m_serializedBinary.begin(), m_serializedBinary.end());
     493           0 : }
     494             : 
     495           0 : std::unique_ptr<Value> SerializedValue::clone() const
     496             : {
     497           0 :     return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary));
     498             : }
     499             : 
     500    16028002 : DictionaryValue::~DictionaryValue()
     501             : {
     502    16028002 : }
     503             : 
     504       26548 : void DictionaryValue::setBoolean(const String& name, bool value)
     505             : {
     506       79644 :     setValue(name, FundamentalValue::create(value));
     507       26548 : }
     508             : 
     509      181854 : void DictionaryValue::setInteger(const String& name, int value)
     510             : {
     511      545562 :     setValue(name, FundamentalValue::create(value));
     512      181854 : }
     513             : 
     514           5 : void DictionaryValue::setDouble(const String& name, double value)
     515             : {
     516          15 :     setValue(name, FundamentalValue::create(value));
     517           5 : }
     518             : 
     519      180900 : void DictionaryValue::setString(const String& name, const String& value)
     520             : {
     521      542700 :     setValue(name, StringValue::create(value));
     522      180900 : }
     523             : 
     524    32602472 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
     525             : {
     526    34216864 :     set(name, value);
     527    32602472 : }
     528             : 
     529       23217 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
     530             : {
     531       24304 :     set(name, value);
     532       23217 : }
     533             : 
     534          10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
     535             : {
     536          10 :     set(name, value);
     537          10 : }
     538             : 
     539        8273 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
     540             : {
     541             :     protocol::Value* value = get(name);
     542        8273 :     if (!value)
     543             :         return false;
     544         214 :     return value->asBoolean(output);
     545             : }
     546             : 
     547      186196 : bool DictionaryValue::getInteger(const String& name, int* output) const
     548             : {
     549             :     Value* value = get(name);
     550      186196 :     if (!value)
     551             :         return false;
     552      186136 :     return value->asInteger(output);
     553             : }
     554             : 
     555           0 : bool DictionaryValue::getDouble(const String& name, double* output) const
     556             : {
     557             :     Value* value = get(name);
     558           0 :     if (!value)
     559             :         return false;
     560           0 :     return value->asDouble(output);
     561             : }
     562             : 
     563         110 : bool DictionaryValue::getString(const String& name, String* output) const
     564             : {
     565             :     protocol::Value* value = get(name);
     566         110 :     if (!value)
     567             :         return false;
     568          90 :     return value->asString(output);
     569             : }
     570             : 
     571      172139 : DictionaryValue* DictionaryValue::getObject(const String& name) const
     572             : {
     573      172139 :     return DictionaryValue::cast(get(name));
     574             : }
     575             : 
     576           0 : protocol::ListValue* DictionaryValue::getArray(const String& name) const
     577             : {
     578           0 :     return ListValue::cast(get(name));
     579             : }
     580             : 
     581      670049 : protocol::Value* DictionaryValue::get(const String& name) const
     582             : {
     583             :     Dictionary::const_iterator it = m_data.find(name);
     584     1373843 :     if (it == m_data.end())
     585             :         return nullptr;
     586      335931 :     return it->second.get();
     587             : }
     588             : 
     589         120 : DictionaryValue::Entry DictionaryValue::at(size_t index) const
     590             : {
     591         120 :     const String key = m_order[index];
     592         120 :     return std::make_pair(key, m_data.find(key)->second.get());
     593             : }
     594             : 
     595        4441 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
     596             : {
     597        4441 :     bool result = defaultValue;
     598        4441 :     getBoolean(name, &result);
     599        4441 :     return result;
     600             : }
     601             : 
     602          35 : int DictionaryValue::integerProperty(const String& name, int defaultValue) const
     603             : {
     604          35 :     int result = defaultValue;
     605          35 :     getInteger(name, &result);
     606          35 :     return result;
     607             : }
     608             : 
     609           0 : double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
     610             : {
     611           0 :     double result = defaultValue;
     612           0 :     getDouble(name, &result);
     613           0 :     return result;
     614             : }
     615             : 
     616       18102 : void DictionaryValue::remove(const String& name)
     617             : {
     618             :     m_data.erase(name);
     619       18102 :     m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
     620       18102 : }
     621             : 
     622     7586980 : void DictionaryValue::writeJSON(StringBuilder* output) const
     623             : {
     624             :     StringUtil::builderAppend(*output, '{');
     625    81779746 :     for (size_t i = 0; i < m_order.size(); ++i) {
     626    40889873 :         Dictionary::const_iterator it = m_data.find(m_order[i]);
     627    33302893 :         CHECK(it != m_data.end());
     628    33302893 :         if (i)
     629             :             StringUtil::builderAppend(*output, ',');
     630    33302893 :         StringUtil::builderAppendQuotedString(*output, it->first);
     631             :         StringUtil::builderAppend(*output, ':');
     632    33302893 :         it->second->writeJSON(output);
     633             :     }
     634             :     StringUtil::builderAppend(*output, '}');
     635     7586980 : }
     636             : 
     637           0 : void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
     638           0 :     EnvelopeEncoder encoder;
     639           0 :     encoder.EncodeStart(bytes);
     640           0 :     bytes->push_back(EncodeIndefiniteLengthMapStart());
     641           0 :     for (size_t i = 0; i < m_order.size(); ++i) {
     642           0 :         const String& key = m_order[i];
     643             :         Dictionary::const_iterator value = m_data.find(key);
     644             :         DCHECK(value != m_data.cend() && value->second);
     645             :         StringUTF8Adapter utf8(key);
     646             :         EncodeString8(span<uint8_t>(reinterpret_cast<const uint8_t*>(utf8.Data()),
     647           0 :                                     utf8.length()), bytes);
     648           0 :         value->second->writeBinary(bytes);
     649             :     }
     650           0 :     bytes->push_back(EncodeStop());
     651           0 :     encoder.EncodeStop(bytes);
     652           0 : }
     653             : 
     654        3000 : std::unique_ptr<Value> DictionaryValue::clone() const
     655             : {
     656        3000 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
     657       22598 :     for (size_t i = 0; i < m_order.size(); ++i) {
     658       11299 :         String key = m_order[i];
     659             :         Dictionary::const_iterator value = m_data.find(key);
     660             :         DCHECK(value != m_data.cend() && value->second);
     661       16598 :         result->setValue(key, value->second->clone());
     662             :     }
     663        3000 :     return std::move(result);
     664             : }
     665             : 
     666     8014001 : DictionaryValue::DictionaryValue()
     667    16028002 :     : Value(TypeObject)
     668             : {
     669     8014001 : }
     670             : 
     671      408699 : ListValue::~ListValue()
     672             : {
     673      408699 : }
     674             : 
     675      407769 : void ListValue::writeJSON(StringBuilder* output) const
     676             : {
     677             :     StringUtil::builderAppend(*output, '[');
     678             :     bool first = true;
     679     3953749 :     for (const std::unique_ptr<protocol::Value>& value : m_data) {
     680     3138211 :         if (!first)
     681             :             StringUtil::builderAppend(*output, ',');
     682     3138211 :         value->writeJSON(output);
     683             :         first = false;
     684             :     }
     685             :     StringUtil::builderAppend(*output, ']');
     686      407769 : }
     687             : 
     688           0 : void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
     689           0 :     EnvelopeEncoder encoder;
     690           0 :     encoder.EncodeStart(bytes);
     691           0 :     bytes->push_back(EncodeIndefiniteLengthArrayStart());
     692           0 :     for (size_t i = 0; i < m_data.size(); ++i) {
     693           0 :         m_data[i]->writeBinary(bytes);
     694             :     }
     695           0 :     bytes->push_back(EncodeStop());
     696           0 :     encoder.EncodeStop(bytes);
     697           0 : }
     698             : 
     699         265 : std::unique_ptr<Value> ListValue::clone() const
     700             : {
     701         265 :     std::unique_ptr<ListValue> result = ListValue::create();
     702        1230 :     for (const std::unique_ptr<protocol::Value>& value : m_data)
     703        1400 :         result->pushValue(value->clone());
     704         265 :     return std::move(result);
     705             : }
     706             : 
     707      407769 : ListValue::ListValue()
     708      408699 :     : Value(TypeArray)
     709             : {
     710      407769 : }
     711             : 
     712     3138211 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
     713             : {
     714             :     DCHECK(value);
     715     3139756 :     m_data.push_back(std::move(value));
     716     3138211 : }
     717             : 
     718         345 : protocol::Value* ListValue::at(size_t index)
     719             : {
     720             :     DCHECK_LT(index, m_data.size());
     721         690 :     return m_data[index].get();
     722             : }
     723             : 
     724           0 : void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
     725             : {
     726           0 :     escapeStringForJSONInternal<uint8_t>(str, len, dst);
     727           0 : }
     728             : 
     729    49604192 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
     730             : {
     731    49604192 :     escapeStringForJSONInternal<uint16_t>(str, len, dst);
     732    49604192 : }
     733             : 
     734             : } // namespace v8_inspector
     735             : } // namespace protocol
     736             : 
     737             : 
     738             : // This file is generated by Object_cpp.template.
     739             : 
     740             : // Copyright 2016 The Chromium Authors. All rights reserved.
     741             : // Use of this source code is governed by a BSD-style license that can be
     742             : // found in the LICENSE file.
     743             : 
     744             : //#include "Object.h"
     745             : 
     746             : namespace v8_inspector {
     747             : namespace protocol {
     748             : 
     749           0 : std::unique_ptr<Object> Object::fromValue(protocol::Value* value, ErrorSupport* errors)
     750             : {
     751             :     protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
     752           0 :     if (!dictionary) {
     753           0 :         errors->addError("object expected");
     754             :         return nullptr;
     755             :     }
     756           0 :     dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
     757           0 :     return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
     758             : }
     759             : 
     760           0 : std::unique_ptr<protocol::DictionaryValue> Object::toValue() const
     761             : {
     762           0 :     return DictionaryValue::cast(m_object->clone());
     763             : }
     764             : 
     765           0 : std::unique_ptr<Object> Object::clone() const
     766             : {
     767           0 :     return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
     768             : }
     769             : 
     770           0 : Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }
     771             : 
     772           0 : Object::~Object() { }
     773             : 
     774             : } // namespace v8_inspector
     775             : } // namespace protocol
     776             : 
     777             : 
     778             : // This file is generated by DispatcherBase_cpp.template.
     779             : 
     780             : // Copyright 2016 The Chromium Authors. All rights reserved.
     781             : // Use of this source code is governed by a BSD-style license that can be
     782             : // found in the LICENSE file.
     783             : 
     784             : //#include "DispatcherBase.h"
     785             : //#include "Parser.h"
     786             : 
     787             : namespace v8_inspector {
     788             : namespace protocol {
     789             : 
     790             : // static
     791    10524309 : DispatchResponse DispatchResponse::OK()
     792             : {
     793             :     DispatchResponse result;
     794    10524309 :     result.m_status = kSuccess;
     795    10524309 :     result.m_errorCode = kParseError;
     796    10524309 :     return result;
     797             : }
     798             : 
     799             : // static
     800        1736 : DispatchResponse DispatchResponse::Error(const String& error)
     801             : {
     802             :     DispatchResponse result;
     803        1736 :     result.m_status = kError;
     804        1736 :     result.m_errorCode = kServerError;
     805             :     result.m_errorMessage = error;
     806        1736 :     return result;
     807             : }
     808             : 
     809             : // static
     810         128 : DispatchResponse DispatchResponse::InternalError()
     811             : {
     812             :     DispatchResponse result;
     813         128 :     result.m_status = kError;
     814         128 :     result.m_errorCode = kInternalError;
     815         256 :     result.m_errorMessage = "Internal error";
     816         128 :     return result;
     817             : }
     818             : 
     819             : // static
     820           0 : DispatchResponse DispatchResponse::InvalidParams(const String& error)
     821             : {
     822             :     DispatchResponse result;
     823           0 :     result.m_status = kError;
     824           0 :     result.m_errorCode = kInvalidParams;
     825             :     result.m_errorMessage = error;
     826           0 :     return result;
     827             : }
     828             : 
     829             : // static
     830           0 : DispatchResponse DispatchResponse::FallThrough()
     831             : {
     832             :     DispatchResponse result;
     833           0 :     result.m_status = kFallThrough;
     834           0 :     result.m_errorCode = kParseError;
     835           0 :     return result;
     836             : }
     837             : 
     838             : // static
     839             : const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";
     840             : 
     841      177931 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
     842             : 
     843      168515 : DispatcherBase::WeakPtr::~WeakPtr()
     844             : {
     845      177931 :     if (m_dispatcher)
     846      355842 :         m_dispatcher->m_weakPtrs.erase(this);
     847      168515 : }
     848             : 
     849        9416 : DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
     850             :     : m_backendImpl(std::move(backendImpl))
     851             :     , m_callId(callId)
     852             :     , m_method(method)
     853       28248 :     , m_message(message) { }
     854             : 
     855             : DispatcherBase::Callback::~Callback() = default;
     856             : 
     857           0 : void DispatcherBase::Callback::dispose()
     858             : {
     859             :     m_backendImpl = nullptr;
     860           0 : }
     861             : 
     862        9416 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
     863             : {
     864       18832 :     if (!m_backendImpl || !m_backendImpl->get())
     865        9416 :         return;
     866       28233 :     m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
     867             :     m_backendImpl = nullptr;
     868             : }
     869             : 
     870           0 : void DispatcherBase::Callback::fallThroughIfActive()
     871             : {
     872           0 :     if (!m_backendImpl || !m_backendImpl->get())
     873           0 :         return;
     874           0 :     m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
     875             :     m_backendImpl = nullptr;
     876             : }
     877             : 
     878       22992 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
     879       45984 :     : m_frontendChannel(frontendChannel) { }
     880             : 
     881       22992 : DispatcherBase::~DispatcherBase()
     882             : {
     883       22992 :     clearFrontend();
     884       22992 : }
     885             : 
     886      338084 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
     887             : {
     888      168510 :     if (!m_frontendChannel)
     889             :         return;
     890      168510 :     if (response.status() == DispatchResponse::kError) {
     891        1064 :         reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
     892             :         return;
     893             :     }
     894     1004676 :     m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
     895             : }
     896             : 
     897       56907 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
     898             : {
     899      113814 :     sendResponse(callId, response, DictionaryValue::create());
     900       56907 : }
     901             : 
     902             : namespace {
     903             : 
     904             : class ProtocolError : public Serializable {
     905             : public:
     906        1087 :     static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     907             :     {
     908        1087 :         std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
     909        1087 :         protocolError->m_callId = callId;
     910        1087 :         protocolError->m_hasCallId = true;
     911        1106 :         if (errors && errors->hasErrors())
     912          38 :             protocolError->m_data = errors->errors();
     913        1087 :         return protocolError;
     914             :     }
     915             : 
     916           0 :     static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
     917             :     {
     918           0 :         return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
     919             :     }
     920             : 
     921        1087 :     String serializeToJSON() override
     922             :     {
     923        3261 :         return serialize()->serializeToJSON();
     924             :     }
     925             : 
     926           0 :     std::vector<uint8_t> serializeToBinary() override
     927             :     {
     928           0 :         return serialize()->serializeToBinary();
     929             :     }
     930             : 
     931        3261 :     ~ProtocolError() override {}
     932             : 
     933             : private:
     934             :     ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
     935             :         : m_code(code)
     936        2174 :         , m_errorMessage(errorMessage)
     937             :     {
     938             :     }
     939             : 
     940        1087 :     std::unique_ptr<DictionaryValue> serialize() {
     941        1087 :         std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
     942        3261 :         error->setInteger("code", m_code);
     943        3261 :         error->setString("message", m_errorMessage);
     944        1087 :         if (m_data.length())
     945          57 :             error->setString("data", m_data);
     946        1087 :         std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
     947        3261 :         message->setObject("error", std::move(error));
     948        1087 :         if (m_hasCallId)
     949        3261 :             message->setInteger("id", m_callId);
     950        1087 :         return message;
     951             :     }
     952             : 
     953             :     DispatchResponse::ErrorCode m_code;
     954             :     String m_errorMessage;
     955             :     String m_data;
     956             :     int m_callId = 0;
     957             :     bool m_hasCallId = false;
     958             : };
     959             : 
     960             : } // namespace
     961             : 
     962        1087 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     963             : {
     964        1087 :     if (frontendChannel)
     965        4348 :         frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
     966        1087 : }
     967             : 
     968           0 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
     969             : {
     970           0 :     if (frontendChannel)
     971           0 :         frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
     972           0 : }
     973             : 
     974          19 : void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     975             : {
     976        1083 :     reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
     977          19 : }
     978             : 
     979       22992 : void DispatcherBase::clearFrontend()
     980             : {
     981       22992 :     m_frontendChannel = nullptr;
     982       45994 :     for (auto& weak : m_weakPtrs)
     983          10 :         weak->dispose();
     984             :     m_weakPtrs.clear();
     985       22992 : }
     986             : 
     987      177931 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
     988             : {
     989      177931 :     std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
     990      355862 :     m_weakPtrs.insert(weak.get());
     991      177931 :     return weak;
     992             : }
     993             : 
     994        3832 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
     995       11496 :     : m_frontendChannel(frontendChannel) { }
     996             : 
     997       22992 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
     998             : {
     999             :     m_dispatchers[name] = std::move(dispatcher);
    1000       22992 : }
    1001             : 
    1002       22992 : void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
    1003             : {
    1004       49816 :     for (const auto& pair : redirects)
    1005        3832 :         m_redirects[pair.first] = pair.second;
    1006       22992 : }
    1007             : 
    1008      168538 : bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
    1009      168538 :     if (!parsedMessage) {
    1010           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
    1011           0 :         return false;
    1012             :     }
    1013             :     protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
    1014      168538 :     if (!messageObject) {
    1015           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
    1016           0 :         return false;
    1017             :     }
    1018             : 
    1019      168538 :     int callId = 0;
    1020      337076 :     protocol::Value* callIdValue = messageObject->get("id");
    1021      168538 :     bool success = callIdValue && callIdValue->asInteger(&callId);
    1022      168538 :     if (!success) {
    1023           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
    1024           0 :         return false;
    1025             :     }
    1026      168538 :     if (outCallId)
    1027      168538 :       *outCallId = callId;
    1028             : 
    1029      337076 :     protocol::Value* methodValue = messageObject->get("method");
    1030             :     String method;
    1031      168538 :     success = methodValue && methodValue->asString(&method);
    1032      168538 :     if (!success) {
    1033           0 :         reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
    1034           0 :         return false;
    1035             :     }
    1036      168538 :     if (outMethod)
    1037             :       *outMethod = method;
    1038             :     return true;
    1039             : }
    1040             : 
    1041      168538 : protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
    1042      168538 :     size_t dotIndex = StringUtil::find(method, ".");
    1043      168538 :     if (dotIndex == StringUtil::kNotFound)
    1044             :         return nullptr;
    1045             :     String domain = StringUtil::substring(method, 0, dotIndex);
    1046             :     auto it = m_dispatchers.find(domain);
    1047      168538 :     if (it == m_dispatchers.end())
    1048             :         return nullptr;
    1049      168538 :     if (!it->second->canDispatch(method))
    1050             :         return nullptr;
    1051      168534 :     return it->second.get();
    1052             : }
    1053             : 
    1054           0 : bool UberDispatcher::canDispatch(const String& in_method)
    1055             : {
    1056             :     String method = in_method;
    1057             :     auto redirectIt = m_redirects.find(method);
    1058           0 :     if (redirectIt != m_redirects.end())
    1059             :         method = redirectIt->second;
    1060           0 :     return !!findDispatcher(method);
    1061             : }
    1062             : 
    1063      168538 : void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const ProtocolMessage& rawMessage)
    1064             : {
    1065             :     String method = in_method;
    1066             :     auto redirectIt = m_redirects.find(method);
    1067      168538 :     if (redirectIt != m_redirects.end())
    1068             :         method = redirectIt->second;
    1069      168538 :     protocol::DispatcherBase* dispatcher = findDispatcher(method);
    1070      168538 :     if (!dispatcher) {
    1071          16 :         reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
    1072      168538 :         return;
    1073             :     }
    1074             :     std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
    1075      505602 :     dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
    1076             : }
    1077             : 
    1078             : UberDispatcher::~UberDispatcher() = default;
    1079             : 
    1080             : // static
    1081      167446 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
    1082             : {
    1083      669784 :     return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
    1084             : }
    1085             : 
    1086             : // static
    1087      179154 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
    1088             : {
    1089      358308 :     return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
    1090             : }
    1091             : 
    1092      346600 : String InternalResponse::serializeToJSON()
    1093             : {
    1094      346600 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    1095      803568 :     std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    1096      346600 :     if (m_notification.length()) {
    1097      537462 :         result->setString("method", m_notification);
    1098     1074924 :         result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
    1099             :     } else {
    1100      502338 :         result->setInteger("id", m_callId);
    1101     1004676 :         result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
    1102             :     }
    1103      693200 :     return result->serializeToJSON();
    1104             : }
    1105             : 
    1106           0 : std::vector<uint8_t> InternalResponse::serializeToBinary()
    1107             : {
    1108           0 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    1109           0 :     std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    1110           0 :     if (m_notification.length()) {
    1111           0 :         result->setString("method", m_notification);
    1112           0 :         result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary()));
    1113             :     } else {
    1114           0 :         result->setInteger("id", m_callId);
    1115           0 :         result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary()));
    1116             :     }
    1117           0 :     return result->serializeToBinary();
    1118             : }
    1119             : 
    1120      346600 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
    1121             :     : m_callId(callId)
    1122             :     , m_notification(notification)
    1123      693200 :     , m_params(params ? std::move(params) : nullptr)
    1124             : {
    1125      346600 : }
    1126             : 
    1127             : } // namespace v8_inspector
    1128             : } // namespace protocol
    1129             : 
    1130             : 
    1131             : // This file is generated by Parser_cpp.template.
    1132             : 
    1133             : // Copyright 2016 The Chromium Authors. All rights reserved.
    1134             : // Use of this source code is governed by a BSD-style license that can be
    1135             : // found in the LICENSE file.
    1136             : 
    1137             : namespace v8_inspector {
    1138             : namespace protocol {
    1139             : 
    1140             : namespace {
    1141             : 
    1142             : const int stackLimit = 1000;
    1143             : 
    1144             : enum Token {
    1145             :     ObjectBegin,
    1146             :     ObjectEnd,
    1147             :     ArrayBegin,
    1148             :     ArrayEnd,
    1149             :     StringLiteral,
    1150             :     Number,
    1151             :     BoolTrue,
    1152             :     BoolFalse,
    1153             :     NullToken,
    1154             :     ListSeparator,
    1155             :     ObjectPairSeparator,
    1156             :     InvalidToken,
    1157             : };
    1158             : 
    1159             : const char* const nullString = "null";
    1160             : const char* const trueString = "true";
    1161             : const char* const falseString = "false";
    1162             : 
    1163             : bool isASCII(uint16_t c)
    1164             : {
    1165     5472938 :     return !(c & ~0x7F);
    1166             : }
    1167             : 
    1168             : bool isSpaceOrNewLine(uint16_t c)
    1169             : {
    1170     4627382 :     return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
    1171             : }
    1172             : 
    1173      361652 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
    1174             : {
    1175             :     std::vector<char> buffer;
    1176      361652 :     buffer.reserve(length + 1);
    1177     1207208 :     for (size_t i = 0; i < length; ++i) {
    1178     1691112 :         if (!isASCII(characters[i])) {
    1179           0 :             *ok = false;
    1180           0 :             return 0;
    1181             :         }
    1182     1691112 :         buffer.push_back(static_cast<char>(characters[i]));
    1183             :     }
    1184      723304 :     buffer.push_back('\0');
    1185      361652 :     return StringUtil::toDouble(buffer.data(), length, ok);
    1186             : }
    1187             : 
    1188           0 : double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
    1189             : {
    1190           0 :     std::string buffer(reinterpret_cast<const char*>(characters), length);
    1191           0 :     return StringUtil::toDouble(buffer.data(), length, ok);
    1192             : }
    1193             : 
    1194             : template<typename Char>
    1195             : bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
    1196             : {
    1197      418254 :     while (start < end && *token != '\0' && *start++ == *token++) { }
    1198       82252 :     if (*token != '\0')
    1199             :         return false;
    1200       82252 :     *tokenEnd = start;
    1201             :     return true;
    1202             : }
    1203             : 
    1204             : template<typename Char>
    1205      361657 : bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
    1206             : {
    1207      361657 :     if (start == end)
    1208             :         return false;
    1209      361657 :     bool haveLeadingZero = '0' == *start;
    1210             :     int length = 0;
    1211     1568852 :     while (start < end && '0' <= *start && *start <= '9') {
    1212      845538 :         ++start;
    1213      845538 :         ++length;
    1214             :     }
    1215      361657 :     if (!length)
    1216             :         return false;
    1217      361657 :     if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
    1218             :         return false;
    1219      361657 :     *tokenEnd = start;
    1220      361657 :     return true;
    1221             : }
    1222             : 
    1223             : template<typename Char>
    1224      361652 : bool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd)
    1225             : {
    1226             :     // We just grab the number here. We validate the size in DecodeNumber.
    1227             :     // According to RFC4627, a valid number is: [minus] int [frac] [exp]
    1228      361652 :     if (start == end)
    1229             :         return false;
    1230      361652 :     Char c = *start;
    1231      361652 :     if ('-' == c)
    1232          13 :         ++start;
    1233             : 
    1234      361652 :     if (!readInt(start, end, &start, false))
    1235             :         return false;
    1236      361652 :     if (start == end) {
    1237           0 :         *tokenEnd = start;
    1238           0 :         return true;
    1239             :     }
    1240             : 
    1241             :     // Optional fraction part
    1242      361652 :     c = *start;
    1243      361652 :     if ('.' == c) {
    1244           5 :         ++start;
    1245           5 :         if (!readInt(start, end, &start, true))
    1246             :             return false;
    1247           5 :         if (start == end) {
    1248           0 :             *tokenEnd = start;
    1249           0 :             return true;
    1250             :         }
    1251           5 :         c = *start;
    1252             :     }
    1253             : 
    1254             :     // Optional exponent part
    1255      361652 :     if ('e' == c || 'E' == c) {
    1256           0 :         ++start;
    1257           0 :         if (start == end)
    1258             :             return false;
    1259           0 :         c = *start;
    1260           0 :         if ('-' == c || '+' == c) {
    1261           0 :             ++start;
    1262           0 :             if (start == end)
    1263             :                 return false;
    1264             :         }
    1265           0 :         if (!readInt(start, end, &start, true))
    1266             :             return false;
    1267             :     }
    1268             : 
    1269      361652 :     *tokenEnd = start;
    1270      361652 :     return true;
    1271             : }
    1272             : 
    1273             : template<typename Char>
    1274          45 : bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
    1275             : {
    1276          45 :     if (end - start < digits)
    1277             :         return false;
    1278         180 :     for (int i = 0; i < digits; ++i) {
    1279         180 :         Char c = *start++;
    1280         180 :         if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
    1281             :             return false;
    1282             :     }
    1283          45 :     *tokenEnd = start;
    1284          45 :     return true;
    1285             : }
    1286             : 
    1287             : template<typename Char>
    1288     1166613 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
    1289             : {
    1290    15280910 :     while (start < end) {
    1291    14114297 :         Char c = *start++;
    1292    14114297 :         if ('\\' == c) {
    1293      331935 :             if (start == end)
    1294             :                 return false;
    1295      331935 :             c = *start++;
    1296             :             // Make sure the escaped char is valid.
    1297      331935 :             switch (c) {
    1298             :             case 'x':
    1299           0 :                 if (!readHexDigits(start, end, &start, 2))
    1300             :                     return false;
    1301             :                 break;
    1302             :             case 'u':
    1303          45 :                 if (!readHexDigits(start, end, &start, 4))
    1304             :                     return false;
    1305             :                 break;
    1306             :             case '\\':
    1307             :             case '/':
    1308             :             case 'b':
    1309             :             case 'f':
    1310             :             case 'n':
    1311             :             case 'r':
    1312             :             case 't':
    1313             :             case 'v':
    1314             :             case '"':
    1315             :                 break;
    1316             :             default:
    1317             :                 return false;
    1318             :             }
    1319    13782362 :         } else if ('"' == c) {
    1320     1166613 :             *tokenEnd = start;
    1321     1166613 :             return true;
    1322             :         }
    1323             :     }
    1324             :     return false;
    1325             : }
    1326             : 
    1327             : template<typename Char>
    1328           0 : bool skipComment(const Char* start, const Char* end, const Char** commentEnd)
    1329             : {
    1330           0 :     if (start == end)
    1331             :         return false;
    1332             : 
    1333           0 :     if (*start != '/' || start + 1 >= end)
    1334             :         return false;
    1335             :     ++start;
    1336             : 
    1337           0 :     if (*start == '/') {
    1338             :         // Single line comment, read to newline.
    1339           0 :         for (++start; start < end; ++start) {
    1340           0 :             if (*start == '\n' || *start == '\r') {
    1341           0 :                 *commentEnd = start + 1;
    1342           0 :                 return true;
    1343             :             }
    1344             :         }
    1345           0 :         *commentEnd = end;
    1346             :         // Comment reaches end-of-input, which is fine.
    1347           0 :         return true;
    1348             :     }
    1349             : 
    1350           0 :     if (*start == '*') {
    1351             :         Char previous = '\0';
    1352             :         // Block comment, read until end marker.
    1353           0 :         for (++start; start < end; previous = *start++) {
    1354           0 :             if (previous == '*' && *start == '/') {
    1355           0 :                 *commentEnd = start + 1;
    1356           0 :                 return true;
    1357             :             }
    1358             :         }
    1359             :         // Block comment must close before end-of-input.
    1360             :         return false;
    1361             :     }
    1362             : 
    1363             :     return false;
    1364             : }
    1365             : 
    1366             : template<typename Char>
    1367     4889108 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
    1368             : {
    1369     9778216 :     while (start < end) {
    1370     9254764 :         if (isSpaceOrNewLine(*start)) {
    1371           0 :             ++start;
    1372     4627382 :         } else if (*start == '/') {
    1373             :             const Char* commentEnd;
    1374           0 :             if (!skipComment(start, end, &commentEnd))
    1375             :                 break;
    1376           0 :             start = commentEnd;
    1377             :         } else {
    1378             :             break;
    1379             :         }
    1380             :     }
    1381     4889108 :     *whitespaceEnd = start;
    1382     4889108 : }
    1383             : 
    1384             : template<typename Char>
    1385     3756351 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
    1386             : {
    1387     3756351 :     skipWhitespaceAndComments(start, end, tokenStart);
    1388     3756351 :     start = *tokenStart;
    1389             : 
    1390     3756351 :     if (start == end)
    1391             :         return InvalidToken;
    1392             : 
    1393     3756351 :     switch (*start) {
    1394             :     case 'n':
    1395           0 :         if (parseConstToken(start, end, tokenEnd, nullString))
    1396             :             return NullToken;
    1397             :         break;
    1398             :     case 't':
    1399       75258 :         if (parseConstToken(start, end, tokenEnd, trueString))
    1400             :             return BoolTrue;
    1401             :         break;
    1402             :     case 'f':
    1403        6994 :         if (parseConstToken(start, end, tokenEnd, falseString))
    1404             :             return BoolFalse;
    1405             :         break;
    1406             :     case '[':
    1407         665 :         *tokenEnd = start + 1;
    1408         665 :         return ArrayBegin;
    1409             :     case ']':
    1410         665 :         *tokenEnd = start + 1;
    1411         665 :         return ArrayEnd;
    1412             :     case ',':
    1413      489841 :         *tokenEnd = start + 1;
    1414      489841 :         return ListSeparator;
    1415             :     case '{':
    1416      392606 :         *tokenEnd = start + 1;
    1417      392606 :         return ObjectBegin;
    1418             :     case '}':
    1419      391871 :         *tokenEnd = start + 1;
    1420      391871 :         return ObjectEnd;
    1421             :     case ':':
    1422      870186 :         *tokenEnd = start + 1;
    1423      870186 :         return ObjectPairSeparator;
    1424             :     case '0':
    1425             :     case '1':
    1426             :     case '2':
    1427             :     case '3':
    1428             :     case '4':
    1429             :     case '5':
    1430             :     case '6':
    1431             :     case '7':
    1432             :     case '8':
    1433             :     case '9':
    1434             :     case '-':
    1435      361652 :         if (parseNumberToken(start, end, tokenEnd))
    1436             :             return Number;
    1437             :         break;
    1438             :     case '"':
    1439     1166613 :         if (parseStringToken(start + 1, end, tokenEnd))
    1440             :             return StringLiteral;
    1441             :         break;
    1442             :     }
    1443             :     return InvalidToken;
    1444             : }
    1445             : 
    1446             : template<typename Char>
    1447             : int hexToInt(Char c)
    1448             : {
    1449         180 :     if ('0' <= c && c <= '9')
    1450         170 :         return c - '0';
    1451          10 :     if ('A' <= c && c <= 'F')
    1452          10 :         return c - 'A' + 10;
    1453           0 :     if ('a' <= c && c <= 'f')
    1454           0 :         return c - 'a' + 10;
    1455             :     DCHECK(false);
    1456             :     return 0;
    1457             : }
    1458             : 
    1459             : template<typename Char>
    1460     1166297 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
    1461             : {
    1462    15279198 :     while (start < end) {
    1463    12946604 :         uint16_t c = *start++;
    1464    12946604 :         if ('\\' != c) {
    1465             :             StringUtil::builderAppend(*output, c);
    1466             :             continue;
    1467             :         }
    1468      331935 :         if (start == end)
    1469             :             return false;
    1470      331935 :         c = *start++;
    1471             : 
    1472      331935 :         if (c == 'x') {
    1473             :             // \x is not supported.
    1474             :             return false;
    1475             :         }
    1476             : 
    1477      331935 :         switch (c) {
    1478             :         case '"':
    1479             :         case '/':
    1480             :         case '\\':
    1481             :             break;
    1482             :         case 'b':
    1483             :             c = '\b';
    1484           0 :             break;
    1485             :         case 'f':
    1486             :             c = '\f';
    1487           0 :             break;
    1488             :         case 'n':
    1489             :             c = '\n';
    1490        7067 :             break;
    1491             :         case 'r':
    1492             :             c = '\r';
    1493           0 :             break;
    1494             :         case 't':
    1495             :             c = '\t';
    1496           0 :             break;
    1497             :         case 'v':
    1498             :             c = '\v';
    1499           0 :             break;
    1500             :         case 'u':
    1501         225 :             c = (hexToInt(*start) << 12) +
    1502          45 :                 (hexToInt(*(start + 1)) << 8) +
    1503          45 :                 (hexToInt(*(start + 2)) << 4) +
    1504          45 :                 hexToInt(*(start + 3));
    1505          45 :             start += 4;
    1506          45 :             break;
    1507             :         default:
    1508             :             return false;
    1509             :         }
    1510             :         StringUtil::builderAppend(*output, c);
    1511             :     }
    1512             :     return true;
    1513             : }
    1514             : 
    1515             : template<typename Char>
    1516     1166503 : bool decodeString(const Char* start, const Char* end, String* output)
    1517             : {
    1518     1166503 :     if (start == end) {
    1519         412 :         *output = "";
    1520         206 :         return true;
    1521             :     }
    1522     1166297 :     if (start > end)
    1523             :         return false;
    1524     1166297 :     StringBuilder buffer;
    1525     1166297 :     StringUtil::builderReserve(buffer, end - start);
    1526     1166297 :     if (!decodeString(start, end, &buffer))
    1527             :         return false;
    1528     1166297 :     *output = StringUtil::builderToString(buffer);
    1529     1166297 :     return true;
    1530             : }
    1531             : 
    1532             : template<typename Char>
    1533     1132757 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
    1534             : {
    1535     1132757 :     if (depth > stackLimit)
    1536             :         return nullptr;
    1537             : 
    1538             :     std::unique_ptr<Value> result;
    1539             :     const Char* tokenStart;
    1540             :     const Char* tokenEnd;
    1541     1132757 :     Token token = parseToken(start, end, &tokenStart, &tokenEnd);
    1542     1132757 :     switch (token) {
    1543             :     case InvalidToken:
    1544             :         return nullptr;
    1545             :     case NullToken:
    1546             :         result = Value::null();
    1547           0 :         break;
    1548             :     case BoolTrue:
    1549      150516 :         result = FundamentalValue::create(true);
    1550       75258 :         break;
    1551             :     case BoolFalse:
    1552       13988 :         result = FundamentalValue::create(false);
    1553        6994 :         break;
    1554             :     case Number: {
    1555             :         bool ok;
    1556      361652 :         double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
    1557      361652 :         if (!ok)
    1558           0 :             return nullptr;
    1559      361652 :         if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
    1560      723294 :             result = FundamentalValue::create(static_cast<int>(value));
    1561             :         else
    1562          10 :             result = FundamentalValue::create(value);
    1563      361652 :         break;
    1564             :     }
    1565             :     case StringLiteral: {
    1566             :         String value;
    1567      296317 :         bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
    1568      296317 :         if (!ok)
    1569             :             return nullptr;
    1570      592634 :         result = StringValue::create(value);
    1571             :         break;
    1572             :     }
    1573             :     case ArrayBegin: {
    1574         665 :         std::unique_ptr<ListValue> array = ListValue::create();
    1575         665 :         start = tokenEnd;
    1576         665 :         token = parseToken(start, end, &tokenStart, &tokenEnd);
    1577         665 :         while (token != ArrayEnd) {
    1578         845 :             std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
    1579         845 :             if (!arrayNode)
    1580             :                 return nullptr;
    1581         845 :             array->pushValue(std::move(arrayNode));
    1582             : 
    1583             :             // After a list value, we expect a comma or the end of the list.
    1584         845 :             start = tokenEnd;
    1585         845 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1586         845 :             if (token == ListSeparator) {
    1587         248 :                 start = tokenEnd;
    1588         248 :                 token = parseToken(start, end, &tokenStart, &tokenEnd);
    1589         248 :                 if (token == ArrayEnd)
    1590             :                     return nullptr;
    1591         597 :             } else if (token != ArrayEnd) {
    1592             :                 // Unexpected value after list value. Bail out.
    1593             :                 return nullptr;
    1594             :             }
    1595             :         }
    1596         665 :         if (token != ArrayEnd)
    1597             :             return nullptr;
    1598             :         result = std::move(array);
    1599             :         break;
    1600             :     }
    1601             :     case ObjectBegin: {
    1602      391871 :         std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
    1603      391871 :         start = tokenEnd;
    1604      391871 :         token = parseToken(start, end, &tokenStart, &tokenEnd);
    1605      391871 :         while (token != ObjectEnd) {
    1606      870186 :             if (token != StringLiteral)
    1607           0 :                 return nullptr;
    1608             :             String key;
    1609      870186 :             if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
    1610             :                 return nullptr;
    1611      870186 :             start = tokenEnd;
    1612             : 
    1613      870186 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1614      870186 :             if (token != ObjectPairSeparator)
    1615             :                 return nullptr;
    1616      870186 :             start = tokenEnd;
    1617             : 
    1618      870186 :             std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
    1619      870186 :             if (!value)
    1620             :                 return nullptr;
    1621      870186 :             object->setValue(key, std::move(value));
    1622      870186 :             start = tokenEnd;
    1623             : 
    1624             :             // After a key/value pair, we expect a comma or the end of the
    1625             :             // object.
    1626      870186 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1627      870186 :             if (token == ListSeparator) {
    1628      489593 :                 start = tokenEnd;
    1629      489593 :                 token = parseToken(start, end, &tokenStart, &tokenEnd);
    1630      489593 :                 if (token == ObjectEnd)
    1631             :                     return nullptr;
    1632      380593 :             } else if (token != ObjectEnd) {
    1633             :                 // Unexpected value after last object value. Bail out.
    1634             :                 return nullptr;
    1635             :             }
    1636             :         }
    1637      391871 :         if (token != ObjectEnd)
    1638             :             return nullptr;
    1639             :         result = std::move(object);
    1640             :         break;
    1641             :     }
    1642             : 
    1643             :     default:
    1644             :         // We got a token that's not a value.
    1645             :         return nullptr;
    1646             :     }
    1647             : 
    1648     1132757 :     skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
    1649             :     return result;
    1650             : }
    1651             : 
    1652             : template<typename Char>
    1653      261726 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
    1654             : {
    1655      261726 :     const Char* end = start + length;
    1656             :     const Char *tokenEnd;
    1657      261726 :     std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
    1658      261726 :     if (!value || tokenEnd != end)
    1659             :         return nullptr;
    1660             :     return value;
    1661             : }
    1662             : 
    1663             : } // anonymous namespace
    1664             : 
    1665      261726 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
    1666             : {
    1667      261726 :     return parseJSONInternal<uint16_t>(characters, length);
    1668             : }
    1669             : 
    1670           0 : std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
    1671             : {
    1672           0 :     return parseJSONInternal<uint8_t>(characters, length);
    1673             : }
    1674             : 
    1675             : } // namespace v8_inspector
    1676             : } // namespace protocol
    1677             : 
    1678             : 
    1679             : // Generated by lib/CBOR_cpp.template.
    1680             : 
    1681             : // Copyright 2019 The Chromium Authors. All rights reserved.
    1682             : // Use of this source code is governed by a BSD-style license that can be
    1683             : // found in the LICENSE file.
    1684             : 
    1685             : 
    1686             : #include <cassert>
    1687             : #include <limits>
    1688             : 
    1689             : namespace v8_inspector {
    1690             : namespace protocol {
    1691             : 
    1692             : // ===== encoding/cbor.cc =====
    1693             : 
    1694             : using namespace cbor;
    1695             : 
    1696             : namespace {
    1697             : 
    1698             : // See RFC 7049 Section 2.3, Table 2.
    1699             : static constexpr uint8_t kEncodedTrue =
    1700             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 21);
    1701             : static constexpr uint8_t kEncodedFalse =
    1702             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 20);
    1703             : static constexpr uint8_t kEncodedNull =
    1704             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
    1705             : static constexpr uint8_t kInitialByteForDouble =
    1706             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
    1707             : 
    1708             : }  // namespace
    1709             : 
    1710           0 : uint8_t EncodeTrue() { return kEncodedTrue; }
    1711           0 : uint8_t EncodeFalse() { return kEncodedFalse; }
    1712           0 : uint8_t EncodeNull() { return kEncodedNull; }
    1713             : 
    1714           0 : uint8_t EncodeIndefiniteLengthArrayStart() {
    1715           0 :   return kInitialByteIndefiniteLengthArray;
    1716             : }
    1717             : 
    1718           0 : uint8_t EncodeIndefiniteLengthMapStart() {
    1719           0 :   return kInitialByteIndefiniteLengthMap;
    1720             : }
    1721             : 
    1722           0 : uint8_t EncodeStop() { return kStopByte; }
    1723             : 
    1724             : namespace {
    1725             : // See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
    1726             : // arbitrary binary data encoded as BYTE_STRING.
    1727             : static constexpr uint8_t kExpectedConversionToBase64Tag =
    1728             :     EncodeInitialByte(MajorType::TAG, 22);
    1729             : 
    1730             : // When parsing CBOR, we limit recursion depth for objects and arrays
    1731             : // to this constant.
    1732             : static constexpr int kStackLimit = 1000;
    1733             : 
    1734             : // Writes the bytes for |v| to |out|, starting with the most significant byte.
    1735             : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1736             : template <typename T>
    1737           0 : void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) {
    1738           0 :   for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes)
    1739           0 :     out->push_back(0xff & (v >> (shift_bytes * 8)));
    1740           0 : }
    1741             : }  // namespace
    1742             : 
    1743             : namespace cbor_internals {
    1744             : // Writes the start of a token with |type|. The |value| may indicate the size,
    1745             : // or it may be the payload if the value is an unsigned integer.
    1746           0 : void WriteTokenStart(MajorType type, uint64_t value,
    1747             :                      std::vector<uint8_t>* encoded) {
    1748           0 :   if (value < 24) {
    1749             :     // Values 0-23 are encoded directly into the additional info of the
    1750             :     // initial byte.
    1751           0 :     encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value));
    1752           0 :     return;
    1753             :   }
    1754           0 :   if (value <= std::numeric_limits<uint8_t>::max()) {
    1755             :     // Values 24-255 are encoded with one initial byte, followed by the value.
    1756           0 :     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte));
    1757           0 :     encoded->push_back(value);
    1758           0 :     return;
    1759             :   }
    1760           0 :   if (value <= std::numeric_limits<uint16_t>::max()) {
    1761             :     // Values 256-65535: 1 initial byte + 2 bytes payload.
    1762           0 :     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes));
    1763           0 :     WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded);
    1764           0 :     return;
    1765             :   }
    1766           0 :   if (value <= std::numeric_limits<uint32_t>::max()) {
    1767             :     // 32 bit uint: 1 initial byte + 4 bytes payload.
    1768           0 :     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes));
    1769             :     WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value),
    1770           0 :                                                  encoded);
    1771           0 :     return;
    1772             :   }
    1773             :   // 64 bit uint: 1 initial byte + 8 bytes payload.
    1774           0 :   encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes));
    1775           0 :   WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded);
    1776             : }
    1777             : }  // namespace cbor_internals
    1778             : 
    1779             : namespace {
    1780             : // Extracts sizeof(T) bytes from |in| to extract a value of type T
    1781             : // (e.g. uint64_t, uint32_t, ...), most significant byte first.
    1782             : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1783             : template <typename T>
    1784             : T ReadBytesMostSignificantByteFirst(span<uint8_t> in) {
    1785             :   assert(static_cast<std::size_t>(in.size()) >= sizeof(T));
    1786             :   T result = 0;
    1787           0 :   for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes)
    1788           0 :     result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8);
    1789             :   return result;
    1790             : }
    1791             : }  // namespace
    1792             : 
    1793             : namespace cbor_internals {
    1794           0 : int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
    1795           0 :   if (bytes.empty()) return -1;
    1796           0 :   uint8_t initial_byte = bytes[0];
    1797           0 :   *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
    1798             : 
    1799           0 :   uint8_t additional_information = initial_byte & kAdditionalInformationMask;
    1800           0 :   if (additional_information < 24) {
    1801             :     // Values 0-23 are encoded directly into the additional info of the
    1802             :     // initial byte.
    1803           0 :     *value = additional_information;
    1804           0 :     return 1;
    1805             :   }
    1806           0 :   if (additional_information == kAdditionalInformation1Byte) {
    1807             :     // Values 24-255 are encoded with one initial byte, followed by the value.
    1808           0 :     if (bytes.size() < 2) return -1;
    1809           0 :     *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
    1810           0 :     return 2;
    1811             :   }
    1812           0 :   if (additional_information == kAdditionalInformation2Bytes) {
    1813             :     // Values 256-65535: 1 initial byte + 2 bytes payload.
    1814           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t))
    1815             :       return -1;
    1816           0 :     *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
    1817           0 :     return 3;
    1818             :   }
    1819           0 :   if (additional_information == kAdditionalInformation4Bytes) {
    1820             :     // 32 bit uint: 1 initial byte + 4 bytes payload.
    1821           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t))
    1822             :       return -1;
    1823           0 :     *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
    1824           0 :     return 5;
    1825             :   }
    1826           0 :   if (additional_information == kAdditionalInformation8Bytes) {
    1827             :     // 64 bit uint: 1 initial byte + 8 bytes payload.
    1828           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t))
    1829             :       return -1;
    1830           0 :     *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
    1831           0 :     return 9;
    1832             :   }
    1833             :   return -1;
    1834             : }
    1835             : }  // namespace cbor_internals
    1836             : 
    1837             : using cbor_internals::WriteTokenStart;
    1838             : using cbor_internals::ReadTokenStart;
    1839             : 
    1840           0 : void EncodeInt32(int32_t value, std::vector<uint8_t>* out) {
    1841           0 :   if (value >= 0) {
    1842           0 :     WriteTokenStart(MajorType::UNSIGNED, value, out);
    1843             :   } else {
    1844           0 :     uint64_t representation = static_cast<uint64_t>(-(value + 1));
    1845           0 :     WriteTokenStart(MajorType::NEGATIVE, representation, out);
    1846             :   }
    1847           0 : }
    1848             : 
    1849           0 : void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) {
    1850             :   uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
    1851           0 :   WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
    1852             :   // When emitting UTF16 characters, we always write the least significant byte
    1853             :   // first; this is because it's the native representation for X86.
    1854             :   // TODO(johannes): Implement a more efficient thing here later, e.g.
    1855             :   // casting *iff* the machine has this byte order.
    1856             :   // The wire format for UTF16 chars will probably remain the same
    1857             :   // (least significant byte first) since this way we can have
    1858             :   // golden files, unittests, etc. that port easily and universally.
    1859             :   // See also:
    1860             :   // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1861           0 :   for (const uint16_t two_bytes : in) {
    1862           0 :     out->push_back(two_bytes);
    1863           0 :     out->push_back(two_bytes >> 8);
    1864             :   }
    1865           0 : }
    1866             : 
    1867           0 : void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) {
    1868             :   WriteTokenStart(MajorType::STRING, static_cast<uint64_t>(in.size_bytes()),
    1869           0 :                   out);
    1870             :   out->insert(out->end(), in.begin(), in.end());
    1871           0 : }
    1872             : 
    1873           0 : void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) {
    1874           0 :   out->push_back(kExpectedConversionToBase64Tag);
    1875           0 :   uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
    1876           0 :   WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
    1877             :   out->insert(out->end(), in.begin(), in.end());
    1878           0 : }
    1879             : 
    1880             : // A double is encoded with a specific initial byte
    1881             : // (kInitialByteForDouble) plus the 64 bits of payload for its value.
    1882             : constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t);
    1883             : 
    1884             : // An envelope is encoded with a specific initial byte
    1885             : // (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32
    1886             : // bit wide length, plus a 32 bit length for that string.
    1887             : constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t);
    1888             : 
    1889           0 : void EncodeDouble(double value, std::vector<uint8_t>* out) {
    1890             :   // The additional_info=27 indicates 64 bits for the double follow.
    1891             :   // See RFC 7049 Section 2.3, Table 1.
    1892           0 :   out->push_back(kInitialByteForDouble);
    1893             :   union {
    1894             :     double from_double;
    1895             :     uint64_t to_uint64;
    1896             :   } reinterpret;
    1897             :   reinterpret.from_double = value;
    1898           0 :   WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out);
    1899           0 : }
    1900             : 
    1901           0 : void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) {
    1902             :   assert(byte_size_pos_ == 0);
    1903           0 :   out->push_back(kInitialByteForEnvelope);
    1904           0 :   out->push_back(kInitialByteFor32BitLengthByteString);
    1905           0 :   byte_size_pos_ = out->size();
    1906           0 :   out->resize(out->size() + sizeof(uint32_t));
    1907           0 : }
    1908             : 
    1909           0 : bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) {
    1910             :   assert(byte_size_pos_ != 0);
    1911             :   // The byte size is the size of the payload, that is, all the
    1912             :   // bytes that were written past the byte size position itself.
    1913           0 :   uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t));
    1914             :   // We store exactly 4 bytes, so at most INT32MAX, with most significant
    1915             :   // byte first.
    1916           0 :   if (byte_size > std::numeric_limits<uint32_t>::max()) return false;
    1917           0 :   for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0;
    1918             :        --shift_bytes) {
    1919           0 :     (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8));
    1920             :   }
    1921             :   return true;
    1922             : }
    1923             : 
    1924             : namespace {
    1925           0 : class JSONToCBOREncoder : public JSONParserHandler {
    1926             :  public:
    1927             :   JSONToCBOREncoder(std::vector<uint8_t>* out, Status* status)
    1928           0 :       : out_(out), status_(status) {
    1929           0 :     *status_ = Status();
    1930             :   }
    1931             : 
    1932           0 :   void HandleObjectBegin() override {
    1933           0 :     envelopes_.emplace_back();
    1934           0 :     envelopes_.back().EncodeStart(out_);
    1935           0 :     out_->push_back(kInitialByteIndefiniteLengthMap);
    1936           0 :   }
    1937             : 
    1938           0 :   void HandleObjectEnd() override {
    1939           0 :     out_->push_back(kStopByte);
    1940             :     assert(!envelopes_.empty());
    1941           0 :     envelopes_.back().EncodeStop(out_);
    1942             :     envelopes_.pop_back();
    1943           0 :   }
    1944             : 
    1945           0 :   void HandleArrayBegin() override {
    1946           0 :     envelopes_.emplace_back();
    1947           0 :     envelopes_.back().EncodeStart(out_);
    1948           0 :     out_->push_back(kInitialByteIndefiniteLengthArray);
    1949           0 :   }
    1950             : 
    1951           0 :   void HandleArrayEnd() override {
    1952           0 :     out_->push_back(kStopByte);
    1953             :     assert(!envelopes_.empty());
    1954           0 :     envelopes_.back().EncodeStop(out_);
    1955             :     envelopes_.pop_back();
    1956           0 :   }
    1957             : 
    1958           0 :   void HandleString16(std::vector<uint16_t> chars) override {
    1959           0 :     for (uint16_t ch : chars) {
    1960           0 :       if (ch >= 0x7f) {
    1961             :         // If there's at least one non-7bit character, we encode as UTF16.
    1962           0 :         EncodeString16(span<uint16_t>(chars.data(), chars.size()), out_);
    1963           0 :         return;
    1964             :       }
    1965             :     }
    1966             :     std::vector<uint8_t> sevenbit_chars(chars.begin(), chars.end());
    1967           0 :     EncodeString8(span<uint8_t>(sevenbit_chars.data(), sevenbit_chars.size()),
    1968           0 :                   out_);
    1969             :   }
    1970             : 
    1971           0 :   void HandleBinary(std::vector<uint8_t> bytes) override {
    1972           0 :     EncodeBinary(span<uint8_t>(bytes.data(), bytes.size()), out_);
    1973           0 :   }
    1974             : 
    1975           0 :   void HandleDouble(double value) override { EncodeDouble(value, out_); }
    1976             : 
    1977           0 :   void HandleInt32(int32_t value) override { EncodeInt32(value, out_); }
    1978             : 
    1979           0 :   void HandleBool(bool value) override {
    1980             :     // See RFC 7049 Section 2.3, Table 2.
    1981           0 :     out_->push_back(value ? kEncodedTrue : kEncodedFalse);
    1982           0 :   }
    1983             : 
    1984           0 :   void HandleNull() override {
    1985             :     // See RFC 7049 Section 2.3, Table 2.
    1986           0 :     out_->push_back(kEncodedNull);
    1987           0 :   }
    1988             : 
    1989           0 :   void HandleError(Status error) override {
    1990             :     assert(!error.ok());
    1991           0 :     *status_ = error;
    1992           0 :     out_->clear();
    1993           0 :   }
    1994             : 
    1995             :  private:
    1996             :   std::vector<uint8_t>* out_;
    1997             :   std::vector<EnvelopeEncoder> envelopes_;
    1998             :   Status* status_;
    1999             : };
    2000             : }  // namespace
    2001             : 
    2002           0 : std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder(
    2003             :     std::vector<uint8_t>* out, Status* status) {
    2004           0 :   return std::unique_ptr<JSONParserHandler>(new JSONToCBOREncoder(out, status));
    2005             : }
    2006             : 
    2007             : namespace {
    2008             : // Below are three parsing routines for CBOR, which cover enough
    2009             : // to roundtrip JSON messages.
    2010             : bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer,
    2011             :               JSONParserHandler* out);
    2012             : bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer,
    2013             :                 JSONParserHandler* out);
    2014             : bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer,
    2015             :                 JSONParserHandler* out);
    2016             : 
    2017           0 : void ParseUTF16String(CBORTokenizer* tokenizer, JSONParserHandler* out) {
    2018             :   std::vector<uint16_t> value;
    2019             :   span<uint8_t> rep = tokenizer->GetString16WireRep();
    2020           0 :   for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2)
    2021           0 :     value.push_back((rep[ii + 1] << 8) | rep[ii]);
    2022           0 :   out->HandleString16(std::move(value));
    2023           0 :   tokenizer->Next();
    2024           0 : }
    2025             : 
    2026             : // For now this method only covers US-ASCII. Later, we may allow UTF8.
    2027           0 : bool ParseASCIIString(CBORTokenizer* tokenizer, JSONParserHandler* out) {
    2028             :   assert(tokenizer->TokenTag() == CBORTokenTag::STRING8);
    2029             :   std::vector<uint16_t> value16;
    2030           0 :   for (uint8_t ch : tokenizer->GetString8()) {
    2031             :     // We only accept us-ascii (7 bit) strings here. Other strings must
    2032             :     // be encoded with 16 bit (the BYTE_STRING case).
    2033           0 :     if (ch >= 0x7f) {
    2034             :       out->HandleError(
    2035           0 :           Status{Error::CBOR_STRING8_MUST_BE_7BIT, tokenizer->Status().pos});
    2036           0 :       return false;
    2037             :     }
    2038           0 :     value16.push_back(ch);
    2039             :   }
    2040           0 :   out->HandleString16(std::move(value16));
    2041           0 :   tokenizer->Next();
    2042           0 :   return true;
    2043             : }
    2044             : 
    2045           0 : bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer,
    2046             :                 JSONParserHandler* out) {
    2047           0 :   if (stack_depth > kStackLimit) {
    2048             :     out->HandleError(
    2049           0 :         Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
    2050           0 :     return false;
    2051             :   }
    2052             :   // Skip past the envelope to get to what's inside.
    2053           0 :   if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
    2054             :     tokenizer->EnterEnvelope();
    2055           0 :   switch (tokenizer->TokenTag()) {
    2056             :     case CBORTokenTag::ERROR_VALUE:
    2057           0 :       out->HandleError(tokenizer->Status());
    2058           0 :       return false;
    2059             :     case CBORTokenTag::DONE:
    2060             :       out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
    2061           0 :                               tokenizer->Status().pos});
    2062           0 :       return false;
    2063             :     case CBORTokenTag::TRUE_VALUE:
    2064           0 :       out->HandleBool(true);
    2065           0 :       tokenizer->Next();
    2066           0 :       return true;
    2067             :     case CBORTokenTag::FALSE_VALUE:
    2068           0 :       out->HandleBool(false);
    2069           0 :       tokenizer->Next();
    2070           0 :       return true;
    2071             :     case CBORTokenTag::NULL_VALUE:
    2072           0 :       out->HandleNull();
    2073           0 :       tokenizer->Next();
    2074           0 :       return true;
    2075             :     case CBORTokenTag::INT32:
    2076           0 :       out->HandleInt32(tokenizer->GetInt32());
    2077           0 :       tokenizer->Next();
    2078           0 :       return true;
    2079             :     case CBORTokenTag::DOUBLE:
    2080           0 :       out->HandleDouble(tokenizer->GetDouble());
    2081           0 :       tokenizer->Next();
    2082           0 :       return true;
    2083             :     case CBORTokenTag::STRING8:
    2084           0 :       return ParseASCIIString(tokenizer, out);
    2085             :     case CBORTokenTag::STRING16:
    2086           0 :       ParseUTF16String(tokenizer, out);
    2087           0 :       return true;
    2088             :     case CBORTokenTag::BINARY: {
    2089             :       span<uint8_t> binary = tokenizer->GetBinary();
    2090           0 :       out->HandleBinary(std::vector<uint8_t>(binary.begin(), binary.end()));
    2091           0 :       tokenizer->Next();
    2092             :       return true;
    2093             :     }
    2094             :     case CBORTokenTag::MAP_START:
    2095           0 :       return ParseMap(stack_depth + 1, tokenizer, out);
    2096             :     case CBORTokenTag::ARRAY_START:
    2097           0 :       return ParseArray(stack_depth + 1, tokenizer, out);
    2098             :     default:
    2099             :       out->HandleError(
    2100           0 :           Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos});
    2101           0 :       return false;
    2102             :   }
    2103             : }
    2104             : 
    2105             : // |bytes| must start with the indefinite length array byte, so basically,
    2106             : // ParseArray may only be called after an indefinite length array has been
    2107             : // detected.
    2108           0 : bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer,
    2109             :                 JSONParserHandler* out) {
    2110             :   assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
    2111           0 :   tokenizer->Next();
    2112           0 :   out->HandleArrayBegin();
    2113           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
    2114           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
    2115             :       out->HandleError(
    2116           0 :           Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
    2117           0 :       return false;
    2118             :     }
    2119           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2120           0 :       out->HandleError(tokenizer->Status());
    2121           0 :       return false;
    2122             :     }
    2123             :     // Parse value.
    2124           0 :     if (!ParseValue(stack_depth, tokenizer, out)) return false;
    2125             :   }
    2126           0 :   out->HandleArrayEnd();
    2127           0 :   tokenizer->Next();
    2128           0 :   return true;
    2129             : }
    2130             : 
    2131             : // |bytes| must start with the indefinite length array byte, so basically,
    2132             : // ParseArray may only be called after an indefinite length array has been
    2133             : // detected.
    2134           0 : bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer,
    2135             :               JSONParserHandler* out) {
    2136             :   assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START);
    2137           0 :   out->HandleObjectBegin();
    2138           0 :   tokenizer->Next();
    2139           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
    2140           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
    2141             :       out->HandleError(
    2142           0 :           Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
    2143           0 :       return false;
    2144             :     }
    2145           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2146           0 :       out->HandleError(tokenizer->Status());
    2147           0 :       return false;
    2148             :     }
    2149             :     // Parse key.
    2150           0 :     if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
    2151           0 :       if (!ParseASCIIString(tokenizer, out)) return false;
    2152           0 :     } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
    2153           0 :       ParseUTF16String(tokenizer, out);
    2154             :     } else {
    2155             :       out->HandleError(
    2156           0 :           Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos});
    2157           0 :       return false;
    2158             :     }
    2159             :     // Parse value.
    2160           0 :     if (!ParseValue(stack_depth, tokenizer, out)) return false;
    2161             :   }
    2162           0 :   out->HandleObjectEnd();
    2163           0 :   tokenizer->Next();
    2164           0 :   return true;
    2165             : }
    2166             : }  // namespace
    2167             : 
    2168           0 : void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out) {
    2169           0 :   if (bytes.empty()) {
    2170           0 :     json_out->HandleError(Status{Error::CBOR_NO_INPUT, 0});
    2171           0 :     return;
    2172             :   }
    2173           0 :   if (bytes[0] != kInitialByteForEnvelope) {
    2174           0 :     json_out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0});
    2175           0 :     return;
    2176             :   }
    2177             :   CBORTokenizer tokenizer(bytes);
    2178           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2179           0 :     json_out->HandleError(tokenizer.Status());
    2180           0 :     return;
    2181             :   }
    2182             :   // We checked for the envelope start byte above, so the tokenizer
    2183             :   // must agree here, since it's not an error.
    2184             :   assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
    2185             :   tokenizer.EnterEnvelope();
    2186           0 :   if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
    2187             :     json_out->HandleError(
    2188           0 :         Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
    2189           0 :     return;
    2190             :   }
    2191           0 :   if (!ParseMap(/*stack_depth=*/1, &tokenizer, json_out)) return;
    2192           0 :   if (tokenizer.TokenTag() == CBORTokenTag::DONE) return;
    2193           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2194           0 :     json_out->HandleError(tokenizer.Status());
    2195           0 :     return;
    2196             :   }
    2197             :   json_out->HandleError(
    2198           0 :       Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos});
    2199             : }
    2200             : 
    2201           0 : CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) {
    2202           0 :   ReadNextToken(/*enter_envelope=*/false);
    2203           0 : }
    2204           0 : CBORTokenizer::~CBORTokenizer() {}
    2205             : 
    2206           0 : CBORTokenTag CBORTokenizer::TokenTag() const { return token_tag_; }
    2207             : 
    2208           0 : void CBORTokenizer::Next() {
    2209           0 :   if (token_tag_ == CBORTokenTag::ERROR_VALUE || token_tag_ == CBORTokenTag::DONE)
    2210           0 :     return;
    2211           0 :   ReadNextToken(/*enter_envelope=*/false);
    2212             : }
    2213             : 
    2214           0 : void CBORTokenizer::EnterEnvelope() {
    2215             :   assert(token_tag_ == CBORTokenTag::ENVELOPE);
    2216           0 :   ReadNextToken(/*enter_envelope=*/true);
    2217           0 : }
    2218             : 
    2219           0 : Status CBORTokenizer::Status() const { return status_; }
    2220             : 
    2221           0 : int32_t CBORTokenizer::GetInt32() const {
    2222             :   assert(token_tag_ == CBORTokenTag::INT32);
    2223             :   // The range checks happen in ::ReadNextToken().
    2224             :   return static_cast<uint32_t>(
    2225           0 :       token_start_type_ == MajorType::UNSIGNED
    2226             :           ? token_start_internal_value_
    2227           0 :           : -static_cast<int64_t>(token_start_internal_value_) - 1);
    2228             : }
    2229             : 
    2230           0 : double CBORTokenizer::GetDouble() const {
    2231             :   assert(token_tag_ == CBORTokenTag::DOUBLE);
    2232             :   union {
    2233             :     uint64_t from_uint64;
    2234             :     double to_double;
    2235             :   } reinterpret;
    2236             :   reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>(
    2237           0 :       bytes_.subspan(status_.pos + 1));
    2238           0 :   return reinterpret.to_double;
    2239             : }
    2240             : 
    2241           0 : span<uint8_t> CBORTokenizer::GetString8() const {
    2242             :   assert(token_tag_ == CBORTokenTag::STRING8);
    2243           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2244           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2245             : }
    2246             : 
    2247           0 : span<uint8_t> CBORTokenizer::GetString16WireRep() const {
    2248             :   assert(token_tag_ == CBORTokenTag::STRING16);
    2249           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2250           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2251             : }
    2252             : 
    2253           0 : span<uint8_t> CBORTokenizer::GetBinary() const {
    2254             :   assert(token_tag_ == CBORTokenTag::BINARY);
    2255           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2256           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2257             : }
    2258             : 
    2259           0 : void CBORTokenizer::ReadNextToken(bool enter_envelope) {
    2260           0 :   if (enter_envelope) {
    2261           0 :     status_.pos += kEncodedEnvelopeHeaderSize;
    2262             :   } else {
    2263             :     status_.pos =
    2264           0 :         status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_;
    2265             :   }
    2266           0 :   status_.error = Error::OK;
    2267           0 :   if (status_.pos >= bytes_.size()) {
    2268           0 :     token_tag_ = CBORTokenTag::DONE;
    2269           0 :     return;
    2270             :   }
    2271           0 :   switch (bytes_[status_.pos]) {
    2272             :     case kStopByte:
    2273             :       SetToken(CBORTokenTag::STOP, 1);
    2274             :       return;
    2275             :     case kInitialByteIndefiniteLengthMap:
    2276             :       SetToken(CBORTokenTag::MAP_START, 1);
    2277             :       return;
    2278             :     case kInitialByteIndefiniteLengthArray:
    2279             :       SetToken(CBORTokenTag::ARRAY_START, 1);
    2280             :       return;
    2281             :     case kEncodedTrue:
    2282             :       SetToken(CBORTokenTag::TRUE_VALUE, 1);
    2283             :       return;
    2284             :     case kEncodedFalse:
    2285             :       SetToken(CBORTokenTag::FALSE_VALUE, 1);
    2286             :       return;
    2287             :     case kEncodedNull:
    2288             :       SetToken(CBORTokenTag::NULL_VALUE, 1);
    2289             :       return;
    2290             :     case kExpectedConversionToBase64Tag: {  // BINARY
    2291             :       int8_t bytes_read =
    2292             :           ReadTokenStart(bytes_.subspan(status_.pos + 1), &token_start_type_,
    2293           0 :                          &token_start_internal_value_);
    2294           0 :       int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_;
    2295           0 :       if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
    2296           0 :           status_.pos + token_byte_length > bytes_.size()) {
    2297             :         SetError(Error::CBOR_INVALID_BINARY);
    2298             :         return;
    2299             :       }
    2300             :       SetToken(CBORTokenTag::BINARY,
    2301             :                static_cast<std::ptrdiff_t>(token_byte_length));
    2302             :       return;
    2303             :     }
    2304             :     case kInitialByteForDouble: {  // DOUBLE
    2305           0 :       if (status_.pos + kEncodedDoubleSize > bytes_.size()) {
    2306             :         SetError(Error::CBOR_INVALID_DOUBLE);
    2307             :         return;
    2308             :       }
    2309             :       SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize);
    2310             :       return;
    2311             :     }
    2312             :     case kInitialByteForEnvelope: {  // ENVELOPE
    2313           0 :       if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) {
    2314             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2315             :         return;
    2316             :       }
    2317             :       // The envelope must be a byte string with 32 bit length.
    2318           0 :       if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) {
    2319             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2320             :         return;
    2321             :       }
    2322             :       // Read the length of the byte string.
    2323             :       token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>(
    2324           0 :           bytes_.subspan(status_.pos + 2));
    2325             :       // Make sure the payload is contained within the message.
    2326           0 :       if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize +
    2327           0 :               status_.pos >
    2328             :           static_cast<std::size_t>(bytes_.size())) {
    2329             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2330             :         return;
    2331             :       }
    2332           0 :       auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2333             :       SetToken(CBORTokenTag::ENVELOPE,
    2334           0 :                kEncodedEnvelopeHeaderSize + length);
    2335             :       return;
    2336             :     }
    2337             :     default: {
    2338             :       span<uint8_t> remainder =
    2339           0 :           bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
    2340             :       assert(!remainder.empty());
    2341             :       int8_t token_start_length = ReadTokenStart(remainder, &token_start_type_,
    2342           0 :                                                  &token_start_internal_value_);
    2343           0 :       bool success = token_start_length != -1;
    2344           0 :       switch (token_start_type_) {
    2345             :         case MajorType::UNSIGNED:  // INT32.
    2346           0 :           if (!success || std::numeric_limits<int32_t>::max() <
    2347             :                               token_start_internal_value_) {
    2348             :             SetError(Error::CBOR_INVALID_INT32);
    2349           0 :             return;
    2350             :           }
    2351           0 :           SetToken(CBORTokenTag::INT32, token_start_length);
    2352             :           return;
    2353             :         case MajorType::NEGATIVE:  // INT32.
    2354           0 :           if (!success ||
    2355             :               std::numeric_limits<int32_t>::min() >
    2356           0 :                   -static_cast<int64_t>(token_start_internal_value_) - 1) {
    2357             :             SetError(Error::CBOR_INVALID_INT32);
    2358             :             return;
    2359             :           }
    2360           0 :           SetToken(CBORTokenTag::INT32, token_start_length);
    2361             :           return;
    2362             :         case MajorType::STRING: {  // STRING8.
    2363           0 :           if (!success || remainder.size() < static_cast<int64_t>(
    2364             :                                                  token_start_internal_value_)) {
    2365             :             SetError(Error::CBOR_INVALID_STRING8);
    2366             :             return;
    2367             :           }
    2368           0 :           auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2369           0 :           SetToken(CBORTokenTag::STRING8, token_start_length + length);
    2370             :           return;
    2371             :         }
    2372             :         case MajorType::BYTE_STRING: {  // STRING16.
    2373           0 :           if (!success ||
    2374           0 :               remainder.size() <
    2375           0 :                   static_cast<int64_t>(token_start_internal_value_) ||
    2376             :               // Must be divisible by 2 since UTF16 is 2 bytes per character.
    2377           0 :               token_start_internal_value_ & 1) {
    2378             :             SetError(Error::CBOR_INVALID_STRING16);
    2379             :             return;
    2380             :           }
    2381           0 :           auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2382           0 :           SetToken(CBORTokenTag::STRING16, token_start_length + length);
    2383             :           return;
    2384             :         }
    2385             :         case MajorType::ARRAY:
    2386             :         case MajorType::MAP:
    2387             :         case MajorType::TAG:
    2388             :         case MajorType::SIMPLE_VALUE:
    2389             :           SetError(Error::CBOR_UNSUPPORTED_VALUE);
    2390             :           return;
    2391             :       }
    2392             :     }
    2393             :   }
    2394             : }
    2395             : 
    2396           0 : void CBORTokenizer::SetToken(CBORTokenTag token_tag,
    2397             :                              std::ptrdiff_t token_byte_length) {
    2398           0 :   token_tag_ = token_tag;
    2399           0 :   token_byte_length_ = token_byte_length;
    2400           0 : }
    2401             : 
    2402           0 : void CBORTokenizer::SetError(Error error) {
    2403           0 :   token_tag_ = CBORTokenTag::ERROR_VALUE;
    2404           0 :   status_.error = error;
    2405           0 : }
    2406             : 
    2407             : #if 0
    2408             : void DumpCBOR(span<uint8_t> cbor) {
    2409             :   std::string indent;
    2410             :   CBORTokenizer tokenizer(cbor);
    2411             :   while (true) {
    2412             :     fprintf(stderr, "%s", indent.c_str());
    2413             :     switch (tokenizer.TokenTag()) {
    2414             :       case CBORTokenTag::ERROR_VALUE:
    2415             :         fprintf(stderr, "ERROR {status.error=%d, status.pos=%ld}\n",
    2416             :                tokenizer.Status().error, tokenizer.Status().pos);
    2417             :         return;
    2418             :       case CBORTokenTag::DONE:
    2419             :         fprintf(stderr, "DONE\n");
    2420             :         return;
    2421             :       case CBORTokenTag::TRUE_VALUE:
    2422             :         fprintf(stderr, "TRUE_VALUE\n");
    2423             :         break;
    2424             :       case CBORTokenTag::FALSE_VALUE:
    2425             :         fprintf(stderr, "FALSE_VALUE\n");
    2426             :         break;
    2427             :       case CBORTokenTag::NULL_VALUE:
    2428             :         fprintf(stderr, "NULL_VALUE\n");
    2429             :         break;
    2430             :       case CBORTokenTag::INT32:
    2431             :         fprintf(stderr, "INT32 [%d]\n", tokenizer.GetInt32());
    2432             :         break;
    2433             :       case CBORTokenTag::DOUBLE:
    2434             :         fprintf(stderr, "DOUBLE [%lf]\n", tokenizer.GetDouble());
    2435             :         break;
    2436             :       case CBORTokenTag::STRING8: {
    2437             :         span<uint8_t> v = tokenizer.GetString8();
    2438             :         std::string t(v.begin(), v.end());
    2439             :         fprintf(stderr, "STRING8 [%s]\n", t.c_str());
    2440             :         break;
    2441             :       }
    2442             :       case CBORTokenTag::STRING16: {
    2443             :         span<uint8_t> v = tokenizer.GetString16WireRep();
    2444             :         std::string t(v.begin(), v.end());
    2445             :         fprintf(stderr, "STRING16 [%s]\n", t.c_str());
    2446             :         break;
    2447             :       }
    2448             :       case CBORTokenTag::BINARY: {
    2449             :         span<uint8_t> v = tokenizer.GetBinary();
    2450             :         std::string t(v.begin(), v.end());
    2451             :         fprintf(stderr, "BINARY [%s]\n", t.c_str());
    2452             :         break;
    2453             :       }
    2454             :       case CBORTokenTag::MAP_START:
    2455             :         fprintf(stderr, "MAP_START\n");
    2456             :         indent += "  ";
    2457             :         break;
    2458             :       case CBORTokenTag::ARRAY_START:
    2459             :         fprintf(stderr, "ARRAY_START\n");
    2460             :         indent += "  ";
    2461             :         break;
    2462             :       case CBORTokenTag::STOP:
    2463             :         fprintf(stderr, "STOP\n");
    2464             :         indent.erase(0, 2);
    2465             :         break;
    2466             :       case CBORTokenTag::ENVELOPE:
    2467             :         fprintf(stderr, "ENVELOPE\n");
    2468             :         tokenizer.EnterEnvelope();
    2469             :         continue;
    2470             :     }
    2471             :     tokenizer.Next();
    2472             :   }
    2473             : }
    2474             : #endif
    2475             : 
    2476             : 
    2477             : } // namespace v8_inspector
    2478             : } // namespace protocol
    2479             : 

Generated by: LCOV version 1.10