• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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