1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights 2 // reserved. Use of this source code is governed by a BSD-style license that 3 // can be found in the LICENSE file. 4 5 #include "libcef/common/values_impl.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "base/memory/ptr_util.h" 11 12 // CefValueImpl implementation. 13 14 // static Create()15 CefRefPtr<CefValue> CefValue::Create() { 16 return new CefValueImpl(new base::Value()); 17 } 18 19 // static GetOrCreateRefOrCopy(base::Value * value,void * parent_value,bool read_only,CefValueController * controller)20 CefRefPtr<CefValue> CefValueImpl::GetOrCreateRefOrCopy( 21 base::Value* value, 22 void* parent_value, 23 bool read_only, 24 CefValueController* controller) { 25 DCHECK(value); 26 27 if (value->is_blob()) { 28 return new CefValueImpl( 29 CefBinaryValueImpl::GetOrCreateRef(value, parent_value, controller)); 30 } 31 32 if (value->is_dict()) { 33 base::DictionaryValue* dict_value = 34 static_cast<base::DictionaryValue*>(value); 35 return new CefValueImpl(CefDictionaryValueImpl::GetOrCreateRef( 36 dict_value, parent_value, read_only, controller)); 37 } 38 39 if (value->is_list()) { 40 base::ListValue* list_value = static_cast<base::ListValue*>(value); 41 return new CefValueImpl(CefListValueImpl::GetOrCreateRef( 42 list_value, parent_value, read_only, controller)); 43 } 44 45 return new CefValueImpl(value->CreateDeepCopy().release()); 46 } 47 CefValueImpl()48 CefValueImpl::CefValueImpl() {} 49 CefValueImpl(base::Value * value)50 CefValueImpl::CefValueImpl(base::Value* value) { 51 SetValue(value); 52 } 53 CefValueImpl(CefRefPtr<CefBinaryValue> value)54 CefValueImpl::CefValueImpl(CefRefPtr<CefBinaryValue> value) 55 : binary_value_(value) {} 56 CefValueImpl(CefRefPtr<CefDictionaryValue> value)57 CefValueImpl::CefValueImpl(CefRefPtr<CefDictionaryValue> value) 58 : dictionary_value_(value) {} 59 CefValueImpl(CefRefPtr<CefListValue> value)60 CefValueImpl::CefValueImpl(CefRefPtr<CefListValue> value) 61 : list_value_(value) {} 62 ~CefValueImpl()63 CefValueImpl::~CefValueImpl() {} 64 SetValue(base::Value * value)65 void CefValueImpl::SetValue(base::Value* value) { 66 base::AutoLock lock_scope(lock_); 67 SetValueInternal(value); 68 } 69 CopyOrDetachValue(CefValueController * new_controller)70 base::Value* CefValueImpl::CopyOrDetachValue( 71 CefValueController* new_controller) { 72 base::AutoLock lock_scope(lock_); 73 74 if (binary_value_) { 75 return static_cast<CefBinaryValueImpl*>(binary_value_.get()) 76 ->CopyOrDetachValue(new_controller); 77 } 78 79 if (dictionary_value_) { 80 return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get()) 81 ->CopyOrDetachValue(new_controller); 82 } 83 84 if (list_value_) { 85 return static_cast<CefListValueImpl*>(list_value_.get()) 86 ->CopyOrDetachValue(new_controller); 87 } 88 89 return value_->CreateDeepCopy().release(); 90 } 91 SwapValue(base::Value * new_value,void * new_parent_value,CefValueController * new_controller)92 void CefValueImpl::SwapValue(base::Value* new_value, 93 void* new_parent_value, 94 CefValueController* new_controller) { 95 base::AutoLock lock_scope(lock_); 96 97 if (binary_value_) { 98 binary_value_ = CefBinaryValueImpl::GetOrCreateRef( 99 new_value, new_parent_value, new_controller); 100 } else if (dictionary_value_) { 101 dictionary_value_ = CefDictionaryValueImpl::GetOrCreateRef( 102 static_cast<base::DictionaryValue*>(new_value), new_parent_value, false, 103 new_controller); 104 } else if (list_value_) { 105 list_value_ = CefListValueImpl::GetOrCreateRef( 106 static_cast<base::ListValue*>(new_value), new_parent_value, false, 107 new_controller); 108 } 109 } 110 IsValid()111 bool CefValueImpl::IsValid() { 112 base::AutoLock lock_scope(lock_); 113 114 if (binary_value_) 115 return binary_value_->IsValid(); 116 if (dictionary_value_) 117 return dictionary_value_->IsValid(); 118 if (list_value_) 119 return list_value_->IsValid(); 120 121 return (value_ != nullptr); 122 } 123 IsOwned()124 bool CefValueImpl::IsOwned() { 125 base::AutoLock lock_scope(lock_); 126 127 if (binary_value_) 128 return binary_value_->IsOwned(); 129 if (dictionary_value_) 130 return dictionary_value_->IsOwned(); 131 if (list_value_) 132 return list_value_->IsOwned(); 133 134 return false; 135 } 136 IsReadOnly()137 bool CefValueImpl::IsReadOnly() { 138 base::AutoLock lock_scope(lock_); 139 140 if (binary_value_) 141 return true; 142 if (dictionary_value_) 143 return dictionary_value_->IsReadOnly(); 144 if (list_value_) 145 return list_value_->IsReadOnly(); 146 147 return false; 148 } 149 IsSame(CefRefPtr<CefValue> that)150 bool CefValueImpl::IsSame(CefRefPtr<CefValue> that) { 151 if (that.get() == this) 152 return true; 153 if (!that.get() || that->GetType() != GetType()) 154 return false; 155 156 CefValueImpl* impl = static_cast<CefValueImpl*>(that.get()); 157 158 base::AutoLock lock_scope(lock_); 159 base::AutoLock lock_scope2(impl->lock_); 160 161 if (binary_value_) 162 return binary_value_->IsSame(impl->binary_value_); 163 if (dictionary_value_) 164 return dictionary_value_->IsSame(impl->dictionary_value_); 165 if (list_value_) 166 return list_value_->IsSame(impl->list_value_); 167 168 // Simple types are never the same. 169 return false; 170 } 171 IsEqual(CefRefPtr<CefValue> that)172 bool CefValueImpl::IsEqual(CefRefPtr<CefValue> that) { 173 if (that.get() == this) 174 return true; 175 if (!that.get() || that->GetType() != GetType()) 176 return false; 177 178 CefValueImpl* impl = static_cast<CefValueImpl*>(that.get()); 179 180 base::AutoLock lock_scope(lock_); 181 base::AutoLock lock_scope2(impl->lock_); 182 183 if (binary_value_) 184 return binary_value_->IsEqual(impl->binary_value_); 185 if (dictionary_value_) 186 return dictionary_value_->IsEqual(impl->dictionary_value_); 187 if (list_value_) 188 return list_value_->IsEqual(impl->list_value_); 189 190 if (!value_) // Invalid types are equal. 191 return true; 192 193 return value_->Equals(impl->value_.get()); 194 } 195 Copy()196 CefRefPtr<CefValue> CefValueImpl::Copy() { 197 base::AutoLock lock_scope(lock_); 198 199 if (binary_value_) 200 return new CefValueImpl(binary_value_->Copy()); 201 if (dictionary_value_) 202 return new CefValueImpl(dictionary_value_->Copy(false)); 203 if (list_value_) 204 return new CefValueImpl(list_value_->Copy()); 205 if (value_) 206 return new CefValueImpl(value_->CreateDeepCopy().release()); 207 208 return new CefValueImpl(); 209 } 210 GetType()211 CefValueType CefValueImpl::GetType() { 212 base::AutoLock lock_scope(lock_); 213 214 if (binary_value_) 215 return VTYPE_BINARY; 216 if (dictionary_value_) 217 return VTYPE_DICTIONARY; 218 if (list_value_) 219 return VTYPE_LIST; 220 221 if (value_) { 222 switch (value_->type()) { 223 case base::Value::Type::NONE: 224 return VTYPE_NULL; 225 case base::Value::Type::BOOLEAN: 226 return VTYPE_BOOL; 227 case base::Value::Type::INTEGER: 228 return VTYPE_INT; 229 case base::Value::Type::DOUBLE: 230 return VTYPE_DOUBLE; 231 case base::Value::Type::STRING: 232 return VTYPE_STRING; 233 default: 234 NOTREACHED(); 235 break; 236 } 237 } 238 239 return VTYPE_INVALID; 240 } 241 GetBool()242 bool CefValueImpl::GetBool() { 243 base::AutoLock lock_scope(lock_); 244 245 bool ret_value = false; 246 if (value_ && value_->is_bool()) 247 ret_value = value_->GetBool(); 248 return ret_value; 249 } 250 GetInt()251 int CefValueImpl::GetInt() { 252 base::AutoLock lock_scope(lock_); 253 254 int ret_value = 0; 255 if (value_ && value_->is_int()) 256 ret_value = value_->GetInt(); 257 return ret_value; 258 } 259 GetDouble()260 double CefValueImpl::GetDouble() { 261 base::AutoLock lock_scope(lock_); 262 263 double ret_value = 0; 264 if (value_ && value_->is_double()) 265 ret_value = value_->GetDouble(); 266 return ret_value; 267 } 268 GetString()269 CefString CefValueImpl::GetString() { 270 base::AutoLock lock_scope(lock_); 271 272 std::string ret_value; 273 if (value_ && value_->is_string()) 274 ret_value = value_->GetString(); 275 return ret_value; 276 } 277 GetBinary()278 CefRefPtr<CefBinaryValue> CefValueImpl::GetBinary() { 279 base::AutoLock lock_scope(lock_); 280 return binary_value_; 281 } 282 GetDictionary()283 CefRefPtr<CefDictionaryValue> CefValueImpl::GetDictionary() { 284 base::AutoLock lock_scope(lock_); 285 return dictionary_value_; 286 } 287 GetList()288 CefRefPtr<CefListValue> CefValueImpl::GetList() { 289 base::AutoLock lock_scope(lock_); 290 return list_value_; 291 } 292 SetNull()293 bool CefValueImpl::SetNull() { 294 SetValue(new base::Value()); 295 return true; 296 } 297 SetBool(bool value)298 bool CefValueImpl::SetBool(bool value) { 299 SetValue(new base::Value(value)); 300 return true; 301 } 302 SetInt(int value)303 bool CefValueImpl::SetInt(int value) { 304 SetValue(new base::Value(value)); 305 return true; 306 } 307 SetDouble(double value)308 bool CefValueImpl::SetDouble(double value) { 309 SetValue(new base::Value(value)); 310 return true; 311 } 312 SetString(const CefString & value)313 bool CefValueImpl::SetString(const CefString& value) { 314 SetValue(new base::Value(value.ToString())); 315 return true; 316 } 317 SetBinary(CefRefPtr<CefBinaryValue> value)318 bool CefValueImpl::SetBinary(CefRefPtr<CefBinaryValue> value) { 319 base::AutoLock lock_scope(lock_); 320 SetValueInternal(nullptr); 321 binary_value_ = value; 322 return true; 323 } 324 SetDictionary(CefRefPtr<CefDictionaryValue> value)325 bool CefValueImpl::SetDictionary(CefRefPtr<CefDictionaryValue> value) { 326 base::AutoLock lock_scope(lock_); 327 SetValueInternal(nullptr); 328 dictionary_value_ = value; 329 return true; 330 } 331 SetList(CefRefPtr<CefListValue> value)332 bool CefValueImpl::SetList(CefRefPtr<CefListValue> value) { 333 base::AutoLock lock_scope(lock_); 334 SetValueInternal(nullptr); 335 list_value_ = value; 336 return true; 337 } 338 SetValueInternal(base::Value * value)339 void CefValueImpl::SetValueInternal(base::Value* value) { 340 lock_.AssertAcquired(); 341 342 value_.reset(nullptr); 343 binary_value_ = nullptr; 344 dictionary_value_ = nullptr; 345 list_value_ = nullptr; 346 347 if (value) { 348 switch (value->type()) { 349 case base::Value::Type::BINARY: 350 binary_value_ = new CefBinaryValueImpl(value, true); 351 return; 352 case base::Value::Type::DICTIONARY: 353 dictionary_value_ = new CefDictionaryValueImpl( 354 static_cast<base::DictionaryValue*>(value), true, false); 355 return; 356 case base::Value::Type::LIST: 357 list_value_ = new CefListValueImpl(static_cast<base::ListValue*>(value), 358 true, false); 359 return; 360 default: 361 value_.reset(value); 362 } 363 } 364 } 365 GetValueController() const366 CefValueController* CefValueImpl::GetValueController() const { 367 lock_.AssertAcquired(); 368 369 if (binary_value_) { 370 return static_cast<CefBinaryValueImpl*>(binary_value_.get())->controller(); 371 } else if (dictionary_value_) { 372 return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get()) 373 ->controller(); 374 } else if (list_value_) { 375 return static_cast<CefListValueImpl*>(list_value_.get())->controller(); 376 } 377 378 return nullptr; 379 } 380 AcquireLock()381 void CefValueImpl::AcquireLock() NO_THREAD_SAFETY_ANALYSIS { 382 lock_.Acquire(); 383 384 CefValueController* controller = GetValueController(); 385 if (controller) 386 controller->lock(); 387 } 388 ReleaseLock()389 void CefValueImpl::ReleaseLock() NO_THREAD_SAFETY_ANALYSIS { 390 CefValueController* controller = GetValueController(); 391 if (controller) { 392 controller->AssertLockAcquired(); 393 controller->unlock(); 394 } 395 396 lock_.Release(); 397 } 398 GetValueUnsafe() const399 base::Value* CefValueImpl::GetValueUnsafe() const { 400 lock_.AssertAcquired(); 401 402 if (binary_value_) { 403 return static_cast<CefBinaryValueImpl*>(binary_value_.get()) 404 ->GetValueUnsafe(); 405 } else if (dictionary_value_) { 406 return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get()) 407 ->GetValueUnsafe(); 408 } else if (list_value_) { 409 return static_cast<CefListValueImpl*>(list_value_.get())->GetValueUnsafe(); 410 } 411 412 return value_.get(); 413 } 414 415 // CefBinaryValueImpl implementation. 416 Create(const void * data,size_t data_size)417 CefRefPtr<CefBinaryValue> CefBinaryValue::Create(const void* data, 418 size_t data_size) { 419 DCHECK(data); 420 DCHECK_GT(data_size, (size_t)0); 421 if (!data || data_size == 0) 422 return nullptr; 423 424 return new CefBinaryValueImpl(static_cast<char*>(const_cast<void*>(data)), 425 data_size); 426 } 427 428 // static GetOrCreateRef(base::Value * value,void * parent_value,CefValueController * controller)429 CefRefPtr<CefBinaryValue> CefBinaryValueImpl::GetOrCreateRef( 430 base::Value* value, 431 void* parent_value, 432 CefValueController* controller) { 433 DCHECK(value); 434 DCHECK(parent_value); 435 DCHECK(controller); 436 437 CefValueController::Object* object = controller->Get(value); 438 if (object) 439 return static_cast<CefBinaryValueImpl*>(object); 440 441 return new CefBinaryValueImpl(value, parent_value, 442 CefBinaryValueImpl::kReference, controller); 443 } 444 CefBinaryValueImpl(base::Value * value,bool will_delete)445 CefBinaryValueImpl::CefBinaryValueImpl(base::Value* value, bool will_delete) 446 : CefValueBase<CefBinaryValue, base::Value>( 447 value, 448 nullptr, 449 will_delete ? kOwnerWillDelete : kOwnerNoDelete, 450 true, 451 nullptr) {} 452 CefBinaryValueImpl(char * data,size_t data_size)453 CefBinaryValueImpl::CefBinaryValueImpl(char* data, size_t data_size) 454 : CefValueBase<CefBinaryValue, base::Value>( 455 new base::Value(std::vector<char>(data, data + data_size)), 456 nullptr, 457 kOwnerWillDelete, 458 true, 459 nullptr) {} 460 CopyValue()461 base::Value* CefBinaryValueImpl::CopyValue() { 462 CEF_VALUE_VERIFY_RETURN(false, nullptr); 463 return const_value().CreateDeepCopy().release(); 464 } 465 CopyOrDetachValue(CefValueController * new_controller)466 base::Value* CefBinaryValueImpl::CopyOrDetachValue( 467 CefValueController* new_controller) { 468 base::Value* new_value; 469 470 if (!will_delete()) { 471 // Copy the value. 472 new_value = CopyValue(); 473 } else { 474 // Take ownership of the value. 475 new_value = Detach(new_controller); 476 } 477 478 DCHECK(new_value); 479 return new_value; 480 } 481 IsSameValue(const base::Value * that)482 bool CefBinaryValueImpl::IsSameValue(const base::Value* that) { 483 CEF_VALUE_VERIFY_RETURN(false, false); 484 return (&const_value() == that); 485 } 486 IsEqualValue(const base::Value * that)487 bool CefBinaryValueImpl::IsEqualValue(const base::Value* that) { 488 CEF_VALUE_VERIFY_RETURN(false, false); 489 return const_value().Equals(that); 490 } 491 GetValueUnsafe()492 base::Value* CefBinaryValueImpl::GetValueUnsafe() { 493 if (!VerifyAttached()) 494 return nullptr; 495 controller()->AssertLockAcquired(); 496 return const_cast<base::Value*>(&const_value()); 497 } 498 IsValid()499 bool CefBinaryValueImpl::IsValid() { 500 return !detached(); 501 } 502 IsOwned()503 bool CefBinaryValueImpl::IsOwned() { 504 return !will_delete(); 505 } 506 IsSame(CefRefPtr<CefBinaryValue> that)507 bool CefBinaryValueImpl::IsSame(CefRefPtr<CefBinaryValue> that) { 508 if (!that.get()) 509 return false; 510 if (that.get() == this) 511 return true; 512 513 CEF_VALUE_VERIFY_RETURN(false, false); 514 return static_cast<CefBinaryValueImpl*>(that.get()) 515 ->IsSameValue(&const_value()); 516 } 517 IsEqual(CefRefPtr<CefBinaryValue> that)518 bool CefBinaryValueImpl::IsEqual(CefRefPtr<CefBinaryValue> that) { 519 if (!that.get()) 520 return false; 521 if (that.get() == this) 522 return true; 523 524 CEF_VALUE_VERIFY_RETURN(false, false); 525 return static_cast<CefBinaryValueImpl*>(that.get()) 526 ->IsEqualValue(&const_value()); 527 } 528 Copy()529 CefRefPtr<CefBinaryValue> CefBinaryValueImpl::Copy() { 530 CEF_VALUE_VERIFY_RETURN(false, nullptr); 531 return new CefBinaryValueImpl(const_value().CreateDeepCopy().release(), 532 nullptr, CefBinaryValueImpl::kOwnerWillDelete, 533 nullptr); 534 } 535 GetSize()536 size_t CefBinaryValueImpl::GetSize() { 537 CEF_VALUE_VERIFY_RETURN(false, 0); 538 return const_value().GetBlob().size(); 539 } 540 GetData(void * buffer,size_t buffer_size,size_t data_offset)541 size_t CefBinaryValueImpl::GetData(void* buffer, 542 size_t buffer_size, 543 size_t data_offset) { 544 DCHECK(buffer); 545 DCHECK_GT(buffer_size, (size_t)0); 546 if (!buffer || buffer_size == 0) 547 return 0; 548 549 CEF_VALUE_VERIFY_RETURN(false, 0); 550 551 size_t size = const_value().GetBlob().size(); 552 DCHECK_LT(data_offset, size); 553 if (data_offset >= size) 554 return 0; 555 556 size = std::min(buffer_size, size - data_offset); 557 auto* data = const_value().GetBlob().data(); 558 memcpy(buffer, data + data_offset, size); 559 return size; 560 } 561 CefBinaryValueImpl(base::Value * value,void * parent_value,ValueMode value_mode,CefValueController * controller)562 CefBinaryValueImpl::CefBinaryValueImpl(base::Value* value, 563 void* parent_value, 564 ValueMode value_mode, 565 CefValueController* controller) 566 : CefValueBase<CefBinaryValue, base::Value>(value, 567 parent_value, 568 value_mode, 569 true, 570 controller) {} 571 572 // CefDictionaryValueImpl implementation. 573 574 // static Create()575 CefRefPtr<CefDictionaryValue> CefDictionaryValue::Create() { 576 return new CefDictionaryValueImpl(new base::DictionaryValue(), true, false); 577 } 578 579 // static GetOrCreateRef(base::DictionaryValue * value,void * parent_value,bool read_only,CefValueController * controller)580 CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetOrCreateRef( 581 base::DictionaryValue* value, 582 void* parent_value, 583 bool read_only, 584 CefValueController* controller) { 585 CefValueController::Object* object = controller->Get(value); 586 if (object) 587 return static_cast<CefDictionaryValueImpl*>(object); 588 589 return new CefDictionaryValueImpl(value, parent_value, 590 CefDictionaryValueImpl::kReference, 591 read_only, controller); 592 } 593 CefDictionaryValueImpl(base::DictionaryValue * value,bool will_delete,bool read_only)594 CefDictionaryValueImpl::CefDictionaryValueImpl(base::DictionaryValue* value, 595 bool will_delete, 596 bool read_only) 597 : CefValueBase<CefDictionaryValue, base::DictionaryValue>( 598 value, 599 nullptr, 600 will_delete ? kOwnerWillDelete : kOwnerNoDelete, 601 read_only, 602 nullptr) {} 603 CopyValue()604 base::DictionaryValue* CefDictionaryValueImpl::CopyValue() { 605 CEF_VALUE_VERIFY_RETURN(false, nullptr); 606 return const_value().CreateDeepCopy().release(); 607 } 608 CopyOrDetachValue(CefValueController * new_controller)609 base::DictionaryValue* CefDictionaryValueImpl::CopyOrDetachValue( 610 CefValueController* new_controller) { 611 base::DictionaryValue* new_value; 612 613 if (!will_delete()) { 614 // Copy the value. 615 new_value = CopyValue(); 616 } else { 617 // Take ownership of the value. 618 new_value = Detach(new_controller); 619 } 620 621 DCHECK(new_value); 622 return new_value; 623 } 624 IsSameValue(const base::DictionaryValue * that)625 bool CefDictionaryValueImpl::IsSameValue(const base::DictionaryValue* that) { 626 CEF_VALUE_VERIFY_RETURN(false, false); 627 return (&const_value() == that); 628 } 629 IsEqualValue(const base::DictionaryValue * that)630 bool CefDictionaryValueImpl::IsEqualValue(const base::DictionaryValue* that) { 631 CEF_VALUE_VERIFY_RETURN(false, false); 632 return const_value().Equals(that); 633 } 634 GetValueUnsafe()635 base::DictionaryValue* CefDictionaryValueImpl::GetValueUnsafe() { 636 if (!VerifyAttached()) 637 return nullptr; 638 controller()->AssertLockAcquired(); 639 return const_cast<base::DictionaryValue*>(&const_value()); 640 } 641 IsValid()642 bool CefDictionaryValueImpl::IsValid() { 643 return !detached(); 644 } 645 IsOwned()646 bool CefDictionaryValueImpl::IsOwned() { 647 return !will_delete(); 648 } 649 IsReadOnly()650 bool CefDictionaryValueImpl::IsReadOnly() { 651 return read_only(); 652 } 653 IsSame(CefRefPtr<CefDictionaryValue> that)654 bool CefDictionaryValueImpl::IsSame(CefRefPtr<CefDictionaryValue> that) { 655 if (!that.get()) 656 return false; 657 if (that.get() == this) 658 return true; 659 660 CEF_VALUE_VERIFY_RETURN(false, false); 661 return static_cast<CefDictionaryValueImpl*>(that.get()) 662 ->IsSameValue(&const_value()); 663 } 664 IsEqual(CefRefPtr<CefDictionaryValue> that)665 bool CefDictionaryValueImpl::IsEqual(CefRefPtr<CefDictionaryValue> that) { 666 if (!that.get()) 667 return false; 668 if (that.get() == this) 669 return true; 670 671 CEF_VALUE_VERIFY_RETURN(false, false); 672 return static_cast<CefDictionaryValueImpl*>(that.get()) 673 ->IsEqualValue(&const_value()); 674 } 675 Copy(bool exclude_empty_children)676 CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::Copy( 677 bool exclude_empty_children) { 678 CEF_VALUE_VERIFY_RETURN(false, nullptr); 679 680 base::DictionaryValue* value; 681 if (exclude_empty_children) { 682 value = const_cast<base::DictionaryValue&>(const_value()) 683 .DeepCopyWithoutEmptyChildren() 684 .release(); 685 } else { 686 value = const_value().CreateDeepCopy().release(); 687 } 688 689 return new CefDictionaryValueImpl( 690 value, nullptr, CefDictionaryValueImpl::kOwnerWillDelete, false, nullptr); 691 } 692 GetSize()693 size_t CefDictionaryValueImpl::GetSize() { 694 CEF_VALUE_VERIFY_RETURN(false, 0); 695 return const_value().DictSize(); 696 } 697 Clear()698 bool CefDictionaryValueImpl::Clear() { 699 CEF_VALUE_VERIFY_RETURN(true, false); 700 701 // Detach any dependent values. 702 controller()->RemoveDependencies(mutable_value()); 703 704 mutable_value()->DictClear(); 705 return true; 706 } 707 HasKey(const CefString & key)708 bool CefDictionaryValueImpl::HasKey(const CefString& key) { 709 CEF_VALUE_VERIFY_RETURN(false, 0); 710 return const_value().HasKey(base::StringPiece(key)); 711 } 712 GetKeys(KeyList & keys)713 bool CefDictionaryValueImpl::GetKeys(KeyList& keys) { 714 CEF_VALUE_VERIFY_RETURN(false, 0); 715 716 for (base::DictionaryValue::Iterator i(const_value()); !i.IsAtEnd(); 717 i.Advance()) { 718 keys.push_back(i.key()); 719 } 720 721 return true; 722 } 723 Remove(const CefString & key)724 bool CefDictionaryValueImpl::Remove(const CefString& key) { 725 CEF_VALUE_VERIFY_RETURN(true, false); 726 return RemoveInternal(key); 727 } 728 GetType(const CefString & key)729 CefValueType CefDictionaryValueImpl::GetType(const CefString& key) { 730 CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID); 731 732 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 733 if (value) { 734 switch (value->type()) { 735 case base::Value::Type::NONE: 736 return VTYPE_NULL; 737 case base::Value::Type::BOOLEAN: 738 return VTYPE_BOOL; 739 case base::Value::Type::INTEGER: 740 return VTYPE_INT; 741 case base::Value::Type::DOUBLE: 742 return VTYPE_DOUBLE; 743 case base::Value::Type::STRING: 744 return VTYPE_STRING; 745 case base::Value::Type::BINARY: 746 return VTYPE_BINARY; 747 case base::Value::Type::DICTIONARY: 748 return VTYPE_DICTIONARY; 749 case base::Value::Type::LIST: 750 return VTYPE_LIST; 751 } 752 } 753 754 return VTYPE_INVALID; 755 } 756 GetValue(const CefString & key)757 CefRefPtr<CefValue> CefDictionaryValueImpl::GetValue(const CefString& key) { 758 CEF_VALUE_VERIFY_RETURN(false, nullptr); 759 760 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 761 if (value) { 762 return CefValueImpl::GetOrCreateRefOrCopy( 763 const_cast<base::Value*>(value), 764 const_cast<base::DictionaryValue*>(&const_value()), read_only(), 765 controller()); 766 } 767 768 return nullptr; 769 } 770 GetBool(const CefString & key)771 bool CefDictionaryValueImpl::GetBool(const CefString& key) { 772 CEF_VALUE_VERIFY_RETURN(false, false); 773 774 bool ret_value = false; 775 776 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 777 if (value && value->is_bool()) { 778 ret_value = value->GetBool(); 779 } 780 781 return ret_value; 782 } 783 GetInt(const CefString & key)784 int CefDictionaryValueImpl::GetInt(const CefString& key) { 785 CEF_VALUE_VERIFY_RETURN(false, 0); 786 787 int ret_value = 0; 788 789 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 790 if (value && value->is_int()) { 791 ret_value = value->GetInt(); 792 } 793 794 return ret_value; 795 } 796 GetDouble(const CefString & key)797 double CefDictionaryValueImpl::GetDouble(const CefString& key) { 798 CEF_VALUE_VERIFY_RETURN(false, 0); 799 800 double ret_value = 0; 801 802 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 803 if (value && value->is_double()) { 804 ret_value = value->GetDouble(); 805 } 806 807 return ret_value; 808 } 809 GetString(const CefString & key)810 CefString CefDictionaryValueImpl::GetString(const CefString& key) { 811 CEF_VALUE_VERIFY_RETURN(false, CefString()); 812 813 std::string ret_value; 814 815 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 816 if (value && value->is_string()) { 817 ret_value = value->GetString(); 818 } 819 820 return ret_value; 821 } 822 GetBinary(const CefString & key)823 CefRefPtr<CefBinaryValue> CefDictionaryValueImpl::GetBinary( 824 const CefString& key) { 825 CEF_VALUE_VERIFY_RETURN(false, nullptr); 826 827 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 828 if (value && value->is_blob()) { 829 base::Value* binary_value = const_cast<base::Value*>(value); 830 return CefBinaryValueImpl::GetOrCreateRef( 831 binary_value, const_cast<base::DictionaryValue*>(&const_value()), 832 controller()); 833 } 834 835 return nullptr; 836 } 837 GetDictionary(const CefString & key)838 CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetDictionary( 839 const CefString& key) { 840 CEF_VALUE_VERIFY_RETURN(false, nullptr); 841 842 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 843 if (value && value->is_dict()) { 844 base::DictionaryValue* dict_value = 845 static_cast<base::DictionaryValue*>(const_cast<base::Value*>(value)); 846 return CefDictionaryValueImpl::GetOrCreateRef( 847 dict_value, const_cast<base::DictionaryValue*>(&const_value()), 848 read_only(), controller()); 849 } 850 851 return nullptr; 852 } 853 GetList(const CefString & key)854 CefRefPtr<CefListValue> CefDictionaryValueImpl::GetList(const CefString& key) { 855 CEF_VALUE_VERIFY_RETURN(false, nullptr); 856 857 const base::Value* value = const_value().FindKey(base::StringPiece(key)); 858 if (value && value->is_list()) { 859 base::ListValue* list_value = 860 static_cast<base::ListValue*>(const_cast<base::Value*>(value)); 861 return CefListValueImpl::GetOrCreateRef( 862 list_value, const_cast<base::DictionaryValue*>(&const_value()), 863 read_only(), controller()); 864 } 865 866 return nullptr; 867 } 868 SetValue(const CefString & key,CefRefPtr<CefValue> value)869 bool CefDictionaryValueImpl::SetValue(const CefString& key, 870 CefRefPtr<CefValue> value) { 871 CEF_VALUE_VERIFY_RETURN(true, false); 872 873 CefValueImpl* impl = static_cast<CefValueImpl*>(value.get()); 874 DCHECK(impl); 875 876 base::Value* new_value = impl->CopyOrDetachValue(controller()); 877 base::Value* actual_value = SetInternal(key, new_value); 878 impl->SwapValue(actual_value, mutable_value(), controller()); 879 return true; 880 } 881 SetNull(const CefString & key)882 bool CefDictionaryValueImpl::SetNull(const CefString& key) { 883 CEF_VALUE_VERIFY_RETURN(true, false); 884 SetInternal(key, new base::Value()); 885 return true; 886 } 887 SetBool(const CefString & key,bool value)888 bool CefDictionaryValueImpl::SetBool(const CefString& key, bool value) { 889 CEF_VALUE_VERIFY_RETURN(true, false); 890 SetInternal(key, new base::Value(value)); 891 return true; 892 } 893 SetInt(const CefString & key,int value)894 bool CefDictionaryValueImpl::SetInt(const CefString& key, int value) { 895 CEF_VALUE_VERIFY_RETURN(true, false); 896 SetInternal(key, new base::Value(value)); 897 return true; 898 } 899 SetDouble(const CefString & key,double value)900 bool CefDictionaryValueImpl::SetDouble(const CefString& key, double value) { 901 CEF_VALUE_VERIFY_RETURN(true, false); 902 SetInternal(key, new base::Value(value)); 903 return true; 904 } 905 SetString(const CefString & key,const CefString & value)906 bool CefDictionaryValueImpl::SetString(const CefString& key, 907 const CefString& value) { 908 CEF_VALUE_VERIFY_RETURN(true, false); 909 SetInternal(key, new base::Value(value.ToString())); 910 return true; 911 } 912 SetBinary(const CefString & key,CefRefPtr<CefBinaryValue> value)913 bool CefDictionaryValueImpl::SetBinary(const CefString& key, 914 CefRefPtr<CefBinaryValue> value) { 915 CEF_VALUE_VERIFY_RETURN(true, false); 916 917 CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get()); 918 DCHECK(impl); 919 920 SetInternal(key, impl->CopyOrDetachValue(controller())); 921 return true; 922 } 923 SetDictionary(const CefString & key,CefRefPtr<CefDictionaryValue> value)924 bool CefDictionaryValueImpl::SetDictionary( 925 const CefString& key, 926 CefRefPtr<CefDictionaryValue> value) { 927 CEF_VALUE_VERIFY_RETURN(true, false); 928 929 CefDictionaryValueImpl* impl = 930 static_cast<CefDictionaryValueImpl*>(value.get()); 931 DCHECK(impl); 932 933 SetInternal(key, impl->CopyOrDetachValue(controller())); 934 return true; 935 } 936 SetList(const CefString & key,CefRefPtr<CefListValue> value)937 bool CefDictionaryValueImpl::SetList(const CefString& key, 938 CefRefPtr<CefListValue> value) { 939 CEF_VALUE_VERIFY_RETURN(true, false); 940 941 CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get()); 942 DCHECK(impl); 943 944 SetInternal(key, impl->CopyOrDetachValue(controller())); 945 return true; 946 } 947 RemoveInternal(const CefString & key)948 bool CefDictionaryValueImpl::RemoveInternal(const CefString& key) { 949 // The ExtractKey() call below which removes the Value from the dictionary 950 // will return a new Value object with the moved contents of the Value that 951 // exists in the implementation std::map. Consequently we use FindKey() to 952 // retrieve the actual Value pointer as it current exists first, for later 953 // comparison purposes. 954 const base::Value* actual_value = 955 const_value().FindKey(base::StringPiece(key)); 956 if (!actual_value) 957 return false; 958 959 // |actual_value| is no longer valid after this call. 960 absl::optional<base::Value> out_value = 961 mutable_value()->ExtractKey(base::StringPiece(key)); 962 if (!out_value.has_value()) { 963 return false; 964 } 965 966 // Remove the value. 967 controller()->Remove(const_cast<base::Value*>(actual_value), true); 968 969 // Only list and dictionary types may have dependencies. 970 if (out_value->is_list() || out_value->is_dict()) { 971 controller()->RemoveDependencies(const_cast<base::Value*>(actual_value)); 972 } 973 974 return true; 975 } 976 SetInternal(const CefString & key,base::Value * value)977 base::Value* CefDictionaryValueImpl::SetInternal(const CefString& key, 978 base::Value* value) { 979 DCHECK(value); 980 RemoveInternal(key); 981 mutable_value()->SetWithoutPathExpansion( 982 base::StringPiece(key), base::WrapUnique<base::Value>(value)); 983 return value; 984 } 985 CefDictionaryValueImpl(base::DictionaryValue * value,void * parent_value,ValueMode value_mode,bool read_only,CefValueController * controller)986 CefDictionaryValueImpl::CefDictionaryValueImpl(base::DictionaryValue* value, 987 void* parent_value, 988 ValueMode value_mode, 989 bool read_only, 990 CefValueController* controller) 991 : CefValueBase<CefDictionaryValue, base::DictionaryValue>(value, 992 parent_value, 993 value_mode, 994 read_only, 995 controller) {} 996 997 // CefListValueImpl implementation. 998 999 // static Create()1000 CefRefPtr<CefListValue> CefListValue::Create() { 1001 return new CefListValueImpl(new base::ListValue(), true, false); 1002 } 1003 1004 // static GetOrCreateRef(base::ListValue * value,void * parent_value,bool read_only,CefValueController * controller)1005 CefRefPtr<CefListValue> CefListValueImpl::GetOrCreateRef( 1006 base::ListValue* value, 1007 void* parent_value, 1008 bool read_only, 1009 CefValueController* controller) { 1010 CefValueController::Object* object = controller->Get(value); 1011 if (object) 1012 return static_cast<CefListValueImpl*>(object); 1013 1014 return new CefListValueImpl(value, parent_value, CefListValueImpl::kReference, 1015 read_only, controller); 1016 } 1017 CefListValueImpl(base::ListValue * value,bool will_delete,bool read_only)1018 CefListValueImpl::CefListValueImpl(base::ListValue* value, 1019 bool will_delete, 1020 bool read_only) 1021 : CefValueBase<CefListValue, base::ListValue>( 1022 value, 1023 nullptr, 1024 will_delete ? kOwnerWillDelete : kOwnerNoDelete, 1025 read_only, 1026 nullptr) {} 1027 CopyValue()1028 base::ListValue* CefListValueImpl::CopyValue() { 1029 CEF_VALUE_VERIFY_RETURN(false, nullptr); 1030 return static_cast<base::ListValue*>( 1031 const_value().CreateDeepCopy().release()); 1032 } 1033 CopyOrDetachValue(CefValueController * new_controller)1034 base::ListValue* CefListValueImpl::CopyOrDetachValue( 1035 CefValueController* new_controller) { 1036 base::ListValue* new_value; 1037 1038 if (!will_delete()) { 1039 // Copy the value. 1040 new_value = CopyValue(); 1041 } else { 1042 // Take ownership of the value. 1043 new_value = Detach(new_controller); 1044 } 1045 1046 DCHECK(new_value); 1047 return new_value; 1048 } 1049 IsSameValue(const base::ListValue * that)1050 bool CefListValueImpl::IsSameValue(const base::ListValue* that) { 1051 CEF_VALUE_VERIFY_RETURN(false, false); 1052 return (&const_value() == that); 1053 } 1054 IsEqualValue(const base::ListValue * that)1055 bool CefListValueImpl::IsEqualValue(const base::ListValue* that) { 1056 CEF_VALUE_VERIFY_RETURN(false, false); 1057 return const_value().Equals(that); 1058 } 1059 GetValueUnsafe()1060 base::ListValue* CefListValueImpl::GetValueUnsafe() { 1061 if (!VerifyAttached()) 1062 return nullptr; 1063 controller()->AssertLockAcquired(); 1064 return const_cast<base::ListValue*>(&const_value()); 1065 } 1066 IsValid()1067 bool CefListValueImpl::IsValid() { 1068 return !detached(); 1069 } 1070 IsOwned()1071 bool CefListValueImpl::IsOwned() { 1072 return !will_delete(); 1073 } 1074 IsReadOnly()1075 bool CefListValueImpl::IsReadOnly() { 1076 return read_only(); 1077 } 1078 IsSame(CefRefPtr<CefListValue> that)1079 bool CefListValueImpl::IsSame(CefRefPtr<CefListValue> that) { 1080 if (!that.get()) 1081 return false; 1082 if (that.get() == this) 1083 return true; 1084 1085 CEF_VALUE_VERIFY_RETURN(false, false); 1086 return static_cast<CefListValueImpl*>(that.get()) 1087 ->IsSameValue(&const_value()); 1088 } 1089 IsEqual(CefRefPtr<CefListValue> that)1090 bool CefListValueImpl::IsEqual(CefRefPtr<CefListValue> that) { 1091 if (!that.get()) 1092 return false; 1093 if (that.get() == this) 1094 return true; 1095 1096 CEF_VALUE_VERIFY_RETURN(false, false); 1097 return static_cast<CefListValueImpl*>(that.get()) 1098 ->IsEqualValue(&const_value()); 1099 } 1100 Copy()1101 CefRefPtr<CefListValue> CefListValueImpl::Copy() { 1102 CEF_VALUE_VERIFY_RETURN(false, nullptr); 1103 1104 return new CefListValueImpl( 1105 static_cast<base::ListValue*>(const_value().CreateDeepCopy().release()), 1106 nullptr, CefListValueImpl::kOwnerWillDelete, false, nullptr); 1107 } 1108 SetSize(size_t size)1109 bool CefListValueImpl::SetSize(size_t size) { 1110 CEF_VALUE_VERIFY_RETURN(true, false); 1111 1112 size_t current_size = const_value().GetList().size(); 1113 if (size < current_size) { 1114 // Clean up any values above the requested size. 1115 for (size_t i = current_size - 1; i >= size; --i) 1116 RemoveInternal(i); 1117 } else if (size > 0) { 1118 // Expand the list size. 1119 // TODO: This approach seems inefficient. See https://crbug.com/1187066#c17 1120 // for background. 1121 auto list = mutable_value()->GetList(); 1122 while (list.size() < size) 1123 mutable_value()->Append(base::Value()); 1124 } 1125 return true; 1126 } 1127 GetSize()1128 size_t CefListValueImpl::GetSize() { 1129 CEF_VALUE_VERIFY_RETURN(false, 0); 1130 return const_value().GetList().size(); 1131 } 1132 Clear()1133 bool CefListValueImpl::Clear() { 1134 CEF_VALUE_VERIFY_RETURN(true, false); 1135 1136 // Detach any dependent values. 1137 controller()->RemoveDependencies(mutable_value()); 1138 1139 mutable_value()->ClearList(); 1140 return true; 1141 } 1142 Remove(size_t index)1143 bool CefListValueImpl::Remove(size_t index) { 1144 CEF_VALUE_VERIFY_RETURN(true, false); 1145 return RemoveInternal(index); 1146 } 1147 GetType(size_t index)1148 CefValueType CefListValueImpl::GetType(size_t index) { 1149 CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID); 1150 1151 const base::Value* out_value = nullptr; 1152 if (const_value().Get(index, &out_value)) { 1153 switch (out_value->type()) { 1154 case base::Value::Type::NONE: 1155 return VTYPE_NULL; 1156 case base::Value::Type::BOOLEAN: 1157 return VTYPE_BOOL; 1158 case base::Value::Type::INTEGER: 1159 return VTYPE_INT; 1160 case base::Value::Type::DOUBLE: 1161 return VTYPE_DOUBLE; 1162 case base::Value::Type::STRING: 1163 return VTYPE_STRING; 1164 case base::Value::Type::BINARY: 1165 return VTYPE_BINARY; 1166 case base::Value::Type::DICTIONARY: 1167 return VTYPE_DICTIONARY; 1168 case base::Value::Type::LIST: 1169 return VTYPE_LIST; 1170 } 1171 } 1172 1173 return VTYPE_INVALID; 1174 } 1175 GetValue(size_t index)1176 CefRefPtr<CefValue> CefListValueImpl::GetValue(size_t index) { 1177 CEF_VALUE_VERIFY_RETURN(false, nullptr); 1178 1179 const base::Value* out_value = nullptr; 1180 if (const_value().Get(index, &out_value)) { 1181 return CefValueImpl::GetOrCreateRefOrCopy( 1182 const_cast<base::Value*>(out_value), 1183 const_cast<base::ListValue*>(&const_value()), read_only(), 1184 controller()); 1185 } 1186 1187 return nullptr; 1188 } 1189 GetBool(size_t index)1190 bool CefListValueImpl::GetBool(size_t index) { 1191 CEF_VALUE_VERIFY_RETURN(false, false); 1192 1193 const base::Value* out_value = nullptr; 1194 bool ret_value = false; 1195 1196 if (const_value().Get(index, &out_value) && out_value->is_bool()) { 1197 ret_value = out_value->GetBool(); 1198 } 1199 1200 return ret_value; 1201 } 1202 GetInt(size_t index)1203 int CefListValueImpl::GetInt(size_t index) { 1204 CEF_VALUE_VERIFY_RETURN(false, 0); 1205 1206 const base::Value* out_value = nullptr; 1207 int ret_value = 0; 1208 1209 if (const_value().Get(index, &out_value) && out_value->is_int()) { 1210 ret_value = out_value->GetInt(); 1211 } 1212 1213 return ret_value; 1214 } 1215 GetDouble(size_t index)1216 double CefListValueImpl::GetDouble(size_t index) { 1217 CEF_VALUE_VERIFY_RETURN(false, 0); 1218 1219 const base::Value* out_value = nullptr; 1220 double ret_value = 0; 1221 1222 if (const_value().Get(index, &out_value) && out_value->is_double()) { 1223 ret_value = out_value->GetDouble(); 1224 } 1225 1226 return ret_value; 1227 } 1228 GetString(size_t index)1229 CefString CefListValueImpl::GetString(size_t index) { 1230 CEF_VALUE_VERIFY_RETURN(false, CefString()); 1231 1232 const base::Value* out_value = nullptr; 1233 std::string ret_value; 1234 1235 if (const_value().Get(index, &out_value) && out_value->is_string()) { 1236 ret_value = out_value->GetString(); 1237 } 1238 1239 return ret_value; 1240 } 1241 GetBinary(size_t index)1242 CefRefPtr<CefBinaryValue> CefListValueImpl::GetBinary(size_t index) { 1243 CEF_VALUE_VERIFY_RETURN(false, nullptr); 1244 1245 const base::Value* out_value = nullptr; 1246 1247 if (const_value().Get(index, &out_value) && out_value->is_blob()) { 1248 base::Value* binary_value = const_cast<base::Value*>(out_value); 1249 return CefBinaryValueImpl::GetOrCreateRef( 1250 binary_value, const_cast<base::ListValue*>(&const_value()), 1251 controller()); 1252 } 1253 1254 return nullptr; 1255 } 1256 GetDictionary(size_t index)1257 CefRefPtr<CefDictionaryValue> CefListValueImpl::GetDictionary(size_t index) { 1258 CEF_VALUE_VERIFY_RETURN(false, nullptr); 1259 1260 const base::Value* out_value = nullptr; 1261 1262 if (const_value().Get(index, &out_value) && out_value->is_dict()) { 1263 base::DictionaryValue* dict_value = static_cast<base::DictionaryValue*>( 1264 const_cast<base::Value*>(out_value)); 1265 return CefDictionaryValueImpl::GetOrCreateRef( 1266 dict_value, const_cast<base::ListValue*>(&const_value()), read_only(), 1267 controller()); 1268 } 1269 1270 return nullptr; 1271 } 1272 GetList(size_t index)1273 CefRefPtr<CefListValue> CefListValueImpl::GetList(size_t index) { 1274 CEF_VALUE_VERIFY_RETURN(false, nullptr); 1275 1276 const base::Value* out_value = nullptr; 1277 1278 if (const_value().Get(index, &out_value) && out_value->is_list()) { 1279 base::ListValue* list_value = 1280 static_cast<base::ListValue*>(const_cast<base::Value*>(out_value)); 1281 return CefListValueImpl::GetOrCreateRef( 1282 list_value, const_cast<base::ListValue*>(&const_value()), read_only(), 1283 controller()); 1284 } 1285 1286 return nullptr; 1287 } 1288 SetValue(size_t index,CefRefPtr<CefValue> value)1289 bool CefListValueImpl::SetValue(size_t index, CefRefPtr<CefValue> value) { 1290 CEF_VALUE_VERIFY_RETURN(true, false); 1291 1292 CefValueImpl* impl = static_cast<CefValueImpl*>(value.get()); 1293 DCHECK(impl); 1294 1295 base::Value* new_value = impl->CopyOrDetachValue(controller()); 1296 base::Value* actual_value = SetInternal(index, new_value); 1297 impl->SwapValue(actual_value, mutable_value(), controller()); 1298 return true; 1299 } 1300 SetNull(size_t index)1301 bool CefListValueImpl::SetNull(size_t index) { 1302 CEF_VALUE_VERIFY_RETURN(true, false); 1303 SetInternal(index, new base::Value()); 1304 return true; 1305 } 1306 SetBool(size_t index,bool value)1307 bool CefListValueImpl::SetBool(size_t index, bool value) { 1308 CEF_VALUE_VERIFY_RETURN(true, false); 1309 SetInternal(index, new base::Value(value)); 1310 return true; 1311 } 1312 SetInt(size_t index,int value)1313 bool CefListValueImpl::SetInt(size_t index, int value) { 1314 CEF_VALUE_VERIFY_RETURN(true, false); 1315 SetInternal(index, new base::Value(value)); 1316 return true; 1317 } 1318 SetDouble(size_t index,double value)1319 bool CefListValueImpl::SetDouble(size_t index, double value) { 1320 CEF_VALUE_VERIFY_RETURN(true, false); 1321 SetInternal(index, new base::Value(value)); 1322 return true; 1323 } 1324 SetString(size_t index,const CefString & value)1325 bool CefListValueImpl::SetString(size_t index, const CefString& value) { 1326 CEF_VALUE_VERIFY_RETURN(true, false); 1327 SetInternal(index, new base::Value(value.ToString())); 1328 return true; 1329 } 1330 SetBinary(size_t index,CefRefPtr<CefBinaryValue> value)1331 bool CefListValueImpl::SetBinary(size_t index, 1332 CefRefPtr<CefBinaryValue> value) { 1333 CEF_VALUE_VERIFY_RETURN(true, false); 1334 1335 CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get()); 1336 DCHECK(impl); 1337 1338 SetInternal(index, impl->CopyOrDetachValue(controller())); 1339 return true; 1340 } 1341 SetDictionary(size_t index,CefRefPtr<CefDictionaryValue> value)1342 bool CefListValueImpl::SetDictionary(size_t index, 1343 CefRefPtr<CefDictionaryValue> value) { 1344 CEF_VALUE_VERIFY_RETURN(true, false); 1345 1346 CefDictionaryValueImpl* impl = 1347 static_cast<CefDictionaryValueImpl*>(value.get()); 1348 DCHECK(impl); 1349 1350 SetInternal(index, impl->CopyOrDetachValue(controller())); 1351 return true; 1352 } 1353 SetList(size_t index,CefRefPtr<CefListValue> value)1354 bool CefListValueImpl::SetList(size_t index, CefRefPtr<CefListValue> value) { 1355 CEF_VALUE_VERIFY_RETURN(true, false); 1356 1357 CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get()); 1358 DCHECK(impl); 1359 1360 SetInternal(index, impl->CopyOrDetachValue(controller())); 1361 return true; 1362 } 1363 RemoveInternal(size_t index)1364 bool CefListValueImpl::RemoveInternal(size_t index) { 1365 auto list = mutable_value()->GetList(); 1366 if (index >= list.size()) 1367 return false; 1368 1369 // The std::move() call below which removes the Value from the list will 1370 // return a new Value object with the moved contents of the Value that exists 1371 // in the implementation std::vector. Consequently we use Get() to retrieve 1372 // the actual Value pointer as it current exists first, for later comparison 1373 // purposes. 1374 const base::Value* actual_value = nullptr; 1375 if (!const_value().Get(index, &actual_value) || !actual_value) 1376 return false; 1377 1378 // |actual_value| is no longer valid after this call. 1379 auto out_value = std::move(list[index]); 1380 mutable_value()->EraseListIter(list.begin() + index); 1381 1382 // Remove the value. 1383 controller()->Remove(const_cast<base::Value*>(actual_value), true); 1384 1385 // Only list and dictionary types may have dependencies. 1386 if (out_value.is_list() || out_value.is_dict()) { 1387 controller()->RemoveDependencies(const_cast<base::Value*>(actual_value)); 1388 } 1389 1390 return true; 1391 } 1392 SetInternal(size_t index,base::Value * value)1393 base::Value* CefListValueImpl::SetInternal(size_t index, base::Value* value) { 1394 DCHECK(value); 1395 1396 auto list = mutable_value()->GetList(); 1397 if (RemoveInternal(index)) { 1398 CHECK_LE(index, list.size()); 1399 mutable_value()->Insert(list.begin() + index, std::move(*value)); 1400 } else { 1401 if (index >= list.size()) { 1402 // Expand the list size. 1403 // TODO: This approach seems inefficient. See 1404 // https://crbug.com/1187066#c17 for background. 1405 while (list.size() <= index) 1406 mutable_value()->Append(base::Value()); 1407 } 1408 list[index] = std::move(*value); 1409 } 1410 1411 // base::Value now uses move semantics which means that Insert()/Set() will 1412 // move the contents of the passed-in base::Value instead of keeping the same 1413 // object. Consequently we use Get() to retrieve the actual base::Value 1414 // pointer as it exists in the std::vector. 1415 const base::Value* actual_value = nullptr; 1416 const_value().Get(index, &actual_value); 1417 DCHECK(actual_value); 1418 1419 // |value| will have been deleted at this point. Update the controller to 1420 // reference |actual_value| instead. 1421 controller()->Swap(value, const_cast<base::Value*>(actual_value)); 1422 1423 return const_cast<base::Value*>(actual_value); 1424 } 1425 CefListValueImpl(base::ListValue * value,void * parent_value,ValueMode value_mode,bool read_only,CefValueController * controller)1426 CefListValueImpl::CefListValueImpl(base::ListValue* value, 1427 void* parent_value, 1428 ValueMode value_mode, 1429 bool read_only, 1430 CefValueController* controller) 1431 : CefValueBase<CefListValue, base::ListValue>(value, 1432 parent_value, 1433 value_mode, 1434 read_only, 1435 controller) {} 1436