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