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