• 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->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