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: 474 1434 33.1 %
Date: 2019-03-21 Functions: 94 244 38.5 %

          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      309822 : ErrorSupport::ErrorSupport() { }
      27      154911 : ErrorSupport::~ErrorSupport() { }
      28             : 
      29      204842 : void ErrorSupport::setName(const char* name)
      30             : {
      31      409684 :     setName(String(name));
      32      204842 : }
      33             : 
      34      205187 : void ErrorSupport::setName(const String& name)
      35             : {
      36             :     DCHECK(m_path.size());
      37      205187 :     m_path[m_path.size() - 1] = name;
      38      205187 : }
      39             : 
      40      143964 : void ErrorSupport::push()
      41             : {
      42      431892 :     m_path.push_back(String());
      43      143964 : }
      44             : 
      45      143964 : void ErrorSupport::pop()
      46             : {
      47             :     m_path.pop_back();
      48      143964 : }
      49             : 
      50          68 : void ErrorSupport::addError(const char* error)
      51             : {
      52         136 :     addError(String(error));
      53          68 : }
      54             : 
      55          68 : void ErrorSupport::addError(const String& error)
      56             : {
      57          68 :     StringBuilder builder;
      58         214 :     for (size_t i = 0; i < m_path.size(); ++i) {
      59          73 :         if (i)
      60             :             StringUtil::builderAppend(builder, '.');
      61             :         StringUtil::builderAppend(builder, m_path[i]);
      62             :     }
      63         136 :     StringUtil::builderAppend(builder, ": ");
      64             :     StringUtil::builderAppend(builder, error);
      65         136 :     m_errors.push_back(StringUtil::builderToString(builder));
      66          68 : }
      67             : 
      68      143964 : bool ErrorSupport::hasErrors()
      69             : {
      70      143964 :     return !!m_errors.size();
      71             : }
      72             : 
      73          59 : String ErrorSupport::errors()
      74             : {
      75          59 :     StringBuilder builder;
      76         195 :     for (size_t i = 0; i < m_errors.size(); ++i) {
      77          68 :         if (i)
      78          18 :             StringUtil::builderAppend(builder, "; ");
      79             :         StringUtil::builderAppend(builder, m_errors[i]);
      80             :     }
      81          59 :     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  1243572448 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
     106             : {
     107  1243572448 :     switch (c) {
     108           0 :     case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
     109           0 :     case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
     110    43624854 :     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      145694 :     case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
     114    36896804 :     case '"': StringUtil::builderAppend(*dst, "\\\""); break;
     115             :     default:
     116             :         return false;
     117             :     }
     118             :     return true;
     119             : }
     120             : 
     121             : const char hexDigits[17] = "0123456789ABCDEF";
     122             : 
     123     2250142 : void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
     124             : {
     125     4500284 :     StringUtil::builderAppend(*dst, "\\u");
     126    20251278 :     for (size_t i = 0; i < 4; ++i) {
     127     9000568 :         uint16_t c = hexDigits[(number & 0xF000) >> 12];
     128             :         StringUtil::builderAppend(*dst, c);
     129     9000568 :         number <<= 4;
     130             :     }
     131     2250142 : }
     132             : 
     133             : template <typename Char>
     134    49487140 : void escapeStringForJSONInternal(const Char* str, unsigned len,
     135             :                                  StringBuilder* dst)
     136             : {
     137  2536632036 :     for (unsigned i = 0; i < len; ++i) {
     138  1243572448 :         Char c = str[i];
     139  1243572448 :         if (escapeChar(c, dst))
     140             :             continue;
     141  1203238772 :         if (c < 32 || c > 126) {
     142     2250142 :             appendUnsignedAsHex(c, dst);
     143             :         } else {
     144             :             StringUtil::builderAppend(*dst, c);
     145             :         }
     146             :     }
     147    49487140 : }
     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, cbor::CBORTokenizer* tokenizer);
     156             : std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
     157             : std::unique_ptr<Value> parseValue(int32_t stack_depth, cbor::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, cbor::CBORTokenizer* tokenizer) {
     163             :   DCHECK(tokenizer->TokenTag() == cbor::CBORTokenTag::ARRAY_START);
     164             :   tokenizer->Next();
     165           0 :   auto list = ListValue::create();
     166           0 :   while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) {
     167             :     // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY
     168           0 :     if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) return nullptr;
     169           0 :     if (tokenizer->TokenTag() == cbor::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             :   tokenizer->Next();
     176             :   return list;
     177             : }
     178             : 
     179           0 : std::unique_ptr<Value> parseValue(
     180             :     int32_t stack_depth, cbor::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() == cbor::CBORTokenTag::ENVELOPE)
     185             :     tokenizer->EnterEnvelope();
     186           0 :   switch (tokenizer->TokenTag()) {
     187             :     case cbor::CBORTokenTag::ERROR_VALUE:
     188             :       return nullptr;
     189             :     case cbor::CBORTokenTag::DONE:
     190             :       // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE
     191             :       return nullptr;
     192             :     case cbor::CBORTokenTag::TRUE_VALUE: {
     193             :       std::unique_ptr<Value> value = FundamentalValue::create(true);
     194             :       tokenizer->Next();
     195             :       return value;
     196             :     }
     197             :     case cbor::CBORTokenTag::FALSE_VALUE: {
     198             :       std::unique_ptr<Value> value = FundamentalValue::create(false);
     199             :       tokenizer->Next();
     200             :       return value;
     201             :     }
     202             :     case cbor::CBORTokenTag::NULL_VALUE: {
     203             :       std::unique_ptr<Value> value = FundamentalValue::null();
     204             :       tokenizer->Next();
     205             :       return value;
     206             :     }
     207             :     case cbor::CBORTokenTag::INT32: {
     208             :       std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32());
     209             :       tokenizer->Next();
     210             :       return value;
     211             :     }
     212             :     case cbor::CBORTokenTag::DOUBLE: {
     213             :       std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble());
     214             :       tokenizer->Next();
     215             :       return value;
     216             :     }
     217             :     case cbor::CBORTokenTag::STRING8: {
     218             :       span<uint8_t> str = tokenizer->GetString8();
     219             :       std::unique_ptr<Value> value =
     220           0 :           StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
     221             :       tokenizer->Next();
     222             :       return value;
     223             :     }
     224             :     case cbor::CBORTokenTag::STRING16: {
     225             :       span<uint8_t> wire = tokenizer->GetString16WireRep();
     226             :       DCHECK_EQ(wire.size() & 1, 0);
     227           0 :       std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF16(
     228           0 :           reinterpret_cast<const uint16_t*>(wire.data()), wire.size() / 2));
     229             :       tokenizer->Next();
     230             :       return value;
     231             :     }
     232             :     case cbor::CBORTokenTag::BINARY: {
     233             :       span<uint8_t> payload = tokenizer->GetBinary();
     234             :       tokenizer->Next();
     235           0 :       return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size()));
     236             :     }
     237             :     case cbor::CBORTokenTag::MAP_START:
     238           0 :       return parseMap(stack_depth + 1, tokenizer);
     239             :     case cbor::CBORTokenTag::ARRAY_START:
     240           0 :       return parseArray(stack_depth + 1, tokenizer);
     241             :     default:
     242             :       // Error::CBOR_UNSUPPORTED_VALUE
     243             :       return nullptr;
     244             :   }
     245             : }
     246             : 
     247             : // |bytes| must start with the indefinite length array byte, so basically,
     248             : // ParseArray may only be called after an indefinite length array has been
     249             : // detected.
     250           0 : std::unique_ptr<DictionaryValue> parseMap(
     251             :     int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
     252           0 :   auto dict = DictionaryValue::create();
     253             :   tokenizer->Next();
     254           0 :   while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) {
     255           0 :     if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) {
     256             :       // Error::CBOR_UNEXPECTED_EOF_IN_MAP
     257           0 :       return nullptr;
     258             :     }
     259           0 :     if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
     260             :     // Parse key.
     261             :     String key;
     262           0 :     if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) {
     263             :       span<uint8_t> key_span = tokenizer->GetString8();
     264           0 :       key = StringUtil::fromUTF8(key_span.data(), key_span.size());
     265             :       tokenizer->Next();
     266           0 :     } else if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) {
     267             :       return nullptr;  // STRING16 not supported yet.
     268             :     } else {
     269             :       // Error::CBOR_INVALID_MAP_KEY
     270             :       return nullptr;
     271             :     }
     272             :     // Parse value.
     273           0 :     auto value = parseValue(stack_depth, tokenizer);
     274           0 :     if (!value) return nullptr;
     275           0 :     dict->setValue(key, std::move(value));
     276             :   }
     277             :   tokenizer->Next();
     278             :   return dict;
     279             : }
     280             : 
     281             : } // anonymous namespace
     282             : 
     283             : // static
     284           0 : std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) {
     285           0 :   span<uint8_t> bytes(data, size);
     286             : 
     287             :   // Error::CBOR_NO_INPUT
     288           0 :   if (bytes.empty()) return nullptr;
     289             : 
     290             :   // Error::CBOR_INVALID_START_BYTE
     291           0 :   if (bytes[0] != cbor::InitialByteForEnvelope()) return nullptr;
     292             : 
     293             :   cbor::CBORTokenizer tokenizer(bytes);
     294           0 :   if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
     295             : 
     296             :   // We checked for the envelope start byte above, so the tokenizer
     297             :   // must agree here, since it's not an error.
     298             :   DCHECK(tokenizer.TokenTag() == cbor::CBORTokenTag::ENVELOPE);
     299             :   tokenizer.EnterEnvelope();
     300             :   // Error::MAP_START_EXPECTED
     301           0 :   if (tokenizer.TokenTag() != cbor::CBORTokenTag::MAP_START) return nullptr;
     302           0 :   std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer);
     303           0 :   if (!result) return nullptr;
     304           0 :   if (tokenizer.TokenTag() == cbor::CBORTokenTag::DONE) return result;
     305           0 :   if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
     306             :   // Error::CBOR_TRAILING_JUNK
     307             :   return nullptr;
     308             : }
     309             : 
     310           0 : bool Value::asBoolean(bool*) const
     311             : {
     312           0 :     return false;
     313             : }
     314             : 
     315           0 : bool Value::asDouble(double*) const
     316             : {
     317           0 :     return false;
     318             : }
     319             : 
     320           5 : bool Value::asInteger(int*) const
     321             : {
     322           5 :     return false;
     323             : }
     324             : 
     325          33 : bool Value::asString(String*) const
     326             : {
     327          33 :     return false;
     328             : }
     329             : 
     330           0 : bool Value::asBinary(Binary*) const
     331             : {
     332           0 :     return false;
     333             : }
     334             : 
     335        2667 : void Value::writeJSON(StringBuilder* output) const
     336             : {
     337             :     DCHECK(m_type == TypeNull);
     338             :     StringUtil::builderAppend(*output, nullValueString, 4);
     339        2667 : }
     340             : 
     341           0 : void Value::writeBinary(std::vector<uint8_t>* bytes) const {
     342             :     DCHECK(m_type == TypeNull);
     343           0 :     bytes->push_back(cbor::EncodeNull());
     344           0 : }
     345             : 
     346        2667 : std::unique_ptr<Value> Value::clone() const
     347             : {
     348        2667 :     return Value::null();
     349             : }
     350             : 
     351      658929 : String Value::toJSONString() const
     352             : {
     353      658929 :     StringBuilder result;
     354             :     StringUtil::builderReserve(result, 512);
     355      658929 :     writeJSON(&result);
     356      658929 :     return StringUtil::builderToString(result);
     357             : }
     358             : 
     359      658533 : String Value::serializeToJSON() {
     360      658533 :     return toJSONString();
     361             : }
     362             : 
     363           0 : std::vector<uint8_t> Value::serializeToBinary() {
     364             :     std::vector<uint8_t> bytes;
     365           0 :     writeBinary(&bytes);
     366           0 :     return bytes;
     367             : }
     368             : 
     369       82351 : bool FundamentalValue::asBoolean(bool* output) const
     370             : {
     371       82351 :     if (type() != TypeBoolean)
     372             :         return false;
     373       82351 :     *output = m_boolValue;
     374       82351 :     return true;
     375             : }
     376             : 
     377          35 : bool FundamentalValue::asDouble(double* output) const
     378             : {
     379          35 :     if (type() == TypeDouble) {
     380           0 :         *output = m_doubleValue;
     381           0 :         return true;
     382             :     }
     383          35 :     if (type() == TypeInteger) {
     384          35 :         *output = m_integerValue;
     385          35 :         return true;
     386             :     }
     387             :     return false;
     388             : }
     389             : 
     390      348251 : bool FundamentalValue::asInteger(int* output) const
     391             : {
     392      348251 :     if (type() != TypeInteger)
     393             :         return false;
     394      348251 :     *output = m_integerValue;
     395      348251 :     return true;
     396             : }
     397             : 
     398    12230668 : void FundamentalValue::writeJSON(StringBuilder* output) const
     399             : {
     400             :     DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
     401    12230668 :     if (type() == TypeBoolean) {
     402    10229265 :         if (m_boolValue)
     403             :             StringUtil::builderAppend(*output, trueValueString, 4);
     404             :         else
     405             :             StringUtil::builderAppend(*output, falseValueString, 5);
     406     2001403 :     } else if (type() == TypeDouble) {
     407      303932 :         if (!std::isfinite(m_doubleValue)) {
     408             :             StringUtil::builderAppend(*output, nullValueString, 4);
     409             :             return;
     410             :         }
     411      151961 :         StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
     412     1849437 :     } else if (type() == TypeInteger) {
     413     3698874 :         StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
     414             :     }
     415             : }
     416             : 
     417           0 : void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const {
     418           0 :     switch (type()) {
     419             :     case TypeDouble:
     420           0 :         cbor::EncodeDouble(m_doubleValue, bytes);
     421           0 :         return;
     422             :     case TypeInteger:
     423           0 :         cbor::EncodeInt32(m_integerValue, bytes);
     424           0 :         return;
     425             :     case TypeBoolean:
     426           0 :         bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse());
     427           0 :         return;
     428             :     default:
     429             :         DCHECK(false);
     430             :     }
     431             : }
     432             : 
     433      167741 : std::unique_ptr<Value> FundamentalValue::clone() const
     434             : {
     435      167741 :     switch (type()) {
     436      144907 :     case TypeDouble: return FundamentalValue::create(m_doubleValue);
     437         837 :     case TypeInteger: return FundamentalValue::create(m_integerValue);
     438       21997 :     case TypeBoolean: return FundamentalValue::create(m_boolValue);
     439             :     default:
     440             :         DCHECK(false);
     441             :     }
     442             :     return nullptr;
     443             : }
     444             : 
     445      268785 : bool StringValue::asString(String* output) const
     446             : {
     447             :     *output = m_stringValue;
     448      268785 :     return true;
     449             : }
     450             : 
     451    16478558 : void StringValue::writeJSON(StringBuilder* output) const
     452             : {
     453             :     DCHECK(type() == TypeString);
     454    16478558 :     StringUtil::builderAppendQuotedString(*output, m_stringValue);
     455    16478558 : }
     456             : 
     457             : namespace {
     458             : // This routine distinguishes between the current encoding for a given
     459             : // string |s|, and calls encoding routines that will
     460             : // - Ensure that all ASCII strings end up being encoded as UTF8 in
     461             : //   the wire format - e.g., EncodeFromUTF16 will detect ASCII and
     462             : //   do the (trivial) transcode to STRING8 on the wire, but if it's
     463             : //   not ASCII it'll do STRING16.
     464             : // - Select a format that's cheap to convert to. E.g., we don't
     465             : //   have LATIN1 on the wire, so we call EncodeFromLatin1 which
     466             : //   transcodes to UTF8 if needed.
     467           0 : void EncodeString(const String& s, std::vector<uint8_t>* out) {
     468           0 :   if (StringUtil::CharacterCount(s) == 0) {
     469           0 :     cbor::EncodeString8(span<uint8_t>(nullptr, 0), out);  // Empty string.
     470             :   } else if (StringUtil::CharactersLatin1(s)) {
     471             :     cbor::EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s),
     472             :                                          StringUtil::CharacterCount(s)),
     473             :                            out);
     474           0 :   } else if (StringUtil::CharactersUTF16(s)) {
     475           0 :     cbor::EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s),
     476             :                                          StringUtil::CharacterCount(s)),
     477           0 :                           out);
     478             :   } else if (StringUtil::CharactersUTF8(s)) {
     479             :     cbor::EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s),
     480             :                                       StringUtil::CharacterCount(s)),
     481             :                         out);
     482             :   }
     483           0 : }
     484             : }  // namespace
     485             : 
     486           0 : void StringValue::writeBinary(std::vector<uint8_t>* bytes) const {
     487           0 :   EncodeString(m_stringValue, bytes);
     488           0 : }
     489             : 
     490       65960 : std::unique_ptr<Value> StringValue::clone() const
     491             : {
     492      131920 :     return StringValue::create(m_stringValue);
     493             : }
     494             : 
     495           0 : bool BinaryValue::asBinary(Binary* output) const
     496             : {
     497             :     *output = m_binaryValue;
     498           0 :     return true;
     499             : }
     500             : 
     501           0 : void BinaryValue::writeJSON(StringBuilder* output) const
     502             : {
     503             :     DCHECK(type() == TypeBinary);
     504           0 :     StringUtil::builderAppendQuotedString(*output, m_binaryValue.toBase64());
     505             : }
     506             : 
     507           0 : void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
     508             :     cbor::EncodeBinary(span<uint8_t>(m_binaryValue.data(),
     509           0 :                                      m_binaryValue.size()), bytes);
     510             : }
     511             : 
     512           0 : std::unique_ptr<Value> BinaryValue::clone() const
     513             : {
     514           0 :     return BinaryValue::create(m_binaryValue);
     515             : }
     516             : 
     517      328812 : void SerializedValue::writeJSON(StringBuilder* output) const
     518             : {
     519             :     DCHECK(type() == TypeSerialized);
     520      328812 :     StringUtil::builderAppend(*output, m_serializedJSON);
     521      328812 : }
     522             : 
     523           0 : void SerializedValue::writeBinary(std::vector<uint8_t>* output) const
     524             : {
     525             :     DCHECK(type() == TypeSerialized);
     526           0 :     output->insert(output->end(), m_serializedBinary.begin(), m_serializedBinary.end());
     527           0 : }
     528             : 
     529           0 : std::unique_ptr<Value> SerializedValue::clone() const
     530             : {
     531           0 :     return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary));
     532             : }
     533             : 
     534    15902112 : DictionaryValue::~DictionaryValue()
     535             : {
     536     7951056 : }
     537             : 
     538       26778 : void DictionaryValue::setBoolean(const String& name, bool value)
     539             : {
     540       26778 :     setValue(name, FundamentalValue::create(value));
     541       26778 : }
     542             : 
     543      168023 : void DictionaryValue::setInteger(const String& name, int value)
     544             : {
     545      168023 :     setValue(name, FundamentalValue::create(value));
     546      168023 : }
     547             : 
     548           5 : void DictionaryValue::setDouble(const String& name, double value)
     549             : {
     550           5 :     setValue(name, FundamentalValue::create(value));
     551           5 : }
     552             : 
     553      176504 : void DictionaryValue::setString(const String& name, const String& value)
     554             : {
     555      176504 :     setValue(name, StringValue::create(value));
     556      176504 : }
     557             : 
     558    32535669 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
     559             : {
     560    34061857 :     set(name, value);
     561    32535669 : }
     562             : 
     563       23426 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
     564             : {
     565       24335 :     set(name, value);
     566       23426 : }
     567             : 
     568          10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
     569             : {
     570          10 :     set(name, value);
     571          10 : }
     572             : 
     573        8341 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
     574             : {
     575             :     protocol::Value* value = get(name);
     576        8341 :     if (!value)
     577             :         return false;
     578         214 :     return value->asBoolean(output);
     579             : }
     580             : 
     581      187822 : bool DictionaryValue::getInteger(const String& name, int* output) const
     582             : {
     583             :     Value* value = get(name);
     584      187822 :     if (!value)
     585             :         return false;
     586      187758 :     return value->asInteger(output);
     587             : }
     588             : 
     589           0 : bool DictionaryValue::getDouble(const String& name, double* output) const
     590             : {
     591             :     Value* value = get(name);
     592           0 :     if (!value)
     593             :         return false;
     594           0 :     return value->asDouble(output);
     595             : }
     596             : 
     597         110 : bool DictionaryValue::getString(const String& name, String* output) const
     598             : {
     599             :     protocol::Value* value = get(name);
     600         110 :     if (!value)
     601             :         return false;
     602          90 :     return value->asString(output);
     603             : }
     604             : 
     605      173326 : DictionaryValue* DictionaryValue::getObject(const String& name) const
     606             : {
     607      173326 :     return DictionaryValue::cast(get(name));
     608             : }
     609             : 
     610           0 : protocol::ListValue* DictionaryValue::getArray(const String& name) const
     611             : {
     612           0 :     return ListValue::cast(get(name));
     613             : }
     614             : 
     615      654676 : protocol::Value* DictionaryValue::get(const String& name) const
     616             : {
     617             :     Dictionary::const_iterator it = m_data.find(name);
     618     1333965 :     if (it == m_data.end())
     619             :         return nullptr;
     620      310069 :     return it->second.get();
     621             : }
     622             : 
     623         120 : DictionaryValue::Entry DictionaryValue::at(size_t index) const
     624             : {
     625             :     const String key = m_order[index];
     626         120 :     return std::make_pair(key, m_data.find(key)->second.get());
     627             : }
     628             : 
     629        4475 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
     630             : {
     631        4475 :     bool result = defaultValue;
     632        4475 :     getBoolean(name, &result);
     633        4475 :     return result;
     634             : }
     635             : 
     636          39 : int DictionaryValue::integerProperty(const String& name, int defaultValue) const
     637             : {
     638          39 :     int result = defaultValue;
     639          39 :     getInteger(name, &result);
     640          39 :     return result;
     641             : }
     642             : 
     643           0 : double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
     644             : {
     645           0 :     double result = defaultValue;
     646           0 :     getDouble(name, &result);
     647           0 :     return result;
     648             : }
     649             : 
     650       18237 : void DictionaryValue::remove(const String& name)
     651             : {
     652             :     m_data.erase(name);
     653       18237 :     m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
     654       18237 : }
     655             : 
     656     7550561 : void DictionaryValue::writeJSON(StringBuilder* output) const
     657             : {
     658             :     StringUtil::builderAppend(*output, '{');
     659    73950255 :     for (size_t i = 0; i < m_order.size(); ++i) {
     660             :         Dictionary::const_iterator it = m_data.find(m_order[i]);
     661    33199847 :         CHECK(it != m_data.end());
     662    33199847 :         if (i)
     663             :             StringUtil::builderAppend(*output, ',');
     664    33199847 :         StringUtil::builderAppendQuotedString(*output, it->first);
     665             :         StringUtil::builderAppend(*output, ':');
     666    33199847 :         it->second->writeJSON(output);
     667             :     }
     668             :     StringUtil::builderAppend(*output, '}');
     669     7550561 : }
     670             : 
     671           0 : void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
     672           0 :     cbor::EnvelopeEncoder encoder;
     673           0 :     encoder.EncodeStart(bytes);
     674           0 :     bytes->push_back(cbor::EncodeIndefiniteLengthMapStart());
     675           0 :     for (size_t i = 0; i < m_order.size(); ++i) {
     676             :         const String& key = m_order[i];
     677             :         Dictionary::const_iterator value = m_data.find(key);
     678             :         DCHECK(value != m_data.cend() && value->second);
     679           0 :         EncodeString(key, bytes);
     680           0 :         value->second->writeBinary(bytes);
     681             :     }
     682           0 :     bytes->push_back(cbor::EncodeStop());
     683             :     encoder.EncodeStop(bytes);
     684           0 : }
     685             : 
     686        3010 : std::unique_ptr<Value> DictionaryValue::clone() const
     687             : {
     688        3010 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
     689       19618 :     for (size_t i = 0; i < m_order.size(); ++i) {
     690             :         String key = m_order[i];
     691             :         Dictionary::const_iterator value = m_data.find(key);
     692             :         DCHECK(value != m_data.cend() && value->second);
     693       16608 :         result->setValue(key, value->second->clone());
     694             :     }
     695        3010 :     return std::move(result);
     696             : }
     697             : 
     698     7139745 : DictionaryValue::DictionaryValue()
     699     7951056 :     : Value(TypeObject)
     700             : {
     701     7139745 : }
     702             : 
     703      810784 : ListValue::~ListValue()
     704             : {
     705      405392 : }
     706             : 
     707      404457 : void ListValue::writeJSON(StringBuilder* output) const
     708             : {
     709             :     StringUtil::builderAppend(*output, '[');
     710             :     bool first = true;
     711     3541404 :     for (const std::unique_ptr<protocol::Value>& value : m_data) {
     712     3136947 :         if (!first)
     713             :             StringUtil::builderAppend(*output, ',');
     714     3136947 :         value->writeJSON(output);
     715             :         first = false;
     716             :     }
     717             :     StringUtil::builderAppend(*output, ']');
     718      404457 : }
     719             : 
     720           0 : void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
     721           0 :     cbor::EnvelopeEncoder encoder;
     722           0 :     encoder.EncodeStart(bytes);
     723           0 :     bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart());
     724           0 :     for (size_t i = 0; i < m_data.size(); ++i) {
     725           0 :         m_data[i]->writeBinary(bytes);
     726             :     }
     727           0 :     bytes->push_back(cbor::EncodeStop());
     728             :     encoder.EncodeStop(bytes);
     729           0 : }
     730             : 
     731         270 : std::unique_ptr<Value> ListValue::clone() const
     732             : {
     733         270 :     std::unique_ptr<ListValue> result = ListValue::create();
     734         985 :     for (const std::unique_ptr<protocol::Value>& value : m_data)
     735        1430 :         result->pushValue(value->clone());
     736         270 :     return std::move(result);
     737             : }
     738             : 
     739      404452 : ListValue::ListValue()
     740      405392 :     : Value(TypeArray)
     741             : {
     742      404452 : }
     743             : 
     744     3136932 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
     745             : {
     746             :     DCHECK(value);
     747     3138507 :     m_data.push_back(std::move(value));
     748     3136932 : }
     749             : 
     750         345 : protocol::Value* ListValue::at(size_t index)
     751             : {
     752             :     DCHECK_LT(index, m_data.size());
     753         345 :     return m_data[index].get();
     754             : }
     755             : 
     756           0 : void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
     757             : {
     758           0 :     escapeStringForJSONInternal<uint8_t>(str, len, dst);
     759           0 : }
     760             : 
     761    49487140 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
     762             : {
     763    49487140 :     escapeStringForJSONInternal<uint16_t>(str, len, dst);
     764    49487140 : }
     765             : 
     766             : } // namespace v8_inspector
     767             : } // namespace protocol
     768             : 
     769             : 
     770             : // This file is generated by Object_cpp.template.
     771             : 
     772             : // Copyright 2016 The Chromium Authors. All rights reserved.
     773             : // Use of this source code is governed by a BSD-style license that can be
     774             : // found in the LICENSE file.
     775             : 
     776             : //#include "Object.h"
     777             : 
     778             : namespace v8_inspector {
     779             : namespace protocol {
     780             : 
     781           0 : std::unique_ptr<Object> Object::fromValue(protocol::Value* value, ErrorSupport* errors)
     782             : {
     783             :     protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
     784           0 :     if (!dictionary) {
     785           0 :         errors->addError("object expected");
     786             :         return nullptr;
     787             :     }
     788           0 :     dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
     789           0 :     return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
     790             : }
     791             : 
     792           0 : std::unique_ptr<protocol::DictionaryValue> Object::toValue() const
     793             : {
     794           0 :     return DictionaryValue::cast(m_object->clone());
     795             : }
     796             : 
     797           0 : std::unique_ptr<Object> Object::clone() const
     798             : {
     799           0 :     return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
     800             : }
     801             : 
     802           0 : Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }
     803             : 
     804           0 : Object::~Object() { }
     805             : 
     806             : } // namespace v8_inspector
     807             : } // namespace protocol
     808             : 
     809             : 
     810             : // This file is generated by DispatcherBase_cpp.template.
     811             : 
     812             : // Copyright 2016 The Chromium Authors. All rights reserved.
     813             : // Use of this source code is governed by a BSD-style license that can be
     814             : // found in the LICENSE file.
     815             : 
     816             : //#include "DispatcherBase.h"
     817             : //#include "Parser.h"
     818             : 
     819             : namespace v8_inspector {
     820             : namespace protocol {
     821             : 
     822             : // static
     823    10527586 : DispatchResponse DispatchResponse::OK()
     824             : {
     825             :     DispatchResponse result;
     826    10527586 :     result.m_status = kSuccess;
     827    10527586 :     result.m_errorCode = kParseError;
     828    10527586 :     return result;
     829             : }
     830             : 
     831             : // static
     832        1533 : DispatchResponse DispatchResponse::Error(const String& error)
     833             : {
     834             :     DispatchResponse result;
     835        1533 :     result.m_status = kError;
     836        1533 :     result.m_errorCode = kServerError;
     837             :     result.m_errorMessage = error;
     838        1533 :     return result;
     839             : }
     840             : 
     841             : // static
     842         133 : DispatchResponse DispatchResponse::InternalError()
     843             : {
     844             :     DispatchResponse result;
     845         133 :     result.m_status = kError;
     846         133 :     result.m_errorCode = kInternalError;
     847         266 :     result.m_errorMessage = "Internal error";
     848         133 :     return result;
     849             : }
     850             : 
     851             : // static
     852           0 : DispatchResponse DispatchResponse::InvalidParams(const String& error)
     853             : {
     854             :     DispatchResponse result;
     855           0 :     result.m_status = kError;
     856           0 :     result.m_errorCode = kInvalidParams;
     857             :     result.m_errorMessage = error;
     858           0 :     return result;
     859             : }
     860             : 
     861             : // static
     862           0 : DispatchResponse DispatchResponse::FallThrough()
     863             : {
     864             :     DispatchResponse result;
     865           0 :     result.m_status = kFallThrough;
     866           0 :     result.m_errorCode = kParseError;
     867           0 :     return result;
     868             : }
     869             : 
     870             : // static
     871             : const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";
     872             : 
     873      164742 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
     874             : 
     875      319524 : DispatcherBase::WeakPtr::~WeakPtr()
     876             : {
     877      164742 :     if (m_dispatcher)
     878      329464 :         m_dispatcher->m_weakPtrs.erase(this);
     879      154782 : }
     880             : 
     881        9960 : DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
     882             :     : m_backendImpl(std::move(backendImpl))
     883             :     , m_callId(callId)
     884             :     , m_method(method)
     885       29880 :     , m_message(message) { }
     886             : 
     887             : DispatcherBase::Callback::~Callback() = default;
     888             : 
     889           0 : void DispatcherBase::Callback::dispose()
     890             : {
     891             :     m_backendImpl = nullptr;
     892           0 : }
     893             : 
     894        9960 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
     895             : {
     896       19920 :     if (!m_backendImpl || !m_backendImpl->get())
     897             :         return;
     898       19910 :     m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
     899             :     m_backendImpl = nullptr;
     900             : }
     901             : 
     902           0 : void DispatcherBase::Callback::fallThroughIfActive()
     903             : {
     904           0 :     if (!m_backendImpl || !m_backendImpl->get())
     905             :         return;
     906           0 :     m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
     907             :     m_backendImpl = nullptr;
     908             : }
     909             : 
     910       23196 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
     911       46392 :     : m_frontendChannel(frontendChannel) { }
     912             : 
     913       46392 : DispatcherBase::~DispatcherBase()
     914             : {
     915             :     clearFrontend();
     916       23196 : }
     917             : 
     918      154777 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
     919             : {
     920      154777 :     if (!m_frontendChannel)
     921             :         return;
     922      154777 :     if (response.status() == DispatchResponse::kError) {
     923             :         reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
     924             :         return;
     925             :     }
     926      923586 :     m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
     927             : }
     928             : 
     929       57097 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
     930             : {
     931      114194 :     sendResponse(callId, response, DictionaryValue::create());
     932       57097 : }
     933             : 
     934             : namespace {
     935             : 
     936             : class ProtocolError : public Serializable {
     937             : public:
     938         909 :     static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     939             :     {
     940         909 :         std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
     941         909 :         protocolError->m_callId = callId;
     942         909 :         protocolError->m_hasCallId = true;
     943         968 :         if (errors && errors->hasErrors())
     944         118 :             protocolError->m_data = errors->errors();
     945         909 :         return protocolError;
     946             :     }
     947             : 
     948             :     static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
     949             :     {
     950           0 :         return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
     951             :     }
     952             : 
     953         909 :     String serializeToJSON() override
     954             :     {
     955        2727 :         return serialize()->serializeToJSON();
     956             :     }
     957             : 
     958           0 :     std::vector<uint8_t> serializeToBinary() override
     959             :     {
     960           0 :         return serialize()->serializeToBinary();
     961             :     }
     962             : 
     963        2727 :     ~ProtocolError() override {}
     964             : 
     965             : private:
     966         909 :     ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
     967             :         : m_code(code)
     968        1818 :         , m_errorMessage(errorMessage)
     969             :     {
     970         909 :     }
     971             : 
     972         909 :     std::unique_ptr<DictionaryValue> serialize() {
     973         909 :         std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
     974        2727 :         error->setInteger("code", m_code);
     975        2727 :         error->setString("message", m_errorMessage);
     976         909 :         if (m_data.length())
     977         177 :             error->setString("data", m_data);
     978         909 :         std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
     979        2727 :         message->setObject("error", std::move(error));
     980         909 :         if (m_hasCallId)
     981        2727 :             message->setInteger("id", m_callId);
     982         909 :         return message;
     983             :     }
     984             : 
     985             :     DispatchResponse::ErrorCode m_code;
     986             :     String m_errorMessage;
     987             :     String m_data;
     988             :     int m_callId = 0;
     989             :     bool m_hasCallId = false;
     990             : };
     991             : 
     992             : } // namespace
     993             : 
     994         909 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     995             : {
     996         909 :     if (frontendChannel)
     997        2727 :         frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
     998         909 : }
     999             : 
    1000           0 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
    1001             : {
    1002           0 :     if (frontendChannel)
    1003           0 :         frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
    1004           0 : }
    1005             : 
    1006          59 : void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
    1007             : {
    1008         905 :     reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
    1009          59 : }
    1010             : 
    1011           0 : void DispatcherBase::clearFrontend()
    1012             : {
    1013       23196 :     m_frontendChannel = nullptr;
    1014       23206 :     for (auto& weak : m_weakPtrs)
    1015          10 :         weak->dispose();
    1016             :     m_weakPtrs.clear();
    1017           0 : }
    1018             : 
    1019      164742 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
    1020             : {
    1021      164742 :     std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
    1022      329484 :     m_weakPtrs.insert(weak.get());
    1023      164742 :     return weak;
    1024             : }
    1025             : 
    1026        3866 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
    1027        7732 :     : m_frontendChannel(frontendChannel) { }
    1028             : 
    1029       23196 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
    1030             : {
    1031             :     m_dispatchers[name] = std::move(dispatcher);
    1032       23196 : }
    1033             : 
    1034       23196 : void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
    1035             : {
    1036       27062 :     for (const auto& pair : redirects)
    1037        3866 :         m_redirects[pair.first] = pair.second;
    1038       23196 : }
    1039             : 
    1040      154845 : bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
    1041      154845 :     if (!parsedMessage) {
    1042           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
    1043           0 :         return false;
    1044             :     }
    1045             :     protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
    1046      154845 :     if (!messageObject) {
    1047           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
    1048           0 :         return false;
    1049             :     }
    1050             : 
    1051      154845 :     int callId = 0;
    1052      309690 :     protocol::Value* callIdValue = messageObject->get("id");
    1053      154845 :     bool success = callIdValue && callIdValue->asInteger(&callId);
    1054      154845 :     if (!success) {
    1055           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
    1056           0 :         return false;
    1057             :     }
    1058      154845 :     if (outCallId)
    1059      154845 :       *outCallId = callId;
    1060             : 
    1061      309690 :     protocol::Value* methodValue = messageObject->get("method");
    1062             :     String method;
    1063      154845 :     success = methodValue && methodValue->asString(&method);
    1064      154845 :     if (!success) {
    1065           0 :         reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
    1066           0 :         return false;
    1067             :     }
    1068      154845 :     if (outMethod)
    1069             :       *outMethod = method;
    1070             :     return true;
    1071             : }
    1072             : 
    1073      154845 : protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
    1074      154845 :     size_t dotIndex = StringUtil::find(method, ".");
    1075      154845 :     if (dotIndex == StringUtil::kNotFound)
    1076             :         return nullptr;
    1077             :     String domain = StringUtil::substring(method, 0, dotIndex);
    1078             :     auto it = m_dispatchers.find(domain);
    1079      154845 :     if (it == m_dispatchers.end())
    1080             :         return nullptr;
    1081      154845 :     if (!it->second->canDispatch(method))
    1082             :         return nullptr;
    1083      154841 :     return it->second.get();
    1084             : }
    1085             : 
    1086           0 : bool UberDispatcher::canDispatch(const String& in_method)
    1087             : {
    1088             :     String method = in_method;
    1089             :     auto redirectIt = m_redirects.find(method);
    1090           0 :     if (redirectIt != m_redirects.end())
    1091             :         method = redirectIt->second;
    1092           0 :     return !!findDispatcher(method);
    1093             : }
    1094             : 
    1095      154845 : void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const ProtocolMessage& rawMessage)
    1096             : {
    1097             :     String method = in_method;
    1098             :     auto redirectIt = m_redirects.find(method);
    1099      154845 :     if (redirectIt != m_redirects.end())
    1100             :         method = redirectIt->second;
    1101      154845 :     protocol::DispatcherBase* dispatcher = findDispatcher(method);
    1102      154845 :     if (!dispatcher) {
    1103          16 :         reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
    1104             :         return;
    1105             :     }
    1106             :     std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
    1107      464523 :     dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
    1108             : }
    1109             : 
    1110             : UberDispatcher::~UberDispatcher() = default;
    1111             : 
    1112             : // static
    1113      153931 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
    1114             : {
    1115      615724 :     return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
    1116             : }
    1117             : 
    1118             : // static
    1119      174881 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
    1120             : {
    1121      349762 :     return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
    1122             : }
    1123             : 
    1124      328812 : String InternalResponse::serializeToJSON()
    1125             : {
    1126      328812 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    1127      768020 :     std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    1128      328812 :     if (m_notification.length()) {
    1129      524643 :         result->setString("method", m_notification);
    1130      874405 :         result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
    1131             :     } else {
    1132      461793 :         result->setInteger("id", m_callId);
    1133      769655 :         result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
    1134             :     }
    1135      657624 :     return result->serializeToJSON();
    1136             : }
    1137             : 
    1138           0 : std::vector<uint8_t> InternalResponse::serializeToBinary()
    1139             : {
    1140           0 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    1141           0 :     std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    1142           0 :     if (m_notification.length()) {
    1143           0 :         result->setString("method", m_notification);
    1144           0 :         result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary()));
    1145             :     } else {
    1146           0 :         result->setInteger("id", m_callId);
    1147           0 :         result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary()));
    1148             :     }
    1149           0 :     return result->serializeToBinary();
    1150             : }
    1151             : 
    1152      328812 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
    1153             :     : m_callId(callId)
    1154             :     , m_notification(notification)
    1155      657624 :     , m_params(params ? std::move(params) : nullptr)
    1156             : {
    1157      328812 : }
    1158             : 
    1159             : } // namespace v8_inspector
    1160             : } // namespace protocol
    1161             : 
    1162             : 
    1163             : // This file is generated by Parser_cpp.template.
    1164             : 
    1165             : // Copyright 2016 The Chromium Authors. All rights reserved.
    1166             : // Use of this source code is governed by a BSD-style license that can be
    1167             : // found in the LICENSE file.
    1168             : 
    1169             : namespace v8_inspector {
    1170             : namespace protocol {
    1171             : 
    1172             : namespace {
    1173             : 
    1174             : const int stackLimit = 1000;
    1175             : 
    1176             : enum Token {
    1177             :     ObjectBegin,
    1178             :     ObjectEnd,
    1179             :     ArrayBegin,
    1180             :     ArrayEnd,
    1181             :     StringLiteral,
    1182             :     Number,
    1183             :     BoolTrue,
    1184             :     BoolFalse,
    1185             :     NullToken,
    1186             :     ListSeparator,
    1187             :     ObjectPairSeparator,
    1188             :     InvalidToken,
    1189             : };
    1190             : 
    1191             : const char* const nullString = "null";
    1192             : const char* const trueString = "true";
    1193             : const char* const falseString = "false";
    1194             : 
    1195             : bool isASCII(uint16_t c)
    1196             : {
    1197     5147798 :     return !(c & ~0x7F);
    1198             : }
    1199             : 
    1200             : bool isSpaceOrNewLine(uint16_t c)
    1201             : {
    1202     4352585 :     return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
    1203             : }
    1204             : 
    1205      349696 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
    1206             : {
    1207             :     std::vector<char> buffer;
    1208      349696 :     buffer.reserve(length + 1);
    1209     1940122 :     for (size_t i = 0; i < length; ++i) {
    1210     1590426 :         if (!isASCII(characters[i])) {
    1211           0 :             *ok = false;
    1212           0 :             return 0;
    1213             :         }
    1214     1590426 :         buffer.push_back(static_cast<char>(characters[i]));
    1215             :     }
    1216      699392 :     buffer.push_back('\0');
    1217      349696 :     return StringUtil::toDouble(buffer.data(), length, ok);
    1218             : }
    1219             : 
    1220           0 : double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
    1221             : {
    1222             :     std::string buffer(reinterpret_cast<const char*>(characters), length);
    1223           0 :     return StringUtil::toDouble(buffer.data(), length, ok);
    1224             : }
    1225             : 
    1226             : template<typename Char>
    1227             : bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
    1228             : {
    1229      419167 :     while (start < end && *token != '\0' && *start++ == *token++) { }
    1230       82430 :     if (*token != '\0')
    1231             :         return false;
    1232       82425 :     *tokenEnd = start;
    1233             :     return true;
    1234             : }
    1235             : 
    1236             : template<typename Char>
    1237             : bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
    1238             : {
    1239      349701 :     if (start == end)
    1240             :         return false;
    1241      349696 :     bool haveLeadingZero = '0' == *start;
    1242             :     int length = 0;
    1243     1144896 :     while (start < end && '0' <= *start && *start <= '9') {
    1244      795195 :         ++start;
    1245      795195 :         ++length;
    1246             :     }
    1247      349701 :     if (!length)
    1248             :         return false;
    1249      349696 :     if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
    1250             :         return false;
    1251             :     *tokenEnd = start;
    1252             :     return true;
    1253             : }
    1254             : 
    1255             : template<typename Char>
    1256      349696 : bool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd)
    1257             : {
    1258             :     // We just grab the number here. We validate the size in DecodeNumber.
    1259             :     // According to RFC4627, a valid number is: [minus] int [frac] [exp]
    1260      349696 :     if (start == end)
    1261             :         return false;
    1262      349696 :     Char c = *start;
    1263      349696 :     if ('-' == c)
    1264          13 :         ++start;
    1265             : 
    1266      349696 :     if (!readInt(start, end, &start, false))
    1267             :         return false;
    1268      349696 :     if (start == end) {
    1269           5 :         *tokenEnd = start;
    1270           5 :         return true;
    1271             :     }
    1272             : 
    1273             :     // Optional fraction part
    1274      349691 :     c = *start;
    1275      349691 :     if ('.' == c) {
    1276           5 :         ++start;
    1277           5 :         if (!readInt(start, end, &start, true))
    1278             :             return false;
    1279           5 :         if (start == end) {
    1280           0 :             *tokenEnd = start;
    1281           0 :             return true;
    1282             :         }
    1283           5 :         c = *start;
    1284             :     }
    1285             : 
    1286             :     // Optional exponent part
    1287      349691 :     if ('e' == c || 'E' == c) {
    1288           0 :         ++start;
    1289           0 :         if (start == end)
    1290             :             return false;
    1291           0 :         c = *start;
    1292           0 :         if ('-' == c || '+' == c) {
    1293           0 :             ++start;
    1294           0 :             if (start == end)
    1295             :                 return false;
    1296             :         }
    1297           0 :         if (!readInt(start, end, &start, true))
    1298             :             return false;
    1299             :     }
    1300             : 
    1301      349691 :     *tokenEnd = start;
    1302      349691 :     return true;
    1303             : }
    1304             : 
    1305             : template<typename Char>
    1306             : bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
    1307             : {
    1308          45 :     if (end - start < digits)
    1309             :         return false;
    1310         405 :     for (int i = 0; i < digits; ++i) {
    1311         180 :         Char c = *start++;
    1312         180 :         if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
    1313             :             return false;
    1314             :     }
    1315             :     *tokenEnd = start;
    1316             :     return true;
    1317             : }
    1318             : 
    1319             : template<typename Char>
    1320     1087201 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
    1321             : {
    1322    13424361 :     while (start < end) {
    1323    13424361 :         Char c = *start++;
    1324    13424361 :         if ('\\' == c) {
    1325      334233 :             if (start == end)
    1326             :                 return false;
    1327      334233 :             c = *start++;
    1328             :             // Make sure the escaped char is valid.
    1329      334233 :             switch (c) {
    1330             :             case 'x':
    1331           0 :                 if (!readHexDigits(start, end, &start, 2))
    1332             :                     return false;
    1333             :                 break;
    1334             :             case 'u':
    1335          45 :                 if (!readHexDigits(start, end, &start, 4))
    1336             :                     return false;
    1337             :                 break;
    1338             :             case '\\':
    1339             :             case '/':
    1340             :             case 'b':
    1341             :             case 'f':
    1342             :             case 'n':
    1343             :             case 'r':
    1344             :             case 't':
    1345             :             case 'v':
    1346             :             case '"':
    1347             :                 break;
    1348             :             default:
    1349             :                 return false;
    1350             :             }
    1351    13090128 :         } else if ('"' == c) {
    1352     1087201 :             *tokenEnd = start;
    1353     1087201 :             return true;
    1354             :         }
    1355             :     }
    1356             :     return false;
    1357             : }
    1358             : 
    1359             : template<typename Char>
    1360           0 : bool skipComment(const Char* start, const Char* end, const Char** commentEnd)
    1361             : {
    1362           0 :     if (start == end)
    1363             :         return false;
    1364             : 
    1365           0 :     if (*start != '/' || start + 1 >= end)
    1366             :         return false;
    1367             :     ++start;
    1368             : 
    1369           0 :     if (*start == '/') {
    1370             :         // Single line comment, read to newline.
    1371           0 :         for (++start; start < end; ++start) {
    1372           0 :             if (*start == '\n' || *start == '\r') {
    1373           0 :                 *commentEnd = start + 1;
    1374           0 :                 return true;
    1375             :             }
    1376             :         }
    1377           0 :         *commentEnd = end;
    1378             :         // Comment reaches end-of-input, which is fine.
    1379           0 :         return true;
    1380             :     }
    1381             : 
    1382           0 :     if (*start == '*') {
    1383             :         Char previous = '\0';
    1384             :         // Block comment, read until end marker.
    1385           0 :         for (++start; start < end; previous = *start++) {
    1386           0 :             if (previous == '*' && *start == '/') {
    1387           0 :                 *commentEnd = start + 1;
    1388           0 :                 return true;
    1389             :             }
    1390             :         }
    1391             :         // Block comment must close before end-of-input.
    1392             :         return false;
    1393             :     }
    1394             : 
    1395             :     return false;
    1396             : }
    1397             : 
    1398             : template<typename Char>
    1399     4601444 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
    1400             : {
    1401     4601444 :     while (start < end) {
    1402     8705170 :         if (isSpaceOrNewLine(*start)) {
    1403           0 :             ++start;
    1404     4352585 :         } else if (*start == '/') {
    1405             :             const Char* commentEnd;
    1406           0 :             if (!skipComment(start, end, &commentEnd))
    1407             :                 break;
    1408           0 :             start = commentEnd;
    1409             :         } else {
    1410             :             break;
    1411             :         }
    1412             :     }
    1413     4601444 :     *whitespaceEnd = start;
    1414     4601444 : }
    1415             : 
    1416             : template<typename Char>
    1417     3533963 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
    1418             : {
    1419     3533963 :     skipWhitespaceAndComments(start, end, tokenStart);
    1420     3533963 :     start = *tokenStart;
    1421             : 
    1422     3533963 :     if (start == end)
    1423             :         return InvalidToken;
    1424             : 
    1425     3533963 :     switch (*start) {
    1426             :     case 'n':
    1427           5 :         if (parseConstToken(start, end, tokenEnd, nullString))
    1428             :             return NullToken;
    1429             :         break;
    1430             :     case 't':
    1431       75393 :         if (parseConstToken(start, end, tokenEnd, trueString))
    1432             :             return BoolTrue;
    1433             :         break;
    1434             :     case 'f':
    1435        7032 :         if (parseConstToken(start, end, tokenEnd, falseString))
    1436             :             return BoolFalse;
    1437             :         break;
    1438             :     case '[':
    1439         670 :         *tokenEnd = start + 1;
    1440         670 :         return ArrayBegin;
    1441             :     case ']':
    1442         670 :         *tokenEnd = start + 1;
    1443         670 :         return ArrayEnd;
    1444             :     case ',':
    1445      464047 :         *tokenEnd = start + 1;
    1446      464047 :         return ListSeparator;
    1447             :     case '{':
    1448      366111 :         *tokenEnd = start + 1;
    1449      366111 :         return ObjectBegin;
    1450             :     case '}':
    1451      365376 :         *tokenEnd = start + 1;
    1452      365376 :         return ObjectEnd;
    1453             :     case ':':
    1454      817762 :         *tokenEnd = start + 1;
    1455      817762 :         return ObjectPairSeparator;
    1456             :     case '0':
    1457             :     case '1':
    1458             :     case '2':
    1459             :     case '3':
    1460             :     case '4':
    1461             :     case '5':
    1462             :     case '6':
    1463             :     case '7':
    1464             :     case '8':
    1465             :     case '9':
    1466             :     case '-':
    1467      349696 :         if (parseNumberToken(start, end, tokenEnd))
    1468             :             return Number;
    1469             :         break;
    1470             :     case '"':
    1471     1087201 :         if (parseStringToken(start + 1, end, tokenEnd))
    1472             :             return StringLiteral;
    1473             :         break;
    1474             :     }
    1475             :     return InvalidToken;
    1476             : }
    1477             : 
    1478             : template<typename Char>
    1479             : int hexToInt(Char c)
    1480             : {
    1481         180 :     if ('0' <= c && c <= '9')
    1482         170 :         return c - '0';
    1483          10 :     if ('A' <= c && c <= 'F')
    1484          10 :         return c - 'A' + 10;
    1485           0 :     if ('a' <= c && c <= 'f')
    1486           0 :         return c - 'a' + 10;
    1487             :     DCHECK(false);
    1488             :     return 0;
    1489             : }
    1490             : 
    1491             : template<typename Char>
    1492     1086870 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
    1493             : {
    1494    13422935 :     while (start < end) {
    1495    12336065 :         uint16_t c = *start++;
    1496    12336065 :         if ('\\' != c) {
    1497             :             StringUtil::builderAppend(*output, c);
    1498             :             continue;
    1499             :         }
    1500      334233 :         if (start == end)
    1501             :             return false;
    1502      334233 :         c = *start++;
    1503             : 
    1504      334233 :         if (c == 'x') {
    1505             :             // \x is not supported.
    1506             :             return false;
    1507             :         }
    1508             : 
    1509      334233 :         switch (c) {
    1510             :         case '"':
    1511             :         case '/':
    1512             :         case '\\':
    1513             :             break;
    1514             :         case 'b':
    1515             :             c = '\b';
    1516           0 :             break;
    1517             :         case 'f':
    1518             :             c = '\f';
    1519           0 :             break;
    1520             :         case 'n':
    1521             :             c = '\n';
    1522        7143 :             break;
    1523             :         case 'r':
    1524             :             c = '\r';
    1525           0 :             break;
    1526             :         case 't':
    1527             :             c = '\t';
    1528           0 :             break;
    1529             :         case 'v':
    1530             :             c = '\v';
    1531           0 :             break;
    1532             :         case 'u':
    1533         225 :             c = (hexToInt(*start) << 12) +
    1534          45 :                 (hexToInt(*(start + 1)) << 8) +
    1535          45 :                 (hexToInt(*(start + 2)) << 4) +
    1536          45 :                 hexToInt(*(start + 3));
    1537          45 :             start += 4;
    1538          45 :             break;
    1539             :         default:
    1540             :             return false;
    1541             :         }
    1542             :         StringUtil::builderAppend(*output, c);
    1543             :     }
    1544             :     return true;
    1545             : }
    1546             : 
    1547             : template<typename Char>
    1548     1087076 : bool decodeString(const Char* start, const Char* end, String* output)
    1549             : {
    1550     1087076 :     if (start == end) {
    1551         412 :         *output = "";
    1552         206 :         return true;
    1553             :     }
    1554     1086870 :     if (start > end)
    1555             :         return false;
    1556     1086870 :     StringBuilder buffer;
    1557     1086870 :     StringUtil::builderReserve(buffer, end - start);
    1558     1086870 :     if (!decodeString(start, end, &buffer))
    1559             :         return false;
    1560     1086870 :     *output = StringUtil::builderToString(buffer);
    1561     1086870 :     return true;
    1562             : }
    1563             : 
    1564             : template<typename Char>
    1565     1067486 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
    1566             : {
    1567     1067486 :     if (depth > stackLimit)
    1568             :         return nullptr;
    1569             : 
    1570             :     std::unique_ptr<Value> result;
    1571             :     const Char* tokenStart;
    1572             :     const Char* tokenEnd;
    1573     1067486 :     Token token = parseToken(start, end, &tokenStart, &tokenEnd);
    1574     1067486 :     switch (token) {
    1575             :     case InvalidToken:
    1576             :         return nullptr;
    1577             :     case NullToken:
    1578             :         result = Value::null();
    1579           5 :         break;
    1580             :     case BoolTrue:
    1581             :         result = FundamentalValue::create(true);
    1582       75393 :         break;
    1583             :     case BoolFalse:
    1584             :         result = FundamentalValue::create(false);
    1585        7027 :         break;
    1586             :     case Number: {
    1587             :         bool ok;
    1588      349696 :         double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
    1589      349696 :         if (!ok)
    1590           0 :             return nullptr;
    1591      349696 :         if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
    1592      349691 :             result = FundamentalValue::create(static_cast<int>(value));
    1593             :         else
    1594             :             result = FundamentalValue::create(value);
    1595      349696 :         break;
    1596             :     }
    1597             :     case StringLiteral: {
    1598             :         String value;
    1599      269314 :         bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
    1600      269314 :         if (!ok)
    1601             :             return nullptr;
    1602             :         result = StringValue::create(value);
    1603             :         break;
    1604             :     }
    1605             :     case ArrayBegin: {
    1606         670 :         std::unique_ptr<ListValue> array = ListValue::create();
    1607         670 :         start = tokenEnd;
    1608         670 :         token = parseToken(start, end, &tokenStart, &tokenEnd);
    1609        1530 :         while (token != ArrayEnd) {
    1610         860 :             std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
    1611         860 :             if (!arrayNode)
    1612             :                 return nullptr;
    1613         860 :             array->pushValue(std::move(arrayNode));
    1614             : 
    1615             :             // After a list value, we expect a comma or the end of the list.
    1616         860 :             start = tokenEnd;
    1617         860 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1618         860 :             if (token == ListSeparator) {
    1619         258 :                 start = tokenEnd;
    1620         258 :                 token = parseToken(start, end, &tokenStart, &tokenEnd);
    1621         258 :                 if (token == ArrayEnd)
    1622             :                     return nullptr;
    1623         602 :             } else if (token != ArrayEnd) {
    1624             :                 // Unexpected value after list value. Bail out.
    1625             :                 return nullptr;
    1626             :             }
    1627             :         }
    1628         670 :         if (token != ArrayEnd)
    1629             :             return nullptr;
    1630             :         result = std::move(array);
    1631             :         break;
    1632             :     }
    1633             :     case ObjectBegin: {
    1634      365376 :         std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
    1635      365376 :         start = tokenEnd;
    1636      365376 :         token = parseToken(start, end, &tokenStart, &tokenEnd);
    1637     1183138 :         while (token != ObjectEnd) {
    1638      817762 :             if (token != StringLiteral)
    1639           0 :                 return nullptr;
    1640             :             String key;
    1641      817762 :             if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
    1642             :                 return nullptr;
    1643      817762 :             start = tokenEnd;
    1644             : 
    1645      817762 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1646      817762 :             if (token != ObjectPairSeparator)
    1647             :                 return nullptr;
    1648      817762 :             start = tokenEnd;
    1649             : 
    1650      817762 :             std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
    1651      817762 :             if (!value)
    1652             :                 return nullptr;
    1653      817762 :             object->setValue(key, std::move(value));
    1654      817762 :             start = tokenEnd;
    1655             : 
    1656             :             // After a key/value pair, we expect a comma or the end of the
    1657             :             // object.
    1658      817762 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1659      817762 :             if (token == ListSeparator) {
    1660      463789 :                 start = tokenEnd;
    1661      463789 :                 token = parseToken(start, end, &tokenStart, &tokenEnd);
    1662      463789 :                 if (token == ObjectEnd)
    1663             :                     return nullptr;
    1664      353973 :             } else if (token != ObjectEnd) {
    1665             :                 // Unexpected value after last object value. Bail out.
    1666             :                 return nullptr;
    1667             :             }
    1668             :         }
    1669      365376 :         if (token != ObjectEnd)
    1670             :             return nullptr;
    1671             :         result = std::move(object);
    1672             :         break;
    1673             :     }
    1674             : 
    1675             :     default:
    1676             :         // We got a token that's not a value.
    1677             :         return nullptr;
    1678             :     }
    1679             : 
    1680     1067481 :     skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
    1681             :     return result;
    1682             : }
    1683             : 
    1684             : template<typename Char>
    1685      248864 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
    1686             : {
    1687      248864 :     const Char* end = start + length;
    1688             :     const Char *tokenEnd;
    1689      248864 :     std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
    1690      248864 :     if (!value || tokenEnd != end)
    1691             :         return nullptr;
    1692             :     return value;
    1693             : }
    1694             : 
    1695             : } // anonymous namespace
    1696             : 
    1697      248864 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
    1698             : {
    1699      248864 :     return parseJSONInternal<uint16_t>(characters, length);
    1700             : }
    1701             : 
    1702           0 : std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
    1703             : {
    1704           0 :     return parseJSONInternal<uint8_t>(characters, length);
    1705             : }
    1706             : 
    1707             : } // namespace v8_inspector
    1708             : } // namespace protocol
    1709             : 
    1710             : 
    1711             : // Generated by lib/encoding_cpp.template.
    1712             : 
    1713             : // Copyright 2019 The Chromium Authors. All rights reserved.
    1714             : // Use of this source code is governed by a BSD-style license that can be
    1715             : // found in the LICENSE file.
    1716             : 
    1717             : 
    1718             : #include <cassert>
    1719             : #include <cstring>
    1720             : #include <limits>
    1721             : #include <stack>
    1722             : 
    1723             : namespace v8_inspector {
    1724             : namespace protocol {
    1725             : 
    1726             : // ===== encoding/encoding.cc =====
    1727             : 
    1728             : namespace cbor {
    1729             : namespace {
    1730             : // Indicates the number of bits the "initial byte" needs to be shifted to the
    1731             : // right after applying |kMajorTypeMask| to produce the major type in the
    1732             : // lowermost bits.
    1733             : static constexpr uint8_t kMajorTypeBitShift = 5u;
    1734             : // Mask selecting the low-order 5 bits of the "initial byte", which is where
    1735             : // the additional information is encoded.
    1736             : static constexpr uint8_t kAdditionalInformationMask = 0x1f;
    1737             : // Mask selecting the high-order 3 bits of the "initial byte", which indicates
    1738             : // the major type of the encoded value.
    1739             : static constexpr uint8_t kMajorTypeMask = 0xe0;
    1740             : // Indicates the integer is in the following byte.
    1741             : static constexpr uint8_t kAdditionalInformation1Byte = 24u;
    1742             : // Indicates the integer is in the next 2 bytes.
    1743             : static constexpr uint8_t kAdditionalInformation2Bytes = 25u;
    1744             : // Indicates the integer is in the next 4 bytes.
    1745             : static constexpr uint8_t kAdditionalInformation4Bytes = 26u;
    1746             : // Indicates the integer is in the next 8 bytes.
    1747             : static constexpr uint8_t kAdditionalInformation8Bytes = 27u;
    1748             : 
    1749             : // Encodes the initial byte, consisting of the |type| in the first 3 bits
    1750             : // followed by 5 bits of |additional_info|.
    1751             : constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) {
    1752           0 :   return (static_cast<uint8_t>(type) << kMajorTypeBitShift) |
    1753           0 :          (additional_info & kAdditionalInformationMask);
    1754             : }
    1755             : 
    1756             : // TAG 24 indicates that what follows is a byte string which is
    1757             : // encoded in CBOR format. We use this as a wrapper for
    1758             : // maps and arrays, allowing us to skip them, because the
    1759             : // byte string carries its size (byte length).
    1760             : // https://tools.ietf.org/html/rfc7049#section-2.4.4.1
    1761             : static constexpr uint8_t kInitialByteForEnvelope =
    1762             :     EncodeInitialByte(MajorType::TAG, 24);
    1763             : // The initial byte for a byte string with at most 2^32 bytes
    1764             : // of payload. This is used for envelope encoding, even if
    1765             : // the byte string is shorter.
    1766             : static constexpr uint8_t kInitialByteFor32BitLengthByteString =
    1767             :     EncodeInitialByte(MajorType::BYTE_STRING, 26);
    1768             : 
    1769             : // See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional
    1770             : // info = 31.
    1771             : static constexpr uint8_t kInitialByteIndefiniteLengthArray =
    1772             :     EncodeInitialByte(MajorType::ARRAY, 31);
    1773             : static constexpr uint8_t kInitialByteIndefiniteLengthMap =
    1774             :     EncodeInitialByte(MajorType::MAP, 31);
    1775             : // See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite
    1776             : // length maps / arrays.
    1777             : static constexpr uint8_t kStopByte =
    1778             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 31);
    1779             : 
    1780             : // See RFC 7049 Section 2.3, Table 2.
    1781             : static constexpr uint8_t kEncodedTrue =
    1782             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 21);
    1783             : static constexpr uint8_t kEncodedFalse =
    1784             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 20);
    1785             : static constexpr uint8_t kEncodedNull =
    1786             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
    1787             : static constexpr uint8_t kInitialByteForDouble =
    1788             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
    1789             : 
    1790             : // See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
    1791             : // arbitrary binary data encoded as BYTE_STRING.
    1792             : static constexpr uint8_t kExpectedConversionToBase64Tag =
    1793             :     EncodeInitialByte(MajorType::TAG, 22);
    1794             : 
    1795             : // Writes the bytes for |v| to |out|, starting with the most significant byte.
    1796             : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1797             : template <typename T>
    1798             : void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) {
    1799           0 :   for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes)
    1800           0 :     out->push_back(0xff & (v >> (shift_bytes * 8)));
    1801             : }
    1802             : 
    1803             : // Extracts sizeof(T) bytes from |in| to extract a value of type T
    1804             : // (e.g. uint64_t, uint32_t, ...), most significant byte first.
    1805             : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1806             : template <typename T>
    1807             : T ReadBytesMostSignificantByteFirst(span<uint8_t> in) {
    1808             :   assert(static_cast<std::size_t>(in.size()) >= sizeof(T));
    1809             :   T result = 0;
    1810           0 :   for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes)
    1811           0 :     result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8);
    1812             :   return result;
    1813             : }
    1814             : }  // namespace
    1815             : 
    1816             : namespace internals {
    1817             : // Reads the start of a token with definitive size from |bytes|.
    1818             : // |type| is the major type as specified in RFC 7049 Section 2.1.
    1819             : // |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size
    1820             : // (e.g. for BYTE_STRING).
    1821             : // If successful, returns the number of bytes read. Otherwise returns -1.
    1822           0 : int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
    1823           0 :   if (bytes.empty())
    1824             :     return -1;
    1825           0 :   uint8_t initial_byte = bytes[0];
    1826           0 :   *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
    1827             : 
    1828           0 :   uint8_t additional_information = initial_byte & kAdditionalInformationMask;
    1829           0 :   if (additional_information < 24) {
    1830             :     // Values 0-23 are encoded directly into the additional info of the
    1831             :     // initial byte.
    1832           0 :     *value = additional_information;
    1833           0 :     return 1;
    1834             :   }
    1835           0 :   if (additional_information == kAdditionalInformation1Byte) {
    1836             :     // Values 24-255 are encoded with one initial byte, followed by the value.
    1837           0 :     if (bytes.size() < 2)
    1838             :       return -1;
    1839           0 :     *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
    1840           0 :     return 2;
    1841             :   }
    1842           0 :   if (additional_information == kAdditionalInformation2Bytes) {
    1843             :     // Values 256-65535: 1 initial byte + 2 bytes payload.
    1844           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t))
    1845             :       return -1;
    1846           0 :     *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
    1847           0 :     return 3;
    1848             :   }
    1849           0 :   if (additional_information == kAdditionalInformation4Bytes) {
    1850             :     // 32 bit uint: 1 initial byte + 4 bytes payload.
    1851           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t))
    1852             :       return -1;
    1853           0 :     *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
    1854           0 :     return 5;
    1855             :   }
    1856           0 :   if (additional_information == kAdditionalInformation8Bytes) {
    1857             :     // 64 bit uint: 1 initial byte + 8 bytes payload.
    1858           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t))
    1859             :       return -1;
    1860           0 :     *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
    1861           0 :     return 9;
    1862             :   }
    1863             :   return -1;
    1864             : }
    1865             : 
    1866             : // Writes the start of a token with |type|. The |value| may indicate the size,
    1867             : // or it may be the payload if the value is an unsigned integer.
    1868           0 : void WriteTokenStart(MajorType type,
    1869             :                      uint64_t value,
    1870             :                      std::vector<uint8_t>* encoded) {
    1871           0 :   if (value < 24) {
    1872             :     // Values 0-23 are encoded directly into the additional info of the
    1873             :     // initial byte.
    1874           0 :     encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value));
    1875           0 :     return;
    1876             :   }
    1877           0 :   if (value <= std::numeric_limits<uint8_t>::max()) {
    1878             :     // Values 24-255 are encoded with one initial byte, followed by the value.
    1879           0 :     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte));
    1880           0 :     encoded->push_back(value);
    1881           0 :     return;
    1882             :   }
    1883           0 :   if (value <= std::numeric_limits<uint16_t>::max()) {
    1884             :     // Values 256-65535: 1 initial byte + 2 bytes payload.
    1885           0 :     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes));
    1886           0 :     WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded);
    1887             :     return;
    1888             :   }
    1889           0 :   if (value <= std::numeric_limits<uint32_t>::max()) {
    1890             :     // 32 bit uint: 1 initial byte + 4 bytes payload.
    1891           0 :     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes));
    1892           0 :     WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value),
    1893             :                                                  encoded);
    1894             :     return;
    1895             :   }
    1896             :   // 64 bit uint: 1 initial byte + 8 bytes payload.
    1897           0 :   encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes));
    1898             :   WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded);
    1899             : }
    1900             : }  // namespace internals
    1901             : 
    1902             : // =============================================================================
    1903             : // Detecting CBOR content
    1904             : // =============================================================================
    1905             : 
    1906           0 : uint8_t InitialByteForEnvelope() {
    1907           0 :   return kInitialByteForEnvelope;
    1908             : }
    1909           0 : uint8_t InitialByteFor32BitLengthByteString() {
    1910           0 :   return kInitialByteFor32BitLengthByteString;
    1911             : }
    1912           0 : bool IsCBORMessage(span<uint8_t> msg) {
    1913           0 :   return msg.size() >= 6 && msg[0] == InitialByteForEnvelope() &&
    1914           0 :          msg[1] == InitialByteFor32BitLengthByteString();
    1915             : }
    1916             : 
    1917             : // =============================================================================
    1918             : // Encoding invidiual CBOR items
    1919             : // =============================================================================
    1920             : 
    1921           0 : uint8_t EncodeTrue() {
    1922           0 :   return kEncodedTrue;
    1923             : }
    1924           0 : uint8_t EncodeFalse() {
    1925           0 :   return kEncodedFalse;
    1926             : }
    1927           0 : uint8_t EncodeNull() {
    1928           0 :   return kEncodedNull;
    1929             : }
    1930             : 
    1931           0 : uint8_t EncodeIndefiniteLengthArrayStart() {
    1932           0 :   return kInitialByteIndefiniteLengthArray;
    1933             : }
    1934             : 
    1935           0 : uint8_t EncodeIndefiniteLengthMapStart() {
    1936           0 :   return kInitialByteIndefiniteLengthMap;
    1937             : }
    1938             : 
    1939           0 : uint8_t EncodeStop() {
    1940           0 :   return kStopByte;
    1941             : }
    1942             : 
    1943           0 : void EncodeInt32(int32_t value, std::vector<uint8_t>* out) {
    1944           0 :   if (value >= 0) {
    1945           0 :     internals::WriteTokenStart(MajorType::UNSIGNED, value, out);
    1946             :   } else {
    1947           0 :     uint64_t representation = static_cast<uint64_t>(-(value + 1));
    1948           0 :     internals::WriteTokenStart(MajorType::NEGATIVE, representation, out);
    1949             :   }
    1950           0 : }
    1951             : 
    1952           0 : void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) {
    1953             :   uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
    1954           0 :   internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
    1955             :   // When emitting UTF16 characters, we always write the least significant byte
    1956             :   // first; this is because it's the native representation for X86.
    1957             :   // TODO(johannes): Implement a more efficient thing here later, e.g.
    1958             :   // casting *iff* the machine has this byte order.
    1959             :   // The wire format for UTF16 chars will probably remain the same
    1960             :   // (least significant byte first) since this way we can have
    1961             :   // golden files, unittests, etc. that port easily and universally.
    1962             :   // See also:
    1963             :   // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1964           0 :   for (const uint16_t two_bytes : in) {
    1965           0 :     out->push_back(two_bytes);
    1966           0 :     out->push_back(two_bytes >> 8);
    1967             :   }
    1968           0 : }
    1969             : 
    1970           0 : void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) {
    1971           0 :   internals::WriteTokenStart(MajorType::STRING,
    1972           0 :                              static_cast<uint64_t>(in.size_bytes()), out);
    1973             :   out->insert(out->end(), in.begin(), in.end());
    1974           0 : }
    1975             : 
    1976           0 : void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) {
    1977           0 :   for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) {
    1978           0 :     if (latin1[ii] <= 127)
    1979           0 :       continue;
    1980             :     // If there's at least one non-ASCII char, convert to UTF8.
    1981             :     std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii);
    1982           0 :     for (; ii < latin1.size(); ++ii) {
    1983           0 :       if (latin1[ii] <= 127) {
    1984           0 :         utf8.push_back(latin1[ii]);
    1985             :       } else {
    1986             :         // 0xC0 means it's a UTF8 sequence with 2 bytes.
    1987           0 :         utf8.push_back((latin1[ii] >> 6) | 0xc0);
    1988           0 :         utf8.push_back((latin1[ii] | 0x80) & 0xbf);
    1989             :       }
    1990             :     }
    1991           0 :     EncodeString8(SpanFromVector(utf8), out);
    1992             :     return;
    1993             :   }
    1994           0 :   EncodeString8(latin1, out);
    1995             : }
    1996             : 
    1997           0 : void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) {
    1998             :   // If there's at least one non-ASCII char, encode as STRING16 (UTF16).
    1999           0 :   for (uint16_t ch : utf16) {
    2000           0 :     if (ch <= 127)
    2001             :       continue;
    2002           0 :     EncodeString16(utf16, out);
    2003           0 :     return;
    2004             :   }
    2005             :   // It's all US-ASCII, strip out every second byte and encode as UTF8.
    2006             :   internals::WriteTokenStart(MajorType::STRING,
    2007           0 :                              static_cast<uint64_t>(utf16.size()), out);
    2008             :   out->insert(out->end(), utf16.begin(), utf16.end());
    2009             : }
    2010             : 
    2011           0 : void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) {
    2012           0 :   out->push_back(kExpectedConversionToBase64Tag);
    2013           0 :   uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
    2014           0 :   internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
    2015             :   out->insert(out->end(), in.begin(), in.end());
    2016           0 : }
    2017             : 
    2018             : // A double is encoded with a specific initial byte
    2019             : // (kInitialByteForDouble) plus the 64 bits of payload for its value.
    2020             : constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t);
    2021             : 
    2022             : // An envelope is encoded with a specific initial byte
    2023             : // (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32
    2024             : // bit wide length, plus a 32 bit length for that string.
    2025             : constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t);
    2026             : 
    2027           0 : void EncodeDouble(double value, std::vector<uint8_t>* out) {
    2028             :   // The additional_info=27 indicates 64 bits for the double follow.
    2029             :   // See RFC 7049 Section 2.3, Table 1.
    2030           0 :   out->push_back(kInitialByteForDouble);
    2031             :   union {
    2032             :     double from_double;
    2033             :     uint64_t to_uint64;
    2034             :   } reinterpret;
    2035             :   reinterpret.from_double = value;
    2036           0 :   WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out);
    2037           0 : }
    2038             : 
    2039             : // =============================================================================
    2040             : // cbor::EnvelopeEncoder - for wrapping submessages
    2041             : // =============================================================================
    2042             : 
    2043           0 : void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) {
    2044             :   assert(byte_size_pos_ == 0);
    2045           0 :   out->push_back(kInitialByteForEnvelope);
    2046           0 :   out->push_back(kInitialByteFor32BitLengthByteString);
    2047           0 :   byte_size_pos_ = out->size();
    2048           0 :   out->resize(out->size() + sizeof(uint32_t));
    2049           0 : }
    2050             : 
    2051           0 : bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) {
    2052             :   assert(byte_size_pos_ != 0);
    2053             :   // The byte size is the size of the payload, that is, all the
    2054             :   // bytes that were written past the byte size position itself.
    2055           0 :   uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t));
    2056             :   // We store exactly 4 bytes, so at most INT32MAX, with most significant
    2057             :   // byte first.
    2058           0 :   if (byte_size > std::numeric_limits<uint32_t>::max())
    2059             :     return false;
    2060           0 :   for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0;
    2061             :        --shift_bytes) {
    2062           0 :     (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8));
    2063             :   }
    2064             :   return true;
    2065             : }
    2066             : 
    2067             : // =============================================================================
    2068             : // cbor::NewCBOREncoder - for encoding from a streaming parser
    2069             : // =============================================================================
    2070             : 
    2071             : namespace {
    2072           0 : class CBOREncoder : public StreamingParserHandler {
    2073             :  public:
    2074             :   CBOREncoder(std::vector<uint8_t>* out, Status* status)
    2075           0 :       : out_(out), status_(status) {
    2076           0 :     *status_ = Status();
    2077             :   }
    2078             : 
    2079           0 :   void HandleMapBegin() override {
    2080           0 :     envelopes_.emplace_back();
    2081           0 :     envelopes_.back().EncodeStart(out_);
    2082           0 :     out_->push_back(kInitialByteIndefiniteLengthMap);
    2083           0 :   }
    2084             : 
    2085           0 :   void HandleMapEnd() override {
    2086           0 :     out_->push_back(kStopByte);
    2087             :     assert(!envelopes_.empty());
    2088           0 :     envelopes_.back().EncodeStop(out_);
    2089             :     envelopes_.pop_back();
    2090           0 :   }
    2091             : 
    2092           0 :   void HandleArrayBegin() override {
    2093           0 :     envelopes_.emplace_back();
    2094           0 :     envelopes_.back().EncodeStart(out_);
    2095           0 :     out_->push_back(kInitialByteIndefiniteLengthArray);
    2096           0 :   }
    2097             : 
    2098           0 :   void HandleArrayEnd() override {
    2099           0 :     out_->push_back(kStopByte);
    2100             :     assert(!envelopes_.empty());
    2101           0 :     envelopes_.back().EncodeStop(out_);
    2102             :     envelopes_.pop_back();
    2103           0 :   }
    2104             : 
    2105           0 :   void HandleString8(span<uint8_t> chars) override {
    2106           0 :     EncodeString8(chars, out_);
    2107           0 :   }
    2108             : 
    2109           0 :   void HandleString16(span<uint16_t> chars) override {
    2110           0 :     EncodeFromUTF16(chars, out_);
    2111           0 :   }
    2112             : 
    2113           0 :   void HandleBinary(span<uint8_t> bytes) override { EncodeBinary(bytes, out_); }
    2114             : 
    2115           0 :   void HandleDouble(double value) override { EncodeDouble(value, out_); }
    2116             : 
    2117           0 :   void HandleInt32(int32_t value) override { EncodeInt32(value, out_); }
    2118             : 
    2119           0 :   void HandleBool(bool value) override {
    2120             :     // See RFC 7049 Section 2.3, Table 2.
    2121           0 :     out_->push_back(value ? kEncodedTrue : kEncodedFalse);
    2122           0 :   }
    2123             : 
    2124           0 :   void HandleNull() override {
    2125             :     // See RFC 7049 Section 2.3, Table 2.
    2126           0 :     out_->push_back(kEncodedNull);
    2127           0 :   }
    2128             : 
    2129           0 :   void HandleError(Status error) override {
    2130             :     assert(!error.ok());
    2131           0 :     *status_ = error;
    2132           0 :     out_->clear();
    2133           0 :   }
    2134             : 
    2135             :  private:
    2136             :   std::vector<uint8_t>* out_;
    2137             :   std::vector<EnvelopeEncoder> envelopes_;
    2138             :   Status* status_;
    2139             : };
    2140             : }  // namespace
    2141             : 
    2142           0 : std::unique_ptr<StreamingParserHandler> NewCBOREncoder(
    2143             :     std::vector<uint8_t>* out,
    2144             :     Status* status) {
    2145           0 :   return std::unique_ptr<StreamingParserHandler>(new CBOREncoder(out, status));
    2146             : }
    2147             : 
    2148             : // =============================================================================
    2149             : // cbor::CBORTokenizer - for parsing individual CBOR items
    2150             : // =============================================================================
    2151             : 
    2152           0 : CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) {
    2153           0 :   ReadNextToken(/*enter_envelope=*/false);
    2154           0 : }
    2155           0 : CBORTokenizer::~CBORTokenizer() {}
    2156             : 
    2157           0 : CBORTokenTag CBORTokenizer::TokenTag() const {
    2158           0 :   return token_tag_;
    2159             : }
    2160             : 
    2161           0 : void CBORTokenizer::Next() {
    2162           0 :   if (token_tag_ == CBORTokenTag::ERROR_VALUE ||
    2163             :       token_tag_ == CBORTokenTag::DONE)
    2164             :     return;
    2165           0 :   ReadNextToken(/*enter_envelope=*/false);
    2166             : }
    2167             : 
    2168           0 : void CBORTokenizer::EnterEnvelope() {
    2169             :   assert(token_tag_ == CBORTokenTag::ENVELOPE);
    2170           0 :   ReadNextToken(/*enter_envelope=*/true);
    2171           0 : }
    2172             : 
    2173           0 : Status CBORTokenizer::Status() const {
    2174           0 :   return status_;
    2175             : }
    2176             : 
    2177           0 : int32_t CBORTokenizer::GetInt32() const {
    2178             :   assert(token_tag_ == CBORTokenTag::INT32);
    2179             :   // The range checks happen in ::ReadNextToken().
    2180             :   return static_cast<uint32_t>(
    2181           0 :       token_start_type_ == MajorType::UNSIGNED
    2182           0 :           ? token_start_internal_value_
    2183           0 :           : -static_cast<int64_t>(token_start_internal_value_) - 1);
    2184             : }
    2185             : 
    2186           0 : double CBORTokenizer::GetDouble() const {
    2187             :   assert(token_tag_ == CBORTokenTag::DOUBLE);
    2188             :   union {
    2189             :     uint64_t from_uint64;
    2190             :     double to_double;
    2191             :   } reinterpret;
    2192           0 :   reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>(
    2193           0 :       bytes_.subspan(status_.pos + 1));
    2194           0 :   return reinterpret.to_double;
    2195             : }
    2196             : 
    2197           0 : span<uint8_t> CBORTokenizer::GetString8() const {
    2198             :   assert(token_tag_ == CBORTokenTag::STRING8);
    2199           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2200           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2201             : }
    2202             : 
    2203           0 : span<uint8_t> CBORTokenizer::GetString16WireRep() const {
    2204             :   assert(token_tag_ == CBORTokenTag::STRING16);
    2205           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2206           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2207             : }
    2208             : 
    2209           0 : span<uint8_t> CBORTokenizer::GetBinary() const {
    2210             :   assert(token_tag_ == CBORTokenTag::BINARY);
    2211           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2212           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2213             : }
    2214             : 
    2215           0 : span<uint8_t> CBORTokenizer::GetEnvelopeContents() const {
    2216             :   assert(token_tag_ == CBORTokenTag::ENVELOPE);
    2217           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2218           0 :   return bytes_.subspan(status_.pos + kEncodedEnvelopeHeaderSize, length);
    2219             : }
    2220             : 
    2221           0 : void CBORTokenizer::ReadNextToken(bool enter_envelope) {
    2222           0 :   if (enter_envelope) {
    2223           0 :     status_.pos += kEncodedEnvelopeHeaderSize;
    2224             :   } else {
    2225             :     status_.pos =
    2226           0 :         status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_;
    2227             :   }
    2228           0 :   status_.error = Error::OK;
    2229           0 :   if (status_.pos >= bytes_.size()) {
    2230           0 :     token_tag_ = CBORTokenTag::DONE;
    2231           0 :     return;
    2232             :   }
    2233           0 :   switch (bytes_[status_.pos]) {
    2234             :     case kStopByte:
    2235             :       SetToken(CBORTokenTag::STOP, 1);
    2236             :       return;
    2237             :     case kInitialByteIndefiniteLengthMap:
    2238             :       SetToken(CBORTokenTag::MAP_START, 1);
    2239             :       return;
    2240             :     case kInitialByteIndefiniteLengthArray:
    2241             :       SetToken(CBORTokenTag::ARRAY_START, 1);
    2242             :       return;
    2243             :     case kEncodedTrue:
    2244             :       SetToken(CBORTokenTag::TRUE_VALUE, 1);
    2245             :       return;
    2246             :     case kEncodedFalse:
    2247             :       SetToken(CBORTokenTag::FALSE_VALUE, 1);
    2248             :       return;
    2249             :     case kEncodedNull:
    2250             :       SetToken(CBORTokenTag::NULL_VALUE, 1);
    2251             :       return;
    2252             :     case kExpectedConversionToBase64Tag: {  // BINARY
    2253           0 :       int8_t bytes_read = internals::ReadTokenStart(
    2254             :           bytes_.subspan(status_.pos + 1), &token_start_type_,
    2255           0 :           &token_start_internal_value_);
    2256           0 :       int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_;
    2257           0 :       if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
    2258           0 :           status_.pos + token_byte_length > bytes_.size()) {
    2259             :         SetError(Error::CBOR_INVALID_BINARY);
    2260             :         return;
    2261             :       }
    2262             :       SetToken(CBORTokenTag::BINARY,
    2263             :                static_cast<std::ptrdiff_t>(token_byte_length));
    2264             :       return;
    2265             :     }
    2266             :     case kInitialByteForDouble: {  // DOUBLE
    2267           0 :       if (status_.pos + kEncodedDoubleSize > bytes_.size()) {
    2268             :         SetError(Error::CBOR_INVALID_DOUBLE);
    2269             :         return;
    2270             :       }
    2271             :       SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize);
    2272             :       return;
    2273             :     }
    2274             :     case kInitialByteForEnvelope: {  // ENVELOPE
    2275           0 :       if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) {
    2276             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2277             :         return;
    2278             :       }
    2279             :       // The envelope must be a byte string with 32 bit length.
    2280           0 :       if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) {
    2281             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2282             :         return;
    2283             :       }
    2284             :       // Read the length of the byte string.
    2285           0 :       token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>(
    2286           0 :           bytes_.subspan(status_.pos + 2));
    2287             :       // Make sure the payload is contained within the message.
    2288           0 :       if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize +
    2289           0 :               status_.pos >
    2290             :           static_cast<std::size_t>(bytes_.size())) {
    2291             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2292             :         return;
    2293             :       }
    2294           0 :       auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2295           0 :       SetToken(CBORTokenTag::ENVELOPE, kEncodedEnvelopeHeaderSize + length);
    2296             :       return;
    2297             :     }
    2298             :     default: {
    2299             :       span<uint8_t> remainder =
    2300           0 :           bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
    2301             :       assert(!remainder.empty());
    2302           0 :       int8_t token_start_length = internals::ReadTokenStart(
    2303           0 :           remainder, &token_start_type_, &token_start_internal_value_);
    2304             :       bool success = token_start_length != -1;
    2305           0 :       switch (token_start_type_) {
    2306             :         case MajorType::UNSIGNED:  // INT32.
    2307           0 :           if (!success || std::numeric_limits<int32_t>::max() <
    2308           0 :                               token_start_internal_value_) {
    2309             :             SetError(Error::CBOR_INVALID_INT32);
    2310           0 :             return;
    2311             :           }
    2312           0 :           SetToken(CBORTokenTag::INT32, token_start_length);
    2313             :           return;
    2314             :         case MajorType::NEGATIVE:  // INT32.
    2315           0 :           if (!success ||
    2316             :               std::numeric_limits<int32_t>::min() >
    2317           0 :                   -static_cast<int64_t>(token_start_internal_value_) - 1) {
    2318             :             SetError(Error::CBOR_INVALID_INT32);
    2319             :             return;
    2320             :           }
    2321           0 :           SetToken(CBORTokenTag::INT32, token_start_length);
    2322             :           return;
    2323             :         case MajorType::STRING: {  // STRING8.
    2324           0 :           if (!success || remainder.size() < static_cast<int64_t>(
    2325           0 :                                                  token_start_internal_value_)) {
    2326             :             SetError(Error::CBOR_INVALID_STRING8);
    2327             :             return;
    2328             :           }
    2329             :           auto length =
    2330           0 :               static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2331           0 :           SetToken(CBORTokenTag::STRING8, token_start_length + length);
    2332             :           return;
    2333             :         }
    2334             :         case MajorType::BYTE_STRING: {  // STRING16.
    2335           0 :           if (!success ||
    2336           0 :               remainder.size() <
    2337           0 :                   static_cast<int64_t>(token_start_internal_value_) ||
    2338             :               // Must be divisible by 2 since UTF16 is 2 bytes per character.
    2339           0 :               token_start_internal_value_ & 1) {
    2340             :             SetError(Error::CBOR_INVALID_STRING16);
    2341             :             return;
    2342             :           }
    2343             :           auto length =
    2344           0 :               static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2345           0 :           SetToken(CBORTokenTag::STRING16, token_start_length + length);
    2346             :           return;
    2347             :         }
    2348             :         case MajorType::ARRAY:
    2349             :         case MajorType::MAP:
    2350             :         case MajorType::TAG:
    2351             :         case MajorType::SIMPLE_VALUE:
    2352             :           SetError(Error::CBOR_UNSUPPORTED_VALUE);
    2353             :           return;
    2354             :       }
    2355             :     }
    2356             :   }
    2357             : }
    2358             : 
    2359           0 : void CBORTokenizer::SetToken(CBORTokenTag token_tag,
    2360             :                              std::ptrdiff_t token_byte_length) {
    2361           0 :   token_tag_ = token_tag;
    2362           0 :   token_byte_length_ = token_byte_length;
    2363           0 : }
    2364             : 
    2365           0 : void CBORTokenizer::SetError(Error error) {
    2366           0 :   token_tag_ = CBORTokenTag::ERROR_VALUE;
    2367           0 :   status_.error = error;
    2368           0 : }
    2369             : 
    2370             : // =============================================================================
    2371             : // cbor::ParseCBOR - for receiving streaming parser events for CBOR messages
    2372             : // =============================================================================
    2373             : 
    2374             : namespace {
    2375             : // When parsing CBOR, we limit recursion depth for objects and arrays
    2376             : // to this constant.
    2377             : static constexpr int kStackLimit = 1000;
    2378             : 
    2379             : // Below are three parsing routines for CBOR, which cover enough
    2380             : // to roundtrip JSON messages.
    2381             : bool ParseMap(int32_t stack_depth,
    2382             :               CBORTokenizer* tokenizer,
    2383             :               StreamingParserHandler* out);
    2384             : bool ParseArray(int32_t stack_depth,
    2385             :                 CBORTokenizer* tokenizer,
    2386             :                 StreamingParserHandler* out);
    2387             : bool ParseValue(int32_t stack_depth,
    2388             :                 CBORTokenizer* tokenizer,
    2389             :                 StreamingParserHandler* out);
    2390             : 
    2391           0 : void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
    2392             :   std::vector<uint16_t> value;
    2393             :   span<uint8_t> rep = tokenizer->GetString16WireRep();
    2394           0 :   for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2)
    2395           0 :     value.push_back((rep[ii + 1] << 8) | rep[ii]);
    2396           0 :   out->HandleString16(span<uint16_t>(value.data(), value.size()));
    2397             :   tokenizer->Next();
    2398           0 : }
    2399             : 
    2400           0 : bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
    2401             :   assert(tokenizer->TokenTag() == CBORTokenTag::STRING8);
    2402           0 :   out->HandleString8(tokenizer->GetString8());
    2403             :   tokenizer->Next();
    2404           0 :   return true;
    2405             : }
    2406             : 
    2407           0 : bool ParseValue(int32_t stack_depth,
    2408             :                 CBORTokenizer* tokenizer,
    2409             :                 StreamingParserHandler* out) {
    2410           0 :   if (stack_depth > kStackLimit) {
    2411           0 :     out->HandleError(
    2412           0 :         Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
    2413           0 :     return false;
    2414             :   }
    2415             :   // Skip past the envelope to get to what's inside.
    2416           0 :   if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
    2417             :     tokenizer->EnterEnvelope();
    2418           0 :   switch (tokenizer->TokenTag()) {
    2419             :     case CBORTokenTag::ERROR_VALUE:
    2420           0 :       out->HandleError(tokenizer->Status());
    2421           0 :       return false;
    2422             :     case CBORTokenTag::DONE:
    2423           0 :       out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
    2424           0 :                               tokenizer->Status().pos});
    2425           0 :       return false;
    2426             :     case CBORTokenTag::TRUE_VALUE:
    2427           0 :       out->HandleBool(true);
    2428             :       tokenizer->Next();
    2429             :       return true;
    2430             :     case CBORTokenTag::FALSE_VALUE:
    2431           0 :       out->HandleBool(false);
    2432             :       tokenizer->Next();
    2433             :       return true;
    2434             :     case CBORTokenTag::NULL_VALUE:
    2435           0 :       out->HandleNull();
    2436             :       tokenizer->Next();
    2437             :       return true;
    2438             :     case CBORTokenTag::INT32:
    2439           0 :       out->HandleInt32(tokenizer->GetInt32());
    2440             :       tokenizer->Next();
    2441             :       return true;
    2442             :     case CBORTokenTag::DOUBLE:
    2443           0 :       out->HandleDouble(tokenizer->GetDouble());
    2444             :       tokenizer->Next();
    2445             :       return true;
    2446             :     case CBORTokenTag::STRING8:
    2447           0 :       return ParseUTF8String(tokenizer, out);
    2448             :     case CBORTokenTag::STRING16:
    2449           0 :       ParseUTF16String(tokenizer, out);
    2450           0 :       return true;
    2451             :     case CBORTokenTag::BINARY: {
    2452           0 :       out->HandleBinary(tokenizer->GetBinary());
    2453             :       tokenizer->Next();
    2454             :       return true;
    2455             :     }
    2456             :     case CBORTokenTag::MAP_START:
    2457           0 :       return ParseMap(stack_depth + 1, tokenizer, out);
    2458             :     case CBORTokenTag::ARRAY_START:
    2459           0 :       return ParseArray(stack_depth + 1, tokenizer, out);
    2460             :     default:
    2461           0 :       out->HandleError(
    2462           0 :           Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos});
    2463           0 :       return false;
    2464             :   }
    2465             : }
    2466             : 
    2467             : // |bytes| must start with the indefinite length array byte, so basically,
    2468             : // ParseArray may only be called after an indefinite length array has been
    2469             : // detected.
    2470           0 : bool ParseArray(int32_t stack_depth,
    2471             :                 CBORTokenizer* tokenizer,
    2472             :                 StreamingParserHandler* out) {
    2473             :   assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
    2474             :   tokenizer->Next();
    2475           0 :   out->HandleArrayBegin();
    2476           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
    2477           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
    2478           0 :       out->HandleError(
    2479           0 :           Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
    2480           0 :       return false;
    2481             :     }
    2482           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2483           0 :       out->HandleError(tokenizer->Status());
    2484           0 :       return false;
    2485             :     }
    2486             :     // Parse value.
    2487           0 :     if (!ParseValue(stack_depth, tokenizer, out))
    2488             :       return false;
    2489             :   }
    2490           0 :   out->HandleArrayEnd();
    2491             :   tokenizer->Next();
    2492             :   return true;
    2493             : }
    2494             : 
    2495             : // |bytes| must start with the indefinite length array byte, so basically,
    2496             : // ParseArray may only be called after an indefinite length array has been
    2497             : // detected.
    2498           0 : bool ParseMap(int32_t stack_depth,
    2499             :               CBORTokenizer* tokenizer,
    2500             :               StreamingParserHandler* out) {
    2501             :   assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START);
    2502           0 :   out->HandleMapBegin();
    2503             :   tokenizer->Next();
    2504           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
    2505           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
    2506           0 :       out->HandleError(
    2507           0 :           Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
    2508           0 :       return false;
    2509             :     }
    2510           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2511           0 :       out->HandleError(tokenizer->Status());
    2512           0 :       return false;
    2513             :     }
    2514             :     // Parse key.
    2515           0 :     if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
    2516           0 :       if (!ParseUTF8String(tokenizer, out))
    2517             :         return false;
    2518           0 :     } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
    2519           0 :       ParseUTF16String(tokenizer, out);
    2520             :     } else {
    2521           0 :       out->HandleError(
    2522           0 :           Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos});
    2523           0 :       return false;
    2524             :     }
    2525             :     // Parse value.
    2526           0 :     if (!ParseValue(stack_depth, tokenizer, out))
    2527             :       return false;
    2528             :   }
    2529           0 :   out->HandleMapEnd();
    2530             :   tokenizer->Next();
    2531             :   return true;
    2532             : }
    2533             : }  // namespace
    2534             : 
    2535           0 : void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) {
    2536           0 :   if (bytes.empty()) {
    2537           0 :     out->HandleError(Status{Error::CBOR_NO_INPUT, 0});
    2538           0 :     return;
    2539             :   }
    2540           0 :   if (bytes[0] != kInitialByteForEnvelope) {
    2541           0 :     out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0});
    2542           0 :     return;
    2543             :   }
    2544             :   CBORTokenizer tokenizer(bytes);
    2545           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2546           0 :     out->HandleError(tokenizer.Status());
    2547           0 :     return;
    2548             :   }
    2549             :   // We checked for the envelope start byte above, so the tokenizer
    2550             :   // must agree here, since it's not an error.
    2551             :   assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
    2552             :   tokenizer.EnterEnvelope();
    2553           0 :   if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
    2554           0 :     out->HandleError(
    2555           0 :         Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
    2556           0 :     return;
    2557             :   }
    2558           0 :   if (!ParseMap(/*stack_depth=*/1, &tokenizer, out))
    2559             :     return;
    2560           0 :   if (tokenizer.TokenTag() == CBORTokenTag::DONE)
    2561             :     return;
    2562           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2563           0 :     out->HandleError(tokenizer.Status());
    2564           0 :     return;
    2565             :   }
    2566           0 :   out->HandleError(Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos});
    2567             : }
    2568             : }  // namespace cbor
    2569             : 
    2570             : namespace json {
    2571             : 
    2572             : // =============================================================================
    2573             : // json::NewJSONEncoder - for encoding streaming parser events as JSON
    2574             : // =============================================================================
    2575             : 
    2576             : namespace {
    2577             : // Prints |value| to |out| with 4 hex digits, most significant chunk first.
    2578           0 : void PrintHex(uint16_t value, std::string* out) {
    2579           0 :   for (int ii = 3; ii >= 0; --ii) {
    2580           0 :     int four_bits = 0xf & (value >> (4 * ii));
    2581           0 :     out->append(1, four_bits + ((four_bits <= 9) ? '0' : ('a' - 10)));
    2582             :   }
    2583           0 : }
    2584             : 
    2585             : // In the writer below, we maintain a stack of State instances.
    2586             : // It is just enough to emit the appropriate delimiters and brackets
    2587             : // in JSON.
    2588             : enum class Container {
    2589             :   // Used for the top-level, initial state.
    2590             :   NONE,
    2591             :   // Inside a JSON object.
    2592             :   MAP,
    2593             :   // Inside a JSON array.
    2594             :   ARRAY
    2595             : };
    2596             : class State {
    2597             :  public:
    2598           0 :   explicit State(Container container) : container_(container) {}
    2599           0 :   void StartElement(std::string* out) {
    2600             :     assert(container_ != Container::NONE || size_ == 0);
    2601           0 :     if (size_ != 0) {
    2602           0 :       char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':';
    2603             :       out->append(1, delim);
    2604             :     }
    2605           0 :     ++size_;
    2606           0 :   }
    2607             :   Container container() const { return container_; }
    2608             : 
    2609             :  private:
    2610             :   Container container_ = Container::NONE;
    2611             :   int size_ = 0;
    2612             : };
    2613             : 
    2614             : constexpr char kBase64Table[] =
    2615             :     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    2616             :     "abcdefghijklmnopqrstuvwxyz0123456789+/";
    2617             : 
    2618           0 : void Base64Encode(const span<uint8_t>& in, std::string* out) {
    2619             :   // The following three cases are based on the tables in the example
    2620             :   // section in https://en.wikipedia.org/wiki/Base64. We process three
    2621             :   // input bytes at a time, emitting 4 output bytes at a time.
    2622             :   std::ptrdiff_t ii = 0;
    2623             : 
    2624             :   // While possible, process three input bytes.
    2625           0 :   for (; ii + 3 <= in.size(); ii += 3) {
    2626           0 :     uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2];
    2627           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
    2628           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
    2629           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
    2630           0 :     out->push_back(kBase64Table[twentyfour_bits & 0x3f]);
    2631             :   }
    2632           0 :   if (ii + 2 <= in.size()) {  // Process two input bytes.
    2633           0 :     uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8);
    2634           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
    2635           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
    2636           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
    2637           0 :     out->push_back('=');  // Emit padding.
    2638           0 :     return;
    2639             :   }
    2640           0 :   if (ii + 1 <= in.size()) {  // Process a single input byte.
    2641           0 :     uint32_t twentyfour_bits = (in[ii] << 16);
    2642           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
    2643           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
    2644           0 :     out->push_back('=');  // Emit padding.
    2645           0 :     out->push_back('=');  // Emit padding.
    2646             :   }
    2647             : }
    2648             : 
    2649             : // Implements a handler for JSON parser events to emit a JSON string.
    2650           0 : class JSONEncoder : public StreamingParserHandler {
    2651             :  public:
    2652           0 :   JSONEncoder(const Platform* platform, std::string* out, Status* status)
    2653           0 :       : platform_(platform), out_(out), status_(status) {
    2654           0 :     *status_ = Status();
    2655           0 :     state_.emplace(Container::NONE);
    2656           0 :   }
    2657             : 
    2658           0 :   void HandleMapBegin() override {
    2659           0 :     if (!status_->ok())
    2660             :       return;
    2661             :     assert(!state_.empty());
    2662           0 :     state_.top().StartElement(out_);
    2663           0 :     state_.emplace(Container::MAP);
    2664           0 :     out_->append("{");
    2665             :   }
    2666             : 
    2667           0 :   void HandleMapEnd() override {
    2668           0 :     if (!status_->ok())
    2669             :       return;
    2670             :     assert(state_.size() >= 2 && state_.top().container() == Container::MAP);
    2671             :     state_.pop();
    2672           0 :     out_->append("}");
    2673             :   }
    2674             : 
    2675           0 :   void HandleArrayBegin() override {
    2676           0 :     if (!status_->ok())
    2677             :       return;
    2678           0 :     state_.top().StartElement(out_);
    2679           0 :     state_.emplace(Container::ARRAY);
    2680           0 :     out_->append("[");
    2681             :   }
    2682             : 
    2683           0 :   void HandleArrayEnd() override {
    2684           0 :     if (!status_->ok())
    2685             :       return;
    2686             :     assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY);
    2687             :     state_.pop();
    2688           0 :     out_->append("]");
    2689             :   }
    2690             : 
    2691           0 :   void HandleString16(span<uint16_t> chars) override {
    2692           0 :     if (!status_->ok())
    2693             :       return;
    2694           0 :     state_.top().StartElement(out_);
    2695           0 :     out_->append("\"");
    2696           0 :     for (const uint16_t ch : chars) {
    2697           0 :       if (ch == '"') {
    2698           0 :         out_->append("\\\"");
    2699           0 :       } else if (ch == '\\') {
    2700           0 :         out_->append("\\\\");
    2701           0 :       } else if (ch == '\b') {
    2702           0 :         out_->append("\\b");
    2703           0 :       } else if (ch == '\f') {
    2704           0 :         out_->append("\\f");
    2705           0 :       } else if (ch == '\n') {
    2706           0 :         out_->append("\\n");
    2707           0 :       } else if (ch == '\r') {
    2708           0 :         out_->append("\\r");
    2709           0 :       } else if (ch == '\t') {
    2710           0 :         out_->append("\\t");
    2711           0 :       } else if (ch >= 32 && ch <= 126) {
    2712           0 :         out_->append(1, ch);
    2713             :       } else {
    2714           0 :         out_->append("\\u");
    2715           0 :         PrintHex(ch, out_);
    2716             :       }
    2717             :     }
    2718           0 :     out_->append("\"");
    2719             :   }
    2720             : 
    2721           0 :   void HandleString8(span<uint8_t> chars) override {
    2722           0 :     if (!status_->ok())
    2723             :       return;
    2724           0 :     state_.top().StartElement(out_);
    2725           0 :     out_->append("\"");
    2726           0 :     for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) {
    2727           0 :       uint8_t c = chars[ii];
    2728           0 :       if (c == '"') {
    2729           0 :         out_->append("\\\"");
    2730           0 :       } else if (c == '\\') {
    2731           0 :         out_->append("\\\\");
    2732           0 :       } else if (c == '\b') {
    2733           0 :         out_->append("\\b");
    2734           0 :       } else if (c == '\f') {
    2735           0 :         out_->append("\\f");
    2736           0 :       } else if (c == '\n') {
    2737           0 :         out_->append("\\n");
    2738           0 :       } else if (c == '\r') {
    2739           0 :         out_->append("\\r");
    2740           0 :       } else if (c == '\t') {
    2741           0 :         out_->append("\\t");
    2742           0 :       } else if (c >= 32 && c <= 126) {
    2743           0 :         out_->append(1, c);
    2744           0 :       } else if (c < 32) {
    2745           0 :         out_->append("\\u");
    2746           0 :         PrintHex(static_cast<uint16_t>(c), out_);
    2747             :       } else {
    2748             :         // Inspect the leading byte to figure out how long the utf8
    2749             :         // byte sequence is; while doing this initialize |codepoint|
    2750             :         // with the first few bits.
    2751             :         // See table in: https://en.wikipedia.org/wiki/UTF-8
    2752             :         // byte one is 110x xxxx -> 2 byte utf8 sequence
    2753             :         // byte one is 1110 xxxx -> 3 byte utf8 sequence
    2754             :         // byte one is 1111 0xxx -> 4 byte utf8 sequence
    2755             :         uint32_t codepoint;
    2756             :         int num_bytes_left;
    2757           0 :         if ((c & 0xe0) == 0xc0) {  // 2 byte utf8 sequence
    2758             :           num_bytes_left = 1;
    2759           0 :           codepoint = c & 0x1f;
    2760           0 :         } else if ((c & 0xf0) == 0xe0) {  // 3 byte utf8 sequence
    2761             :           num_bytes_left = 2;
    2762           0 :           codepoint = c & 0x0f;
    2763           0 :         } else if ((c & 0xf8) == 0xf0) {  // 4 byte utf8 sequence
    2764           0 :           codepoint = c & 0x07;
    2765             :           num_bytes_left = 3;
    2766             :         } else {
    2767             :           continue;  // invalid leading byte
    2768             :         }
    2769             : 
    2770             :         // If we have enough bytes in our input, decode the remaining ones
    2771             :         // belonging to this Unicode character into |codepoint|.
    2772           0 :         if (ii + num_bytes_left > chars.size())
    2773             :           continue;
    2774           0 :         while (num_bytes_left > 0) {
    2775           0 :           c = chars[++ii];
    2776           0 :           --num_bytes_left;
    2777             :           // Check the next byte is a continuation byte, that is 10xx xxxx.
    2778           0 :           if ((c & 0xc0) != 0x80)
    2779             :             continue;
    2780           0 :           codepoint = (codepoint << 6) | (c & 0x3f);
    2781             :         }
    2782             : 
    2783             :         // Disallow overlong encodings for ascii characters, as these
    2784             :         // would include " and other characters significant to JSON
    2785             :         // string termination / control.
    2786           0 :         if (codepoint < 0x7f)
    2787             :           continue;
    2788             :         // Invalid in UTF8, and can't be represented in UTF16 anyway.
    2789           0 :         if (codepoint > 0x10ffff)
    2790             :           continue;
    2791             : 
    2792             :         // So, now we transcode to UTF16,
    2793             :         // using the math described at https://en.wikipedia.org/wiki/UTF-16,
    2794             :         // for either one or two 16 bit characters.
    2795           0 :         if (codepoint < 0xffff) {
    2796           0 :           out_->append("\\u");
    2797           0 :           PrintHex(static_cast<uint16_t>(codepoint), out_);
    2798           0 :           continue;
    2799             :         }
    2800           0 :         codepoint -= 0x10000;
    2801             :         // high surrogate
    2802           0 :         out_->append("\\u");
    2803           0 :         PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_);
    2804             :         // low surrogate
    2805           0 :         out_->append("\\u");
    2806           0 :         PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_);
    2807             :       }
    2808             :     }
    2809           0 :     out_->append("\"");
    2810             :   }
    2811             : 
    2812           0 :   void HandleBinary(span<uint8_t> bytes) override {
    2813           0 :     if (!status_->ok())
    2814             :       return;
    2815           0 :     state_.top().StartElement(out_);
    2816           0 :     out_->append("\"");
    2817           0 :     Base64Encode(bytes, out_);
    2818           0 :     out_->append("\"");
    2819             :   }
    2820             : 
    2821           0 :   void HandleDouble(double value) override {
    2822           0 :     if (!status_->ok())
    2823           0 :       return;
    2824           0 :     state_.top().StartElement(out_);
    2825           0 :     std::unique_ptr<char[]> str_value = platform_->DToStr(value);
    2826             : 
    2827             :     // DToStr may fail to emit a 0 before the decimal dot. E.g. this is
    2828             :     // the case in base::NumberToString in Chromium (which is based on
    2829             :     // dmg_fp). So, much like
    2830             :     // https://cs.chromium.org/chromium/src/base/json/json_writer.cc
    2831             :     // we probe for this and emit the leading 0 anyway if necessary.
    2832             :     const char* chars = str_value.get();
    2833           0 :     if (chars[0] == '.') {
    2834           0 :       out_->append("0");
    2835           0 :     } else if (chars[0] == '-' && chars[1] == '.') {
    2836           0 :       out_->append("-0");
    2837           0 :       ++chars;
    2838             :     }
    2839           0 :     out_->append(chars);
    2840             :   }
    2841             : 
    2842           0 :   void HandleInt32(int32_t value) override {
    2843           0 :     if (!status_->ok())
    2844             :       return;
    2845           0 :     state_.top().StartElement(out_);
    2846           0 :     out_->append(std::to_string(value));
    2847             :   }
    2848             : 
    2849           0 :   void HandleBool(bool value) override {
    2850           0 :     if (!status_->ok())
    2851             :       return;
    2852           0 :     state_.top().StartElement(out_);
    2853           0 :     out_->append(value ? "true" : "false");
    2854             :   }
    2855             : 
    2856           0 :   void HandleNull() override {
    2857           0 :     if (!status_->ok())
    2858             :       return;
    2859           0 :     state_.top().StartElement(out_);
    2860           0 :     out_->append("null");
    2861             :   }
    2862             : 
    2863           0 :   void HandleError(Status error) override {
    2864             :     assert(!error.ok());
    2865           0 :     *status_ = error;
    2866           0 :     out_->clear();
    2867           0 :   }
    2868             : 
    2869             :  private:
    2870             :   const Platform* platform_;
    2871             :   std::string* out_;
    2872             :   Status* status_;
    2873             :   std::stack<State> state_;
    2874             : };
    2875             : }  // namespace
    2876             : 
    2877           0 : std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform,
    2878             :                                                        std::string* out,
    2879             :                                                        Status* status) {
    2880             :   return std::unique_ptr<StreamingParserHandler>(
    2881           0 :       new JSONEncoder(platform, out, status));
    2882             : }
    2883             : 
    2884             : // =============================================================================
    2885             : // json::ParseJSON - for receiving streaming parser events for JSON.
    2886             : // =============================================================================
    2887             : 
    2888             : namespace {
    2889             : const int kStackLimit = 1000;
    2890             : 
    2891             : enum Token {
    2892             :   ObjectBegin,
    2893             :   ObjectEnd,
    2894             :   ArrayBegin,
    2895             :   ArrayEnd,
    2896             :   StringLiteral,
    2897             :   Number,
    2898             :   BoolTrue,
    2899             :   BoolFalse,
    2900             :   NullToken,
    2901             :   ListSeparator,
    2902             :   ObjectPairSeparator,
    2903             :   InvalidToken,
    2904             :   NoInput
    2905             : };
    2906             : 
    2907             : const char* const kNullString = "null";
    2908             : const char* const kTrueString = "true";
    2909             : const char* const kFalseString = "false";
    2910             : 
    2911             : template <typename Char>
    2912             : class JsonParser {
    2913             :  public:
    2914             :   JsonParser(const Platform* platform, StreamingParserHandler* handler)
    2915           0 :       : platform_(platform), handler_(handler) {}
    2916             : 
    2917           0 :   void Parse(const Char* start, std::size_t length) {
    2918           0 :     start_pos_ = start;
    2919           0 :     const Char* end = start + length;
    2920             :     const Char* tokenEnd;
    2921           0 :     ParseValue(start, end, &tokenEnd, 0);
    2922           0 :     if (tokenEnd != end) {
    2923             :       HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd);
    2924             :     }
    2925           0 :   }
    2926             : 
    2927             :  private:
    2928           0 :   bool CharsToDouble(const uint16_t* chars,
    2929             :                      std::size_t length,
    2930             :                      double* result) {
    2931             :     std::string buffer;
    2932           0 :     buffer.reserve(length + 1);
    2933           0 :     for (std::size_t ii = 0; ii < length; ++ii) {
    2934           0 :       bool is_ascii = !(chars[ii] & ~0x7F);
    2935           0 :       if (!is_ascii)
    2936             :         return false;
    2937           0 :       buffer.push_back(static_cast<char>(chars[ii]));
    2938             :     }
    2939           0 :     return platform_->StrToD(buffer.c_str(), result);
    2940             :   }
    2941             : 
    2942           0 :   bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) {
    2943             :     std::string buffer(reinterpret_cast<const char*>(chars), length);
    2944           0 :     return platform_->StrToD(buffer.c_str(), result);
    2945             :   }
    2946             : 
    2947             :   static bool ParseConstToken(const Char* start,
    2948             :                               const Char* end,
    2949             :                               const Char** token_end,
    2950             :                               const char* token) {
    2951             :     // |token| is \0 terminated, it's one of the constants at top of the file.
    2952           0 :     while (start < end && *token != '\0' && *start++ == *token++) {
    2953             :     }
    2954           0 :     if (*token != '\0')
    2955             :       return false;
    2956           0 :     *token_end = start;
    2957             :     return true;
    2958             :   }
    2959             : 
    2960             :   static bool ReadInt(const Char* start,
    2961             :                       const Char* end,
    2962             :                       const Char** token_end,
    2963             :                       bool allow_leading_zeros) {
    2964           0 :     if (start == end)
    2965             :       return false;
    2966           0 :     bool has_leading_zero = '0' == *start;
    2967             :     int length = 0;
    2968           0 :     while (start < end && '0' <= *start && *start <= '9') {
    2969           0 :       ++start;
    2970           0 :       ++length;
    2971             :     }
    2972           0 :     if (!length)
    2973             :       return false;
    2974           0 :     if (!allow_leading_zeros && length > 1 && has_leading_zero)
    2975             :       return false;
    2976             :     *token_end = start;
    2977             :     return true;
    2978             :   }
    2979             : 
    2980           0 :   static bool ParseNumberToken(const Char* start,
    2981             :                                const Char* end,
    2982             :                                const Char** token_end) {
    2983             :     // We just grab the number here. We validate the size in DecodeNumber.
    2984             :     // According to RFC4627, a valid number is: [minus] int [frac] [exp]
    2985           0 :     if (start == end)
    2986             :       return false;
    2987           0 :     Char c = *start;
    2988           0 :     if ('-' == c)
    2989           0 :       ++start;
    2990             : 
    2991           0 :     if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false))
    2992             :       return false;
    2993           0 :     if (start == end) {
    2994           0 :       *token_end = start;
    2995           0 :       return true;
    2996             :     }
    2997             : 
    2998             :     // Optional fraction part
    2999           0 :     c = *start;
    3000           0 :     if ('.' == c) {
    3001           0 :       ++start;
    3002           0 :       if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
    3003             :         return false;
    3004           0 :       if (start == end) {
    3005           0 :         *token_end = start;
    3006           0 :         return true;
    3007             :       }
    3008           0 :       c = *start;
    3009             :     }
    3010             : 
    3011             :     // Optional exponent part
    3012           0 :     if ('e' == c || 'E' == c) {
    3013           0 :       ++start;
    3014           0 :       if (start == end)
    3015             :         return false;
    3016           0 :       c = *start;
    3017           0 :       if ('-' == c || '+' == c) {
    3018           0 :         ++start;
    3019           0 :         if (start == end)
    3020             :           return false;
    3021             :       }
    3022           0 :       if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
    3023             :         return false;
    3024             :     }
    3025             : 
    3026           0 :     *token_end = start;
    3027           0 :     return true;
    3028             :   }
    3029             : 
    3030             :   static bool ReadHexDigits(const Char* start,
    3031             :                             const Char* end,
    3032             :                             const Char** token_end,
    3033             :                             int digits) {
    3034           0 :     if (end - start < digits)
    3035             :       return false;
    3036           0 :     for (int i = 0; i < digits; ++i) {
    3037           0 :       Char c = *start++;
    3038           0 :       if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
    3039             :             ('A' <= c && c <= 'F')))
    3040             :         return false;
    3041             :     }
    3042             :     *token_end = start;
    3043             :     return true;
    3044             :   }
    3045             : 
    3046           0 :   static bool ParseStringToken(const Char* start,
    3047             :                                const Char* end,
    3048             :                                const Char** token_end) {
    3049           0 :     while (start < end) {
    3050           0 :       Char c = *start++;
    3051           0 :       if ('\\' == c) {
    3052           0 :         if (start == end)
    3053             :           return false;
    3054           0 :         c = *start++;
    3055             :         // Make sure the escaped char is valid.
    3056           0 :         switch (c) {
    3057             :           case 'x':
    3058           0 :             if (!ReadHexDigits(start, end, &start, 2))
    3059             :               return false;
    3060             :             break;
    3061             :           case 'u':
    3062           0 :             if (!ReadHexDigits(start, end, &start, 4))
    3063             :               return false;
    3064             :             break;
    3065             :           case '\\':
    3066             :           case '/':
    3067             :           case 'b':
    3068             :           case 'f':
    3069             :           case 'n':
    3070             :           case 'r':
    3071             :           case 't':
    3072             :           case 'v':
    3073             :           case '"':
    3074             :             break;
    3075             :           default:
    3076             :             return false;
    3077             :         }
    3078           0 :       } else if ('"' == c) {
    3079           0 :         *token_end = start;
    3080           0 :         return true;
    3081             :       }
    3082             :     }
    3083             :     return false;
    3084             :   }
    3085             : 
    3086           0 :   static bool SkipComment(const Char* start,
    3087             :                           const Char* end,
    3088             :                           const Char** comment_end) {
    3089           0 :     if (start == end)
    3090             :       return false;
    3091             : 
    3092           0 :     if (*start != '/' || start + 1 >= end)
    3093             :       return false;
    3094             :     ++start;
    3095             : 
    3096           0 :     if (*start == '/') {
    3097             :       // Single line comment, read to newline.
    3098           0 :       for (++start; start < end; ++start) {
    3099           0 :         if (*start == '\n' || *start == '\r') {
    3100           0 :           *comment_end = start + 1;
    3101           0 :           return true;
    3102             :         }
    3103             :       }
    3104           0 :       *comment_end = end;
    3105             :       // Comment reaches end-of-input, which is fine.
    3106           0 :       return true;
    3107             :     }
    3108             : 
    3109           0 :     if (*start == '*') {
    3110             :       Char previous = '\0';
    3111             :       // Block comment, read until end marker.
    3112           0 :       for (++start; start < end; previous = *start++) {
    3113           0 :         if (previous == '*' && *start == '/') {
    3114           0 :           *comment_end = start + 1;
    3115           0 :           return true;
    3116             :         }
    3117             :       }
    3118             :       // Block comment must close before end-of-input.
    3119             :       return false;
    3120             :     }
    3121             : 
    3122             :     return false;
    3123             :   }
    3124             : 
    3125             :   static bool IsSpaceOrNewLine(Char c) {
    3126             :     // \v = vertial tab; \f = form feed page break.
    3127             :     return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' ||
    3128           0 :            c == '\t';
    3129             :   }
    3130             : 
    3131           0 :   static void SkipWhitespaceAndComments(const Char* start,
    3132             :                                         const Char* end,
    3133             :                                         const Char** whitespace_end) {
    3134           0 :     while (start < end) {
    3135           0 :       if (IsSpaceOrNewLine(*start)) {
    3136           0 :         ++start;
    3137           0 :       } else if (*start == '/') {
    3138             :         const Char* comment_end;
    3139           0 :         if (!SkipComment(start, end, &comment_end))
    3140             :           break;
    3141           0 :         start = comment_end;
    3142             :       } else {
    3143             :         break;
    3144             :       }
    3145             :     }
    3146           0 :     *whitespace_end = start;
    3147           0 :   }
    3148             : 
    3149           0 :   static Token ParseToken(const Char* start,
    3150             :                           const Char* end,
    3151             :                           const Char** tokenStart,
    3152             :                           const Char** token_end) {
    3153           0 :     SkipWhitespaceAndComments(start, end, tokenStart);
    3154           0 :     start = *tokenStart;
    3155             : 
    3156           0 :     if (start == end)
    3157             :       return NoInput;
    3158             : 
    3159           0 :     switch (*start) {
    3160             :       case 'n':
    3161           0 :         if (ParseConstToken(start, end, token_end, kNullString))
    3162             :           return NullToken;
    3163             :         break;
    3164             :       case 't':
    3165           0 :         if (ParseConstToken(start, end, token_end, kTrueString))
    3166             :           return BoolTrue;
    3167             :         break;
    3168             :       case 'f':
    3169           0 :         if (ParseConstToken(start, end, token_end, kFalseString))
    3170             :           return BoolFalse;
    3171             :         break;
    3172             :       case '[':
    3173           0 :         *token_end = start + 1;
    3174           0 :         return ArrayBegin;
    3175             :       case ']':
    3176           0 :         *token_end = start + 1;
    3177           0 :         return ArrayEnd;
    3178             :       case ',':
    3179           0 :         *token_end = start + 1;
    3180           0 :         return ListSeparator;
    3181             :       case '{':
    3182           0 :         *token_end = start + 1;
    3183           0 :         return ObjectBegin;
    3184             :       case '}':
    3185           0 :         *token_end = start + 1;
    3186           0 :         return ObjectEnd;
    3187             :       case ':':
    3188           0 :         *token_end = start + 1;
    3189           0 :         return ObjectPairSeparator;
    3190             :       case '0':
    3191             :       case '1':
    3192             :       case '2':
    3193             :       case '3':
    3194             :       case '4':
    3195             :       case '5':
    3196             :       case '6':
    3197             :       case '7':
    3198             :       case '8':
    3199             :       case '9':
    3200             :       case '-':
    3201           0 :         if (ParseNumberToken(start, end, token_end))
    3202             :           return Number;
    3203             :         break;
    3204             :       case '"':
    3205           0 :         if (ParseStringToken(start + 1, end, token_end))
    3206             :           return StringLiteral;
    3207             :         break;
    3208             :     }
    3209             :     return InvalidToken;
    3210             :   }
    3211             : 
    3212             :   static int HexToInt(Char c) {
    3213           0 :     if ('0' <= c && c <= '9')
    3214           0 :       return c - '0';
    3215           0 :     if ('A' <= c && c <= 'F')
    3216           0 :       return c - 'A' + 10;
    3217           0 :     if ('a' <= c && c <= 'f')
    3218           0 :       return c - 'a' + 10;
    3219             :     assert(false);  // Unreachable.
    3220             :     return 0;
    3221             :   }
    3222             : 
    3223           0 :   static bool DecodeString(const Char* start,
    3224             :                            const Char* end,
    3225             :                            std::vector<uint16_t>* output) {
    3226           0 :     if (start == end)
    3227             :       return true;
    3228           0 :     if (start > end)
    3229             :       return false;
    3230           0 :     output->reserve(end - start);
    3231           0 :     while (start < end) {
    3232           0 :       uint16_t c = *start++;
    3233             :       // If the |Char| we're dealing with is really a byte, then
    3234             :       // we have utf8 here, and we need to check for multibyte characters
    3235             :       // and transcode them to utf16 (either one or two utf16 chars).
    3236           0 :       if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) {
    3237             :         // Inspect the leading byte to figure out how long the utf8
    3238             :         // byte sequence is; while doing this initialize |codepoint|
    3239             :         // with the first few bits.
    3240             :         // See table in: https://en.wikipedia.org/wiki/UTF-8
    3241             :         // byte one is 110x xxxx -> 2 byte utf8 sequence
    3242             :         // byte one is 1110 xxxx -> 3 byte utf8 sequence
    3243             :         // byte one is 1111 0xxx -> 4 byte utf8 sequence
    3244             :         uint32_t codepoint;
    3245             :         int num_bytes_left;
    3246           0 :         if ((c & 0xe0) == 0xc0) {  // 2 byte utf8 sequence
    3247             :           num_bytes_left = 1;
    3248           0 :           codepoint = c & 0x1f;
    3249           0 :         } else if ((c & 0xf0) == 0xe0) {  // 3 byte utf8 sequence
    3250             :           num_bytes_left = 2;
    3251           0 :           codepoint = c & 0x0f;
    3252           0 :         } else if ((c & 0xf8) == 0xf0) {  // 4 byte utf8 sequence
    3253           0 :           codepoint = c & 0x07;
    3254             :           num_bytes_left = 3;
    3255             :         } else {
    3256           0 :           return false;  // invalid leading byte
    3257             :         }
    3258             : 
    3259             :         // If we have enough bytes in our inpput, decode the remaining ones
    3260             :         // belonging to this Unicode character into |codepoint|.
    3261           0 :         if (start + num_bytes_left > end)
    3262             :           return false;
    3263           0 :         while (num_bytes_left > 0) {
    3264           0 :           c = *start++;
    3265           0 :           --num_bytes_left;
    3266             :           // Check the next byte is a continuation byte, that is 10xx xxxx.
    3267           0 :           if ((c & 0xc0) != 0x80)
    3268             :             return false;
    3269           0 :           codepoint = (codepoint << 6) | (c & 0x3f);
    3270             :         }
    3271             : 
    3272             :         // Disallow overlong encodings for ascii characters, as these
    3273             :         // would include " and other characters significant to JSON
    3274             :         // string termination / control.
    3275           0 :         if (codepoint < 0x7f)
    3276             :           return false;
    3277             :         // Invalid in UTF8, and can't be represented in UTF16 anyway.
    3278           0 :         if (codepoint > 0x10ffff)
    3279             :           return false;
    3280             : 
    3281             :         // So, now we transcode to UTF16,
    3282             :         // using the math described at https://en.wikipedia.org/wiki/UTF-16,
    3283             :         // for either one or two 16 bit characters.
    3284           0 :         if (codepoint < 0xffff) {
    3285           0 :           output->push_back(codepoint);
    3286           0 :           continue;
    3287             :         }
    3288           0 :         codepoint -= 0x10000;
    3289           0 :         output->push_back((codepoint >> 10) + 0xd800);    // high surrogate
    3290           0 :         output->push_back((codepoint & 0x3ff) + 0xdc00);  // low surrogate
    3291           0 :         continue;
    3292             :       }
    3293           0 :       if ('\\' != c) {
    3294           0 :         output->push_back(c);
    3295           0 :         continue;
    3296             :       }
    3297           0 :       if (start == end)
    3298             :         return false;
    3299           0 :       c = *start++;
    3300             : 
    3301           0 :       if (c == 'x') {
    3302             :         // \x is not supported.
    3303             :         return false;
    3304             :       }
    3305             : 
    3306           0 :       switch (c) {
    3307             :         case '"':
    3308             :         case '/':
    3309             :         case '\\':
    3310             :           break;
    3311             :         case 'b':
    3312           0 :           c = '\b';
    3313           0 :           break;
    3314             :         case 'f':
    3315           0 :           c = '\f';
    3316           0 :           break;
    3317             :         case 'n':
    3318           0 :           c = '\n';
    3319           0 :           break;
    3320             :         case 'r':
    3321           0 :           c = '\r';
    3322           0 :           break;
    3323             :         case 't':
    3324           0 :           c = '\t';
    3325           0 :           break;
    3326             :         case 'v':
    3327           0 :           c = '\v';
    3328           0 :           break;
    3329             :         case 'u':
    3330           0 :           c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) +
    3331           0 :               (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3));
    3332           0 :           start += 4;
    3333           0 :           break;
    3334             :         default:
    3335             :           return false;
    3336             :       }
    3337           0 :       output->push_back(c);
    3338             :     }
    3339             :     return true;
    3340             :   }
    3341             : 
    3342           0 :   void ParseValue(const Char* start,
    3343             :                   const Char* end,
    3344             :                   const Char** value_token_end,
    3345             :                   int depth) {
    3346           0 :     if (depth > kStackLimit) {
    3347             :       HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start);
    3348           0 :       return;
    3349             :     }
    3350             :     const Char* token_start;
    3351             :     const Char* token_end;
    3352           0 :     Token token = ParseToken(start, end, &token_start, &token_end);
    3353           0 :     switch (token) {
    3354             :       case NoInput:
    3355           0 :         HandleError(Error::JSON_PARSER_NO_INPUT, token_start);
    3356             :         return;
    3357             :       case InvalidToken:
    3358           0 :         HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start);
    3359             :         return;
    3360             :       case NullToken:
    3361           0 :         handler_->HandleNull();
    3362           0 :         break;
    3363             :       case BoolTrue:
    3364           0 :         handler_->HandleBool(true);
    3365           0 :         break;
    3366             :       case BoolFalse:
    3367           0 :         handler_->HandleBool(false);
    3368           0 :         break;
    3369             :       case Number: {
    3370             :         double value;
    3371           0 :         if (!CharsToDouble(token_start, token_end - token_start, &value)) {
    3372           0 :           HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start);
    3373           0 :           return;
    3374             :         }
    3375           0 :         if (value >= std::numeric_limits<int32_t>::min() &&
    3376             :             value <= std::numeric_limits<int32_t>::max() &&
    3377             :             static_cast<int32_t>(value) == value)
    3378           0 :           handler_->HandleInt32(static_cast<int32_t>(value));
    3379             :         else
    3380           0 :           handler_->HandleDouble(value);
    3381           0 :         break;
    3382             :       }
    3383             :       case StringLiteral: {
    3384             :         std::vector<uint16_t> value;
    3385           0 :         bool ok = DecodeString(token_start + 1, token_end - 1, &value);
    3386           0 :         if (!ok) {
    3387           0 :           HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
    3388             :           return;
    3389             :         }
    3390           0 :         handler_->HandleString16(span<uint16_t>(value.data(), value.size()));
    3391             :         break;
    3392             :       }
    3393             :       case ArrayBegin: {
    3394           0 :         handler_->HandleArrayBegin();
    3395           0 :         start = token_end;
    3396           0 :         token = ParseToken(start, end, &token_start, &token_end);
    3397           0 :         while (token != ArrayEnd) {
    3398           0 :           ParseValue(start, end, &token_end, depth + 1);
    3399           0 :           if (error_)
    3400             :             return;
    3401             : 
    3402             :           // After a list value, we expect a comma or the end of the list.
    3403           0 :           start = token_end;
    3404           0 :           token = ParseToken(start, end, &token_start, &token_end);
    3405           0 :           if (token == ListSeparator) {
    3406           0 :             start = token_end;
    3407           0 :             token = ParseToken(start, end, &token_start, &token_end);
    3408           0 :             if (token == ArrayEnd) {
    3409           0 :               HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start);
    3410             :               return;
    3411             :             }
    3412           0 :           } else if (token != ArrayEnd) {
    3413             :             // Unexpected value after list value. Bail out.
    3414           0 :             HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED,
    3415             :                         token_start);
    3416             :             return;
    3417             :           }
    3418             :         }
    3419           0 :         handler_->HandleArrayEnd();
    3420           0 :         break;
    3421             :       }
    3422             :       case ObjectBegin: {
    3423           0 :         handler_->HandleMapBegin();
    3424           0 :         start = token_end;
    3425           0 :         token = ParseToken(start, end, &token_start, &token_end);
    3426           0 :         while (token != ObjectEnd) {
    3427           0 :           if (token != StringLiteral) {
    3428           0 :             HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED,
    3429             :                         token_start);
    3430           0 :             return;
    3431             :           }
    3432             :           std::vector<uint16_t> key;
    3433           0 :           if (!DecodeString(token_start + 1, token_end - 1, &key)) {
    3434           0 :             HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
    3435             :             return;
    3436             :           }
    3437           0 :           handler_->HandleString16(span<uint16_t>(key.data(), key.size()));
    3438           0 :           start = token_end;
    3439             : 
    3440           0 :           token = ParseToken(start, end, &token_start, &token_end);
    3441           0 :           if (token != ObjectPairSeparator) {
    3442           0 :             HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start);
    3443             :             return;
    3444             :           }
    3445           0 :           start = token_end;
    3446             : 
    3447           0 :           ParseValue(start, end, &token_end, depth + 1);
    3448           0 :           if (error_)
    3449             :             return;
    3450           0 :           start = token_end;
    3451             : 
    3452             :           // After a key/value pair, we expect a comma or the end of the
    3453             :           // object.
    3454           0 :           token = ParseToken(start, end, &token_start, &token_end);
    3455           0 :           if (token == ListSeparator) {
    3456           0 :             start = token_end;
    3457           0 :             token = ParseToken(start, end, &token_start, &token_end);
    3458           0 :             if (token == ObjectEnd) {
    3459           0 :               HandleError(Error::JSON_PARSER_UNEXPECTED_MAP_END, token_start);
    3460             :               return;
    3461             :             }
    3462           0 :           } else if (token != ObjectEnd) {
    3463             :             // Unexpected value after last object value. Bail out.
    3464           0 :             HandleError(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED,
    3465             :                         token_start);
    3466             :             return;
    3467             :           }
    3468             :         }
    3469           0 :         handler_->HandleMapEnd();
    3470           0 :         break;
    3471             :       }
    3472             : 
    3473             :       default:
    3474             :         // We got a token that's not a value.
    3475           0 :         HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start);
    3476             :         return;
    3477             :     }
    3478             : 
    3479           0 :     SkipWhitespaceAndComments(token_end, end, value_token_end);
    3480             :   }
    3481             : 
    3482             :   void HandleError(Error error, const Char* pos) {
    3483             :     assert(error != Error::OK);
    3484           0 :     if (!error_) {
    3485           0 :       handler_->HandleError(Status{error, pos - start_pos_});
    3486           0 :       error_ = true;
    3487             :     }
    3488             :   }
    3489             : 
    3490             :   const Char* start_pos_ = nullptr;
    3491             :   bool error_ = false;
    3492             :   const Platform* platform_;
    3493             :   StreamingParserHandler* handler_;
    3494             : };
    3495             : }  // namespace
    3496             : 
    3497           0 : void ParseJSON(const Platform* platform,
    3498             :                span<uint8_t> chars,
    3499             :                StreamingParserHandler* handler) {
    3500             :   JsonParser<uint8_t> parser(platform, handler);
    3501           0 :   parser.Parse(chars.data(), chars.size());
    3502           0 : }
    3503             : 
    3504           0 : void ParseJSON(const Platform* platform,
    3505             :                span<uint16_t> chars,
    3506             :                StreamingParserHandler* handler) {
    3507             :   JsonParser<uint16_t> parser(platform, handler);
    3508           0 :   parser.Parse(chars.data(), chars.size());
    3509           0 : }
    3510             : }  // namespace json
    3511             : 
    3512             : } // namespace v8_inspector
    3513             : } // namespace protocol
    3514             : 

Generated by: LCOV version 1.10