1// This file is generated by Values_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 "Values.h" 8 9{% for namespace in config.protocol.namespace %} 10namespace {{namespace}} { 11{% endfor %} 12 13namespace { 14 15const char* const nullValueString = "null"; 16const char* const trueValueString = "true"; 17const char* const falseValueString = "false"; 18 19inline bool escapeChar(uint16_t c, StringBuilder* dst) 20{ 21 switch (c) { 22 case '\b': StringUtil::builderAppend(*dst, "\\b"); break; 23 case '\f': StringUtil::builderAppend(*dst, "\\f"); break; 24 case '\n': StringUtil::builderAppend(*dst, "\\n"); break; 25 case '\r': StringUtil::builderAppend(*dst, "\\r"); break; 26 case '\t': StringUtil::builderAppend(*dst, "\\t"); break; 27 case '\\': StringUtil::builderAppend(*dst, "\\\\"); break; 28 case '"': StringUtil::builderAppend(*dst, "\\\""); break; 29 default: 30 return false; 31 } 32 return true; 33} 34 35const char hexDigits[17] = "0123456789ABCDEF"; 36 37void appendUnsignedAsHex(uint16_t number, StringBuilder* dst) 38{ 39 StringUtil::builderAppend(*dst, "\\u"); 40 for (size_t i = 0; i < 4; ++i) { 41 uint16_t c = hexDigits[(number & 0xF000) >> 12]; 42 StringUtil::builderAppend(*dst, c); 43 number <<= 4; 44 } 45} 46 47template <typename Char> 48void escapeStringForJSONInternal(const Char* str, unsigned len, 49 StringBuilder* dst) 50{ 51 for (unsigned i = 0; i < len; ++i) { 52 Char c = str[i]; 53 if (escapeChar(c, dst)) 54 continue; 55 if (c < 32 || c > 126) { 56 appendUnsignedAsHex(c, dst); 57 } else { 58 StringUtil::builderAppend(*dst, c); 59 } 60 } 61} 62 63// When parsing CBOR, we limit recursion depth for objects and arrays 64// to this constant. 65static constexpr int kStackLimitValues = 1000; 66 67// Below are three parsing routines for CBOR, which cover enough 68// to roundtrip JSON messages. 69std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); 70std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); 71std::unique_ptr<Value> parseValue(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); 72 73// |bytes| must start with the indefinite length array byte, so basically, 74// ParseArray may only be called after an indefinite length array has been 75// detected. 76std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer) { 77 DCHECK(tokenizer->TokenTag() == cbor::CBORTokenTag::ARRAY_START); 78 tokenizer->Next(); 79 auto list = ListValue::create(); 80 while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) { 81 // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY 82 if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) return nullptr; 83 if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; 84 // Parse value. 85 auto value = parseValue(stack_depth, tokenizer); 86 if (!value) return nullptr; 87 list->pushValue(std::move(value)); 88 } 89 tokenizer->Next(); 90 return list; 91} 92 93std::unique_ptr<Value> parseValue( 94 int32_t stack_depth, cbor::CBORTokenizer* tokenizer) { 95 // Error::CBOR_STACK_LIMIT_EXCEEDED 96 if (stack_depth > kStackLimitValues) return nullptr; 97 // Skip past the envelope to get to what's inside. 98 if (tokenizer->TokenTag() == cbor::CBORTokenTag::ENVELOPE) 99 tokenizer->EnterEnvelope(); 100 switch (tokenizer->TokenTag()) { 101 case cbor::CBORTokenTag::ERROR_VALUE: 102 return nullptr; 103 case cbor::CBORTokenTag::DONE: 104 // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE 105 return nullptr; 106 case cbor::CBORTokenTag::TRUE_VALUE: { 107 std::unique_ptr<Value> value = FundamentalValue::create(true); 108 tokenizer->Next(); 109 return value; 110 } 111 case cbor::CBORTokenTag::FALSE_VALUE: { 112 std::unique_ptr<Value> value = FundamentalValue::create(false); 113 tokenizer->Next(); 114 return value; 115 } 116 case cbor::CBORTokenTag::NULL_VALUE: { 117 std::unique_ptr<Value> value = FundamentalValue::null(); 118 tokenizer->Next(); 119 return value; 120 } 121 case cbor::CBORTokenTag::INT32: { 122 std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32()); 123 tokenizer->Next(); 124 return value; 125 } 126 case cbor::CBORTokenTag::DOUBLE: { 127 std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble()); 128 tokenizer->Next(); 129 return value; 130 } 131 case cbor::CBORTokenTag::STRING8: { 132 span<uint8_t> str = tokenizer->GetString8(); 133 std::unique_ptr<Value> value = 134 StringValue::create(StringUtil::fromUTF8(str.data(), str.size())); 135 tokenizer->Next(); 136 return value; 137 } 138 case cbor::CBORTokenTag::STRING16: { 139 span<uint8_t> wire = tokenizer->GetString16WireRep(); 140 DCHECK_EQ(wire.size() & 1, 0u); 141 std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF16( 142 reinterpret_cast<const uint16_t*>(wire.data()), wire.size() / 2)); 143 tokenizer->Next(); 144 return value; 145 } 146 case cbor::CBORTokenTag::BINARY: { 147 span<uint8_t> payload = tokenizer->GetBinary(); 148 tokenizer->Next(); 149 return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size())); 150 } 151 case cbor::CBORTokenTag::MAP_START: 152 return parseMap(stack_depth + 1, tokenizer); 153 case cbor::CBORTokenTag::ARRAY_START: 154 return parseArray(stack_depth + 1, tokenizer); 155 default: 156 // Error::CBOR_UNSUPPORTED_VALUE 157 return nullptr; 158 } 159} 160 161// |bytes| must start with the indefinite length array byte, so basically, 162// ParseArray may only be called after an indefinite length array has been 163// detected. 164std::unique_ptr<DictionaryValue> parseMap( 165 int32_t stack_depth, cbor::CBORTokenizer* tokenizer) { 166 auto dict = DictionaryValue::create(); 167 tokenizer->Next(); 168 while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) { 169 if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) { 170 // Error::CBOR_UNEXPECTED_EOF_IN_MAP 171 return nullptr; 172 } 173 if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; 174 // Parse key. 175 String key; 176 if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) { 177 span<uint8_t> key_span = tokenizer->GetString8(); 178 key = StringUtil::fromUTF8(key_span.data(), key_span.size()); 179 tokenizer->Next(); 180 } else if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) { 181 return nullptr; // STRING16 not supported yet. 182 } else { 183 // Error::CBOR_INVALID_MAP_KEY 184 return nullptr; 185 } 186 // Parse value. 187 auto value = parseValue(stack_depth, tokenizer); 188 if (!value) return nullptr; 189 dict->setValue(key, std::move(value)); 190 } 191 tokenizer->Next(); 192 return dict; 193} 194 195} // anonymous namespace 196 197// static 198std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) { 199 span<uint8_t> bytes(data, size); 200 201 // Error::CBOR_NO_INPUT 202 if (bytes.empty()) return nullptr; 203 204 // Error::CBOR_INVALID_START_BYTE 205 if (bytes[0] != cbor::InitialByteForEnvelope()) return nullptr; 206 207 cbor::CBORTokenizer tokenizer(bytes); 208 if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; 209 210 // We checked for the envelope start byte above, so the tokenizer 211 // must agree here, since it's not an error. 212 DCHECK(tokenizer.TokenTag() == cbor::CBORTokenTag::ENVELOPE); 213 tokenizer.EnterEnvelope(); 214 // Error::MAP_START_EXPECTED 215 if (tokenizer.TokenTag() != cbor::CBORTokenTag::MAP_START) return nullptr; 216 std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer); 217 if (!result) return nullptr; 218 if (tokenizer.TokenTag() == cbor::CBORTokenTag::DONE) return result; 219 if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; 220 // Error::CBOR_TRAILING_JUNK 221 return nullptr; 222} 223 224bool Value::asBoolean(bool*) const 225{ 226 return false; 227} 228 229bool Value::asDouble(double*) const 230{ 231 return false; 232} 233 234bool Value::asInteger(int*) const 235{ 236 return false; 237} 238 239bool Value::asString(String*) const 240{ 241 return false; 242} 243 244bool Value::asBinary(Binary*) const 245{ 246 return false; 247} 248 249void Value::writeJSON(StringBuilder* output) const 250{ 251 DCHECK(m_type == TypeNull); 252 StringUtil::builderAppend(*output, nullValueString, 4); 253} 254 255void Value::writeBinary(std::vector<uint8_t>* bytes) const { 256 DCHECK(m_type == TypeNull); 257 bytes->push_back(cbor::EncodeNull()); 258} 259 260std::unique_ptr<Value> Value::clone() const 261{ 262 return Value::null(); 263} 264 265String Value::toJSONString() const 266{ 267 StringBuilder result; 268 StringUtil::builderReserve(result, 512); 269 writeJSON(&result); 270 return StringUtil::builderToString(result); 271} 272 273String Value::serializeToJSON() { 274 return toJSONString(); 275} 276 277std::vector<uint8_t> Value::serializeToBinary() { 278 std::vector<uint8_t> bytes; 279 writeBinary(&bytes); 280 return bytes; 281} 282 283bool FundamentalValue::asBoolean(bool* output) const 284{ 285 if (type() != TypeBoolean) 286 return false; 287 *output = m_boolValue; 288 return true; 289} 290 291bool FundamentalValue::asDouble(double* output) const 292{ 293 if (type() == TypeDouble) { 294 *output = m_doubleValue; 295 return true; 296 } 297 if (type() == TypeInteger) { 298 *output = m_integerValue; 299 return true; 300 } 301 return false; 302} 303 304bool FundamentalValue::asInteger(int* output) const 305{ 306 if (type() != TypeInteger) 307 return false; 308 *output = m_integerValue; 309 return true; 310} 311 312void FundamentalValue::writeJSON(StringBuilder* output) const 313{ 314 DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble); 315 if (type() == TypeBoolean) { 316 if (m_boolValue) 317 StringUtil::builderAppend(*output, trueValueString, 4); 318 else 319 StringUtil::builderAppend(*output, falseValueString, 5); 320 } else if (type() == TypeDouble) { 321 if (!std::isfinite(m_doubleValue)) { 322 StringUtil::builderAppend(*output, nullValueString, 4); 323 return; 324 } 325 StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue)); 326 } else if (type() == TypeInteger) { 327 StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue)); 328 } 329} 330 331void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const { 332 switch (type()) { 333 case TypeDouble: 334 cbor::EncodeDouble(m_doubleValue, bytes); 335 return; 336 case TypeInteger: 337 cbor::EncodeInt32(m_integerValue, bytes); 338 return; 339 case TypeBoolean: 340 bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse()); 341 return; 342 default: 343 DCHECK(false); 344 } 345} 346 347std::unique_ptr<Value> FundamentalValue::clone() const 348{ 349 switch (type()) { 350 case TypeDouble: return FundamentalValue::create(m_doubleValue); 351 case TypeInteger: return FundamentalValue::create(m_integerValue); 352 case TypeBoolean: return FundamentalValue::create(m_boolValue); 353 default: 354 DCHECK(false); 355 } 356 return nullptr; 357} 358 359bool StringValue::asString(String* output) const 360{ 361 *output = m_stringValue; 362 return true; 363} 364 365void StringValue::writeJSON(StringBuilder* output) const 366{ 367 DCHECK(type() == TypeString); 368 StringUtil::builderAppendQuotedString(*output, m_stringValue); 369} 370 371namespace { 372// This routine distinguishes between the current encoding for a given 373// string |s|, and calls encoding routines that will 374// - Ensure that all ASCII strings end up being encoded as UTF8 in 375// the wire format - e.g., EncodeFromUTF16 will detect ASCII and 376// do the (trivial) transcode to STRING8 on the wire, but if it's 377// not ASCII it'll do STRING16. 378// - Select a format that's cheap to convert to. E.g., we don't 379// have LATIN1 on the wire, so we call EncodeFromLatin1 which 380// transcodes to UTF8 if needed. 381void EncodeString(const String& s, std::vector<uint8_t>* out) { 382 if (StringUtil::CharacterCount(s) == 0) { 383 cbor::EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string. 384 } else if (StringUtil::CharactersLatin1(s)) { 385 cbor::EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s), 386 StringUtil::CharacterCount(s)), 387 out); 388 } else if (StringUtil::CharactersUTF16(s)) { 389 cbor::EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s), 390 StringUtil::CharacterCount(s)), 391 out); 392 } else if (StringUtil::CharactersUTF8(s)) { 393 cbor::EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s), 394 StringUtil::CharacterCount(s)), 395 out); 396 } 397} 398} // namespace 399 400void StringValue::writeBinary(std::vector<uint8_t>* bytes) const { 401 EncodeString(m_stringValue, bytes); 402} 403 404std::unique_ptr<Value> StringValue::clone() const 405{ 406 return StringValue::create(m_stringValue); 407} 408 409bool BinaryValue::asBinary(Binary* output) const 410{ 411 *output = m_binaryValue; 412 return true; 413} 414 415void BinaryValue::writeJSON(StringBuilder* output) const 416{ 417 DCHECK(type() == TypeBinary); 418 StringUtil::builderAppendQuotedString(*output, m_binaryValue.toBase64()); 419} 420 421void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const { 422 cbor::EncodeBinary(span<uint8_t>(m_binaryValue.data(), 423 m_binaryValue.size()), bytes); 424} 425 426std::unique_ptr<Value> BinaryValue::clone() const 427{ 428 return BinaryValue::create(m_binaryValue); 429} 430 431void SerializedValue::writeJSON(StringBuilder* output) const 432{ 433 DCHECK(type() == TypeSerialized); 434 StringUtil::builderAppend(*output, m_serializedJSON); 435} 436 437void SerializedValue::writeBinary(std::vector<uint8_t>* output) const 438{ 439 DCHECK(type() == TypeSerialized); 440 output->insert(output->end(), m_serializedBinary.begin(), m_serializedBinary.end()); 441} 442 443std::unique_ptr<Value> SerializedValue::clone() const 444{ 445 return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary)); 446} 447 448DictionaryValue::~DictionaryValue() 449{ 450} 451 452void DictionaryValue::setBoolean(const String& name, bool value) 453{ 454 setValue(name, FundamentalValue::create(value)); 455} 456 457void DictionaryValue::setInteger(const String& name, int value) 458{ 459 setValue(name, FundamentalValue::create(value)); 460} 461 462void DictionaryValue::setDouble(const String& name, double value) 463{ 464 setValue(name, FundamentalValue::create(value)); 465} 466 467void DictionaryValue::setString(const String& name, const String& value) 468{ 469 setValue(name, StringValue::create(value)); 470} 471 472void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value) 473{ 474 set(name, value); 475} 476 477void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value) 478{ 479 set(name, value); 480} 481 482void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value) 483{ 484 set(name, value); 485} 486 487bool DictionaryValue::getBoolean(const String& name, bool* output) const 488{ 489 protocol::Value* value = get(name); 490 if (!value) 491 return false; 492 return value->asBoolean(output); 493} 494 495bool DictionaryValue::getInteger(const String& name, int* output) const 496{ 497 Value* value = get(name); 498 if (!value) 499 return false; 500 return value->asInteger(output); 501} 502 503bool DictionaryValue::getDouble(const String& name, double* output) const 504{ 505 Value* value = get(name); 506 if (!value) 507 return false; 508 return value->asDouble(output); 509} 510 511bool DictionaryValue::getString(const String& name, String* output) const 512{ 513 protocol::Value* value = get(name); 514 if (!value) 515 return false; 516 return value->asString(output); 517} 518 519DictionaryValue* DictionaryValue::getObject(const String& name) const 520{ 521 return DictionaryValue::cast(get(name)); 522} 523 524protocol::ListValue* DictionaryValue::getArray(const String& name) const 525{ 526 return ListValue::cast(get(name)); 527} 528 529protocol::Value* DictionaryValue::get(const String& name) const 530{ 531 Dictionary::const_iterator it = m_data.find(name); 532 if (it == m_data.end()) 533 return nullptr; 534 return it->second.get(); 535} 536 537DictionaryValue::Entry DictionaryValue::at(size_t index) const 538{ 539 const String key = m_order[index]; 540 return std::make_pair(key, m_data.find(key)->second.get()); 541} 542 543bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const 544{ 545 bool result = defaultValue; 546 getBoolean(name, &result); 547 return result; 548} 549 550int DictionaryValue::integerProperty(const String& name, int defaultValue) const 551{ 552 int result = defaultValue; 553 getInteger(name, &result); 554 return result; 555} 556 557double DictionaryValue::doubleProperty(const String& name, double defaultValue) const 558{ 559 double result = defaultValue; 560 getDouble(name, &result); 561 return result; 562} 563 564void DictionaryValue::remove(const String& name) 565{ 566 m_data.erase(name); 567 m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end()); 568} 569 570void DictionaryValue::writeJSON(StringBuilder* output) const 571{ 572 StringUtil::builderAppend(*output, '{'); 573 for (size_t i = 0; i < m_order.size(); ++i) { 574 Dictionary::const_iterator it = m_data.find(m_order[i]); 575 CHECK(it != m_data.end()); 576 if (i) 577 StringUtil::builderAppend(*output, ','); 578 StringUtil::builderAppendQuotedString(*output, it->first); 579 StringUtil::builderAppend(*output, ':'); 580 it->second->writeJSON(output); 581 } 582 StringUtil::builderAppend(*output, '}'); 583} 584 585void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const { 586 cbor::EnvelopeEncoder encoder; 587 encoder.EncodeStart(bytes); 588 bytes->push_back(cbor::EncodeIndefiniteLengthMapStart()); 589 for (size_t i = 0; i < m_order.size(); ++i) { 590 const String& key = m_order[i]; 591 Dictionary::const_iterator value = m_data.find(key); 592 DCHECK(value != m_data.cend() && value->second); 593 EncodeString(key, bytes); 594 value->second->writeBinary(bytes); 595 } 596 bytes->push_back(cbor::EncodeStop()); 597 encoder.EncodeStop(bytes); 598} 599 600std::unique_ptr<Value> DictionaryValue::clone() const 601{ 602 std::unique_ptr<DictionaryValue> result = DictionaryValue::create(); 603 for (size_t i = 0; i < m_order.size(); ++i) { 604 String key = m_order[i]; 605 Dictionary::const_iterator value = m_data.find(key); 606 DCHECK(value != m_data.cend() && value->second); 607 result->setValue(key, value->second->clone()); 608 } 609 return std::move(result); 610} 611 612DictionaryValue::DictionaryValue() 613 : Value(TypeObject) 614{ 615} 616 617ListValue::~ListValue() 618{ 619} 620 621void ListValue::writeJSON(StringBuilder* output) const 622{ 623 StringUtil::builderAppend(*output, '['); 624 bool first = true; 625 for (const std::unique_ptr<protocol::Value>& value : m_data) { 626 if (!first) 627 StringUtil::builderAppend(*output, ','); 628 value->writeJSON(output); 629 first = false; 630 } 631 StringUtil::builderAppend(*output, ']'); 632} 633 634void ListValue::writeBinary(std::vector<uint8_t>* bytes) const { 635 cbor::EnvelopeEncoder encoder; 636 encoder.EncodeStart(bytes); 637 bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart()); 638 for (size_t i = 0; i < m_data.size(); ++i) { 639 m_data[i]->writeBinary(bytes); 640 } 641 bytes->push_back(cbor::EncodeStop()); 642 encoder.EncodeStop(bytes); 643} 644 645std::unique_ptr<Value> ListValue::clone() const 646{ 647 std::unique_ptr<ListValue> result = ListValue::create(); 648 for (const std::unique_ptr<protocol::Value>& value : m_data) 649 result->pushValue(value->clone()); 650 return std::move(result); 651} 652 653ListValue::ListValue() 654 : Value(TypeArray) 655{ 656} 657 658void ListValue::pushValue(std::unique_ptr<protocol::Value> value) 659{ 660 DCHECK(value); 661 m_data.push_back(std::move(value)); 662} 663 664protocol::Value* ListValue::at(size_t index) 665{ 666 DCHECK_LT(index, m_data.size()); 667 return m_data[index].get(); 668} 669 670void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst) 671{ 672 escapeStringForJSONInternal<uint8_t>(str, len, dst); 673} 674 675void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst) 676{ 677 escapeStringForJSONInternal<uint16_t>(str, len, dst); 678} 679 680{% for namespace in config.protocol.namespace %} 681} // namespace {{namespace}} 682{% endfor %} 683