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->DeepCopy());
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_->DeepCopy();
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_->DeepCopy());
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_)
247 value_->GetAsBoolean(&ret_value);
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_)
256 value_->GetAsInteger(&ret_value);
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_)
265 value_->GetAsDouble(&ret_value);
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_)
274 value_->GetAsString(&ret_value);
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().DeepCopy();
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().DeepCopy(), nullptr,
532 CefBinaryValueImpl::kOwnerWillDelete, nullptr);
533 }
534
GetSize()535 size_t CefBinaryValueImpl::GetSize() {
536 CEF_VALUE_VERIFY_RETURN(false, 0);
537 return const_value().GetBlob().size();
538 }
539
GetData(void * buffer,size_t buffer_size,size_t data_offset)540 size_t CefBinaryValueImpl::GetData(void* buffer,
541 size_t buffer_size,
542 size_t data_offset) {
543 DCHECK(buffer);
544 DCHECK_GT(buffer_size, (size_t)0);
545 if (!buffer || buffer_size == 0)
546 return 0;
547
548 CEF_VALUE_VERIFY_RETURN(false, 0);
549
550 size_t size = const_value().GetBlob().size();
551 DCHECK_LT(data_offset, size);
552 if (data_offset >= size)
553 return 0;
554
555 size = std::min(buffer_size, size - data_offset);
556 auto* data = const_value().GetBlob().data();
557 memcpy(buffer, data + data_offset, size);
558 return size;
559 }
560
CefBinaryValueImpl(base::Value * value,void * parent_value,ValueMode value_mode,CefValueController * controller)561 CefBinaryValueImpl::CefBinaryValueImpl(base::Value* value,
562 void* parent_value,
563 ValueMode value_mode,
564 CefValueController* controller)
565 : CefValueBase<CefBinaryValue, base::Value>(value,
566 parent_value,
567 value_mode,
568 true,
569 controller) {}
570
571 // CefDictionaryValueImpl implementation.
572
573 // static
Create()574 CefRefPtr<CefDictionaryValue> CefDictionaryValue::Create() {
575 return new CefDictionaryValueImpl(new base::DictionaryValue(), true, false);
576 }
577
578 // static
GetOrCreateRef(base::DictionaryValue * value,void * parent_value,bool read_only,CefValueController * controller)579 CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetOrCreateRef(
580 base::DictionaryValue* value,
581 void* parent_value,
582 bool read_only,
583 CefValueController* controller) {
584 CefValueController::Object* object = controller->Get(value);
585 if (object)
586 return static_cast<CefDictionaryValueImpl*>(object);
587
588 return new CefDictionaryValueImpl(value, parent_value,
589 CefDictionaryValueImpl::kReference,
590 read_only, controller);
591 }
592
CefDictionaryValueImpl(base::DictionaryValue * value,bool will_delete,bool read_only)593 CefDictionaryValueImpl::CefDictionaryValueImpl(base::DictionaryValue* value,
594 bool will_delete,
595 bool read_only)
596 : CefValueBase<CefDictionaryValue, base::DictionaryValue>(
597 value,
598 nullptr,
599 will_delete ? kOwnerWillDelete : kOwnerNoDelete,
600 read_only,
601 nullptr) {}
602
CopyValue()603 base::DictionaryValue* CefDictionaryValueImpl::CopyValue() {
604 CEF_VALUE_VERIFY_RETURN(false, nullptr);
605 return const_value().DeepCopy();
606 }
607
CopyOrDetachValue(CefValueController * new_controller)608 base::DictionaryValue* CefDictionaryValueImpl::CopyOrDetachValue(
609 CefValueController* new_controller) {
610 base::DictionaryValue* new_value;
611
612 if (!will_delete()) {
613 // Copy the value.
614 new_value = CopyValue();
615 } else {
616 // Take ownership of the value.
617 new_value = Detach(new_controller);
618 }
619
620 DCHECK(new_value);
621 return new_value;
622 }
623
IsSameValue(const base::DictionaryValue * that)624 bool CefDictionaryValueImpl::IsSameValue(const base::DictionaryValue* that) {
625 CEF_VALUE_VERIFY_RETURN(false, false);
626 return (&const_value() == that);
627 }
628
IsEqualValue(const base::DictionaryValue * that)629 bool CefDictionaryValueImpl::IsEqualValue(const base::DictionaryValue* that) {
630 CEF_VALUE_VERIFY_RETURN(false, false);
631 return const_value().Equals(that);
632 }
633
GetValueUnsafe()634 base::DictionaryValue* CefDictionaryValueImpl::GetValueUnsafe() {
635 if (!VerifyAttached())
636 return nullptr;
637 controller()->AssertLockAcquired();
638 return const_cast<base::DictionaryValue*>(&const_value());
639 }
640
IsValid()641 bool CefDictionaryValueImpl::IsValid() {
642 return !detached();
643 }
644
IsOwned()645 bool CefDictionaryValueImpl::IsOwned() {
646 return !will_delete();
647 }
648
IsReadOnly()649 bool CefDictionaryValueImpl::IsReadOnly() {
650 return read_only();
651 }
652
IsSame(CefRefPtr<CefDictionaryValue> that)653 bool CefDictionaryValueImpl::IsSame(CefRefPtr<CefDictionaryValue> that) {
654 if (!that.get())
655 return false;
656 if (that.get() == this)
657 return true;
658
659 CEF_VALUE_VERIFY_RETURN(false, false);
660 return static_cast<CefDictionaryValueImpl*>(that.get())
661 ->IsSameValue(&const_value());
662 }
663
IsEqual(CefRefPtr<CefDictionaryValue> that)664 bool CefDictionaryValueImpl::IsEqual(CefRefPtr<CefDictionaryValue> that) {
665 if (!that.get())
666 return false;
667 if (that.get() == this)
668 return true;
669
670 CEF_VALUE_VERIFY_RETURN(false, false);
671 return static_cast<CefDictionaryValueImpl*>(that.get())
672 ->IsEqualValue(&const_value());
673 }
674
Copy(bool exclude_empty_children)675 CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::Copy(
676 bool exclude_empty_children) {
677 CEF_VALUE_VERIFY_RETURN(false, nullptr);
678
679 base::DictionaryValue* value;
680 if (exclude_empty_children) {
681 value = const_cast<base::DictionaryValue&>(const_value())
682 .DeepCopyWithoutEmptyChildren()
683 .release();
684 } else {
685 value = const_value().DeepCopy();
686 }
687
688 return new CefDictionaryValueImpl(
689 value, nullptr, CefDictionaryValueImpl::kOwnerWillDelete, false, nullptr);
690 }
691
GetSize()692 size_t CefDictionaryValueImpl::GetSize() {
693 CEF_VALUE_VERIFY_RETURN(false, 0);
694 return const_value().size();
695 }
696
Clear()697 bool CefDictionaryValueImpl::Clear() {
698 CEF_VALUE_VERIFY_RETURN(true, false);
699
700 // Detach any dependent values.
701 controller()->RemoveDependencies(mutable_value());
702
703 mutable_value()->Clear();
704 return true;
705 }
706
HasKey(const CefString & key)707 bool CefDictionaryValueImpl::HasKey(const CefString& key) {
708 CEF_VALUE_VERIFY_RETURN(false, 0);
709 return const_value().HasKey(base::StringPiece(key));
710 }
711
GetKeys(KeyList & keys)712 bool CefDictionaryValueImpl::GetKeys(KeyList& keys) {
713 CEF_VALUE_VERIFY_RETURN(false, 0);
714
715 for (base::DictionaryValue::Iterator i(const_value()); !i.IsAtEnd();
716 i.Advance()) {
717 keys.push_back(i.key());
718 }
719
720 return true;
721 }
722
Remove(const CefString & key)723 bool CefDictionaryValueImpl::Remove(const CefString& key) {
724 CEF_VALUE_VERIFY_RETURN(true, false);
725 return RemoveInternal(key);
726 }
727
GetType(const CefString & key)728 CefValueType CefDictionaryValueImpl::GetType(const CefString& key) {
729 CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID);
730
731 const base::Value* out_value = nullptr;
732 if (const_value().GetWithoutPathExpansion(base::StringPiece(key),
733 &out_value)) {
734 switch (out_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 case base::Value::Type::DEAD:
752 return VTYPE_INVALID;
753 }
754 }
755
756 return VTYPE_INVALID;
757 }
758
GetValue(const CefString & key)759 CefRefPtr<CefValue> CefDictionaryValueImpl::GetValue(const CefString& key) {
760 CEF_VALUE_VERIFY_RETURN(false, nullptr);
761
762 const base::Value* out_value = nullptr;
763 if (const_value().GetWithoutPathExpansion(base::StringPiece(key),
764 &out_value)) {
765 return CefValueImpl::GetOrCreateRefOrCopy(
766 const_cast<base::Value*>(out_value),
767 const_cast<base::DictionaryValue*>(&const_value()), read_only(),
768 controller());
769 }
770
771 return nullptr;
772 }
773
GetBool(const CefString & key)774 bool CefDictionaryValueImpl::GetBool(const CefString& key) {
775 CEF_VALUE_VERIFY_RETURN(false, false);
776
777 const base::Value* out_value = nullptr;
778 bool ret_value = false;
779
780 if (const_value().GetWithoutPathExpansion(base::StringPiece(key), &out_value))
781 out_value->GetAsBoolean(&ret_value);
782
783 return ret_value;
784 }
785
GetInt(const CefString & key)786 int CefDictionaryValueImpl::GetInt(const CefString& key) {
787 CEF_VALUE_VERIFY_RETURN(false, 0);
788
789 const base::Value* out_value = nullptr;
790 int ret_value = 0;
791
792 if (const_value().GetWithoutPathExpansion(base::StringPiece(key), &out_value))
793 out_value->GetAsInteger(&ret_value);
794
795 return ret_value;
796 }
797
GetDouble(const CefString & key)798 double CefDictionaryValueImpl::GetDouble(const CefString& key) {
799 CEF_VALUE_VERIFY_RETURN(false, 0);
800
801 const base::Value* out_value = nullptr;
802 double ret_value = 0;
803
804 if (const_value().GetWithoutPathExpansion(base::StringPiece(key), &out_value))
805 out_value->GetAsDouble(&ret_value);
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 const base::Value* out_value = nullptr;
814 std::string ret_value;
815
816 if (const_value().GetWithoutPathExpansion(base::StringPiece(key), &out_value))
817 out_value->GetAsString(&ret_value);
818
819 return ret_value;
820 }
821
GetBinary(const CefString & key)822 CefRefPtr<CefBinaryValue> CefDictionaryValueImpl::GetBinary(
823 const CefString& key) {
824 CEF_VALUE_VERIFY_RETURN(false, nullptr);
825
826 const base::Value* out_value = nullptr;
827
828 if (const_value().GetWithoutPathExpansion(base::StringPiece(key),
829 &out_value) &&
830 out_value->is_blob()) {
831 base::Value* binary_value = const_cast<base::Value*>(out_value);
832 return CefBinaryValueImpl::GetOrCreateRef(
833 binary_value, const_cast<base::DictionaryValue*>(&const_value()),
834 controller());
835 }
836
837 return nullptr;
838 }
839
GetDictionary(const CefString & key)840 CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetDictionary(
841 const CefString& key) {
842 CEF_VALUE_VERIFY_RETURN(false, nullptr);
843
844 const base::Value* out_value = nullptr;
845
846 if (const_value().GetWithoutPathExpansion(base::StringPiece(key),
847 &out_value) &&
848 out_value->is_dict()) {
849 base::DictionaryValue* dict_value = static_cast<base::DictionaryValue*>(
850 const_cast<base::Value*>(out_value));
851 return CefDictionaryValueImpl::GetOrCreateRef(
852 dict_value, const_cast<base::DictionaryValue*>(&const_value()),
853 read_only(), controller());
854 }
855
856 return nullptr;
857 }
858
GetList(const CefString & key)859 CefRefPtr<CefListValue> CefDictionaryValueImpl::GetList(const CefString& key) {
860 CEF_VALUE_VERIFY_RETURN(false, nullptr);
861
862 const base::Value* out_value = nullptr;
863
864 if (const_value().GetWithoutPathExpansion(base::StringPiece(key),
865 &out_value) &&
866 out_value->is_list()) {
867 base::ListValue* list_value =
868 static_cast<base::ListValue*>(const_cast<base::Value*>(out_value));
869 return CefListValueImpl::GetOrCreateRef(
870 list_value, const_cast<base::DictionaryValue*>(&const_value()),
871 read_only(), controller());
872 }
873
874 return nullptr;
875 }
876
SetValue(const CefString & key,CefRefPtr<CefValue> value)877 bool CefDictionaryValueImpl::SetValue(const CefString& key,
878 CefRefPtr<CefValue> value) {
879 CEF_VALUE_VERIFY_RETURN(true, false);
880
881 CefValueImpl* impl = static_cast<CefValueImpl*>(value.get());
882 DCHECK(impl);
883
884 base::Value* new_value = impl->CopyOrDetachValue(controller());
885 base::Value* actual_value = SetInternal(key, new_value);
886 impl->SwapValue(actual_value, mutable_value(), controller());
887 return true;
888 }
889
SetNull(const CefString & key)890 bool CefDictionaryValueImpl::SetNull(const CefString& key) {
891 CEF_VALUE_VERIFY_RETURN(true, false);
892 SetInternal(key, new base::Value());
893 return true;
894 }
895
SetBool(const CefString & key,bool value)896 bool CefDictionaryValueImpl::SetBool(const CefString& key, bool value) {
897 CEF_VALUE_VERIFY_RETURN(true, false);
898 SetInternal(key, new base::Value(value));
899 return true;
900 }
901
SetInt(const CefString & key,int value)902 bool CefDictionaryValueImpl::SetInt(const CefString& key, int value) {
903 CEF_VALUE_VERIFY_RETURN(true, false);
904 SetInternal(key, new base::Value(value));
905 return true;
906 }
907
SetDouble(const CefString & key,double value)908 bool CefDictionaryValueImpl::SetDouble(const CefString& key, double value) {
909 CEF_VALUE_VERIFY_RETURN(true, false);
910 SetInternal(key, new base::Value(value));
911 return true;
912 }
913
SetString(const CefString & key,const CefString & value)914 bool CefDictionaryValueImpl::SetString(const CefString& key,
915 const CefString& value) {
916 CEF_VALUE_VERIFY_RETURN(true, false);
917 SetInternal(key, new base::Value(value.ToString()));
918 return true;
919 }
920
SetBinary(const CefString & key,CefRefPtr<CefBinaryValue> value)921 bool CefDictionaryValueImpl::SetBinary(const CefString& key,
922 CefRefPtr<CefBinaryValue> value) {
923 CEF_VALUE_VERIFY_RETURN(true, false);
924
925 CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get());
926 DCHECK(impl);
927
928 SetInternal(key, impl->CopyOrDetachValue(controller()));
929 return true;
930 }
931
SetDictionary(const CefString & key,CefRefPtr<CefDictionaryValue> value)932 bool CefDictionaryValueImpl::SetDictionary(
933 const CefString& key,
934 CefRefPtr<CefDictionaryValue> value) {
935 CEF_VALUE_VERIFY_RETURN(true, false);
936
937 CefDictionaryValueImpl* impl =
938 static_cast<CefDictionaryValueImpl*>(value.get());
939 DCHECK(impl);
940
941 SetInternal(key, impl->CopyOrDetachValue(controller()));
942 return true;
943 }
944
SetList(const CefString & key,CefRefPtr<CefListValue> value)945 bool CefDictionaryValueImpl::SetList(const CefString& key,
946 CefRefPtr<CefListValue> value) {
947 CEF_VALUE_VERIFY_RETURN(true, false);
948
949 CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get());
950 DCHECK(impl);
951
952 SetInternal(key, impl->CopyOrDetachValue(controller()));
953 return true;
954 }
955
RemoveInternal(const CefString & key)956 bool CefDictionaryValueImpl::RemoveInternal(const CefString& key) {
957 std::unique_ptr<base::Value> out_value;
958 if (!mutable_value()->RemoveWithoutPathExpansion(base::StringPiece(key),
959 &out_value)) {
960 return false;
961 }
962
963 // Remove the value.
964 controller()->Remove(out_value.get(), true);
965
966 // Only list and dictionary types may have dependencies.
967 if (out_value->is_list() || out_value->is_dict()) {
968 controller()->RemoveDependencies(out_value.get());
969 }
970
971 return true;
972 }
973
SetInternal(const CefString & key,base::Value * value)974 base::Value* CefDictionaryValueImpl::SetInternal(const CefString& key,
975 base::Value* value) {
976 DCHECK(value);
977 RemoveInternal(key);
978 mutable_value()->SetWithoutPathExpansion(
979 base::StringPiece(key), base::WrapUnique<base::Value>(value));
980 return value;
981 }
982
CefDictionaryValueImpl(base::DictionaryValue * value,void * parent_value,ValueMode value_mode,bool read_only,CefValueController * controller)983 CefDictionaryValueImpl::CefDictionaryValueImpl(base::DictionaryValue* value,
984 void* parent_value,
985 ValueMode value_mode,
986 bool read_only,
987 CefValueController* controller)
988 : CefValueBase<CefDictionaryValue, base::DictionaryValue>(value,
989 parent_value,
990 value_mode,
991 read_only,
992 controller) {}
993
994 // CefListValueImpl implementation.
995
996 // static
Create()997 CefRefPtr<CefListValue> CefListValue::Create() {
998 return new CefListValueImpl(new base::ListValue(), true, false);
999 }
1000
1001 // static
GetOrCreateRef(base::ListValue * value,void * parent_value,bool read_only,CefValueController * controller)1002 CefRefPtr<CefListValue> CefListValueImpl::GetOrCreateRef(
1003 base::ListValue* value,
1004 void* parent_value,
1005 bool read_only,
1006 CefValueController* controller) {
1007 CefValueController::Object* object = controller->Get(value);
1008 if (object)
1009 return static_cast<CefListValueImpl*>(object);
1010
1011 return new CefListValueImpl(value, parent_value, CefListValueImpl::kReference,
1012 read_only, controller);
1013 }
1014
CefListValueImpl(base::ListValue * value,bool will_delete,bool read_only)1015 CefListValueImpl::CefListValueImpl(base::ListValue* value,
1016 bool will_delete,
1017 bool read_only)
1018 : CefValueBase<CefListValue, base::ListValue>(
1019 value,
1020 nullptr,
1021 will_delete ? kOwnerWillDelete : kOwnerNoDelete,
1022 read_only,
1023 nullptr) {}
1024
CopyValue()1025 base::ListValue* CefListValueImpl::CopyValue() {
1026 CEF_VALUE_VERIFY_RETURN(false, nullptr);
1027 return const_value().DeepCopy();
1028 }
1029
CopyOrDetachValue(CefValueController * new_controller)1030 base::ListValue* CefListValueImpl::CopyOrDetachValue(
1031 CefValueController* new_controller) {
1032 base::ListValue* new_value;
1033
1034 if (!will_delete()) {
1035 // Copy the value.
1036 new_value = CopyValue();
1037 } else {
1038 // Take ownership of the value.
1039 new_value = Detach(new_controller);
1040 }
1041
1042 DCHECK(new_value);
1043 return new_value;
1044 }
1045
IsSameValue(const base::ListValue * that)1046 bool CefListValueImpl::IsSameValue(const base::ListValue* that) {
1047 CEF_VALUE_VERIFY_RETURN(false, false);
1048 return (&const_value() == that);
1049 }
1050
IsEqualValue(const base::ListValue * that)1051 bool CefListValueImpl::IsEqualValue(const base::ListValue* that) {
1052 CEF_VALUE_VERIFY_RETURN(false, false);
1053 return const_value().Equals(that);
1054 }
1055
GetValueUnsafe()1056 base::ListValue* CefListValueImpl::GetValueUnsafe() {
1057 if (!VerifyAttached())
1058 return nullptr;
1059 controller()->AssertLockAcquired();
1060 return const_cast<base::ListValue*>(&const_value());
1061 }
1062
IsValid()1063 bool CefListValueImpl::IsValid() {
1064 return !detached();
1065 }
1066
IsOwned()1067 bool CefListValueImpl::IsOwned() {
1068 return !will_delete();
1069 }
1070
IsReadOnly()1071 bool CefListValueImpl::IsReadOnly() {
1072 return read_only();
1073 }
1074
IsSame(CefRefPtr<CefListValue> that)1075 bool CefListValueImpl::IsSame(CefRefPtr<CefListValue> that) {
1076 if (!that.get())
1077 return false;
1078 if (that.get() == this)
1079 return true;
1080
1081 CEF_VALUE_VERIFY_RETURN(false, false);
1082 return static_cast<CefListValueImpl*>(that.get())
1083 ->IsSameValue(&const_value());
1084 }
1085
IsEqual(CefRefPtr<CefListValue> that)1086 bool CefListValueImpl::IsEqual(CefRefPtr<CefListValue> that) {
1087 if (!that.get())
1088 return false;
1089 if (that.get() == this)
1090 return true;
1091
1092 CEF_VALUE_VERIFY_RETURN(false, false);
1093 return static_cast<CefListValueImpl*>(that.get())
1094 ->IsEqualValue(&const_value());
1095 }
1096
Copy()1097 CefRefPtr<CefListValue> CefListValueImpl::Copy() {
1098 CEF_VALUE_VERIFY_RETURN(false, nullptr);
1099
1100 return new CefListValueImpl(const_value().DeepCopy(), nullptr,
1101 CefListValueImpl::kOwnerWillDelete, false,
1102 nullptr);
1103 }
1104
SetSize(size_t size)1105 bool CefListValueImpl::SetSize(size_t size) {
1106 CEF_VALUE_VERIFY_RETURN(true, false);
1107
1108 size_t current_size = const_value().GetSize();
1109 if (size < current_size) {
1110 // Clean up any values above the requested size.
1111 for (size_t i = current_size - 1; i >= size; --i)
1112 RemoveInternal(i);
1113 } else if (size > 0) {
1114 // Expand the list size.
1115 mutable_value()->Set(size - 1, std::make_unique<base::Value>());
1116 }
1117 return true;
1118 }
1119
GetSize()1120 size_t CefListValueImpl::GetSize() {
1121 CEF_VALUE_VERIFY_RETURN(false, 0);
1122 return const_value().GetSize();
1123 }
1124
Clear()1125 bool CefListValueImpl::Clear() {
1126 CEF_VALUE_VERIFY_RETURN(true, false);
1127
1128 // Detach any dependent values.
1129 controller()->RemoveDependencies(mutable_value());
1130
1131 mutable_value()->Clear();
1132 return true;
1133 }
1134
Remove(size_t index)1135 bool CefListValueImpl::Remove(size_t index) {
1136 CEF_VALUE_VERIFY_RETURN(true, false);
1137 return RemoveInternal(index);
1138 }
1139
GetType(size_t index)1140 CefValueType CefListValueImpl::GetType(size_t index) {
1141 CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID);
1142
1143 const base::Value* out_value = nullptr;
1144 if (const_value().Get(index, &out_value)) {
1145 switch (out_value->type()) {
1146 case base::Value::Type::NONE:
1147 return VTYPE_NULL;
1148 case base::Value::Type::BOOLEAN:
1149 return VTYPE_BOOL;
1150 case base::Value::Type::INTEGER:
1151 return VTYPE_INT;
1152 case base::Value::Type::DOUBLE:
1153 return VTYPE_DOUBLE;
1154 case base::Value::Type::STRING:
1155 return VTYPE_STRING;
1156 case base::Value::Type::BINARY:
1157 return VTYPE_BINARY;
1158 case base::Value::Type::DICTIONARY:
1159 return VTYPE_DICTIONARY;
1160 case base::Value::Type::LIST:
1161 return VTYPE_LIST;
1162 case base::Value::Type::DEAD:
1163 return VTYPE_INVALID;
1164 }
1165 }
1166
1167 return VTYPE_INVALID;
1168 }
1169
GetValue(size_t index)1170 CefRefPtr<CefValue> CefListValueImpl::GetValue(size_t index) {
1171 CEF_VALUE_VERIFY_RETURN(false, nullptr);
1172
1173 const base::Value* out_value = nullptr;
1174 if (const_value().Get(index, &out_value)) {
1175 return CefValueImpl::GetOrCreateRefOrCopy(
1176 const_cast<base::Value*>(out_value),
1177 const_cast<base::ListValue*>(&const_value()), read_only(),
1178 controller());
1179 }
1180
1181 return nullptr;
1182 }
1183
GetBool(size_t index)1184 bool CefListValueImpl::GetBool(size_t index) {
1185 CEF_VALUE_VERIFY_RETURN(false, false);
1186
1187 const base::Value* out_value = nullptr;
1188 bool ret_value = false;
1189
1190 if (const_value().Get(index, &out_value))
1191 out_value->GetAsBoolean(&ret_value);
1192
1193 return ret_value;
1194 }
1195
GetInt(size_t index)1196 int CefListValueImpl::GetInt(size_t index) {
1197 CEF_VALUE_VERIFY_RETURN(false, 0);
1198
1199 const base::Value* out_value = nullptr;
1200 int ret_value = 0;
1201
1202 if (const_value().Get(index, &out_value))
1203 out_value->GetAsInteger(&ret_value);
1204
1205 return ret_value;
1206 }
1207
GetDouble(size_t index)1208 double CefListValueImpl::GetDouble(size_t index) {
1209 CEF_VALUE_VERIFY_RETURN(false, 0);
1210
1211 const base::Value* out_value = nullptr;
1212 double ret_value = 0;
1213
1214 if (const_value().Get(index, &out_value))
1215 out_value->GetAsDouble(&ret_value);
1216
1217 return ret_value;
1218 }
1219
GetString(size_t index)1220 CefString CefListValueImpl::GetString(size_t index) {
1221 CEF_VALUE_VERIFY_RETURN(false, CefString());
1222
1223 const base::Value* out_value = nullptr;
1224 std::string ret_value;
1225
1226 if (const_value().Get(index, &out_value))
1227 out_value->GetAsString(&ret_value);
1228
1229 return ret_value;
1230 }
1231
GetBinary(size_t index)1232 CefRefPtr<CefBinaryValue> CefListValueImpl::GetBinary(size_t index) {
1233 CEF_VALUE_VERIFY_RETURN(false, nullptr);
1234
1235 const base::Value* out_value = nullptr;
1236
1237 if (const_value().Get(index, &out_value) && out_value->is_blob()) {
1238 base::Value* binary_value = const_cast<base::Value*>(out_value);
1239 return CefBinaryValueImpl::GetOrCreateRef(
1240 binary_value, const_cast<base::ListValue*>(&const_value()),
1241 controller());
1242 }
1243
1244 return nullptr;
1245 }
1246
GetDictionary(size_t index)1247 CefRefPtr<CefDictionaryValue> CefListValueImpl::GetDictionary(size_t index) {
1248 CEF_VALUE_VERIFY_RETURN(false, nullptr);
1249
1250 const base::Value* out_value = nullptr;
1251
1252 if (const_value().Get(index, &out_value) && out_value->is_dict()) {
1253 base::DictionaryValue* dict_value = static_cast<base::DictionaryValue*>(
1254 const_cast<base::Value*>(out_value));
1255 return CefDictionaryValueImpl::GetOrCreateRef(
1256 dict_value, const_cast<base::ListValue*>(&const_value()), read_only(),
1257 controller());
1258 }
1259
1260 return nullptr;
1261 }
1262
GetList(size_t index)1263 CefRefPtr<CefListValue> CefListValueImpl::GetList(size_t index) {
1264 CEF_VALUE_VERIFY_RETURN(false, nullptr);
1265
1266 const base::Value* out_value = nullptr;
1267
1268 if (const_value().Get(index, &out_value) && out_value->is_list()) {
1269 base::ListValue* list_value =
1270 static_cast<base::ListValue*>(const_cast<base::Value*>(out_value));
1271 return CefListValueImpl::GetOrCreateRef(
1272 list_value, const_cast<base::ListValue*>(&const_value()), read_only(),
1273 controller());
1274 }
1275
1276 return nullptr;
1277 }
1278
SetValue(size_t index,CefRefPtr<CefValue> value)1279 bool CefListValueImpl::SetValue(size_t index, CefRefPtr<CefValue> value) {
1280 CEF_VALUE_VERIFY_RETURN(true, false);
1281
1282 CefValueImpl* impl = static_cast<CefValueImpl*>(value.get());
1283 DCHECK(impl);
1284
1285 base::Value* new_value = impl->CopyOrDetachValue(controller());
1286 base::Value* actual_value = SetInternal(index, new_value);
1287 impl->SwapValue(actual_value, mutable_value(), controller());
1288 return true;
1289 }
1290
SetNull(size_t index)1291 bool CefListValueImpl::SetNull(size_t index) {
1292 CEF_VALUE_VERIFY_RETURN(true, false);
1293 SetInternal(index, new base::Value());
1294 return true;
1295 }
1296
SetBool(size_t index,bool value)1297 bool CefListValueImpl::SetBool(size_t index, bool value) {
1298 CEF_VALUE_VERIFY_RETURN(true, false);
1299 SetInternal(index, new base::Value(value));
1300 return true;
1301 }
1302
SetInt(size_t index,int value)1303 bool CefListValueImpl::SetInt(size_t index, int value) {
1304 CEF_VALUE_VERIFY_RETURN(true, false);
1305 SetInternal(index, new base::Value(value));
1306 return true;
1307 }
1308
SetDouble(size_t index,double value)1309 bool CefListValueImpl::SetDouble(size_t index, double value) {
1310 CEF_VALUE_VERIFY_RETURN(true, false);
1311 SetInternal(index, new base::Value(value));
1312 return true;
1313 }
1314
SetString(size_t index,const CefString & value)1315 bool CefListValueImpl::SetString(size_t index, const CefString& value) {
1316 CEF_VALUE_VERIFY_RETURN(true, false);
1317 SetInternal(index, new base::Value(value.ToString()));
1318 return true;
1319 }
1320
SetBinary(size_t index,CefRefPtr<CefBinaryValue> value)1321 bool CefListValueImpl::SetBinary(size_t index,
1322 CefRefPtr<CefBinaryValue> value) {
1323 CEF_VALUE_VERIFY_RETURN(true, false);
1324
1325 CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get());
1326 DCHECK(impl);
1327
1328 SetInternal(index, impl->CopyOrDetachValue(controller()));
1329 return true;
1330 }
1331
SetDictionary(size_t index,CefRefPtr<CefDictionaryValue> value)1332 bool CefListValueImpl::SetDictionary(size_t index,
1333 CefRefPtr<CefDictionaryValue> value) {
1334 CEF_VALUE_VERIFY_RETURN(true, false);
1335
1336 CefDictionaryValueImpl* impl =
1337 static_cast<CefDictionaryValueImpl*>(value.get());
1338 DCHECK(impl);
1339
1340 SetInternal(index, impl->CopyOrDetachValue(controller()));
1341 return true;
1342 }
1343
SetList(size_t index,CefRefPtr<CefListValue> value)1344 bool CefListValueImpl::SetList(size_t index, CefRefPtr<CefListValue> value) {
1345 CEF_VALUE_VERIFY_RETURN(true, false);
1346
1347 CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get());
1348 DCHECK(impl);
1349
1350 SetInternal(index, impl->CopyOrDetachValue(controller()));
1351 return true;
1352 }
1353
RemoveInternal(size_t index)1354 bool CefListValueImpl::RemoveInternal(size_t index) {
1355 // base::Value now uses move semantics which means that Remove() will return
1356 // a new base::Value object with the moved contents of the base::Value that
1357 // exists in the implementation std::vector. Consequently we use Get() to
1358 // retrieve the actual base::Value pointer as it exists in the std::vector.
1359 const base::Value* actual_value = nullptr;
1360 if (!const_value().Get(index, &actual_value))
1361 return false;
1362 DCHECK(actual_value);
1363
1364 std::unique_ptr<base::Value> out_value;
1365 if (!mutable_value()->Remove(index, &out_value))
1366 return false;
1367
1368 // Remove the value.
1369 controller()->Remove(const_cast<base::Value*>(actual_value), true);
1370
1371 // Only list and dictionary types may have dependencies.
1372 if (out_value->is_list() || out_value->is_dict()) {
1373 controller()->RemoveDependencies(const_cast<base::Value*>(actual_value));
1374 }
1375
1376 return true;
1377 }
1378
SetInternal(size_t index,base::Value * value)1379 base::Value* CefListValueImpl::SetInternal(size_t index, base::Value* value) {
1380 DCHECK(value);
1381
1382 if (RemoveInternal(index))
1383 mutable_value()->Insert(index, base::WrapUnique(value));
1384 else
1385 mutable_value()->Set(index, base::WrapUnique(value));
1386
1387 // base::Value now uses move semantics which means that Insert()/Set() will
1388 // move the contents of the passed-in base::Value instead of keeping the same
1389 // object. Consequently we use Get() to retrieve the actual base::Value
1390 // pointer as it exists in the std::vector.
1391 const base::Value* actual_value = nullptr;
1392 const_value().Get(index, &actual_value);
1393 DCHECK(actual_value);
1394
1395 // |value| will have been deleted at this point. Update the controller to
1396 // reference |actual_value| instead.
1397 controller()->Swap(value, const_cast<base::Value*>(actual_value));
1398
1399 return const_cast<base::Value*>(actual_value);
1400 }
1401
CefListValueImpl(base::ListValue * value,void * parent_value,ValueMode value_mode,bool read_only,CefValueController * controller)1402 CefListValueImpl::CefListValueImpl(base::ListValue* value,
1403 void* parent_value,
1404 ValueMode value_mode,
1405 bool read_only,
1406 CefValueController* controller)
1407 : CefValueBase<CefListValue, base::ListValue>(value,
1408 parent_value,
1409 value_mode,
1410 read_only,
1411 controller) {}
1412