• 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