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 1523 31.1 %
Date: 2019-04-17 Functions: 94 321 29.3 %

          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      309966 : ErrorSupport::ErrorSupport() { }
      27      154983 : ErrorSupport::~ErrorSupport() { }
      28             : 
      29      204946 : void ErrorSupport::setName(const char* name)
      30             : {
      31      409892 :     setName(String(name));
      32      204946 : }
      33             : 
      34      205291 : void ErrorSupport::setName(const String& name)
      35             : {
      36             :     DCHECK(m_path.size());
      37      205291 :     m_path[m_path.size() - 1] = name;
      38      205291 : }
      39             : 
      40      144039 : void ErrorSupport::push()
      41             : {
      42      432117 :     m_path.push_back(String());
      43      144039 : }
      44             : 
      45      144039 : void ErrorSupport::pop()
      46             : {
      47             :     m_path.pop_back();
      48      144039 : }
      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      144039 : bool ErrorSupport::hasErrors()
      69             : {
      70      144039 :     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  1243506090 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
     106             : {
     107  1243506090 :     switch (c) {
     108           0 :     case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
     109           0 :     case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
     110    43626130 :     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    36897652 :     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    49491077 : void escapeStringForJSONInternal(const Char* str, unsigned len,
     135             :                                  StringBuilder* dst)
     136             : {
     137  2536503257 :     for (unsigned i = 0; i < len; ++i) {
     138  1243506090 :         Char c = str[i];
     139  1243506090 :         if (escapeChar(c, dst))
     140             :             continue;
     141  1203171352 :         if (c < 32 || c > 126) {
     142     2250142 :             appendUnsignedAsHex(c, dst);
     143             :         } else {
     144             :             StringUtil::builderAppend(*dst, c);
     145             :         }
     146             :     }
     147    49491077 : }
     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      659375 : String Value::toJSONString() const
     352             : {
     353      659375 :     StringBuilder result;
     354             :     StringUtil::builderReserve(result, 512);
     355      659375 :     writeJSON(&result);
     356      659375 :     return StringUtil::builderToString(result);
     357             : }
     358             : 
     359      658979 : String Value::serializeToJSON() {
     360      658979 :     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       82361 : bool FundamentalValue::asBoolean(bool* output) const
     370             : {
     371       82361 :     if (type() != TypeBoolean)
     372             :         return false;
     373       82361 :     *output = m_boolValue;
     374       82361 :     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      348385 : bool FundamentalValue::asInteger(int* output) const
     391             : {
     392      348385 :     if (type() != TypeInteger)
     393             :         return false;
     394      348385 :     *output = m_integerValue;
     395      348385 :     return true;
     396             : }
     397             : 
     398    12232131 : void FundamentalValue::writeJSON(StringBuilder* output) const
     399             : {
     400             :     DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
     401    12232131 :     if (type() == TypeBoolean) {
     402    10229634 :         if (m_boolValue)
     403             :             StringUtil::builderAppend(*output, trueValueString, 4);
     404             :         else
     405             :             StringUtil::builderAppend(*output, falseValueString, 5);
     406     2002497 :     } else if (type() == TypeDouble) {
     407      303936 :         if (!std::isfinite(m_doubleValue)) {
     408             :             StringUtil::builderAppend(*output, nullValueString, 4);
     409             :             return;
     410             :         }
     411      151963 :         StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
     412     1850529 :     } else if (type() == TypeInteger) {
     413     3701058 :         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             :         return;
     422             :     case TypeInteger:
     423           0 :         cbor::EncodeInt32(m_integerValue, bytes);
     424             :         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      167740 : std::unique_ptr<Value> FundamentalValue::clone() const
     434             : {
     435      167740 :     switch (type()) {
     436      144906 :     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      268920 : bool StringValue::asString(String* output) const
     446             : {
     447             :     *output = m_stringValue;
     448      268920 :     return true;
     449             : }
     450             : 
     451    16479594 : void StringValue::writeJSON(StringBuilder* output) const
     452             : {
     453             :     DCHECK(type() == TypeString);
     454    16479594 :     StringUtil::builderAppendQuotedString(*output, m_stringValue);
     455    16479594 : }
     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             :     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             :                           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       66050 : std::unique_ptr<Value> StringValue::clone() const
     491             : {
     492      132100 :     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      329034 : void SerializedValue::writeJSON(StringBuilder* output) const
     518             : {
     519             :     DCHECK(type() == TypeSerialized);
     520      329034 :     StringUtil::builderAppend(*output, m_serializedJSON);
     521      329034 : }
     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    15904380 : DictionaryValue::~DictionaryValue()
     535             : {
     536     7952190 : }
     537             : 
     538       26856 : void DictionaryValue::setBoolean(const String& name, bool value)
     539             : {
     540       26856 :     setValue(name, FundamentalValue::create(value));
     541       26856 : }
     542             : 
     543      168123 : void DictionaryValue::setInteger(const String& name, int value)
     544             : {
     545      168123 :     setValue(name, FundamentalValue::create(value));
     546      168123 : }
     547             : 
     548           5 : void DictionaryValue::setDouble(const String& name, double value)
     549             : {
     550           5 :     setValue(name, FundamentalValue::create(value));
     551           5 : }
     552             : 
     553      176662 : void DictionaryValue::setString(const String& name, const String& value)
     554             : {
     555      176662 :     setValue(name, StringValue::create(value));
     556      176662 : }
     557             : 
     558    32538306 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
     559             : {
     560    34065403 :     set(name, value);
     561    32538306 : }
     562             : 
     563       23512 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
     564             : {
     565       24423 :     set(name, value);
     566       23512 : }
     567             : 
     568          10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
     569             : {
     570          10 :     set(name, value);
     571          10 : }
     572             : 
     573        8367 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
     574             : {
     575             :     protocol::Value* value = get(name);
     576        8367 :     if (!value)
     577             :         return false;
     578         214 :     return value->asBoolean(output);
     579             : }
     580             : 
     581      187862 : bool DictionaryValue::getInteger(const String& name, int* output) const
     582             : {
     583             :     Value* value = get(name);
     584      187862 :     if (!value)
     585             :         return false;
     586      187798 :     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      173853 : DictionaryValue* DictionaryValue::getObject(const String& name) const
     606             : {
     607      173853 :     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      655109 : protocol::Value* DictionaryValue::get(const String& name) const
     616             : {
     617             :     Dictionary::const_iterator it = m_data.find(name);
     618     1335135 :     if (it == m_data.end())
     619             :         return nullptr;
     620      310230 :     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        4488 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
     630             : {
     631        4488 :     bool result = defaultValue;
     632        4488 :     getBoolean(name, &result);
     633        4488 :     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       18302 : void DictionaryValue::remove(const String& name)
     651             : {
     652             :     m_data.erase(name);
     653       18302 :     m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
     654       18302 : }
     655             : 
     656     7551430 : void DictionaryValue::writeJSON(StringBuilder* output) const
     657             : {
     658             :     StringUtil::builderAppend(*output, '{');
     659    73957302 :     for (size_t i = 0; i < m_order.size(); ++i) {
     660             :         Dictionary::const_iterator it = m_data.find(m_order[i]);
     661    33202936 :         CHECK(it != m_data.end());
     662    33202936 :         if (i)
     663             :             StringUtil::builderAppend(*output, ',');
     664    33202936 :         StringUtil::builderAppendQuotedString(*output, it->first);
     665             :         StringUtil::builderAppend(*output, ':');
     666    33202936 :         it->second->writeJSON(output);
     667             :     }
     668             :     StringUtil::builderAppend(*output, '}');
     669     7551430 : }
     670             : 
     671           0 : void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
     672           0 :     cbor::EnvelopeEncoder encoder;
     673             :     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     7140461 : DictionaryValue::DictionaryValue()
     699     7952190 :     : Value(TypeObject)
     700             : {
     701     7140461 : }
     702             : 
     703      811142 : ListValue::~ListValue()
     704             : {
     705      405571 : }
     706             : 
     707      404636 : void ListValue::writeJSON(StringBuilder* output) const
     708             : {
     709             :     StringUtil::builderAppend(*output, '[');
     710             :     bool first = true;
     711     3541817 :     for (const std::unique_ptr<protocol::Value>& value : m_data) {
     712     3137181 :         if (!first)
     713             :             StringUtil::builderAppend(*output, ',');
     714     3137181 :         value->writeJSON(output);
     715             :         first = false;
     716             :     }
     717             :     StringUtil::builderAppend(*output, ']');
     718      404636 : }
     719             : 
     720           0 : void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
     721           0 :     cbor::EnvelopeEncoder encoder;
     722             :     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      404631 : ListValue::ListValue()
     740      405571 :     : Value(TypeArray)
     741             : {
     742      404631 : }
     743             : 
     744     3137166 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
     745             : {
     746             :     DCHECK(value);
     747     3138741 :     m_data.push_back(std::move(value));
     748     3137166 : }
     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    49491077 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
     762             : {
     763    49491077 :     escapeStringForJSONInternal<uint16_t>(str, len, dst);
     764    49491077 : }
     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    10528114 : DispatchResponse DispatchResponse::OK()
     824             : {
     825             :     DispatchResponse result;
     826    10528114 :     result.m_status = kSuccess;
     827    10528114 :     result.m_errorCode = kParseError;
     828    10528114 :     return result;
     829             : }
     830             : 
     831             : // static
     832        1535 : DispatchResponse DispatchResponse::Error(const String& error)
     833             : {
     834             :     DispatchResponse result;
     835        1535 :     result.m_status = kError;
     836        1535 :     result.m_errorCode = kServerError;
     837             :     result.m_errorMessage = error;
     838        1535 :     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      164831 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
     874             : 
     875      319685 : DispatcherBase::WeakPtr::~WeakPtr()
     876             : {
     877      164831 :     if (m_dispatcher)
     878      329642 :         m_dispatcher->m_weakPtrs.erase(this);
     879      154854 : }
     880             : 
     881        9977 : 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       29931 :     , 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        9977 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
     895             : {
     896       19954 :     if (!m_backendImpl || !m_backendImpl->get())
     897             :         return;
     898       19944 :     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       23274 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
     911       46548 :     : m_frontendChannel(frontendChannel) { }
     912             : 
     913       46548 : DispatcherBase::~DispatcherBase()
     914             : {
     915             :     clearFrontend();
     916       23274 : }
     917             : 
     918      154849 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
     919             : {
     920      154849 :     if (!m_frontendChannel)
     921             :         return;
     922      154849 :     if (response.status() == DispatchResponse::kError) {
     923             :         reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
     924             :         return;
     925             :     }
     926      924006 :     m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
     927             : }
     928             : 
     929       57112 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
     930             : {
     931      114224 :     sendResponse(callId, response, DictionaryValue::create());
     932       57112 : }
     933             : 
     934             : namespace {
     935             : 
     936             : class ProtocolError : public Serializable {
     937             : public:
     938         911 :     static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     939             :     {
     940         911 :         std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
     941         911 :         protocolError->m_callId = callId;
     942         911 :         protocolError->m_hasCallId = true;
     943         970 :         if (errors && errors->hasErrors())
     944         118 :             protocolError->m_data = errors->errors();
     945         911 :         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         911 :     String serializeToJSON() override
     954             :     {
     955        2733 :         return serialize()->serializeToJSON();
     956             :     }
     957             : 
     958           0 :     std::vector<uint8_t> serializeToBinary() override
     959             :     {
     960           0 :         return serialize()->serializeToBinary();
     961             :     }
     962             : 
     963        2733 :     ~ProtocolError() override {}
     964             : 
     965             : private:
     966         911 :     ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
     967             :         : m_code(code)
     968        1822 :         , m_errorMessage(errorMessage)
     969             :     {
     970         911 :     }
     971             : 
     972         911 :     std::unique_ptr<DictionaryValue> serialize() {
     973         911 :         std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
     974        2733 :         error->setInteger("code", m_code);
     975        2733 :         error->setString("message", m_errorMessage);
     976         911 :         if (m_data.length())
     977         177 :             error->setString("data", m_data);
     978         911 :         std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
     979        2733 :         message->setObject("error", std::move(error));
     980         911 :         if (m_hasCallId)
     981        2733 :             message->setInteger("id", m_callId);
     982         911 :         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         911 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
     995             : {
     996         911 :     if (frontendChannel)
     997        2733 :         frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
     998         911 : }
     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         907 :     reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
    1009          59 : }
    1010             : 
    1011           0 : void DispatcherBase::clearFrontend()
    1012             : {
    1013       23274 :     m_frontendChannel = nullptr;
    1014       23284 :     for (auto& weak : m_weakPtrs)
    1015          10 :         weak->dispose();
    1016             :     m_weakPtrs.clear();
    1017           0 : }
    1018             : 
    1019      164831 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
    1020             : {
    1021      164831 :     std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
    1022      329662 :     m_weakPtrs.insert(weak.get());
    1023      164831 :     return weak;
    1024             : }
    1025             : 
    1026        3879 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
    1027        7758 :     : m_frontendChannel(frontendChannel) { }
    1028             : 
    1029       23274 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
    1030             : {
    1031             :     m_dispatchers[name] = std::move(dispatcher);
    1032       23274 : }
    1033             : 
    1034       23274 : void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
    1035             : {
    1036       27153 :     for (const auto& pair : redirects)
    1037        3879 :         m_redirects[pair.first] = pair.second;
    1038       23274 : }
    1039             : 
    1040      154917 : bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
    1041      154917 :     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      154917 :     if (!messageObject) {
    1047           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
    1048           0 :         return false;
    1049             :     }
    1050             : 
    1051      154917 :     int callId = 0;
    1052      309834 :     protocol::Value* callIdValue = messageObject->get("id");
    1053      154917 :     bool success = callIdValue && callIdValue->asInteger(&callId);
    1054      154917 :     if (!success) {
    1055           0 :         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
    1056           0 :         return false;
    1057             :     }
    1058      154917 :     if (outCallId)
    1059      154917 :       *outCallId = callId;
    1060             : 
    1061      309834 :     protocol::Value* methodValue = messageObject->get("method");
    1062             :     String method;
    1063      154917 :     success = methodValue && methodValue->asString(&method);
    1064      154917 :     if (!success) {
    1065           0 :         reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
    1066           0 :         return false;
    1067             :     }
    1068      154917 :     if (outMethod)
    1069             :       *outMethod = method;
    1070             :     return true;
    1071             : }
    1072             : 
    1073      154917 : protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
    1074      154917 :     size_t dotIndex = StringUtil::find(method, ".");
    1075      154917 :     if (dotIndex == StringUtil::kNotFound)
    1076             :         return nullptr;
    1077             :     String domain = StringUtil::substring(method, 0, dotIndex);
    1078             :     auto it = m_dispatchers.find(domain);
    1079      154917 :     if (it == m_dispatchers.end())
    1080             :         return nullptr;
    1081      154917 :     if (!it->second->canDispatch(method))
    1082             :         return nullptr;
    1083      154913 :     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      154917 : 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      154917 :     if (redirectIt != m_redirects.end())
    1100             :         method = redirectIt->second;
    1101      154917 :     protocol::DispatcherBase* dispatcher = findDispatcher(method);
    1102      154917 :     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      464739 :     dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
    1108             : }
    1109             : 
    1110             : UberDispatcher::~UberDispatcher() = default;
    1111             : 
    1112             : // static
    1113      154001 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
    1114             : {
    1115      616004 :     return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
    1116             : }
    1117             : 
    1118             : // static
    1119      175033 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
    1120             : {
    1121      350066 :     return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
    1122             : }
    1123             : 
    1124      329034 : String InternalResponse::serializeToJSON()
    1125             : {
    1126      329034 :     std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    1127      768490 :     std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    1128      329034 :     if (m_notification.length()) {
    1129      525099 :         result->setString("method", m_notification);
    1130      875165 :         result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
    1131             :     } else {
    1132      462003 :         result->setInteger("id", m_callId);
    1133      770005 :         result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
    1134             :     }
    1135      658068 :     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      329034 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
    1153             :     : m_callId(callId)
    1154             :     , m_notification(notification)
    1155      658068 :     , m_params(params ? std::move(params) : nullptr)
    1156             : {
    1157      329034 : }
    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     5149828 :     return !(c & ~0x7F);
    1198             : }
    1199             : 
    1200             : bool isSpaceOrNewLine(uint16_t c)
    1201             : {
    1202     4354442 :     return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
    1203             : }
    1204             : 
    1205      349830 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
    1206             : {
    1207             :     std::vector<char> buffer;
    1208      349830 :     buffer.reserve(length + 1);
    1209     1940602 :     for (size_t i = 0; i < length; ++i) {
    1210     1590772 :         if (!isASCII(characters[i])) {
    1211           0 :             *ok = false;
    1212           0 :             return 0;
    1213             :         }
    1214     1590772 :         buffer.push_back(static_cast<char>(characters[i]));
    1215             :     }
    1216      699660 :     buffer.push_back('\0');
    1217      349830 :     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      419209 :     while (start < end && *token != '\0' && *start++ == *token++) { }
    1230       82440 :     if (*token != '\0')
    1231             :         return false;
    1232       82435 :     *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      349835 :     if (start == end)
    1240             :         return false;
    1241      349830 :     bool haveLeadingZero = '0' == *start;
    1242             :     int length = 0;
    1243     1145203 :     while (start < end && '0' <= *start && *start <= '9') {
    1244      795368 :         ++start;
    1245      795368 :         ++length;
    1246             :     }
    1247      349835 :     if (!length)
    1248             :         return false;
    1249      349830 :     if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
    1250             :         return false;
    1251             :     *tokenEnd = start;
    1252             :     return true;
    1253             : }
    1254             : 
    1255             : template<typename Char>
    1256      349830 : 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      349830 :     if (start == end)
    1261             :         return false;
    1262      349830 :     Char c = *start;
    1263      349830 :     if ('-' == c)
    1264          13 :         ++start;
    1265             : 
    1266      349830 :     if (!readInt(start, end, &start, false))
    1267             :         return false;
    1268      349830 :     if (start == end) {
    1269           5 :         *tokenEnd = start;
    1270           5 :         return true;
    1271             :     }
    1272             : 
    1273             :     // Optional fraction part
    1274      349825 :     c = *start;
    1275      349825 :     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      349825 :     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      349825 :     *tokenEnd = start;
    1302      349825 :     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     1087687 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
    1321             : {
    1322    13433629 :     while (start < end) {
    1323    13433629 :         Char c = *start++;
    1324    13433629 :         if ('\\' == c) {
    1325      334337 :             if (start == end)
    1326             :                 return false;
    1327      334337 :             c = *start++;
    1328             :             // Make sure the escaped char is valid.
    1329      334337 :             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    13099292 :         } else if ('"' == c) {
    1352     1087687 :             *tokenEnd = start;
    1353     1087687 :             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     4603393 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
    1400             : {
    1401     4603393 :     while (start < end) {
    1402     8708884 :         if (isSpaceOrNewLine(*start)) {
    1403           0 :             ++start;
    1404     4354442 :         } 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     4603393 :     *whitespaceEnd = start;
    1414     4603393 : }
    1415             : 
    1416             : template<typename Char>
    1417     3535469 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
    1418             : {
    1419     3535469 :     skipWhitespaceAndComments(start, end, tokenStart);
    1420     3535469 :     start = *tokenStart;
    1421             : 
    1422     3535469 :     if (start == end)
    1423             :         return InvalidToken;
    1424             : 
    1425     3535469 :     switch (*start) {
    1426             :     case 'n':
    1427           5 :         if (parseConstToken(start, end, tokenEnd, nullString))
    1428             :             return NullToken;
    1429             :         break;
    1430             :     case 't':
    1431       75411 :         if (parseConstToken(start, end, tokenEnd, trueString))
    1432             :             return BoolTrue;
    1433             :         break;
    1434             :     case 'f':
    1435        7024 :         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      464244 :         *tokenEnd = start + 1;
    1446      464244 :         return ListSeparator;
    1447             :     case '{':
    1448      366275 :         *tokenEnd = start + 1;
    1449      366275 :         return ObjectBegin;
    1450             :     case '}':
    1451      365540 :         *tokenEnd = start + 1;
    1452      365540 :         return ObjectEnd;
    1453             :     case ':':
    1454      818113 :         *tokenEnd = start + 1;
    1455      818113 :         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      349830 :         if (parseNumberToken(start, end, tokenEnd))
    1468             :             return Number;
    1469             :         break;
    1470             :     case '"':
    1471     1087687 :         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     1087356 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
    1493             : {
    1494    13432203 :     while (start < end) {
    1495    12344847 :         uint16_t c = *start++;
    1496    12344847 :         if ('\\' != c) {
    1497             :             StringUtil::builderAppend(*output, c);
    1498             :             continue;
    1499             :         }
    1500      334337 :         if (start == end)
    1501             :             return false;
    1502      334337 :         c = *start++;
    1503             : 
    1504      334337 :         if (c == 'x') {
    1505             :             // \x is not supported.
    1506             :             return false;
    1507             :         }
    1508             : 
    1509      334337 :         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        7207 :             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     1087562 : bool decodeString(const Char* start, const Char* end, String* output)
    1549             : {
    1550     1087562 :     if (start == end) {
    1551         412 :         *output = "";
    1552         206 :         return true;
    1553             :     }
    1554     1087356 :     if (start > end)
    1555             :         return false;
    1556     1087356 :     StringBuilder buffer;
    1557     1087356 :     StringUtil::builderReserve(buffer, end - start);
    1558     1087356 :     if (!decodeString(start, end, &buffer))
    1559             :         return false;
    1560     1087356 :     *output = StringUtil::builderToString(buffer);
    1561     1087356 :     return true;
    1562             : }
    1563             : 
    1564             : template<typename Char>
    1565     1067929 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
    1566             : {
    1567     1067929 :     if (depth > stackLimit)
    1568             :         return nullptr;
    1569             : 
    1570             :     std::unique_ptr<Value> result;
    1571             :     const Char* tokenStart;
    1572             :     const Char* tokenEnd;
    1573     1067929 :     Token token = parseToken(start, end, &tokenStart, &tokenEnd);
    1574     1067929 :     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       75411 :         break;
    1583             :     case BoolFalse:
    1584             :         result = FundamentalValue::create(false);
    1585        7019 :         break;
    1586             :     case Number: {
    1587             :         bool ok;
    1588      349830 :         double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
    1589      349830 :         if (!ok)
    1590           0 :             return nullptr;
    1591      349830 :         if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
    1592      349825 :             result = FundamentalValue::create(static_cast<int>(value));
    1593             :         else
    1594             :             result = FundamentalValue::create(value);
    1595      349830 :         break;
    1596             :     }
    1597             :     case StringLiteral: {
    1598             :         String value;
    1599      269449 :         bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
    1600      269449 :         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      365540 :         std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
    1635      365540 :         start = tokenEnd;
    1636      365540 :         token = parseToken(start, end, &tokenStart, &tokenEnd);
    1637     1183653 :         while (token != ObjectEnd) {
    1638      818113 :             if (token != StringLiteral)
    1639           0 :                 return nullptr;
    1640             :             String key;
    1641      818113 :             if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
    1642             :                 return nullptr;
    1643      818113 :             start = tokenEnd;
    1644             : 
    1645      818113 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1646      818113 :             if (token != ObjectPairSeparator)
    1647             :                 return nullptr;
    1648      818113 :             start = tokenEnd;
    1649             : 
    1650      818113 :             std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
    1651      818113 :             if (!value)
    1652             :                 return nullptr;
    1653      818113 :             object->setValue(key, std::move(value));
    1654      818113 :             start = tokenEnd;
    1655             : 
    1656             :             // After a key/value pair, we expect a comma or the end of the
    1657             :             // object.
    1658      818113 :             token = parseToken(start, end, &tokenStart, &tokenEnd);
    1659      818113 :             if (token == ListSeparator) {
    1660      463986 :                 start = tokenEnd;
    1661      463986 :                 token = parseToken(start, end, &tokenStart, &tokenEnd);
    1662      463986 :                 if (token == ObjectEnd)
    1663             :                     return nullptr;
    1664      354127 :             } else if (token != ObjectEnd) {
    1665             :                 // Unexpected value after last object value. Bail out.
    1666             :                 return nullptr;
    1667             :             }
    1668             :         }
    1669      365540 :         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     1067924 :     skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
    1681             :     return result;
    1682             : }
    1683             : 
    1684             : template<typename Char>
    1685      248956 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
    1686             : {
    1687      248956 :     const Char* end = start + length;
    1688             :     const Char *tokenEnd;
    1689      248956 :     std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
    1690      248956 :     if (!value || tokenEnd != end)
    1691             :         return nullptr;
    1692             :     return value;
    1693             : }
    1694             : 
    1695             : } // anonymous namespace
    1696             : 
    1697      248956 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
    1698             : {
    1699      248956 :     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 <cmath>
    1720             : #include <cstring>
    1721             : #include <limits>
    1722             : #include <stack>
    1723             : 
    1724             : namespace v8_inspector {
    1725             : namespace protocol {
    1726             : 
    1727             : // ===== encoding/encoding.cc =====
    1728             : 
    1729             : namespace cbor {
    1730             : namespace {
    1731             : // Indicates the number of bits the "initial byte" needs to be shifted to the
    1732             : // right after applying |kMajorTypeMask| to produce the major type in the
    1733             : // lowermost bits.
    1734             : static constexpr uint8_t kMajorTypeBitShift = 5u;
    1735             : // Mask selecting the low-order 5 bits of the "initial byte", which is where
    1736             : // the additional information is encoded.
    1737             : static constexpr uint8_t kAdditionalInformationMask = 0x1f;
    1738             : // Mask selecting the high-order 3 bits of the "initial byte", which indicates
    1739             : // the major type of the encoded value.
    1740             : static constexpr uint8_t kMajorTypeMask = 0xe0;
    1741             : // Indicates the integer is in the following byte.
    1742             : static constexpr uint8_t kAdditionalInformation1Byte = 24u;
    1743             : // Indicates the integer is in the next 2 bytes.
    1744             : static constexpr uint8_t kAdditionalInformation2Bytes = 25u;
    1745             : // Indicates the integer is in the next 4 bytes.
    1746             : static constexpr uint8_t kAdditionalInformation4Bytes = 26u;
    1747             : // Indicates the integer is in the next 8 bytes.
    1748             : static constexpr uint8_t kAdditionalInformation8Bytes = 27u;
    1749             : 
    1750             : // Encodes the initial byte, consisting of the |type| in the first 3 bits
    1751             : // followed by 5 bits of |additional_info|.
    1752             : constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) {
    1753           0 :   return (static_cast<uint8_t>(type) << kMajorTypeBitShift) |
    1754           0 :          (additional_info & kAdditionalInformationMask);
    1755             : }
    1756             : 
    1757             : // TAG 24 indicates that what follows is a byte string which is
    1758             : // encoded in CBOR format. We use this as a wrapper for
    1759             : // maps and arrays, allowing us to skip them, because the
    1760             : // byte string carries its size (byte length).
    1761             : // https://tools.ietf.org/html/rfc7049#section-2.4.4.1
    1762             : static constexpr uint8_t kInitialByteForEnvelope =
    1763             :     EncodeInitialByte(MajorType::TAG, 24);
    1764             : // The initial byte for a byte string with at most 2^32 bytes
    1765             : // of payload. This is used for envelope encoding, even if
    1766             : // the byte string is shorter.
    1767             : static constexpr uint8_t kInitialByteFor32BitLengthByteString =
    1768             :     EncodeInitialByte(MajorType::BYTE_STRING, 26);
    1769             : 
    1770             : // See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional
    1771             : // info = 31.
    1772             : static constexpr uint8_t kInitialByteIndefiniteLengthArray =
    1773             :     EncodeInitialByte(MajorType::ARRAY, 31);
    1774             : static constexpr uint8_t kInitialByteIndefiniteLengthMap =
    1775             :     EncodeInitialByte(MajorType::MAP, 31);
    1776             : // See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite
    1777             : // length maps / arrays.
    1778             : static constexpr uint8_t kStopByte =
    1779             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 31);
    1780             : 
    1781             : // See RFC 7049 Section 2.3, Table 2.
    1782             : static constexpr uint8_t kEncodedTrue =
    1783             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 21);
    1784             : static constexpr uint8_t kEncodedFalse =
    1785             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 20);
    1786             : static constexpr uint8_t kEncodedNull =
    1787             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
    1788             : static constexpr uint8_t kInitialByteForDouble =
    1789             :     EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
    1790             : 
    1791             : // See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
    1792             : // arbitrary binary data encoded as BYTE_STRING.
    1793             : static constexpr uint8_t kExpectedConversionToBase64Tag =
    1794             :     EncodeInitialByte(MajorType::TAG, 22);
    1795             : 
    1796             : // Writes the bytes for |v| to |out|, starting with the most significant byte.
    1797             : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1798             : template <typename T, class C>
    1799             : void WriteBytesMostSignificantByteFirst(T v, C* out) {
    1800           0 :   for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes)
    1801           0 :     out->push_back(0xff & (v >> (shift_bytes * 8)));
    1802             : }
    1803             : 
    1804             : // Extracts sizeof(T) bytes from |in| to extract a value of type T
    1805             : // (e.g. uint64_t, uint32_t, ...), most significant byte first.
    1806             : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1807             : template <typename T>
    1808             : T ReadBytesMostSignificantByteFirst(span<uint8_t> in) {
    1809             :   assert(static_cast<std::size_t>(in.size()) >= sizeof(T));
    1810             :   T result = 0;
    1811           0 :   for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes)
    1812           0 :     result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8);
    1813             :   return result;
    1814             : }
    1815             : }  // namespace
    1816             : 
    1817             : namespace internals {
    1818             : // Reads the start of a token with definitive size from |bytes|.
    1819             : // |type| is the major type as specified in RFC 7049 Section 2.1.
    1820             : // |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size
    1821             : // (e.g. for BYTE_STRING).
    1822             : // If successful, returns the number of bytes read. Otherwise returns -1.
    1823           0 : int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
    1824           0 :   if (bytes.empty())
    1825             :     return -1;
    1826           0 :   uint8_t initial_byte = bytes[0];
    1827           0 :   *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
    1828             : 
    1829           0 :   uint8_t additional_information = initial_byte & kAdditionalInformationMask;
    1830           0 :   if (additional_information < 24) {
    1831             :     // Values 0-23 are encoded directly into the additional info of the
    1832             :     // initial byte.
    1833           0 :     *value = additional_information;
    1834           0 :     return 1;
    1835             :   }
    1836           0 :   if (additional_information == kAdditionalInformation1Byte) {
    1837             :     // Values 24-255 are encoded with one initial byte, followed by the value.
    1838           0 :     if (bytes.size() < 2)
    1839             :       return -1;
    1840           0 :     *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
    1841           0 :     return 2;
    1842             :   }
    1843           0 :   if (additional_information == kAdditionalInformation2Bytes) {
    1844             :     // Values 256-65535: 1 initial byte + 2 bytes payload.
    1845           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t))
    1846             :       return -1;
    1847           0 :     *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
    1848           0 :     return 3;
    1849             :   }
    1850           0 :   if (additional_information == kAdditionalInformation4Bytes) {
    1851             :     // 32 bit uint: 1 initial byte + 4 bytes payload.
    1852           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t))
    1853             :       return -1;
    1854           0 :     *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
    1855           0 :     return 5;
    1856             :   }
    1857           0 :   if (additional_information == kAdditionalInformation8Bytes) {
    1858             :     // 64 bit uint: 1 initial byte + 8 bytes payload.
    1859           0 :     if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t))
    1860             :       return -1;
    1861           0 :     *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
    1862           0 :     return 9;
    1863             :   }
    1864             :   return -1;
    1865             : }
    1866             : 
    1867             : // Writes the start of a token with |type|. The |value| may indicate the size,
    1868             : // or it may be the payload if the value is an unsigned integer.
    1869             : template <typename C>
    1870           0 : void WriteTokenStartTmpl(MajorType type, uint64_t value, C* 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           0 : void WriteTokenStart(MajorType type,
    1901             :                      uint64_t value,
    1902             :                      std::vector<uint8_t>* encoded) {
    1903           0 :   WriteTokenStartTmpl(type, value, encoded);
    1904           0 : }
    1905           0 : void WriteTokenStart(MajorType type, uint64_t value, std::string* encoded) {
    1906           0 :   WriteTokenStartTmpl(type, value, encoded);
    1907           0 : }
    1908             : }  // namespace internals
    1909             : 
    1910             : // =============================================================================
    1911             : // Detecting CBOR content
    1912             : // =============================================================================
    1913             : 
    1914           0 : uint8_t InitialByteForEnvelope() {
    1915           0 :   return kInitialByteForEnvelope;
    1916             : }
    1917           0 : uint8_t InitialByteFor32BitLengthByteString() {
    1918           0 :   return kInitialByteFor32BitLengthByteString;
    1919             : }
    1920           0 : bool IsCBORMessage(span<uint8_t> msg) {
    1921           0 :   return msg.size() >= 6 && msg[0] == InitialByteForEnvelope() &&
    1922           0 :          msg[1] == InitialByteFor32BitLengthByteString();
    1923             : }
    1924             : 
    1925             : // =============================================================================
    1926             : // Encoding invidiual CBOR items
    1927             : // =============================================================================
    1928             : 
    1929           0 : uint8_t EncodeTrue() {
    1930           0 :   return kEncodedTrue;
    1931             : }
    1932           0 : uint8_t EncodeFalse() {
    1933           0 :   return kEncodedFalse;
    1934             : }
    1935           0 : uint8_t EncodeNull() {
    1936           0 :   return kEncodedNull;
    1937             : }
    1938             : 
    1939           0 : uint8_t EncodeIndefiniteLengthArrayStart() {
    1940           0 :   return kInitialByteIndefiniteLengthArray;
    1941             : }
    1942             : 
    1943           0 : uint8_t EncodeIndefiniteLengthMapStart() {
    1944           0 :   return kInitialByteIndefiniteLengthMap;
    1945             : }
    1946             : 
    1947           0 : uint8_t EncodeStop() {
    1948           0 :   return kStopByte;
    1949             : }
    1950             : 
    1951             : template <typename C>
    1952           0 : void EncodeInt32Tmpl(int32_t value, C* out) {
    1953           0 :   if (value >= 0) {
    1954           0 :     internals::WriteTokenStart(MajorType::UNSIGNED, value, out);
    1955             :   } else {
    1956           0 :     uint64_t representation = static_cast<uint64_t>(-(value + 1));
    1957             :     internals::WriteTokenStart(MajorType::NEGATIVE, representation, out);
    1958             :   }
    1959           0 : }
    1960           0 : void EncodeInt32(int32_t value, std::vector<uint8_t>* out) {
    1961           0 :   EncodeInt32Tmpl(value, out);
    1962           0 : }
    1963           0 : void EncodeInt32(int32_t value, std::string* out) {
    1964           0 :   EncodeInt32Tmpl(value, out);
    1965           0 : }
    1966             : 
    1967             : template <typename C>
    1968           0 : void EncodeString16Tmpl(span<uint16_t> in, C* out) {
    1969             :   uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
    1970             :   internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
    1971             :   // When emitting UTF16 characters, we always write the least significant byte
    1972             :   // first; this is because it's the native representation for X86.
    1973             :   // TODO(johannes): Implement a more efficient thing here later, e.g.
    1974             :   // casting *iff* the machine has this byte order.
    1975             :   // The wire format for UTF16 chars will probably remain the same
    1976             :   // (least significant byte first) since this way we can have
    1977             :   // golden files, unittests, etc. that port easily and universally.
    1978             :   // See also:
    1979             :   // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
    1980           0 :   for (const uint16_t two_bytes : in) {
    1981           0 :     out->push_back(two_bytes);
    1982           0 :     out->push_back(two_bytes >> 8);
    1983             :   }
    1984           0 : }
    1985           0 : void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) {
    1986           0 :   EncodeString16Tmpl(in, out);
    1987           0 : }
    1988           0 : void EncodeString16(span<uint16_t> in, std::string* out) {
    1989           0 :   EncodeString16Tmpl(in, out);
    1990           0 : }
    1991             : 
    1992             : template <typename C>
    1993           0 : void EncodeString8Tmpl(span<uint8_t> in, C* out) {
    1994           0 :   internals::WriteTokenStart(MajorType::STRING,
    1995             :                              static_cast<uint64_t>(in.size_bytes()), out);
    1996           0 :   out->insert(out->end(), in.begin(), in.end());
    1997           0 : }
    1998           0 : void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) {
    1999           0 :   EncodeString8Tmpl(in, out);
    2000           0 : }
    2001           0 : void EncodeString8(span<uint8_t> in, std::string* out) {
    2002           0 :   EncodeString8Tmpl(in, out);
    2003           0 : }
    2004             : 
    2005             : template <typename C>
    2006           0 : void EncodeFromLatin1Tmpl(span<uint8_t> latin1, C* out) {
    2007           0 :   for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) {
    2008           0 :     if (latin1[ii] <= 127)
    2009           0 :       continue;
    2010             :     // If there's at least one non-ASCII char, convert to UTF8.
    2011             :     std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii);
    2012           0 :     for (; ii < latin1.size(); ++ii) {
    2013           0 :       if (latin1[ii] <= 127) {
    2014           0 :         utf8.push_back(latin1[ii]);
    2015             :       } else {
    2016             :         // 0xC0 means it's a UTF8 sequence with 2 bytes.
    2017           0 :         utf8.push_back((latin1[ii] >> 6) | 0xc0);
    2018           0 :         utf8.push_back((latin1[ii] | 0x80) & 0xbf);
    2019             :       }
    2020             :     }
    2021             :     EncodeString8(SpanFromVector(utf8), out);
    2022             :     return;
    2023             :   }
    2024             :   EncodeString8(latin1, out);
    2025             : }
    2026           0 : void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) {
    2027           0 :   EncodeFromLatin1Tmpl(latin1, out);
    2028           0 : }
    2029           0 : void EncodeFromLatin1(span<uint8_t> latin1, std::string* out) {
    2030           0 :   EncodeFromLatin1Tmpl(latin1, out);
    2031           0 : }
    2032             : 
    2033             : template <typename C>
    2034           0 : void EncodeFromUTF16Tmpl(span<uint16_t> utf16, C* out) {
    2035             :   // If there's at least one non-ASCII char, encode as STRING16 (UTF16).
    2036           0 :   for (uint16_t ch : utf16) {
    2037           0 :     if (ch <= 127)
    2038             :       continue;
    2039             :     EncodeString16(utf16, out);
    2040             :     return;
    2041             :   }
    2042             :   // It's all US-ASCII, strip out every second byte and encode as UTF8.
    2043             :   internals::WriteTokenStart(MajorType::STRING,
    2044             :                              static_cast<uint64_t>(utf16.size()), out);
    2045           0 :   out->insert(out->end(), utf16.begin(), utf16.end());
    2046             : }
    2047           0 : void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) {
    2048           0 :   EncodeFromUTF16Tmpl(utf16, out);
    2049           0 : }
    2050           0 : void EncodeFromUTF16(span<uint16_t> utf16, std::string* out) {
    2051           0 :   EncodeFromUTF16Tmpl(utf16, out);
    2052           0 : }
    2053             : 
    2054             : template <typename C>
    2055           0 : void EncodeBinaryTmpl(span<uint8_t> in, C* out) {
    2056           0 :   out->push_back(kExpectedConversionToBase64Tag);
    2057           0 :   uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
    2058             :   internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
    2059           0 :   out->insert(out->end(), in.begin(), in.end());
    2060           0 : }
    2061           0 : void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) {
    2062           0 :   EncodeBinaryTmpl(in, out);
    2063           0 : }
    2064           0 : void EncodeBinary(span<uint8_t> in, std::string* out) {
    2065           0 :   EncodeBinaryTmpl(in, out);
    2066           0 : }
    2067             : 
    2068             : // A double is encoded with a specific initial byte
    2069             : // (kInitialByteForDouble) plus the 64 bits of payload for its value.
    2070             : constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t);
    2071             : 
    2072             : // An envelope is encoded with a specific initial byte
    2073             : // (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32
    2074             : // bit wide length, plus a 32 bit length for that string.
    2075             : constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t);
    2076             : 
    2077             : template <typename C>
    2078           0 : void EncodeDoubleTmpl(double value, C* out) {
    2079             :   // The additional_info=27 indicates 64 bits for the double follow.
    2080             :   // See RFC 7049 Section 2.3, Table 1.
    2081           0 :   out->push_back(kInitialByteForDouble);
    2082             :   union {
    2083             :     double from_double;
    2084             :     uint64_t to_uint64;
    2085             :   } reinterpret;
    2086             :   reinterpret.from_double = value;
    2087           0 :   WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out);
    2088           0 : }
    2089           0 : void EncodeDouble(double value, std::vector<uint8_t>* out) {
    2090           0 :   EncodeDoubleTmpl(value, out);
    2091           0 : }
    2092           0 : void EncodeDouble(double value, std::string* out) {
    2093           0 :   EncodeDoubleTmpl(value, out);
    2094           0 : }
    2095             : 
    2096             : // =============================================================================
    2097             : // cbor::EnvelopeEncoder - for wrapping submessages
    2098             : // =============================================================================
    2099             : 
    2100             : template <typename C>
    2101           0 : void EncodeStartTmpl(C* out, std::size_t& byte_size_pos) {
    2102             :   assert(byte_size_pos == 0);
    2103           0 :   out->push_back(kInitialByteForEnvelope);
    2104           0 :   out->push_back(kInitialByteFor32BitLengthByteString);
    2105           0 :   byte_size_pos = out->size();
    2106           0 :   out->resize(out->size() + sizeof(uint32_t));
    2107           0 : }
    2108             : 
    2109           0 : void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) {
    2110           0 :   EncodeStartTmpl<std::vector<uint8_t>>(out, byte_size_pos_);
    2111           0 : }
    2112             : 
    2113           0 : void EnvelopeEncoder::EncodeStart(std::string* out) {
    2114           0 :   EncodeStartTmpl<std::string>(out, byte_size_pos_);
    2115           0 : }
    2116             : 
    2117             : template <typename C>
    2118             : bool EncodeStopTmpl(C* out, std::size_t& byte_size_pos) {
    2119             :   assert(byte_size_pos != 0);
    2120             :   // The byte size is the size of the payload, that is, all the
    2121             :   // bytes that were written past the byte size position itself.
    2122           0 :   uint64_t byte_size = out->size() - (byte_size_pos + sizeof(uint32_t));
    2123             :   // We store exactly 4 bytes, so at most INT32MAX, with most significant
    2124             :   // byte first.
    2125           0 :   if (byte_size > std::numeric_limits<uint32_t>::max())
    2126             :     return false;
    2127           0 :   for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0;
    2128             :        --shift_bytes) {
    2129           0 :     (*out)[byte_size_pos++] = 0xff & (byte_size >> (shift_bytes * 8));
    2130             :   }
    2131             :   return true;
    2132             : }
    2133             : 
    2134           0 : bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) {
    2135           0 :   return EncodeStopTmpl(out, byte_size_pos_);
    2136             : }
    2137             : 
    2138           0 : bool EnvelopeEncoder::EncodeStop(std::string* out) {
    2139           0 :   return EncodeStopTmpl(out, byte_size_pos_);
    2140             : }
    2141             : 
    2142             : // =============================================================================
    2143             : // cbor::NewCBOREncoder - for encoding from a streaming parser
    2144             : // =============================================================================
    2145             : 
    2146             : namespace {
    2147             : template <typename C>
    2148           0 : class CBOREncoder : public StreamingParserHandler {
    2149             :  public:
    2150           0 :   CBOREncoder(C* out, Status* status) : out_(out), status_(status) {
    2151           0 :     *status_ = Status();
    2152             :   }
    2153             : 
    2154           0 :   void HandleMapBegin() override {
    2155           0 :     envelopes_.emplace_back();
    2156           0 :     envelopes_.back().EncodeStart(out_);
    2157           0 :     out_->push_back(kInitialByteIndefiniteLengthMap);
    2158           0 :   }
    2159             : 
    2160           0 :   void HandleMapEnd() override {
    2161           0 :     out_->push_back(kStopByte);
    2162             :     assert(!envelopes_.empty());
    2163           0 :     envelopes_.back().EncodeStop(out_);
    2164             :     envelopes_.pop_back();
    2165           0 :   }
    2166             : 
    2167           0 :   void HandleArrayBegin() override {
    2168           0 :     envelopes_.emplace_back();
    2169           0 :     envelopes_.back().EncodeStart(out_);
    2170           0 :     out_->push_back(kInitialByteIndefiniteLengthArray);
    2171           0 :   }
    2172             : 
    2173           0 :   void HandleArrayEnd() override {
    2174           0 :     out_->push_back(kStopByte);
    2175             :     assert(!envelopes_.empty());
    2176           0 :     envelopes_.back().EncodeStop(out_);
    2177             :     envelopes_.pop_back();
    2178           0 :   }
    2179             : 
    2180           0 :   void HandleString8(span<uint8_t> chars) override {
    2181           0 :     EncodeString8(chars, out_);
    2182           0 :   }
    2183             : 
    2184           0 :   void HandleString16(span<uint16_t> chars) override {
    2185           0 :     EncodeFromUTF16(chars, out_);
    2186           0 :   }
    2187             : 
    2188           0 :   void HandleBinary(span<uint8_t> bytes) override { EncodeBinary(bytes, out_); }
    2189             : 
    2190           0 :   void HandleDouble(double value) override { EncodeDouble(value, out_); }
    2191             : 
    2192           0 :   void HandleInt32(int32_t value) override { EncodeInt32(value, out_); }
    2193             : 
    2194           0 :   void HandleBool(bool value) override {
    2195             :     // See RFC 7049 Section 2.3, Table 2.
    2196           0 :     out_->push_back(value ? kEncodedTrue : kEncodedFalse);
    2197           0 :   }
    2198             : 
    2199           0 :   void HandleNull() override {
    2200             :     // See RFC 7049 Section 2.3, Table 2.
    2201           0 :     out_->push_back(kEncodedNull);
    2202           0 :   }
    2203             : 
    2204           0 :   void HandleError(Status error) override {
    2205             :     assert(!error.ok());
    2206           0 :     *status_ = error;
    2207           0 :     out_->clear();
    2208           0 :   }
    2209             : 
    2210             :  private:
    2211             :   C* out_;
    2212             :   std::vector<EnvelopeEncoder> envelopes_;
    2213             :   Status* status_;
    2214             : };
    2215             : }  // namespace
    2216             : 
    2217           0 : std::unique_ptr<StreamingParserHandler> NewCBOREncoder(
    2218             :     std::vector<uint8_t>* out,
    2219             :     Status* status) {
    2220             :   return std::unique_ptr<StreamingParserHandler>(
    2221           0 :       new CBOREncoder<std::vector<uint8_t>>(out, status));
    2222             : }
    2223           0 : std::unique_ptr<StreamingParserHandler> NewCBOREncoder(std::string* out,
    2224             :                                                        Status* status) {
    2225             :   return std::unique_ptr<StreamingParserHandler>(
    2226           0 :       new CBOREncoder<std::string>(out, status));
    2227             : }
    2228             : 
    2229             : // =============================================================================
    2230             : // cbor::CBORTokenizer - for parsing individual CBOR items
    2231             : // =============================================================================
    2232             : 
    2233           0 : CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) {
    2234           0 :   ReadNextToken(/*enter_envelope=*/false);
    2235           0 : }
    2236           0 : CBORTokenizer::~CBORTokenizer() {}
    2237             : 
    2238           0 : CBORTokenTag CBORTokenizer::TokenTag() const {
    2239           0 :   return token_tag_;
    2240             : }
    2241             : 
    2242           0 : void CBORTokenizer::Next() {
    2243           0 :   if (token_tag_ == CBORTokenTag::ERROR_VALUE ||
    2244             :       token_tag_ == CBORTokenTag::DONE)
    2245             :     return;
    2246           0 :   ReadNextToken(/*enter_envelope=*/false);
    2247             : }
    2248             : 
    2249           0 : void CBORTokenizer::EnterEnvelope() {
    2250             :   assert(token_tag_ == CBORTokenTag::ENVELOPE);
    2251           0 :   ReadNextToken(/*enter_envelope=*/true);
    2252           0 : }
    2253             : 
    2254           0 : Status CBORTokenizer::Status() const {
    2255           0 :   return status_;
    2256             : }
    2257             : 
    2258           0 : int32_t CBORTokenizer::GetInt32() const {
    2259             :   assert(token_tag_ == CBORTokenTag::INT32);
    2260             :   // The range checks happen in ::ReadNextToken().
    2261             :   return static_cast<uint32_t>(
    2262           0 :       token_start_type_ == MajorType::UNSIGNED
    2263           0 :           ? token_start_internal_value_
    2264           0 :           : -static_cast<int64_t>(token_start_internal_value_) - 1);
    2265             : }
    2266             : 
    2267           0 : double CBORTokenizer::GetDouble() const {
    2268             :   assert(token_tag_ == CBORTokenTag::DOUBLE);
    2269             :   union {
    2270             :     uint64_t from_uint64;
    2271             :     double to_double;
    2272             :   } reinterpret;
    2273           0 :   reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>(
    2274           0 :       bytes_.subspan(status_.pos + 1));
    2275           0 :   return reinterpret.to_double;
    2276             : }
    2277             : 
    2278           0 : span<uint8_t> CBORTokenizer::GetString8() const {
    2279             :   assert(token_tag_ == CBORTokenTag::STRING8);
    2280           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2281           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2282             : }
    2283             : 
    2284           0 : span<uint8_t> CBORTokenizer::GetString16WireRep() const {
    2285             :   assert(token_tag_ == CBORTokenTag::STRING16);
    2286           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2287           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2288             : }
    2289             : 
    2290           0 : span<uint8_t> CBORTokenizer::GetBinary() const {
    2291             :   assert(token_tag_ == CBORTokenTag::BINARY);
    2292           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2293           0 :   return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
    2294             : }
    2295             : 
    2296           0 : span<uint8_t> CBORTokenizer::GetEnvelopeContents() const {
    2297             :   assert(token_tag_ == CBORTokenTag::ENVELOPE);
    2298           0 :   auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2299           0 :   return bytes_.subspan(status_.pos + kEncodedEnvelopeHeaderSize, length);
    2300             : }
    2301             : 
    2302           0 : void CBORTokenizer::ReadNextToken(bool enter_envelope) {
    2303           0 :   if (enter_envelope) {
    2304           0 :     status_.pos += kEncodedEnvelopeHeaderSize;
    2305             :   } else {
    2306             :     status_.pos =
    2307           0 :         status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_;
    2308             :   }
    2309           0 :   status_.error = Error::OK;
    2310           0 :   if (status_.pos >= bytes_.size()) {
    2311           0 :     token_tag_ = CBORTokenTag::DONE;
    2312           0 :     return;
    2313             :   }
    2314           0 :   switch (bytes_[status_.pos]) {
    2315             :     case kStopByte:
    2316             :       SetToken(CBORTokenTag::STOP, 1);
    2317             :       return;
    2318             :     case kInitialByteIndefiniteLengthMap:
    2319             :       SetToken(CBORTokenTag::MAP_START, 1);
    2320             :       return;
    2321             :     case kInitialByteIndefiniteLengthArray:
    2322             :       SetToken(CBORTokenTag::ARRAY_START, 1);
    2323             :       return;
    2324             :     case kEncodedTrue:
    2325             :       SetToken(CBORTokenTag::TRUE_VALUE, 1);
    2326             :       return;
    2327             :     case kEncodedFalse:
    2328             :       SetToken(CBORTokenTag::FALSE_VALUE, 1);
    2329             :       return;
    2330             :     case kEncodedNull:
    2331             :       SetToken(CBORTokenTag::NULL_VALUE, 1);
    2332             :       return;
    2333             :     case kExpectedConversionToBase64Tag: {  // BINARY
    2334           0 :       int8_t bytes_read = internals::ReadTokenStart(
    2335             :           bytes_.subspan(status_.pos + 1), &token_start_type_,
    2336           0 :           &token_start_internal_value_);
    2337           0 :       int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_;
    2338           0 :       if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
    2339           0 :           status_.pos + token_byte_length > bytes_.size()) {
    2340             :         SetError(Error::CBOR_INVALID_BINARY);
    2341             :         return;
    2342             :       }
    2343             :       SetToken(CBORTokenTag::BINARY,
    2344             :                static_cast<std::ptrdiff_t>(token_byte_length));
    2345             :       return;
    2346             :     }
    2347             :     case kInitialByteForDouble: {  // DOUBLE
    2348           0 :       if (status_.pos + kEncodedDoubleSize > bytes_.size()) {
    2349             :         SetError(Error::CBOR_INVALID_DOUBLE);
    2350             :         return;
    2351             :       }
    2352             :       SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize);
    2353             :       return;
    2354             :     }
    2355             :     case kInitialByteForEnvelope: {  // ENVELOPE
    2356           0 :       if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) {
    2357             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2358             :         return;
    2359             :       }
    2360             :       // The envelope must be a byte string with 32 bit length.
    2361           0 :       if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) {
    2362             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2363             :         return;
    2364             :       }
    2365             :       // Read the length of the byte string.
    2366           0 :       token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>(
    2367           0 :           bytes_.subspan(status_.pos + 2));
    2368             :       // Make sure the payload is contained within the message.
    2369           0 :       if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize +
    2370           0 :               status_.pos >
    2371             :           static_cast<std::size_t>(bytes_.size())) {
    2372             :         SetError(Error::CBOR_INVALID_ENVELOPE);
    2373             :         return;
    2374             :       }
    2375           0 :       auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2376           0 :       SetToken(CBORTokenTag::ENVELOPE, kEncodedEnvelopeHeaderSize + length);
    2377             :       return;
    2378             :     }
    2379             :     default: {
    2380             :       span<uint8_t> remainder =
    2381           0 :           bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
    2382             :       assert(!remainder.empty());
    2383           0 :       int8_t token_start_length = internals::ReadTokenStart(
    2384           0 :           remainder, &token_start_type_, &token_start_internal_value_);
    2385             :       bool success = token_start_length != -1;
    2386           0 :       switch (token_start_type_) {
    2387             :         case MajorType::UNSIGNED:  // INT32.
    2388           0 :           if (!success || std::numeric_limits<int32_t>::max() <
    2389           0 :                               token_start_internal_value_) {
    2390             :             SetError(Error::CBOR_INVALID_INT32);
    2391           0 :             return;
    2392             :           }
    2393           0 :           SetToken(CBORTokenTag::INT32, token_start_length);
    2394             :           return;
    2395             :         case MajorType::NEGATIVE:  // INT32.
    2396           0 :           if (!success ||
    2397             :               std::numeric_limits<int32_t>::min() >
    2398           0 :                   -static_cast<int64_t>(token_start_internal_value_) - 1) {
    2399             :             SetError(Error::CBOR_INVALID_INT32);
    2400             :             return;
    2401             :           }
    2402           0 :           SetToken(CBORTokenTag::INT32, token_start_length);
    2403             :           return;
    2404             :         case MajorType::STRING: {  // STRING8.
    2405           0 :           if (!success || remainder.size() < static_cast<int64_t>(
    2406           0 :                                                  token_start_internal_value_)) {
    2407             :             SetError(Error::CBOR_INVALID_STRING8);
    2408             :             return;
    2409             :           }
    2410             :           auto length =
    2411           0 :               static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2412           0 :           SetToken(CBORTokenTag::STRING8, token_start_length + length);
    2413             :           return;
    2414             :         }
    2415             :         case MajorType::BYTE_STRING: {  // STRING16.
    2416           0 :           if (!success ||
    2417           0 :               remainder.size() <
    2418           0 :                   static_cast<int64_t>(token_start_internal_value_) ||
    2419             :               // Must be divisible by 2 since UTF16 is 2 bytes per character.
    2420           0 :               token_start_internal_value_ & 1) {
    2421             :             SetError(Error::CBOR_INVALID_STRING16);
    2422             :             return;
    2423             :           }
    2424             :           auto length =
    2425           0 :               static_cast<std::ptrdiff_t>(token_start_internal_value_);
    2426           0 :           SetToken(CBORTokenTag::STRING16, token_start_length + length);
    2427             :           return;
    2428             :         }
    2429             :         case MajorType::ARRAY:
    2430             :         case MajorType::MAP:
    2431             :         case MajorType::TAG:
    2432             :         case MajorType::SIMPLE_VALUE:
    2433             :           SetError(Error::CBOR_UNSUPPORTED_VALUE);
    2434             :           return;
    2435             :       }
    2436             :     }
    2437             :   }
    2438             : }
    2439             : 
    2440           0 : void CBORTokenizer::SetToken(CBORTokenTag token_tag,
    2441             :                              std::ptrdiff_t token_byte_length) {
    2442           0 :   token_tag_ = token_tag;
    2443           0 :   token_byte_length_ = token_byte_length;
    2444           0 : }
    2445             : 
    2446           0 : void CBORTokenizer::SetError(Error error) {
    2447           0 :   token_tag_ = CBORTokenTag::ERROR_VALUE;
    2448           0 :   status_.error = error;
    2449           0 : }
    2450             : 
    2451             : // =============================================================================
    2452             : // cbor::ParseCBOR - for receiving streaming parser events for CBOR messages
    2453             : // =============================================================================
    2454             : 
    2455             : namespace {
    2456             : // When parsing CBOR, we limit recursion depth for objects and arrays
    2457             : // to this constant.
    2458             : static constexpr int kStackLimit = 300;
    2459             : 
    2460             : // Below are three parsing routines for CBOR, which cover enough
    2461             : // to roundtrip JSON messages.
    2462             : bool ParseMap(int32_t stack_depth,
    2463             :               CBORTokenizer* tokenizer,
    2464             :               StreamingParserHandler* out);
    2465             : bool ParseArray(int32_t stack_depth,
    2466             :                 CBORTokenizer* tokenizer,
    2467             :                 StreamingParserHandler* out);
    2468             : bool ParseValue(int32_t stack_depth,
    2469             :                 CBORTokenizer* tokenizer,
    2470             :                 StreamingParserHandler* out);
    2471             : 
    2472           0 : void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
    2473             :   std::vector<uint16_t> value;
    2474             :   span<uint8_t> rep = tokenizer->GetString16WireRep();
    2475           0 :   for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2)
    2476           0 :     value.push_back((rep[ii + 1] << 8) | rep[ii]);
    2477           0 :   out->HandleString16(span<uint16_t>(value.data(), value.size()));
    2478             :   tokenizer->Next();
    2479           0 : }
    2480             : 
    2481           0 : bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
    2482             :   assert(tokenizer->TokenTag() == CBORTokenTag::STRING8);
    2483           0 :   out->HandleString8(tokenizer->GetString8());
    2484             :   tokenizer->Next();
    2485           0 :   return true;
    2486             : }
    2487             : 
    2488           0 : bool ParseValue(int32_t stack_depth,
    2489             :                 CBORTokenizer* tokenizer,
    2490             :                 StreamingParserHandler* out) {
    2491           0 :   if (stack_depth > kStackLimit) {
    2492           0 :     out->HandleError(
    2493           0 :         Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
    2494           0 :     return false;
    2495             :   }
    2496             :   // Skip past the envelope to get to what's inside.
    2497           0 :   if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
    2498             :     tokenizer->EnterEnvelope();
    2499           0 :   switch (tokenizer->TokenTag()) {
    2500             :     case CBORTokenTag::ERROR_VALUE:
    2501           0 :       out->HandleError(tokenizer->Status());
    2502           0 :       return false;
    2503             :     case CBORTokenTag::DONE:
    2504           0 :       out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
    2505           0 :                               tokenizer->Status().pos});
    2506           0 :       return false;
    2507             :     case CBORTokenTag::TRUE_VALUE:
    2508           0 :       out->HandleBool(true);
    2509             :       tokenizer->Next();
    2510             :       return true;
    2511             :     case CBORTokenTag::FALSE_VALUE:
    2512           0 :       out->HandleBool(false);
    2513             :       tokenizer->Next();
    2514             :       return true;
    2515             :     case CBORTokenTag::NULL_VALUE:
    2516           0 :       out->HandleNull();
    2517             :       tokenizer->Next();
    2518             :       return true;
    2519             :     case CBORTokenTag::INT32:
    2520           0 :       out->HandleInt32(tokenizer->GetInt32());
    2521             :       tokenizer->Next();
    2522             :       return true;
    2523             :     case CBORTokenTag::DOUBLE:
    2524           0 :       out->HandleDouble(tokenizer->GetDouble());
    2525             :       tokenizer->Next();
    2526             :       return true;
    2527             :     case CBORTokenTag::STRING8:
    2528           0 :       return ParseUTF8String(tokenizer, out);
    2529             :     case CBORTokenTag::STRING16:
    2530           0 :       ParseUTF16String(tokenizer, out);
    2531           0 :       return true;
    2532             :     case CBORTokenTag::BINARY: {
    2533           0 :       out->HandleBinary(tokenizer->GetBinary());
    2534             :       tokenizer->Next();
    2535             :       return true;
    2536             :     }
    2537             :     case CBORTokenTag::MAP_START:
    2538           0 :       return ParseMap(stack_depth + 1, tokenizer, out);
    2539             :     case CBORTokenTag::ARRAY_START:
    2540           0 :       return ParseArray(stack_depth + 1, tokenizer, out);
    2541             :     default:
    2542           0 :       out->HandleError(
    2543           0 :           Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos});
    2544           0 :       return false;
    2545             :   }
    2546             : }
    2547             : 
    2548             : // |bytes| must start with the indefinite length array byte, so basically,
    2549             : // ParseArray may only be called after an indefinite length array has been
    2550             : // detected.
    2551           0 : bool ParseArray(int32_t stack_depth,
    2552             :                 CBORTokenizer* tokenizer,
    2553             :                 StreamingParserHandler* out) {
    2554             :   assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
    2555             :   tokenizer->Next();
    2556           0 :   out->HandleArrayBegin();
    2557           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
    2558           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
    2559           0 :       out->HandleError(
    2560           0 :           Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
    2561           0 :       return false;
    2562             :     }
    2563           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2564           0 :       out->HandleError(tokenizer->Status());
    2565           0 :       return false;
    2566             :     }
    2567             :     // Parse value.
    2568           0 :     if (!ParseValue(stack_depth, tokenizer, out))
    2569             :       return false;
    2570             :   }
    2571           0 :   out->HandleArrayEnd();
    2572             :   tokenizer->Next();
    2573             :   return true;
    2574             : }
    2575             : 
    2576             : // |bytes| must start with the indefinite length array byte, so basically,
    2577             : // ParseArray may only be called after an indefinite length array has been
    2578             : // detected.
    2579           0 : bool ParseMap(int32_t stack_depth,
    2580             :               CBORTokenizer* tokenizer,
    2581             :               StreamingParserHandler* out) {
    2582             :   assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START);
    2583           0 :   out->HandleMapBegin();
    2584             :   tokenizer->Next();
    2585           0 :   while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
    2586           0 :     if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
    2587           0 :       out->HandleError(
    2588           0 :           Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
    2589           0 :       return false;
    2590             :     }
    2591           0 :     if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2592           0 :       out->HandleError(tokenizer->Status());
    2593           0 :       return false;
    2594             :     }
    2595             :     // Parse key.
    2596           0 :     if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
    2597           0 :       if (!ParseUTF8String(tokenizer, out))
    2598             :         return false;
    2599           0 :     } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
    2600           0 :       ParseUTF16String(tokenizer, out);
    2601             :     } else {
    2602           0 :       out->HandleError(
    2603           0 :           Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos});
    2604           0 :       return false;
    2605             :     }
    2606             :     // Parse value.
    2607           0 :     if (!ParseValue(stack_depth, tokenizer, out))
    2608             :       return false;
    2609             :   }
    2610           0 :   out->HandleMapEnd();
    2611             :   tokenizer->Next();
    2612             :   return true;
    2613             : }
    2614             : }  // namespace
    2615             : 
    2616           0 : void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) {
    2617           0 :   if (bytes.empty()) {
    2618           0 :     out->HandleError(Status{Error::CBOR_NO_INPUT, 0});
    2619           0 :     return;
    2620             :   }
    2621           0 :   if (bytes[0] != kInitialByteForEnvelope) {
    2622           0 :     out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0});
    2623           0 :     return;
    2624             :   }
    2625             :   CBORTokenizer tokenizer(bytes);
    2626           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2627           0 :     out->HandleError(tokenizer.Status());
    2628           0 :     return;
    2629             :   }
    2630             :   // We checked for the envelope start byte above, so the tokenizer
    2631             :   // must agree here, since it's not an error.
    2632             :   assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
    2633             :   tokenizer.EnterEnvelope();
    2634           0 :   if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
    2635           0 :     out->HandleError(
    2636           0 :         Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
    2637           0 :     return;
    2638             :   }
    2639           0 :   if (!ParseMap(/*stack_depth=*/1, &tokenizer, out))
    2640             :     return;
    2641           0 :   if (tokenizer.TokenTag() == CBORTokenTag::DONE)
    2642             :     return;
    2643           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
    2644           0 :     out->HandleError(tokenizer.Status());
    2645           0 :     return;
    2646             :   }
    2647           0 :   out->HandleError(Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos});
    2648             : }
    2649             : 
    2650             : // =============================================================================
    2651             : // cbor::AppendString8EntryToMap - for limited in-place editing of messages
    2652             : // =============================================================================
    2653             : 
    2654             : template <typename C>
    2655           0 : Status AppendString8EntryToCBORMapTmpl(span<uint8_t> string8_key,
    2656             :                                        span<uint8_t> string8_value,
    2657             :                                        C* cbor) {
    2658             :   span<uint8_t> bytes(reinterpret_cast<const uint8_t*>(cbor->data()),
    2659           0 :                       cbor->size());
    2660             :   CBORTokenizer tokenizer(bytes);
    2661           0 :   if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE)
    2662             :     return tokenizer.Status();
    2663           0 :   if (tokenizer.TokenTag() != CBORTokenTag::ENVELOPE)
    2664           0 :     return Status(Error::CBOR_INVALID_ENVELOPE, 0);
    2665             :   std::ptrdiff_t envelope_size = tokenizer.GetEnvelopeContents().size();
    2666             :   std::size_t old_size = cbor->size();
    2667           0 :   if (old_size != std::size_t(envelope_size) + kEncodedEnvelopeHeaderSize)
    2668           0 :     return Status(Error::CBOR_INVALID_ENVELOPE, 0);
    2669           0 :   if (envelope_size == 0 ||
    2670             :       (tokenizer.GetEnvelopeContents()[0] != EncodeIndefiniteLengthMapStart()))
    2671           0 :     return Status(Error::CBOR_MAP_START_EXPECTED, kEncodedEnvelopeHeaderSize);
    2672           0 :   if (cbor->back() != EncodeStop())
    2673           0 :     return Status(Error::CBOR_MAP_STOP_EXPECTED, cbor->size() - 1);
    2674             :   cbor->pop_back();
    2675             :   EncodeString8(string8_key, cbor);
    2676             :   EncodeString8(string8_value, cbor);
    2677           0 :   cbor->push_back(EncodeStop());
    2678           0 :   std::size_t new_envelope_size = envelope_size + (cbor->size() - old_size);
    2679           0 :   if (new_envelope_size > std::numeric_limits<uint32_t>::max())
    2680           0 :     return Status(Error::CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED, 0);
    2681           0 :   std::size_t size_pos = cbor->size() - new_envelope_size - sizeof(uint32_t);
    2682             :   uint8_t* out = reinterpret_cast<uint8_t*>(&cbor->at(size_pos));
    2683           0 :   *(out++) = (new_envelope_size >> 24) & 0xff;
    2684           0 :   *(out++) = (new_envelope_size >> 16) & 0xff;
    2685           0 :   *(out++) = (new_envelope_size >> 8) & 0xff;
    2686           0 :   *(out) = new_envelope_size & 0xff;
    2687           0 :   return Status();
    2688             : }
    2689           0 : Status AppendString8EntryToCBORMap(span<uint8_t> string8_key,
    2690             :                                    span<uint8_t> string8_value,
    2691             :                                    std::vector<uint8_t>* cbor) {
    2692           0 :   return AppendString8EntryToCBORMapTmpl(string8_key, string8_value, cbor);
    2693             : }
    2694           0 : Status AppendString8EntryToCBORMap(span<uint8_t> string8_key,
    2695             :                                    span<uint8_t> string8_value,
    2696             :                                    std::string* cbor) {
    2697           0 :   return AppendString8EntryToCBORMapTmpl(string8_key, string8_value, cbor);
    2698             : }
    2699             : }  // namespace cbor
    2700             : 
    2701             : namespace json {
    2702             : 
    2703             : // =============================================================================
    2704             : // json::NewJSONEncoder - for encoding streaming parser events as JSON
    2705             : // =============================================================================
    2706             : 
    2707             : namespace {
    2708             : // Prints |value| to |out| with 4 hex digits, most significant chunk first.
    2709             : template <typename C>
    2710           0 : void PrintHex(uint16_t value, C* out) {
    2711           0 :   for (int ii = 3; ii >= 0; --ii) {
    2712           0 :     int four_bits = 0xf & (value >> (4 * ii));
    2713           0 :     out->push_back(four_bits + ((four_bits <= 9) ? '0' : ('a' - 10)));
    2714             :   }
    2715           0 : }
    2716             : 
    2717             : // In the writer below, we maintain a stack of State instances.
    2718             : // It is just enough to emit the appropriate delimiters and brackets
    2719             : // in JSON.
    2720             : enum class Container {
    2721             :   // Used for the top-level, initial state.
    2722             :   NONE,
    2723             :   // Inside a JSON object.
    2724             :   MAP,
    2725             :   // Inside a JSON array.
    2726             :   ARRAY
    2727             : };
    2728             : class State {
    2729             :  public:
    2730           0 :   explicit State(Container container) : container_(container) {}
    2731             :   void StartElement(std::vector<uint8_t>* out) {
    2732             :     // FIXME!!!
    2733             :   }
    2734           0 :   void StartElement(std::string* out) {
    2735             :     assert(container_ != Container::NONE || size_ == 0);
    2736           0 :     if (size_ != 0) {
    2737           0 :       char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':';
    2738             :       out->append(1, delim);
    2739             :     }
    2740           0 :     ++size_;
    2741           0 :   }
    2742             :   Container container() const { return container_; }
    2743             : 
    2744             :  private:
    2745             :   Container container_ = Container::NONE;
    2746             :   int size_ = 0;
    2747             : };
    2748             : 
    2749             : constexpr char kBase64Table[] =
    2750             :     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    2751             :     "abcdefghijklmnopqrstuvwxyz0123456789+/";
    2752             : 
    2753             : template <typename C>
    2754           0 : void Base64Encode(const span<uint8_t>& in, C* out) {
    2755             :   // The following three cases are based on the tables in the example
    2756             :   // section in https://en.wikipedia.org/wiki/Base64. We process three
    2757             :   // input bytes at a time, emitting 4 output bytes at a time.
    2758             :   std::ptrdiff_t ii = 0;
    2759             : 
    2760             :   // While possible, process three input bytes.
    2761           0 :   for (; ii + 3 <= in.size(); ii += 3) {
    2762           0 :     uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2];
    2763           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
    2764           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
    2765           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
    2766           0 :     out->push_back(kBase64Table[twentyfour_bits & 0x3f]);
    2767             :   }
    2768           0 :   if (ii + 2 <= in.size()) {  // Process two input bytes.
    2769           0 :     uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8);
    2770           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
    2771           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
    2772           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
    2773           0 :     out->push_back('=');  // Emit padding.
    2774           0 :     return;
    2775             :   }
    2776           0 :   if (ii + 1 <= in.size()) {  // Process a single input byte.
    2777           0 :     uint32_t twentyfour_bits = (in[ii] << 16);
    2778           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
    2779           0 :     out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
    2780           0 :     out->push_back('=');  // Emit padding.
    2781           0 :     out->push_back('=');  // Emit padding.
    2782             :   }
    2783             : }
    2784             : 
    2785             : // Implements a handler for JSON parser events to emit a JSON string.
    2786             : template <typename C>
    2787           0 : class JSONEncoder : public StreamingParserHandler {
    2788             :  public:
    2789           0 :   JSONEncoder(const Platform* platform, C* out, Status* status)
    2790           0 :       : platform_(platform), out_(out), status_(status) {
    2791           0 :     *status_ = Status();
    2792           0 :     state_.emplace(Container::NONE);
    2793           0 :   }
    2794             : 
    2795           0 :   void HandleMapBegin() override {
    2796           0 :     if (!status_->ok())
    2797             :       return;
    2798             :     assert(!state_.empty());
    2799           0 :     state_.top().StartElement(out_);
    2800           0 :     state_.emplace(Container::MAP);
    2801             :     Emit('{');
    2802             :   }
    2803             : 
    2804           0 :   void HandleMapEnd() override {
    2805           0 :     if (!status_->ok())
    2806             :       return;
    2807             :     assert(state_.size() >= 2 && state_.top().container() == Container::MAP);
    2808             :     state_.pop();
    2809             :     Emit('}');
    2810             :   }
    2811             : 
    2812           0 :   void HandleArrayBegin() override {
    2813           0 :     if (!status_->ok())
    2814             :       return;
    2815           0 :     state_.top().StartElement(out_);
    2816           0 :     state_.emplace(Container::ARRAY);
    2817             :     Emit('[');
    2818             :   }
    2819             : 
    2820           0 :   void HandleArrayEnd() override {
    2821           0 :     if (!status_->ok())
    2822             :       return;
    2823             :     assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY);
    2824             :     state_.pop();
    2825             :     Emit(']');
    2826             :   }
    2827             : 
    2828           0 :   void HandleString16(span<uint16_t> chars) override {
    2829           0 :     if (!status_->ok())
    2830             :       return;
    2831           0 :     state_.top().StartElement(out_);
    2832             :     Emit('"');
    2833           0 :     for (const uint16_t ch : chars) {
    2834           0 :       if (ch == '"') {
    2835           0 :         Emit("\\\"");
    2836           0 :       } else if (ch == '\\') {
    2837           0 :         Emit("\\\\");
    2838           0 :       } else if (ch == '\b') {
    2839           0 :         Emit("\\b");
    2840           0 :       } else if (ch == '\f') {
    2841           0 :         Emit("\\f");
    2842           0 :       } else if (ch == '\n') {
    2843           0 :         Emit("\\n");
    2844           0 :       } else if (ch == '\r') {
    2845           0 :         Emit("\\r");
    2846           0 :       } else if (ch == '\t') {
    2847           0 :         Emit("\\t");
    2848           0 :       } else if (ch >= 32 && ch <= 126) {
    2849           0 :         Emit(ch);
    2850             :       } else {
    2851           0 :         Emit("\\u");
    2852           0 :         PrintHex(ch, out_);
    2853             :       }
    2854             :     }
    2855             :     Emit('"');
    2856             :   }
    2857             : 
    2858           0 :   void HandleString8(span<uint8_t> chars) override {
    2859           0 :     if (!status_->ok())
    2860             :       return;
    2861           0 :     state_.top().StartElement(out_);
    2862             :     Emit('"');
    2863           0 :     for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) {
    2864           0 :       uint8_t c = chars[ii];
    2865           0 :       if (c == '"') {
    2866           0 :         Emit("\\\"");
    2867           0 :       } else if (c == '\\') {
    2868           0 :         Emit("\\\\");
    2869           0 :       } else if (c == '\b') {
    2870           0 :         Emit("\\b");
    2871           0 :       } else if (c == '\f') {
    2872           0 :         Emit("\\f");
    2873           0 :       } else if (c == '\n') {
    2874           0 :         Emit("\\n");
    2875           0 :       } else if (c == '\r') {
    2876           0 :         Emit("\\r");
    2877           0 :       } else if (c == '\t') {
    2878           0 :         Emit("\\t");
    2879           0 :       } else if (c >= 32 && c <= 126) {
    2880           0 :         Emit(c);
    2881           0 :       } else if (c < 32) {
    2882           0 :         Emit("\\u");
    2883           0 :         PrintHex(static_cast<uint16_t>(c), out_);
    2884             :       } else {
    2885             :         // Inspect the leading byte to figure out how long the utf8
    2886             :         // byte sequence is; while doing this initialize |codepoint|
    2887             :         // with the first few bits.
    2888             :         // See table in: https://en.wikipedia.org/wiki/UTF-8
    2889             :         // byte one is 110x xxxx -> 2 byte utf8 sequence
    2890             :         // byte one is 1110 xxxx -> 3 byte utf8 sequence
    2891             :         // byte one is 1111 0xxx -> 4 byte utf8 sequence
    2892             :         uint32_t codepoint;
    2893             :         int num_bytes_left;
    2894           0 :         if ((c & 0xe0) == 0xc0) {  // 2 byte utf8 sequence
    2895             :           num_bytes_left = 1;
    2896           0 :           codepoint = c & 0x1f;
    2897           0 :         } else if ((c & 0xf0) == 0xe0) {  // 3 byte utf8 sequence
    2898             :           num_bytes_left = 2;
    2899           0 :           codepoint = c & 0x0f;
    2900           0 :         } else if ((c & 0xf8) == 0xf0) {  // 4 byte utf8 sequence
    2901           0 :           codepoint = c & 0x07;
    2902             :           num_bytes_left = 3;
    2903             :         } else {
    2904             :           continue;  // invalid leading byte
    2905             :         }
    2906             : 
    2907             :         // If we have enough bytes in our input, decode the remaining ones
    2908             :         // belonging to this Unicode character into |codepoint|.
    2909           0 :         if (ii + num_bytes_left > chars.size())
    2910             :           continue;
    2911           0 :         while (num_bytes_left > 0) {
    2912           0 :           c = chars[++ii];
    2913           0 :           --num_bytes_left;
    2914             :           // Check the next byte is a continuation byte, that is 10xx xxxx.
    2915           0 :           if ((c & 0xc0) != 0x80)
    2916             :             continue;
    2917           0 :           codepoint = (codepoint << 6) | (c & 0x3f);
    2918             :         }
    2919             : 
    2920             :         // Disallow overlong encodings for ascii characters, as these
    2921             :         // would include " and other characters significant to JSON
    2922             :         // string termination / control.
    2923           0 :         if (codepoint < 0x7f)
    2924             :           continue;
    2925             :         // Invalid in UTF8, and can't be represented in UTF16 anyway.
    2926           0 :         if (codepoint > 0x10ffff)
    2927             :           continue;
    2928             : 
    2929             :         // So, now we transcode to UTF16,
    2930             :         // using the math described at https://en.wikipedia.org/wiki/UTF-16,
    2931             :         // for either one or two 16 bit characters.
    2932           0 :         if (codepoint < 0xffff) {
    2933           0 :           Emit("\\u");
    2934           0 :           PrintHex(static_cast<uint16_t>(codepoint), out_);
    2935           0 :           continue;
    2936             :         }
    2937           0 :         codepoint -= 0x10000;
    2938             :         // high surrogate
    2939           0 :         Emit("\\u");
    2940           0 :         PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_);
    2941             :         // low surrogate
    2942           0 :         Emit("\\u");
    2943           0 :         PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_);
    2944             :       }
    2945             :     }
    2946             :     Emit('"');
    2947             :   }
    2948             : 
    2949           0 :   void HandleBinary(span<uint8_t> bytes) override {
    2950           0 :     if (!status_->ok())
    2951             :       return;
    2952           0 :     state_.top().StartElement(out_);
    2953             :     Emit('"');
    2954           0 :     Base64Encode(bytes, out_);
    2955             :     Emit('"');
    2956             :   }
    2957             : 
    2958           0 :   void HandleDouble(double value) override {
    2959           0 :     if (!status_->ok())
    2960           0 :       return;
    2961           0 :     state_.top().StartElement(out_);
    2962             :     // JSON cannot represent NaN or Infinity. So, for compatibility,
    2963             :     // we behave like the JSON object in web browsers: emit 'null'.
    2964           0 :     if (!std::isfinite(value)) {
    2965           0 :       Emit("null");
    2966           0 :       return;
    2967             :     }
    2968           0 :     std::unique_ptr<char[]> str_value = platform_->DToStr(value);
    2969             : 
    2970             :     // DToStr may fail to emit a 0 before the decimal dot. E.g. this is
    2971             :     // the case in base::NumberToString in Chromium (which is based on
    2972             :     // dmg_fp). So, much like
    2973             :     // https://cs.chromium.org/chromium/src/base/json/json_writer.cc
    2974             :     // we probe for this and emit the leading 0 anyway if necessary.
    2975             :     const char* chars = str_value.get();
    2976           0 :     if (chars[0] == '.') {
    2977             :       Emit('0');
    2978           0 :     } else if (chars[0] == '-' && chars[1] == '.') {
    2979           0 :       Emit("-0");
    2980           0 :       ++chars;
    2981             :     }
    2982           0 :     Emit(chars);
    2983             :   }
    2984             : 
    2985           0 :   void HandleInt32(int32_t value) override {
    2986           0 :     if (!status_->ok())
    2987             :       return;
    2988           0 :     state_.top().StartElement(out_);
    2989           0 :     Emit(std::to_string(value));
    2990             :   }
    2991             : 
    2992           0 :   void HandleBool(bool value) override {
    2993           0 :     if (!status_->ok())
    2994             :       return;
    2995           0 :     state_.top().StartElement(out_);
    2996           0 :     Emit(value ? "true" : "false");
    2997             :   }
    2998             : 
    2999           0 :   void HandleNull() override {
    3000           0 :     if (!status_->ok())
    3001             :       return;
    3002           0 :     state_.top().StartElement(out_);
    3003           0 :     Emit("null");
    3004             :   }
    3005             : 
    3006           0 :   void HandleError(Status error) override {
    3007             :     assert(!error.ok());
    3008           0 :     *status_ = error;
    3009           0 :     out_->clear();
    3010           0 :   }
    3011             : 
    3012             :  private:
    3013           0 :   void Emit(char c) { out_->push_back(c); }
    3014           0 :   void Emit(const char* str) {
    3015           0 :     out_->insert(out_->end(), str, str + strlen(str));
    3016           0 :   }
    3017           0 :   void Emit(const std::string& str) {
    3018           0 :     out_->insert(out_->end(), str.begin(), str.end());
    3019           0 :   }
    3020             : 
    3021             :   const Platform* platform_;
    3022             :   C* out_;
    3023             :   Status* status_;
    3024             :   std::stack<State> state_;
    3025             : };
    3026             : }  // namespace
    3027             : 
    3028           0 : std::unique_ptr<StreamingParserHandler> NewJSONEncoder(
    3029             :     const Platform* platform,
    3030             :     std::vector<uint8_t>* out,
    3031             :     Status* status) {
    3032             :   return std::unique_ptr<StreamingParserHandler>(
    3033           0 :       new JSONEncoder<std::vector<uint8_t>>(platform, out, status));
    3034             : }
    3035           0 : std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform,
    3036             :                                                        std::string* out,
    3037             :                                                        Status* status) {
    3038             :   return std::unique_ptr<StreamingParserHandler>(
    3039           0 :       new JSONEncoder<std::string>(platform, out, status));
    3040             : }
    3041             : 
    3042             : // =============================================================================
    3043             : // json::ParseJSON - for receiving streaming parser events for JSON.
    3044             : // =============================================================================
    3045             : 
    3046             : namespace {
    3047             : const int kStackLimit = 300;
    3048             : 
    3049             : enum Token {
    3050             :   ObjectBegin,
    3051             :   ObjectEnd,
    3052             :   ArrayBegin,
    3053             :   ArrayEnd,
    3054             :   StringLiteral,
    3055             :   Number,
    3056             :   BoolTrue,
    3057             :   BoolFalse,
    3058             :   NullToken,
    3059             :   ListSeparator,
    3060             :   ObjectPairSeparator,
    3061             :   InvalidToken,
    3062             :   NoInput
    3063             : };
    3064             : 
    3065             : const char* const kNullString = "null";
    3066             : const char* const kTrueString = "true";
    3067             : const char* const kFalseString = "false";
    3068             : 
    3069             : template <typename Char>
    3070             : class JsonParser {
    3071             :  public:
    3072             :   JsonParser(const Platform* platform, StreamingParserHandler* handler)
    3073           0 :       : platform_(platform), handler_(handler) {}
    3074             : 
    3075           0 :   void Parse(const Char* start, std::size_t length) {
    3076           0 :     start_pos_ = start;
    3077           0 :     const Char* end = start + length;
    3078             :     const Char* tokenEnd;
    3079           0 :     ParseValue(start, end, &tokenEnd, 0);
    3080           0 :     if (tokenEnd != end) {
    3081             :       HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd);
    3082             :     }
    3083           0 :   }
    3084             : 
    3085             :  private:
    3086           0 :   bool CharsToDouble(const uint16_t* chars,
    3087             :                      std::size_t length,
    3088             :                      double* result) {
    3089             :     std::string buffer;
    3090           0 :     buffer.reserve(length + 1);
    3091           0 :     for (std::size_t ii = 0; ii < length; ++ii) {
    3092           0 :       bool is_ascii = !(chars[ii] & ~0x7F);
    3093           0 :       if (!is_ascii)
    3094             :         return false;
    3095           0 :       buffer.push_back(static_cast<char>(chars[ii]));
    3096             :     }
    3097           0 :     return platform_->StrToD(buffer.c_str(), result);
    3098             :   }
    3099             : 
    3100           0 :   bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) {
    3101             :     std::string buffer(reinterpret_cast<const char*>(chars), length);
    3102           0 :     return platform_->StrToD(buffer.c_str(), result);
    3103             :   }
    3104             : 
    3105             :   static bool ParseConstToken(const Char* start,
    3106             :                               const Char* end,
    3107             :                               const Char** token_end,
    3108             :                               const char* token) {
    3109             :     // |token| is \0 terminated, it's one of the constants at top of the file.
    3110           0 :     while (start < end && *token != '\0' && *start++ == *token++) {
    3111             :     }
    3112           0 :     if (*token != '\0')
    3113             :       return false;
    3114           0 :     *token_end = start;
    3115             :     return true;
    3116             :   }
    3117             : 
    3118             :   static bool ReadInt(const Char* start,
    3119             :                       const Char* end,
    3120             :                       const Char** token_end,
    3121             :                       bool allow_leading_zeros) {
    3122           0 :     if (start == end)
    3123             :       return false;
    3124           0 :     bool has_leading_zero = '0' == *start;
    3125             :     int length = 0;
    3126           0 :     while (start < end && '0' <= *start && *start <= '9') {
    3127           0 :       ++start;
    3128           0 :       ++length;
    3129             :     }
    3130           0 :     if (!length)
    3131             :       return false;
    3132           0 :     if (!allow_leading_zeros && length > 1 && has_leading_zero)
    3133             :       return false;
    3134             :     *token_end = start;
    3135             :     return true;
    3136             :   }
    3137             : 
    3138           0 :   static bool ParseNumberToken(const Char* start,
    3139             :                                const Char* end,
    3140             :                                const Char** token_end) {
    3141             :     // We just grab the number here. We validate the size in DecodeNumber.
    3142             :     // According to RFC4627, a valid number is: [minus] int [frac] [exp]
    3143           0 :     if (start == end)
    3144             :       return false;
    3145           0 :     Char c = *start;
    3146           0 :     if ('-' == c)
    3147           0 :       ++start;
    3148             : 
    3149           0 :     if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false))
    3150             :       return false;
    3151           0 :     if (start == end) {
    3152           0 :       *token_end = start;
    3153           0 :       return true;
    3154             :     }
    3155             : 
    3156             :     // Optional fraction part
    3157           0 :     c = *start;
    3158           0 :     if ('.' == c) {
    3159           0 :       ++start;
    3160           0 :       if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
    3161             :         return false;
    3162           0 :       if (start == end) {
    3163           0 :         *token_end = start;
    3164           0 :         return true;
    3165             :       }
    3166           0 :       c = *start;
    3167             :     }
    3168             : 
    3169             :     // Optional exponent part
    3170           0 :     if ('e' == c || 'E' == c) {
    3171           0 :       ++start;
    3172           0 :       if (start == end)
    3173             :         return false;
    3174           0 :       c = *start;
    3175           0 :       if ('-' == c || '+' == c) {
    3176           0 :         ++start;
    3177           0 :         if (start == end)
    3178             :           return false;
    3179             :       }
    3180           0 :       if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
    3181             :         return false;
    3182             :     }
    3183             : 
    3184           0 :     *token_end = start;
    3185           0 :     return true;
    3186             :   }
    3187             : 
    3188             :   static bool ReadHexDigits(const Char* start,
    3189             :                             const Char* end,
    3190             :                             const Char** token_end,
    3191             :                             int digits) {
    3192           0 :     if (end - start < digits)
    3193             :       return false;
    3194           0 :     for (int i = 0; i < digits; ++i) {
    3195           0 :       Char c = *start++;
    3196           0 :       if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
    3197             :             ('A' <= c && c <= 'F')))
    3198             :         return false;
    3199             :     }
    3200             :     *token_end = start;
    3201             :     return true;
    3202             :   }
    3203             : 
    3204           0 :   static bool ParseStringToken(const Char* start,
    3205             :                                const Char* end,
    3206             :                                const Char** token_end) {
    3207           0 :     while (start < end) {
    3208           0 :       Char c = *start++;
    3209           0 :       if ('\\' == c) {
    3210           0 :         if (start == end)
    3211             :           return false;
    3212           0 :         c = *start++;
    3213             :         // Make sure the escaped char is valid.
    3214           0 :         switch (c) {
    3215             :           case 'x':
    3216           0 :             if (!ReadHexDigits(start, end, &start, 2))
    3217             :               return false;
    3218             :             break;
    3219             :           case 'u':
    3220           0 :             if (!ReadHexDigits(start, end, &start, 4))
    3221             :               return false;
    3222             :             break;
    3223             :           case '\\':
    3224             :           case '/':
    3225             :           case 'b':
    3226             :           case 'f':
    3227             :           case 'n':
    3228             :           case 'r':
    3229             :           case 't':
    3230             :           case 'v':
    3231             :           case '"':
    3232             :             break;
    3233             :           default:
    3234             :             return false;
    3235             :         }
    3236           0 :       } else if ('"' == c) {
    3237           0 :         *token_end = start;
    3238           0 :         return true;
    3239             :       }
    3240             :     }
    3241             :     return false;
    3242             :   }
    3243             : 
    3244           0 :   static bool SkipComment(const Char* start,
    3245             :                           const Char* end,
    3246             :                           const Char** comment_end) {
    3247           0 :     if (start == end)
    3248             :       return false;
    3249             : 
    3250           0 :     if (*start != '/' || start + 1 >= end)
    3251             :       return false;
    3252             :     ++start;
    3253             : 
    3254           0 :     if (*start == '/') {
    3255             :       // Single line comment, read to newline.
    3256           0 :       for (++start; start < end; ++start) {
    3257           0 :         if (*start == '\n' || *start == '\r') {
    3258           0 :           *comment_end = start + 1;
    3259           0 :           return true;
    3260             :         }
    3261             :       }
    3262           0 :       *comment_end = end;
    3263             :       // Comment reaches end-of-input, which is fine.
    3264           0 :       return true;
    3265             :     }
    3266             : 
    3267           0 :     if (*start == '*') {
    3268             :       Char previous = '\0';
    3269             :       // Block comment, read until end marker.
    3270           0 :       for (++start; start < end; previous = *start++) {
    3271           0 :         if (previous == '*' && *start == '/') {
    3272           0 :           *comment_end = start + 1;
    3273           0 :           return true;
    3274             :         }
    3275             :       }
    3276             :       // Block comment must close before end-of-input.
    3277             :       return false;
    3278             :     }
    3279             : 
    3280             :     return false;
    3281             :   }
    3282             : 
    3283             :   static bool IsSpaceOrNewLine(Char c) {
    3284             :     // \v = vertial tab; \f = form feed page break.
    3285             :     return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' ||
    3286           0 :            c == '\t';
    3287             :   }
    3288             : 
    3289           0 :   static void SkipWhitespaceAndComments(const Char* start,
    3290             :                                         const Char* end,
    3291             :                                         const Char** whitespace_end) {
    3292           0 :     while (start < end) {
    3293           0 :       if (IsSpaceOrNewLine(*start)) {
    3294           0 :         ++start;
    3295           0 :       } else if (*start == '/') {
    3296             :         const Char* comment_end;
    3297           0 :         if (!SkipComment(start, end, &comment_end))
    3298             :           break;
    3299           0 :         start = comment_end;
    3300             :       } else {
    3301             :         break;
    3302             :       }
    3303             :     }
    3304           0 :     *whitespace_end = start;
    3305           0 :   }
    3306             : 
    3307           0 :   static Token ParseToken(const Char* start,
    3308             :                           const Char* end,
    3309             :                           const Char** tokenStart,
    3310             :                           const Char** token_end) {
    3311           0 :     SkipWhitespaceAndComments(start, end, tokenStart);
    3312           0 :     start = *tokenStart;
    3313             : 
    3314           0 :     if (start == end)
    3315             :       return NoInput;
    3316             : 
    3317           0 :     switch (*start) {
    3318             :       case 'n':
    3319           0 :         if (ParseConstToken(start, end, token_end, kNullString))
    3320             :           return NullToken;
    3321             :         break;
    3322             :       case 't':
    3323           0 :         if (ParseConstToken(start, end, token_end, kTrueString))
    3324             :           return BoolTrue;
    3325             :         break;
    3326             :       case 'f':
    3327           0 :         if (ParseConstToken(start, end, token_end, kFalseString))
    3328             :           return BoolFalse;
    3329             :         break;
    3330             :       case '[':
    3331           0 :         *token_end = start + 1;
    3332           0 :         return ArrayBegin;
    3333             :       case ']':
    3334           0 :         *token_end = start + 1;
    3335           0 :         return ArrayEnd;
    3336             :       case ',':
    3337           0 :         *token_end = start + 1;
    3338           0 :         return ListSeparator;
    3339             :       case '{':
    3340           0 :         *token_end = start + 1;
    3341           0 :         return ObjectBegin;
    3342             :       case '}':
    3343           0 :         *token_end = start + 1;
    3344           0 :         return ObjectEnd;
    3345             :       case ':':
    3346           0 :         *token_end = start + 1;
    3347           0 :         return ObjectPairSeparator;
    3348             :       case '0':
    3349             :       case '1':
    3350             :       case '2':
    3351             :       case '3':
    3352             :       case '4':
    3353             :       case '5':
    3354             :       case '6':
    3355             :       case '7':
    3356             :       case '8':
    3357             :       case '9':
    3358             :       case '-':
    3359           0 :         if (ParseNumberToken(start, end, token_end))
    3360             :           return Number;
    3361             :         break;
    3362             :       case '"':
    3363           0 :         if (ParseStringToken(start + 1, end, token_end))
    3364             :           return StringLiteral;
    3365             :         break;
    3366             :     }
    3367             :     return InvalidToken;
    3368             :   }
    3369             : 
    3370             :   static int HexToInt(Char c) {
    3371           0 :     if ('0' <= c && c <= '9')
    3372           0 :       return c - '0';
    3373           0 :     if ('A' <= c && c <= 'F')
    3374           0 :       return c - 'A' + 10;
    3375           0 :     if ('a' <= c && c <= 'f')
    3376           0 :       return c - 'a' + 10;
    3377             :     assert(false);  // Unreachable.
    3378             :     return 0;
    3379             :   }
    3380             : 
    3381           0 :   static bool DecodeString(const Char* start,
    3382             :                            const Char* end,
    3383             :                            std::vector<uint16_t>* output) {
    3384           0 :     if (start == end)
    3385             :       return true;
    3386           0 :     if (start > end)
    3387             :       return false;
    3388           0 :     output->reserve(end - start);
    3389           0 :     while (start < end) {
    3390           0 :       uint16_t c = *start++;
    3391             :       // If the |Char| we're dealing with is really a byte, then
    3392             :       // we have utf8 here, and we need to check for multibyte characters
    3393             :       // and transcode them to utf16 (either one or two utf16 chars).
    3394           0 :       if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) {
    3395             :         // Inspect the leading byte to figure out how long the utf8
    3396             :         // byte sequence is; while doing this initialize |codepoint|
    3397             :         // with the first few bits.
    3398             :         // See table in: https://en.wikipedia.org/wiki/UTF-8
    3399             :         // byte one is 110x xxxx -> 2 byte utf8 sequence
    3400             :         // byte one is 1110 xxxx -> 3 byte utf8 sequence
    3401             :         // byte one is 1111 0xxx -> 4 byte utf8 sequence
    3402             :         uint32_t codepoint;
    3403             :         int num_bytes_left;
    3404           0 :         if ((c & 0xe0) == 0xc0) {  // 2 byte utf8 sequence
    3405             :           num_bytes_left = 1;
    3406           0 :           codepoint = c & 0x1f;
    3407           0 :         } else if ((c & 0xf0) == 0xe0) {  // 3 byte utf8 sequence
    3408             :           num_bytes_left = 2;
    3409           0 :           codepoint = c & 0x0f;
    3410           0 :         } else if ((c & 0xf8) == 0xf0) {  // 4 byte utf8 sequence
    3411           0 :           codepoint = c & 0x07;
    3412             :           num_bytes_left = 3;
    3413             :         } else {
    3414           0 :           return false;  // invalid leading byte
    3415             :         }
    3416             : 
    3417             :         // If we have enough bytes in our inpput, decode the remaining ones
    3418             :         // belonging to this Unicode character into |codepoint|.
    3419           0 :         if (start + num_bytes_left > end)
    3420             :           return false;
    3421           0 :         while (num_bytes_left > 0) {
    3422           0 :           c = *start++;
    3423           0 :           --num_bytes_left;
    3424             :           // Check the next byte is a continuation byte, that is 10xx xxxx.
    3425           0 :           if ((c & 0xc0) != 0x80)
    3426             :             return false;
    3427           0 :           codepoint = (codepoint << 6) | (c & 0x3f);
    3428             :         }
    3429             : 
    3430             :         // Disallow overlong encodings for ascii characters, as these
    3431             :         // would include " and other characters significant to JSON
    3432             :         // string termination / control.
    3433           0 :         if (codepoint < 0x7f)
    3434             :           return false;
    3435             :         // Invalid in UTF8, and can't be represented in UTF16 anyway.
    3436           0 :         if (codepoint > 0x10ffff)
    3437             :           return false;
    3438             : 
    3439             :         // So, now we transcode to UTF16,
    3440             :         // using the math described at https://en.wikipedia.org/wiki/UTF-16,
    3441             :         // for either one or two 16 bit characters.
    3442           0 :         if (codepoint < 0xffff) {
    3443           0 :           output->push_back(codepoint);
    3444           0 :           continue;
    3445             :         }
    3446           0 :         codepoint -= 0x10000;
    3447           0 :         output->push_back((codepoint >> 10) + 0xd800);    // high surrogate
    3448           0 :         output->push_back((codepoint & 0x3ff) + 0xdc00);  // low surrogate
    3449           0 :         continue;
    3450             :       }
    3451           0 :       if ('\\' != c) {
    3452           0 :         output->push_back(c);
    3453           0 :         continue;
    3454             :       }
    3455           0 :       if (start == end)
    3456             :         return false;
    3457           0 :       c = *start++;
    3458             : 
    3459           0 :       if (c == 'x') {
    3460             :         // \x is not supported.
    3461             :         return false;
    3462             :       }
    3463             : 
    3464           0 :       switch (c) {
    3465             :         case '"':
    3466             :         case '/':
    3467             :         case '\\':
    3468             :           break;
    3469             :         case 'b':
    3470           0 :           c = '\b';
    3471           0 :           break;
    3472             :         case 'f':
    3473           0 :           c = '\f';
    3474           0 :           break;
    3475             :         case 'n':
    3476           0 :           c = '\n';
    3477           0 :           break;
    3478             :         case 'r':
    3479           0 :           c = '\r';
    3480           0 :           break;
    3481             :         case 't':
    3482           0 :           c = '\t';
    3483           0 :           break;
    3484             :         case 'v':
    3485           0 :           c = '\v';
    3486           0 :           break;
    3487             :         case 'u':
    3488           0 :           c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) +
    3489           0 :               (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3));
    3490           0 :           start += 4;
    3491           0 :           break;
    3492             :         default:
    3493             :           return false;
    3494             :       }
    3495           0 :       output->push_back(c);
    3496             :     }
    3497             :     return true;
    3498             :   }
    3499             : 
    3500           0 :   void ParseValue(const Char* start,
    3501             :                   const Char* end,
    3502             :                   const Char** value_token_end,
    3503             :                   int depth) {
    3504           0 :     if (depth > kStackLimit) {
    3505             :       HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start);
    3506           0 :       return;
    3507             :     }
    3508             :     const Char* token_start;
    3509             :     const Char* token_end;
    3510           0 :     Token token = ParseToken(start, end, &token_start, &token_end);
    3511           0 :     switch (token) {
    3512             :       case NoInput:
    3513           0 :         HandleError(Error::JSON_PARSER_NO_INPUT, token_start);
    3514             :         return;
    3515             :       case InvalidToken:
    3516           0 :         HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start);
    3517             :         return;
    3518             :       case NullToken:
    3519           0 :         handler_->HandleNull();
    3520           0 :         break;
    3521             :       case BoolTrue:
    3522           0 :         handler_->HandleBool(true);
    3523           0 :         break;
    3524             :       case BoolFalse:
    3525           0 :         handler_->HandleBool(false);
    3526           0 :         break;
    3527             :       case Number: {
    3528             :         double value;
    3529           0 :         if (!CharsToDouble(token_start, token_end - token_start, &value)) {
    3530           0 :           HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start);
    3531           0 :           return;
    3532             :         }
    3533           0 :         if (value >= std::numeric_limits<int32_t>::min() &&
    3534             :             value <= std::numeric_limits<int32_t>::max() &&
    3535             :             static_cast<int32_t>(value) == value)
    3536           0 :           handler_->HandleInt32(static_cast<int32_t>(value));
    3537             :         else
    3538           0 :           handler_->HandleDouble(value);
    3539           0 :         break;
    3540             :       }
    3541             :       case StringLiteral: {
    3542             :         std::vector<uint16_t> value;
    3543           0 :         bool ok = DecodeString(token_start + 1, token_end - 1, &value);
    3544           0 :         if (!ok) {
    3545           0 :           HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
    3546             :           return;
    3547             :         }
    3548           0 :         handler_->HandleString16(span<uint16_t>(value.data(), value.size()));
    3549             :         break;
    3550             :       }
    3551             :       case ArrayBegin: {
    3552           0 :         handler_->HandleArrayBegin();
    3553           0 :         start = token_end;
    3554           0 :         token = ParseToken(start, end, &token_start, &token_end);
    3555           0 :         while (token != ArrayEnd) {
    3556           0 :           ParseValue(start, end, &token_end, depth + 1);
    3557           0 :           if (error_)
    3558             :             return;
    3559             : 
    3560             :           // After a list value, we expect a comma or the end of the list.
    3561           0 :           start = token_end;
    3562           0 :           token = ParseToken(start, end, &token_start, &token_end);
    3563           0 :           if (token == ListSeparator) {
    3564           0 :             start = token_end;
    3565           0 :             token = ParseToken(start, end, &token_start, &token_end);
    3566           0 :             if (token == ArrayEnd) {
    3567           0 :               HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start);
    3568             :               return;
    3569             :             }
    3570           0 :           } else if (token != ArrayEnd) {
    3571             :             // Unexpected value after list value. Bail out.
    3572           0 :             HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED,
    3573             :                         token_start);
    3574             :             return;
    3575             :           }
    3576             :         }
    3577           0 :         handler_->HandleArrayEnd();
    3578           0 :         break;
    3579             :       }
    3580             :       case ObjectBegin: {
    3581           0 :         handler_->HandleMapBegin();
    3582           0 :         start = token_end;
    3583           0 :         token = ParseToken(start, end, &token_start, &token_end);
    3584           0 :         while (token != ObjectEnd) {
    3585           0 :           if (token != StringLiteral) {
    3586           0 :             HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED,
    3587             :                         token_start);
    3588           0 :             return;
    3589             :           }
    3590             :           std::vector<uint16_t> key;
    3591           0 :           if (!DecodeString(token_start + 1, token_end - 1, &key)) {
    3592           0 :             HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
    3593             :             return;
    3594             :           }
    3595           0 :           handler_->HandleString16(span<uint16_t>(key.data(), key.size()));
    3596           0 :           start = token_end;
    3597             : 
    3598           0 :           token = ParseToken(start, end, &token_start, &token_end);
    3599           0 :           if (token != ObjectPairSeparator) {
    3600           0 :             HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start);
    3601             :             return;
    3602             :           }
    3603           0 :           start = token_end;
    3604             : 
    3605           0 :           ParseValue(start, end, &token_end, depth + 1);
    3606           0 :           if (error_)
    3607             :             return;
    3608           0 :           start = token_end;
    3609             : 
    3610             :           // After a key/value pair, we expect a comma or the end of the
    3611             :           // object.
    3612           0 :           token = ParseToken(start, end, &token_start, &token_end);
    3613           0 :           if (token == ListSeparator) {
    3614           0 :             start = token_end;
    3615           0 :             token = ParseToken(start, end, &token_start, &token_end);
    3616           0 :             if (token == ObjectEnd) {
    3617           0 :               HandleError(Error::JSON_PARSER_UNEXPECTED_MAP_END, token_start);
    3618             :               return;
    3619             :             }
    3620           0 :           } else if (token != ObjectEnd) {
    3621             :             // Unexpected value after last object value. Bail out.
    3622           0 :             HandleError(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED,
    3623             :                         token_start);
    3624             :             return;
    3625             :           }
    3626             :         }
    3627           0 :         handler_->HandleMapEnd();
    3628           0 :         break;
    3629             :       }
    3630             : 
    3631             :       default:
    3632             :         // We got a token that's not a value.
    3633           0 :         HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start);
    3634             :         return;
    3635             :     }
    3636             : 
    3637           0 :     SkipWhitespaceAndComments(token_end, end, value_token_end);
    3638             :   }
    3639             : 
    3640             :   void HandleError(Error error, const Char* pos) {
    3641             :     assert(error != Error::OK);
    3642           0 :     if (!error_) {
    3643           0 :       handler_->HandleError(Status{error, pos - start_pos_});
    3644           0 :       error_ = true;
    3645             :     }
    3646             :   }
    3647             : 
    3648             :   const Char* start_pos_ = nullptr;
    3649             :   bool error_ = false;
    3650             :   const Platform* platform_;
    3651             :   StreamingParserHandler* handler_;
    3652             : };
    3653             : }  // namespace
    3654             : 
    3655           0 : void ParseJSON(const Platform& platform,
    3656             :                span<uint8_t> chars,
    3657             :                StreamingParserHandler* handler) {
    3658             :   JsonParser<uint8_t> parser(&platform, handler);
    3659           0 :   parser.Parse(chars.data(), chars.size());
    3660           0 : }
    3661             : 
    3662           0 : void ParseJSON(const Platform& platform,
    3663             :                span<uint16_t> chars,
    3664             :                StreamingParserHandler* handler) {
    3665             :   JsonParser<uint16_t> parser(&platform, handler);
    3666           0 :   parser.Parse(chars.data(), chars.size());
    3667           0 : }
    3668             : 
    3669             : // =============================================================================
    3670             : // json::ConvertCBORToJSON, json::ConvertJSONToCBOR - for transcoding
    3671             : // =============================================================================
    3672             : template <typename C>
    3673           0 : Status ConvertCBORToJSONTmpl(const Platform& platform,
    3674             :                              span<uint8_t> cbor,
    3675             :                              C* json) {
    3676           0 :   Status status;
    3677             :   std::unique_ptr<StreamingParserHandler> json_writer =
    3678             :       NewJSONEncoder(&platform, json, &status);
    3679           0 :   cbor::ParseCBOR(cbor, json_writer.get());
    3680           0 :   return status;
    3681             : }
    3682             : 
    3683           0 : Status ConvertCBORToJSON(const Platform& platform,
    3684             :                          span<uint8_t> cbor,
    3685             :                          std::vector<uint8_t>* json) {
    3686           0 :   return ConvertCBORToJSONTmpl(platform, cbor, json);
    3687             : }
    3688           0 : Status ConvertCBORToJSON(const Platform& platform,
    3689             :                          span<uint8_t> cbor,
    3690             :                          std::string* json) {
    3691           0 :   return ConvertCBORToJSONTmpl(platform, cbor, json);
    3692             : }
    3693             : 
    3694             : template <typename C>
    3695           0 : Status ConvertJSONToCBORTmpl(const Platform& platform,
    3696             :                              span<uint8_t> json,
    3697             :                              C* cbor) {
    3698           0 :   Status status;
    3699             :   std::unique_ptr<StreamingParserHandler> encoder =
    3700           0 :       cbor::NewCBOREncoder(cbor, &status);
    3701             :   ParseJSON(platform, json, encoder.get());
    3702           0 :   return status;
    3703             : }
    3704           0 : Status ConvertJSONToCBOR(const Platform& platform,
    3705             :                          span<uint8_t> json,
    3706             :                          std::string* cbor) {
    3707           0 :   return ConvertJSONToCBORTmpl(platform, json, cbor);
    3708             : }
    3709           0 : Status ConvertJSONToCBOR(const Platform& platform,
    3710             :                          span<uint8_t> json,
    3711             :                          std::vector<uint8_t>* cbor) {
    3712           0 :   return ConvertJSONToCBORTmpl(platform, json, cbor);
    3713             : }
    3714             : }  // namespace json
    3715             : 
    3716             : } // namespace v8_inspector
    3717             : } // namespace protocol
    3718             : 

Generated by: LCOV version 1.10