1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <string.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <algorithm>
10*635a8641SAndroid Build Coastguard Worker #include <cmath>
11*635a8641SAndroid Build Coastguard Worker #include <new>
12*635a8641SAndroid Build Coastguard Worker #include <ostream>
13*635a8641SAndroid Build Coastguard Worker #include <utility>
14*635a8641SAndroid Build Coastguard Worker
15*635a8641SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/stl_util.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
21*635a8641SAndroid Build Coastguard Worker // Unsupported in libchrome
22*635a8641SAndroid Build Coastguard Worker // #include "base/trace_event/memory_usage_estimator.h"
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker namespace base {
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard Worker namespace {
27*635a8641SAndroid Build Coastguard Worker
28*635a8641SAndroid Build Coastguard Worker const char* const kTypeNames[] = {"null", "boolean", "integer", "double",
29*635a8641SAndroid Build Coastguard Worker "string", "binary", "dictionary", "list"};
30*635a8641SAndroid Build Coastguard Worker static_assert(arraysize(kTypeNames) ==
31*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(Value::Type::LIST) + 1,
32*635a8641SAndroid Build Coastguard Worker "kTypeNames Has Wrong Size");
33*635a8641SAndroid Build Coastguard Worker
34*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
35*635a8641SAndroid Build Coastguard Worker
36*635a8641SAndroid Build Coastguard Worker // Make a deep copy of |node|, but don't include empty lists or dictionaries
37*635a8641SAndroid Build Coastguard Worker // in the copy. It's possible for this function to return NULL and it
38*635a8641SAndroid Build Coastguard Worker // expects |node| to always be non-NULL.
CopyListWithoutEmptyChildren(const Value & list)39*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> CopyListWithoutEmptyChildren(const Value& list) {
40*635a8641SAndroid Build Coastguard Worker Value copy(Value::Type::LIST);
41*635a8641SAndroid Build Coastguard Worker for (const auto& entry : list.GetList()) {
42*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(entry);
43*635a8641SAndroid Build Coastguard Worker if (child_copy)
44*635a8641SAndroid Build Coastguard Worker copy.GetList().push_back(std::move(*child_copy));
45*635a8641SAndroid Build Coastguard Worker }
46*635a8641SAndroid Build Coastguard Worker return copy.GetList().empty() ? nullptr
47*635a8641SAndroid Build Coastguard Worker : std::make_unique<Value>(std::move(copy));
48*635a8641SAndroid Build Coastguard Worker }
49*635a8641SAndroid Build Coastguard Worker
CopyDictionaryWithoutEmptyChildren(const DictionaryValue & dict)50*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
51*635a8641SAndroid Build Coastguard Worker const DictionaryValue& dict) {
52*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> copy;
53*635a8641SAndroid Build Coastguard Worker for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
54*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(it.value());
55*635a8641SAndroid Build Coastguard Worker if (child_copy) {
56*635a8641SAndroid Build Coastguard Worker if (!copy)
57*635a8641SAndroid Build Coastguard Worker copy = std::make_unique<DictionaryValue>();
58*635a8641SAndroid Build Coastguard Worker copy->SetWithoutPathExpansion(it.key(), std::move(child_copy));
59*635a8641SAndroid Build Coastguard Worker }
60*635a8641SAndroid Build Coastguard Worker }
61*635a8641SAndroid Build Coastguard Worker return copy;
62*635a8641SAndroid Build Coastguard Worker }
63*635a8641SAndroid Build Coastguard Worker
CopyWithoutEmptyChildren(const Value & node)64*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
65*635a8641SAndroid Build Coastguard Worker switch (node.type()) {
66*635a8641SAndroid Build Coastguard Worker case Value::Type::LIST:
67*635a8641SAndroid Build Coastguard Worker return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node));
68*635a8641SAndroid Build Coastguard Worker
69*635a8641SAndroid Build Coastguard Worker case Value::Type::DICTIONARY:
70*635a8641SAndroid Build Coastguard Worker return CopyDictionaryWithoutEmptyChildren(
71*635a8641SAndroid Build Coastguard Worker static_cast<const DictionaryValue&>(node));
72*635a8641SAndroid Build Coastguard Worker
73*635a8641SAndroid Build Coastguard Worker default:
74*635a8641SAndroid Build Coastguard Worker return std::make_unique<Value>(node.Clone());
75*635a8641SAndroid Build Coastguard Worker }
76*635a8641SAndroid Build Coastguard Worker }
77*635a8641SAndroid Build Coastguard Worker
78*635a8641SAndroid Build Coastguard Worker } // namespace
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker // static
CreateWithCopiedBuffer(const char * buffer,size_t size)81*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> Value::CreateWithCopiedBuffer(const char* buffer,
82*635a8641SAndroid Build Coastguard Worker size_t size) {
83*635a8641SAndroid Build Coastguard Worker return std::make_unique<Value>(BlobStorage(buffer, buffer + size));
84*635a8641SAndroid Build Coastguard Worker }
85*635a8641SAndroid Build Coastguard Worker
86*635a8641SAndroid Build Coastguard Worker // static
FromUniquePtrValue(std::unique_ptr<Value> val)87*635a8641SAndroid Build Coastguard Worker Value Value::FromUniquePtrValue(std::unique_ptr<Value> val) {
88*635a8641SAndroid Build Coastguard Worker return std::move(*val);
89*635a8641SAndroid Build Coastguard Worker }
90*635a8641SAndroid Build Coastguard Worker
91*635a8641SAndroid Build Coastguard Worker // static
ToUniquePtrValue(Value val)92*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> Value::ToUniquePtrValue(Value val) {
93*635a8641SAndroid Build Coastguard Worker return std::make_unique<Value>(std::move(val));
94*635a8641SAndroid Build Coastguard Worker }
95*635a8641SAndroid Build Coastguard Worker
Value(Value && that)96*635a8641SAndroid Build Coastguard Worker Value::Value(Value&& that) noexcept {
97*635a8641SAndroid Build Coastguard Worker InternalMoveConstructFrom(std::move(that));
98*635a8641SAndroid Build Coastguard Worker }
99*635a8641SAndroid Build Coastguard Worker
Value()100*635a8641SAndroid Build Coastguard Worker Value::Value() noexcept : type_(Type::NONE) {}
101*635a8641SAndroid Build Coastguard Worker
Value(Type type)102*635a8641SAndroid Build Coastguard Worker Value::Value(Type type) : type_(type) {
103*635a8641SAndroid Build Coastguard Worker // Initialize with the default value.
104*635a8641SAndroid Build Coastguard Worker switch (type_) {
105*635a8641SAndroid Build Coastguard Worker case Type::NONE:
106*635a8641SAndroid Build Coastguard Worker return;
107*635a8641SAndroid Build Coastguard Worker
108*635a8641SAndroid Build Coastguard Worker case Type::BOOLEAN:
109*635a8641SAndroid Build Coastguard Worker bool_value_ = false;
110*635a8641SAndroid Build Coastguard Worker return;
111*635a8641SAndroid Build Coastguard Worker case Type::INTEGER:
112*635a8641SAndroid Build Coastguard Worker int_value_ = 0;
113*635a8641SAndroid Build Coastguard Worker return;
114*635a8641SAndroid Build Coastguard Worker case Type::DOUBLE:
115*635a8641SAndroid Build Coastguard Worker double_value_ = 0.0;
116*635a8641SAndroid Build Coastguard Worker return;
117*635a8641SAndroid Build Coastguard Worker case Type::STRING:
118*635a8641SAndroid Build Coastguard Worker new (&string_value_) std::string();
119*635a8641SAndroid Build Coastguard Worker return;
120*635a8641SAndroid Build Coastguard Worker case Type::BINARY:
121*635a8641SAndroid Build Coastguard Worker new (&binary_value_) BlobStorage();
122*635a8641SAndroid Build Coastguard Worker return;
123*635a8641SAndroid Build Coastguard Worker case Type::DICTIONARY:
124*635a8641SAndroid Build Coastguard Worker new (&dict_) DictStorage();
125*635a8641SAndroid Build Coastguard Worker return;
126*635a8641SAndroid Build Coastguard Worker case Type::LIST:
127*635a8641SAndroid Build Coastguard Worker new (&list_) ListStorage();
128*635a8641SAndroid Build Coastguard Worker return;
129*635a8641SAndroid Build Coastguard Worker }
130*635a8641SAndroid Build Coastguard Worker }
131*635a8641SAndroid Build Coastguard Worker
Value(bool in_bool)132*635a8641SAndroid Build Coastguard Worker Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
133*635a8641SAndroid Build Coastguard Worker
Value(int in_int)134*635a8641SAndroid Build Coastguard Worker Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
135*635a8641SAndroid Build Coastguard Worker
Value(double in_double)136*635a8641SAndroid Build Coastguard Worker Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
137*635a8641SAndroid Build Coastguard Worker if (!std::isfinite(double_value_)) {
138*635a8641SAndroid Build Coastguard Worker NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
139*635a8641SAndroid Build Coastguard Worker << "values cannot be represented in JSON";
140*635a8641SAndroid Build Coastguard Worker double_value_ = 0.0;
141*635a8641SAndroid Build Coastguard Worker }
142*635a8641SAndroid Build Coastguard Worker }
143*635a8641SAndroid Build Coastguard Worker
Value(const char * in_string)144*635a8641SAndroid Build Coastguard Worker Value::Value(const char* in_string) : Value(std::string(in_string)) {}
145*635a8641SAndroid Build Coastguard Worker
Value(StringPiece in_string)146*635a8641SAndroid Build Coastguard Worker Value::Value(StringPiece in_string) : Value(std::string(in_string)) {}
147*635a8641SAndroid Build Coastguard Worker
Value(std::string && in_string)148*635a8641SAndroid Build Coastguard Worker Value::Value(std::string&& in_string) noexcept
149*635a8641SAndroid Build Coastguard Worker : type_(Type::STRING), string_value_(std::move(in_string)) {
150*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(string_value_));
151*635a8641SAndroid Build Coastguard Worker }
152*635a8641SAndroid Build Coastguard Worker
Value(const char16 * in_string16)153*635a8641SAndroid Build Coastguard Worker Value::Value(const char16* in_string16) : Value(StringPiece16(in_string16)) {}
154*635a8641SAndroid Build Coastguard Worker
Value(StringPiece16 in_string16)155*635a8641SAndroid Build Coastguard Worker Value::Value(StringPiece16 in_string16) : Value(UTF16ToUTF8(in_string16)) {}
156*635a8641SAndroid Build Coastguard Worker
Value(const BlobStorage & in_blob)157*635a8641SAndroid Build Coastguard Worker Value::Value(const BlobStorage& in_blob)
158*635a8641SAndroid Build Coastguard Worker : type_(Type::BINARY), binary_value_(in_blob) {}
159*635a8641SAndroid Build Coastguard Worker
Value(BlobStorage && in_blob)160*635a8641SAndroid Build Coastguard Worker Value::Value(BlobStorage&& in_blob) noexcept
161*635a8641SAndroid Build Coastguard Worker : type_(Type::BINARY), binary_value_(std::move(in_blob)) {}
162*635a8641SAndroid Build Coastguard Worker
Value(const DictStorage & in_dict)163*635a8641SAndroid Build Coastguard Worker Value::Value(const DictStorage& in_dict) : type_(Type::DICTIONARY), dict_() {
164*635a8641SAndroid Build Coastguard Worker dict_.reserve(in_dict.size());
165*635a8641SAndroid Build Coastguard Worker for (const auto& it : in_dict) {
166*635a8641SAndroid Build Coastguard Worker dict_.try_emplace(dict_.end(), it.first,
167*635a8641SAndroid Build Coastguard Worker std::make_unique<Value>(it.second->Clone()));
168*635a8641SAndroid Build Coastguard Worker }
169*635a8641SAndroid Build Coastguard Worker }
170*635a8641SAndroid Build Coastguard Worker
Value(DictStorage && in_dict)171*635a8641SAndroid Build Coastguard Worker Value::Value(DictStorage&& in_dict) noexcept
172*635a8641SAndroid Build Coastguard Worker : type_(Type::DICTIONARY), dict_(std::move(in_dict)) {}
173*635a8641SAndroid Build Coastguard Worker
Value(const ListStorage & in_list)174*635a8641SAndroid Build Coastguard Worker Value::Value(const ListStorage& in_list) : type_(Type::LIST), list_() {
175*635a8641SAndroid Build Coastguard Worker list_.reserve(in_list.size());
176*635a8641SAndroid Build Coastguard Worker for (const auto& val : in_list)
177*635a8641SAndroid Build Coastguard Worker list_.emplace_back(val.Clone());
178*635a8641SAndroid Build Coastguard Worker }
179*635a8641SAndroid Build Coastguard Worker
Value(ListStorage && in_list)180*635a8641SAndroid Build Coastguard Worker Value::Value(ListStorage&& in_list) noexcept
181*635a8641SAndroid Build Coastguard Worker : type_(Type::LIST), list_(std::move(in_list)) {}
182*635a8641SAndroid Build Coastguard Worker
operator =(Value && that)183*635a8641SAndroid Build Coastguard Worker Value& Value::operator=(Value&& that) noexcept {
184*635a8641SAndroid Build Coastguard Worker InternalCleanup();
185*635a8641SAndroid Build Coastguard Worker InternalMoveConstructFrom(std::move(that));
186*635a8641SAndroid Build Coastguard Worker
187*635a8641SAndroid Build Coastguard Worker return *this;
188*635a8641SAndroid Build Coastguard Worker }
189*635a8641SAndroid Build Coastguard Worker
Clone() const190*635a8641SAndroid Build Coastguard Worker Value Value::Clone() const {
191*635a8641SAndroid Build Coastguard Worker switch (type_) {
192*635a8641SAndroid Build Coastguard Worker case Type::NONE:
193*635a8641SAndroid Build Coastguard Worker return Value();
194*635a8641SAndroid Build Coastguard Worker case Type::BOOLEAN:
195*635a8641SAndroid Build Coastguard Worker return Value(bool_value_);
196*635a8641SAndroid Build Coastguard Worker case Type::INTEGER:
197*635a8641SAndroid Build Coastguard Worker return Value(int_value_);
198*635a8641SAndroid Build Coastguard Worker case Type::DOUBLE:
199*635a8641SAndroid Build Coastguard Worker return Value(double_value_);
200*635a8641SAndroid Build Coastguard Worker case Type::STRING:
201*635a8641SAndroid Build Coastguard Worker return Value(string_value_);
202*635a8641SAndroid Build Coastguard Worker case Type::BINARY:
203*635a8641SAndroid Build Coastguard Worker return Value(binary_value_);
204*635a8641SAndroid Build Coastguard Worker case Type::DICTIONARY:
205*635a8641SAndroid Build Coastguard Worker return Value(dict_);
206*635a8641SAndroid Build Coastguard Worker case Type::LIST:
207*635a8641SAndroid Build Coastguard Worker return Value(list_);
208*635a8641SAndroid Build Coastguard Worker }
209*635a8641SAndroid Build Coastguard Worker
210*635a8641SAndroid Build Coastguard Worker NOTREACHED();
211*635a8641SAndroid Build Coastguard Worker return Value();
212*635a8641SAndroid Build Coastguard Worker }
213*635a8641SAndroid Build Coastguard Worker
~Value()214*635a8641SAndroid Build Coastguard Worker Value::~Value() {
215*635a8641SAndroid Build Coastguard Worker InternalCleanup();
216*635a8641SAndroid Build Coastguard Worker }
217*635a8641SAndroid Build Coastguard Worker
218*635a8641SAndroid Build Coastguard Worker // static
GetTypeName(Value::Type type)219*635a8641SAndroid Build Coastguard Worker const char* Value::GetTypeName(Value::Type type) {
220*635a8641SAndroid Build Coastguard Worker DCHECK_GE(static_cast<int>(type), 0);
221*635a8641SAndroid Build Coastguard Worker DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames));
222*635a8641SAndroid Build Coastguard Worker return kTypeNames[static_cast<size_t>(type)];
223*635a8641SAndroid Build Coastguard Worker }
224*635a8641SAndroid Build Coastguard Worker
GetBool() const225*635a8641SAndroid Build Coastguard Worker bool Value::GetBool() const {
226*635a8641SAndroid Build Coastguard Worker CHECK(is_bool());
227*635a8641SAndroid Build Coastguard Worker return bool_value_;
228*635a8641SAndroid Build Coastguard Worker }
229*635a8641SAndroid Build Coastguard Worker
GetInt() const230*635a8641SAndroid Build Coastguard Worker int Value::GetInt() const {
231*635a8641SAndroid Build Coastguard Worker CHECK(is_int());
232*635a8641SAndroid Build Coastguard Worker return int_value_;
233*635a8641SAndroid Build Coastguard Worker }
234*635a8641SAndroid Build Coastguard Worker
GetDouble() const235*635a8641SAndroid Build Coastguard Worker double Value::GetDouble() const {
236*635a8641SAndroid Build Coastguard Worker if (is_double())
237*635a8641SAndroid Build Coastguard Worker return double_value_;
238*635a8641SAndroid Build Coastguard Worker if (is_int())
239*635a8641SAndroid Build Coastguard Worker return int_value_;
240*635a8641SAndroid Build Coastguard Worker CHECK(false);
241*635a8641SAndroid Build Coastguard Worker return 0.0;
242*635a8641SAndroid Build Coastguard Worker }
243*635a8641SAndroid Build Coastguard Worker
GetString() const244*635a8641SAndroid Build Coastguard Worker const std::string& Value::GetString() const {
245*635a8641SAndroid Build Coastguard Worker CHECK(is_string());
246*635a8641SAndroid Build Coastguard Worker return string_value_;
247*635a8641SAndroid Build Coastguard Worker }
248*635a8641SAndroid Build Coastguard Worker
GetBlob() const249*635a8641SAndroid Build Coastguard Worker const Value::BlobStorage& Value::GetBlob() const {
250*635a8641SAndroid Build Coastguard Worker CHECK(is_blob());
251*635a8641SAndroid Build Coastguard Worker return binary_value_;
252*635a8641SAndroid Build Coastguard Worker }
253*635a8641SAndroid Build Coastguard Worker
GetList()254*635a8641SAndroid Build Coastguard Worker Value::ListStorage& Value::GetList() {
255*635a8641SAndroid Build Coastguard Worker CHECK(is_list());
256*635a8641SAndroid Build Coastguard Worker return list_;
257*635a8641SAndroid Build Coastguard Worker }
258*635a8641SAndroid Build Coastguard Worker
GetList() const259*635a8641SAndroid Build Coastguard Worker const Value::ListStorage& Value::GetList() const {
260*635a8641SAndroid Build Coastguard Worker CHECK(is_list());
261*635a8641SAndroid Build Coastguard Worker return list_;
262*635a8641SAndroid Build Coastguard Worker }
263*635a8641SAndroid Build Coastguard Worker
FindKey(StringPiece key)264*635a8641SAndroid Build Coastguard Worker Value* Value::FindKey(StringPiece key) {
265*635a8641SAndroid Build Coastguard Worker return const_cast<Value*>(static_cast<const Value*>(this)->FindKey(key));
266*635a8641SAndroid Build Coastguard Worker }
267*635a8641SAndroid Build Coastguard Worker
FindKey(StringPiece key) const268*635a8641SAndroid Build Coastguard Worker const Value* Value::FindKey(StringPiece key) const {
269*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
270*635a8641SAndroid Build Coastguard Worker auto found = dict_.find(key);
271*635a8641SAndroid Build Coastguard Worker if (found == dict_.end())
272*635a8641SAndroid Build Coastguard Worker return nullptr;
273*635a8641SAndroid Build Coastguard Worker return found->second.get();
274*635a8641SAndroid Build Coastguard Worker }
275*635a8641SAndroid Build Coastguard Worker
FindKeyOfType(StringPiece key,Type type)276*635a8641SAndroid Build Coastguard Worker Value* Value::FindKeyOfType(StringPiece key, Type type) {
277*635a8641SAndroid Build Coastguard Worker return const_cast<Value*>(
278*635a8641SAndroid Build Coastguard Worker static_cast<const Value*>(this)->FindKeyOfType(key, type));
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker
FindKeyOfType(StringPiece key,Type type) const281*635a8641SAndroid Build Coastguard Worker const Value* Value::FindKeyOfType(StringPiece key, Type type) const {
282*635a8641SAndroid Build Coastguard Worker const Value* result = FindKey(key);
283*635a8641SAndroid Build Coastguard Worker if (!result || result->type() != type)
284*635a8641SAndroid Build Coastguard Worker return nullptr;
285*635a8641SAndroid Build Coastguard Worker return result;
286*635a8641SAndroid Build Coastguard Worker }
287*635a8641SAndroid Build Coastguard Worker
RemoveKey(StringPiece key)288*635a8641SAndroid Build Coastguard Worker bool Value::RemoveKey(StringPiece key) {
289*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
290*635a8641SAndroid Build Coastguard Worker // NOTE: Can't directly return dict_->erase(key) due to MSVC warning C4800.
291*635a8641SAndroid Build Coastguard Worker return dict_.erase(key) != 0;
292*635a8641SAndroid Build Coastguard Worker }
293*635a8641SAndroid Build Coastguard Worker
SetKey(StringPiece key,Value value)294*635a8641SAndroid Build Coastguard Worker Value* Value::SetKey(StringPiece key, Value value) {
295*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
296*635a8641SAndroid Build Coastguard Worker // NOTE: We can't use |insert_or_assign| here, as only |try_emplace| does
297*635a8641SAndroid Build Coastguard Worker // an explicit conversion from StringPiece to std::string if necessary.
298*635a8641SAndroid Build Coastguard Worker auto val_ptr = std::make_unique<Value>(std::move(value));
299*635a8641SAndroid Build Coastguard Worker auto result = dict_.try_emplace(key, std::move(val_ptr));
300*635a8641SAndroid Build Coastguard Worker if (!result.second) {
301*635a8641SAndroid Build Coastguard Worker // val_ptr is guaranteed to be still intact at this point.
302*635a8641SAndroid Build Coastguard Worker result.first->second = std::move(val_ptr);
303*635a8641SAndroid Build Coastguard Worker }
304*635a8641SAndroid Build Coastguard Worker return result.first->second.get();
305*635a8641SAndroid Build Coastguard Worker }
306*635a8641SAndroid Build Coastguard Worker
SetKey(std::string && key,Value value)307*635a8641SAndroid Build Coastguard Worker Value* Value::SetKey(std::string&& key, Value value) {
308*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
309*635a8641SAndroid Build Coastguard Worker return dict_
310*635a8641SAndroid Build Coastguard Worker .insert_or_assign(std::move(key),
311*635a8641SAndroid Build Coastguard Worker std::make_unique<Value>(std::move(value)))
312*635a8641SAndroid Build Coastguard Worker .first->second.get();
313*635a8641SAndroid Build Coastguard Worker }
314*635a8641SAndroid Build Coastguard Worker
SetKey(const char * key,Value value)315*635a8641SAndroid Build Coastguard Worker Value* Value::SetKey(const char* key, Value value) {
316*635a8641SAndroid Build Coastguard Worker return SetKey(StringPiece(key), std::move(value));
317*635a8641SAndroid Build Coastguard Worker }
318*635a8641SAndroid Build Coastguard Worker
FindPath(std::initializer_list<StringPiece> path)319*635a8641SAndroid Build Coastguard Worker Value* Value::FindPath(std::initializer_list<StringPiece> path) {
320*635a8641SAndroid Build Coastguard Worker return const_cast<Value*>(const_cast<const Value*>(this)->FindPath(path));
321*635a8641SAndroid Build Coastguard Worker }
322*635a8641SAndroid Build Coastguard Worker
FindPath(span<const StringPiece> path)323*635a8641SAndroid Build Coastguard Worker Value* Value::FindPath(span<const StringPiece> path) {
324*635a8641SAndroid Build Coastguard Worker return const_cast<Value*>(const_cast<const Value*>(this)->FindPath(path));
325*635a8641SAndroid Build Coastguard Worker }
326*635a8641SAndroid Build Coastguard Worker
FindPath(std::initializer_list<StringPiece> path) const327*635a8641SAndroid Build Coastguard Worker const Value* Value::FindPath(std::initializer_list<StringPiece> path) const {
328*635a8641SAndroid Build Coastguard Worker DCHECK_GE(path.size(), 2u) << "Use FindKey() for a path of length 1.";
329*635a8641SAndroid Build Coastguard Worker return FindPath(make_span(path.begin(), path.size()));
330*635a8641SAndroid Build Coastguard Worker }
331*635a8641SAndroid Build Coastguard Worker
FindPath(span<const StringPiece> path) const332*635a8641SAndroid Build Coastguard Worker const Value* Value::FindPath(span<const StringPiece> path) const {
333*635a8641SAndroid Build Coastguard Worker const Value* cur = this;
334*635a8641SAndroid Build Coastguard Worker for (const StringPiece component : path) {
335*635a8641SAndroid Build Coastguard Worker if (!cur->is_dict() || (cur = cur->FindKey(component)) == nullptr)
336*635a8641SAndroid Build Coastguard Worker return nullptr;
337*635a8641SAndroid Build Coastguard Worker }
338*635a8641SAndroid Build Coastguard Worker return cur;
339*635a8641SAndroid Build Coastguard Worker }
340*635a8641SAndroid Build Coastguard Worker
FindPathOfType(std::initializer_list<StringPiece> path,Type type)341*635a8641SAndroid Build Coastguard Worker Value* Value::FindPathOfType(std::initializer_list<StringPiece> path,
342*635a8641SAndroid Build Coastguard Worker Type type) {
343*635a8641SAndroid Build Coastguard Worker return const_cast<Value*>(
344*635a8641SAndroid Build Coastguard Worker const_cast<const Value*>(this)->FindPathOfType(path, type));
345*635a8641SAndroid Build Coastguard Worker }
346*635a8641SAndroid Build Coastguard Worker
FindPathOfType(span<const StringPiece> path,Type type)347*635a8641SAndroid Build Coastguard Worker Value* Value::FindPathOfType(span<const StringPiece> path, Type type) {
348*635a8641SAndroid Build Coastguard Worker return const_cast<Value*>(
349*635a8641SAndroid Build Coastguard Worker const_cast<const Value*>(this)->FindPathOfType(path, type));
350*635a8641SAndroid Build Coastguard Worker }
351*635a8641SAndroid Build Coastguard Worker
FindPathOfType(std::initializer_list<StringPiece> path,Type type) const352*635a8641SAndroid Build Coastguard Worker const Value* Value::FindPathOfType(std::initializer_list<StringPiece> path,
353*635a8641SAndroid Build Coastguard Worker Type type) const {
354*635a8641SAndroid Build Coastguard Worker DCHECK_GE(path.size(), 2u) << "Use FindKeyOfType() for a path of length 1.";
355*635a8641SAndroid Build Coastguard Worker return FindPathOfType(make_span(path.begin(), path.size()), type);
356*635a8641SAndroid Build Coastguard Worker }
357*635a8641SAndroid Build Coastguard Worker
FindPathOfType(span<const StringPiece> path,Type type) const358*635a8641SAndroid Build Coastguard Worker const Value* Value::FindPathOfType(span<const StringPiece> path,
359*635a8641SAndroid Build Coastguard Worker Type type) const {
360*635a8641SAndroid Build Coastguard Worker const Value* result = FindPath(path);
361*635a8641SAndroid Build Coastguard Worker if (!result || result->type() != type)
362*635a8641SAndroid Build Coastguard Worker return nullptr;
363*635a8641SAndroid Build Coastguard Worker return result;
364*635a8641SAndroid Build Coastguard Worker }
365*635a8641SAndroid Build Coastguard Worker
SetPath(std::initializer_list<StringPiece> path,Value value)366*635a8641SAndroid Build Coastguard Worker Value* Value::SetPath(std::initializer_list<StringPiece> path, Value value) {
367*635a8641SAndroid Build Coastguard Worker DCHECK_GE(path.size(), 2u) << "Use SetKey() for a path of length 1.";
368*635a8641SAndroid Build Coastguard Worker return SetPath(make_span(path.begin(), path.size()), std::move(value));
369*635a8641SAndroid Build Coastguard Worker }
370*635a8641SAndroid Build Coastguard Worker
SetPath(span<const StringPiece> path,Value value)371*635a8641SAndroid Build Coastguard Worker Value* Value::SetPath(span<const StringPiece> path, Value value) {
372*635a8641SAndroid Build Coastguard Worker DCHECK_NE(path.begin(), path.end()); // Can't be empty path.
373*635a8641SAndroid Build Coastguard Worker
374*635a8641SAndroid Build Coastguard Worker // Walk/construct intermediate dictionaries. The last element requires
375*635a8641SAndroid Build Coastguard Worker // special handling so skip it in this loop.
376*635a8641SAndroid Build Coastguard Worker Value* cur = this;
377*635a8641SAndroid Build Coastguard Worker const StringPiece* cur_path = path.begin();
378*635a8641SAndroid Build Coastguard Worker for (; (cur_path + 1) < path.end(); ++cur_path) {
379*635a8641SAndroid Build Coastguard Worker if (!cur->is_dict())
380*635a8641SAndroid Build Coastguard Worker return nullptr;
381*635a8641SAndroid Build Coastguard Worker
382*635a8641SAndroid Build Coastguard Worker // Use lower_bound to avoid doing the search twice for missing keys.
383*635a8641SAndroid Build Coastguard Worker const StringPiece path_component = *cur_path;
384*635a8641SAndroid Build Coastguard Worker auto found = cur->dict_.lower_bound(path_component);
385*635a8641SAndroid Build Coastguard Worker if (found == cur->dict_.end() || found->first != path_component) {
386*635a8641SAndroid Build Coastguard Worker // No key found, insert one.
387*635a8641SAndroid Build Coastguard Worker auto inserted = cur->dict_.try_emplace(
388*635a8641SAndroid Build Coastguard Worker found, path_component, std::make_unique<Value>(Type::DICTIONARY));
389*635a8641SAndroid Build Coastguard Worker cur = inserted->second.get();
390*635a8641SAndroid Build Coastguard Worker } else {
391*635a8641SAndroid Build Coastguard Worker cur = found->second.get();
392*635a8641SAndroid Build Coastguard Worker }
393*635a8641SAndroid Build Coastguard Worker }
394*635a8641SAndroid Build Coastguard Worker
395*635a8641SAndroid Build Coastguard Worker // "cur" will now contain the last dictionary to insert or replace into.
396*635a8641SAndroid Build Coastguard Worker if (!cur->is_dict())
397*635a8641SAndroid Build Coastguard Worker return nullptr;
398*635a8641SAndroid Build Coastguard Worker return cur->SetKey(*cur_path, std::move(value));
399*635a8641SAndroid Build Coastguard Worker }
400*635a8641SAndroid Build Coastguard Worker
RemovePath(std::initializer_list<StringPiece> path)401*635a8641SAndroid Build Coastguard Worker bool Value::RemovePath(std::initializer_list<StringPiece> path) {
402*635a8641SAndroid Build Coastguard Worker DCHECK_GE(path.size(), 2u) << "Use RemoveKey() for a path of length 1.";
403*635a8641SAndroid Build Coastguard Worker return RemovePath(make_span(path.begin(), path.size()));
404*635a8641SAndroid Build Coastguard Worker }
405*635a8641SAndroid Build Coastguard Worker
RemovePath(span<const StringPiece> path)406*635a8641SAndroid Build Coastguard Worker bool Value::RemovePath(span<const StringPiece> path) {
407*635a8641SAndroid Build Coastguard Worker if (!is_dict() || path.empty())
408*635a8641SAndroid Build Coastguard Worker return false;
409*635a8641SAndroid Build Coastguard Worker
410*635a8641SAndroid Build Coastguard Worker if (path.size() == 1)
411*635a8641SAndroid Build Coastguard Worker return RemoveKey(path[0]);
412*635a8641SAndroid Build Coastguard Worker
413*635a8641SAndroid Build Coastguard Worker auto found = dict_.find(path[0]);
414*635a8641SAndroid Build Coastguard Worker if (found == dict_.end() || !found->second->is_dict())
415*635a8641SAndroid Build Coastguard Worker return false;
416*635a8641SAndroid Build Coastguard Worker
417*635a8641SAndroid Build Coastguard Worker bool removed = found->second->RemovePath(path.subspan(1));
418*635a8641SAndroid Build Coastguard Worker if (removed && found->second->dict_.empty())
419*635a8641SAndroid Build Coastguard Worker dict_.erase(found);
420*635a8641SAndroid Build Coastguard Worker
421*635a8641SAndroid Build Coastguard Worker return removed;
422*635a8641SAndroid Build Coastguard Worker }
423*635a8641SAndroid Build Coastguard Worker
DictItems()424*635a8641SAndroid Build Coastguard Worker Value::dict_iterator_proxy Value::DictItems() {
425*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
426*635a8641SAndroid Build Coastguard Worker return dict_iterator_proxy(&dict_);
427*635a8641SAndroid Build Coastguard Worker }
428*635a8641SAndroid Build Coastguard Worker
DictItems() const429*635a8641SAndroid Build Coastguard Worker Value::const_dict_iterator_proxy Value::DictItems() const {
430*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
431*635a8641SAndroid Build Coastguard Worker return const_dict_iterator_proxy(&dict_);
432*635a8641SAndroid Build Coastguard Worker }
433*635a8641SAndroid Build Coastguard Worker
DictSize() const434*635a8641SAndroid Build Coastguard Worker size_t Value::DictSize() const {
435*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
436*635a8641SAndroid Build Coastguard Worker return dict_.size();
437*635a8641SAndroid Build Coastguard Worker }
438*635a8641SAndroid Build Coastguard Worker
DictEmpty() const439*635a8641SAndroid Build Coastguard Worker bool Value::DictEmpty() const {
440*635a8641SAndroid Build Coastguard Worker CHECK(is_dict());
441*635a8641SAndroid Build Coastguard Worker return dict_.empty();
442*635a8641SAndroid Build Coastguard Worker }
443*635a8641SAndroid Build Coastguard Worker
GetAsBoolean(bool * out_value) const444*635a8641SAndroid Build Coastguard Worker bool Value::GetAsBoolean(bool* out_value) const {
445*635a8641SAndroid Build Coastguard Worker if (out_value && is_bool()) {
446*635a8641SAndroid Build Coastguard Worker *out_value = bool_value_;
447*635a8641SAndroid Build Coastguard Worker return true;
448*635a8641SAndroid Build Coastguard Worker }
449*635a8641SAndroid Build Coastguard Worker return is_bool();
450*635a8641SAndroid Build Coastguard Worker }
451*635a8641SAndroid Build Coastguard Worker
GetAsInteger(int * out_value) const452*635a8641SAndroid Build Coastguard Worker bool Value::GetAsInteger(int* out_value) const {
453*635a8641SAndroid Build Coastguard Worker if (out_value && is_int()) {
454*635a8641SAndroid Build Coastguard Worker *out_value = int_value_;
455*635a8641SAndroid Build Coastguard Worker return true;
456*635a8641SAndroid Build Coastguard Worker }
457*635a8641SAndroid Build Coastguard Worker return is_int();
458*635a8641SAndroid Build Coastguard Worker }
459*635a8641SAndroid Build Coastguard Worker
GetAsDouble(double * out_value) const460*635a8641SAndroid Build Coastguard Worker bool Value::GetAsDouble(double* out_value) const {
461*635a8641SAndroid Build Coastguard Worker if (out_value && is_double()) {
462*635a8641SAndroid Build Coastguard Worker *out_value = double_value_;
463*635a8641SAndroid Build Coastguard Worker return true;
464*635a8641SAndroid Build Coastguard Worker } else if (out_value && is_int()) {
465*635a8641SAndroid Build Coastguard Worker // Allow promotion from int to double.
466*635a8641SAndroid Build Coastguard Worker *out_value = int_value_;
467*635a8641SAndroid Build Coastguard Worker return true;
468*635a8641SAndroid Build Coastguard Worker }
469*635a8641SAndroid Build Coastguard Worker return is_double() || is_int();
470*635a8641SAndroid Build Coastguard Worker }
471*635a8641SAndroid Build Coastguard Worker
GetAsString(std::string * out_value) const472*635a8641SAndroid Build Coastguard Worker bool Value::GetAsString(std::string* out_value) const {
473*635a8641SAndroid Build Coastguard Worker if (out_value && is_string()) {
474*635a8641SAndroid Build Coastguard Worker *out_value = string_value_;
475*635a8641SAndroid Build Coastguard Worker return true;
476*635a8641SAndroid Build Coastguard Worker }
477*635a8641SAndroid Build Coastguard Worker return is_string();
478*635a8641SAndroid Build Coastguard Worker }
479*635a8641SAndroid Build Coastguard Worker
GetAsString(string16 * out_value) const480*635a8641SAndroid Build Coastguard Worker bool Value::GetAsString(string16* out_value) const {
481*635a8641SAndroid Build Coastguard Worker if (out_value && is_string()) {
482*635a8641SAndroid Build Coastguard Worker *out_value = UTF8ToUTF16(string_value_);
483*635a8641SAndroid Build Coastguard Worker return true;
484*635a8641SAndroid Build Coastguard Worker }
485*635a8641SAndroid Build Coastguard Worker return is_string();
486*635a8641SAndroid Build Coastguard Worker }
487*635a8641SAndroid Build Coastguard Worker
GetAsString(const Value ** out_value) const488*635a8641SAndroid Build Coastguard Worker bool Value::GetAsString(const Value** out_value) const {
489*635a8641SAndroid Build Coastguard Worker if (out_value && is_string()) {
490*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const Value*>(this);
491*635a8641SAndroid Build Coastguard Worker return true;
492*635a8641SAndroid Build Coastguard Worker }
493*635a8641SAndroid Build Coastguard Worker return is_string();
494*635a8641SAndroid Build Coastguard Worker }
495*635a8641SAndroid Build Coastguard Worker
GetAsString(StringPiece * out_value) const496*635a8641SAndroid Build Coastguard Worker bool Value::GetAsString(StringPiece* out_value) const {
497*635a8641SAndroid Build Coastguard Worker if (out_value && is_string()) {
498*635a8641SAndroid Build Coastguard Worker *out_value = string_value_;
499*635a8641SAndroid Build Coastguard Worker return true;
500*635a8641SAndroid Build Coastguard Worker }
501*635a8641SAndroid Build Coastguard Worker return is_string();
502*635a8641SAndroid Build Coastguard Worker }
503*635a8641SAndroid Build Coastguard Worker
GetAsList(ListValue ** out_value)504*635a8641SAndroid Build Coastguard Worker bool Value::GetAsList(ListValue** out_value) {
505*635a8641SAndroid Build Coastguard Worker if (out_value && is_list()) {
506*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<ListValue*>(this);
507*635a8641SAndroid Build Coastguard Worker return true;
508*635a8641SAndroid Build Coastguard Worker }
509*635a8641SAndroid Build Coastguard Worker return is_list();
510*635a8641SAndroid Build Coastguard Worker }
511*635a8641SAndroid Build Coastguard Worker
GetAsList(const ListValue ** out_value) const512*635a8641SAndroid Build Coastguard Worker bool Value::GetAsList(const ListValue** out_value) const {
513*635a8641SAndroid Build Coastguard Worker if (out_value && is_list()) {
514*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const ListValue*>(this);
515*635a8641SAndroid Build Coastguard Worker return true;
516*635a8641SAndroid Build Coastguard Worker }
517*635a8641SAndroid Build Coastguard Worker return is_list();
518*635a8641SAndroid Build Coastguard Worker }
519*635a8641SAndroid Build Coastguard Worker
GetAsDictionary(DictionaryValue ** out_value)520*635a8641SAndroid Build Coastguard Worker bool Value::GetAsDictionary(DictionaryValue** out_value) {
521*635a8641SAndroid Build Coastguard Worker if (out_value && is_dict()) {
522*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<DictionaryValue*>(this);
523*635a8641SAndroid Build Coastguard Worker return true;
524*635a8641SAndroid Build Coastguard Worker }
525*635a8641SAndroid Build Coastguard Worker return is_dict();
526*635a8641SAndroid Build Coastguard Worker }
527*635a8641SAndroid Build Coastguard Worker
GetAsDictionary(const DictionaryValue ** out_value) const528*635a8641SAndroid Build Coastguard Worker bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
529*635a8641SAndroid Build Coastguard Worker if (out_value && is_dict()) {
530*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const DictionaryValue*>(this);
531*635a8641SAndroid Build Coastguard Worker return true;
532*635a8641SAndroid Build Coastguard Worker }
533*635a8641SAndroid Build Coastguard Worker return is_dict();
534*635a8641SAndroid Build Coastguard Worker }
535*635a8641SAndroid Build Coastguard Worker
DeepCopy() const536*635a8641SAndroid Build Coastguard Worker Value* Value::DeepCopy() const {
537*635a8641SAndroid Build Coastguard Worker return new Value(Clone());
538*635a8641SAndroid Build Coastguard Worker }
539*635a8641SAndroid Build Coastguard Worker
CreateDeepCopy() const540*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> Value::CreateDeepCopy() const {
541*635a8641SAndroid Build Coastguard Worker return std::make_unique<Value>(Clone());
542*635a8641SAndroid Build Coastguard Worker }
543*635a8641SAndroid Build Coastguard Worker
operator ==(const Value & lhs,const Value & rhs)544*635a8641SAndroid Build Coastguard Worker bool operator==(const Value& lhs, const Value& rhs) {
545*635a8641SAndroid Build Coastguard Worker if (lhs.type_ != rhs.type_)
546*635a8641SAndroid Build Coastguard Worker return false;
547*635a8641SAndroid Build Coastguard Worker
548*635a8641SAndroid Build Coastguard Worker switch (lhs.type_) {
549*635a8641SAndroid Build Coastguard Worker case Value::Type::NONE:
550*635a8641SAndroid Build Coastguard Worker return true;
551*635a8641SAndroid Build Coastguard Worker case Value::Type::BOOLEAN:
552*635a8641SAndroid Build Coastguard Worker return lhs.bool_value_ == rhs.bool_value_;
553*635a8641SAndroid Build Coastguard Worker case Value::Type::INTEGER:
554*635a8641SAndroid Build Coastguard Worker return lhs.int_value_ == rhs.int_value_;
555*635a8641SAndroid Build Coastguard Worker case Value::Type::DOUBLE:
556*635a8641SAndroid Build Coastguard Worker return lhs.double_value_ == rhs.double_value_;
557*635a8641SAndroid Build Coastguard Worker case Value::Type::STRING:
558*635a8641SAndroid Build Coastguard Worker return lhs.string_value_ == rhs.string_value_;
559*635a8641SAndroid Build Coastguard Worker case Value::Type::BINARY:
560*635a8641SAndroid Build Coastguard Worker return lhs.binary_value_ == rhs.binary_value_;
561*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
562*635a8641SAndroid Build Coastguard Worker // are completely inlined.
563*635a8641SAndroid Build Coastguard Worker case Value::Type::DICTIONARY:
564*635a8641SAndroid Build Coastguard Worker if (lhs.dict_.size() != rhs.dict_.size())
565*635a8641SAndroid Build Coastguard Worker return false;
566*635a8641SAndroid Build Coastguard Worker return std::equal(std::begin(lhs.dict_), std::end(lhs.dict_),
567*635a8641SAndroid Build Coastguard Worker std::begin(rhs.dict_),
568*635a8641SAndroid Build Coastguard Worker [](const auto& u, const auto& v) {
569*635a8641SAndroid Build Coastguard Worker return std::tie(u.first, *u.second) ==
570*635a8641SAndroid Build Coastguard Worker std::tie(v.first, *v.second);
571*635a8641SAndroid Build Coastguard Worker });
572*635a8641SAndroid Build Coastguard Worker case Value::Type::LIST:
573*635a8641SAndroid Build Coastguard Worker return lhs.list_ == rhs.list_;
574*635a8641SAndroid Build Coastguard Worker }
575*635a8641SAndroid Build Coastguard Worker
576*635a8641SAndroid Build Coastguard Worker NOTREACHED();
577*635a8641SAndroid Build Coastguard Worker return false;
578*635a8641SAndroid Build Coastguard Worker }
579*635a8641SAndroid Build Coastguard Worker
operator !=(const Value & lhs,const Value & rhs)580*635a8641SAndroid Build Coastguard Worker bool operator!=(const Value& lhs, const Value& rhs) {
581*635a8641SAndroid Build Coastguard Worker return !(lhs == rhs);
582*635a8641SAndroid Build Coastguard Worker }
583*635a8641SAndroid Build Coastguard Worker
operator <(const Value & lhs,const Value & rhs)584*635a8641SAndroid Build Coastguard Worker bool operator<(const Value& lhs, const Value& rhs) {
585*635a8641SAndroid Build Coastguard Worker if (lhs.type_ != rhs.type_)
586*635a8641SAndroid Build Coastguard Worker return lhs.type_ < rhs.type_;
587*635a8641SAndroid Build Coastguard Worker
588*635a8641SAndroid Build Coastguard Worker switch (lhs.type_) {
589*635a8641SAndroid Build Coastguard Worker case Value::Type::NONE:
590*635a8641SAndroid Build Coastguard Worker return false;
591*635a8641SAndroid Build Coastguard Worker case Value::Type::BOOLEAN:
592*635a8641SAndroid Build Coastguard Worker return lhs.bool_value_ < rhs.bool_value_;
593*635a8641SAndroid Build Coastguard Worker case Value::Type::INTEGER:
594*635a8641SAndroid Build Coastguard Worker return lhs.int_value_ < rhs.int_value_;
595*635a8641SAndroid Build Coastguard Worker case Value::Type::DOUBLE:
596*635a8641SAndroid Build Coastguard Worker return lhs.double_value_ < rhs.double_value_;
597*635a8641SAndroid Build Coastguard Worker case Value::Type::STRING:
598*635a8641SAndroid Build Coastguard Worker return lhs.string_value_ < rhs.string_value_;
599*635a8641SAndroid Build Coastguard Worker case Value::Type::BINARY:
600*635a8641SAndroid Build Coastguard Worker return lhs.binary_value_ < rhs.binary_value_;
601*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
602*635a8641SAndroid Build Coastguard Worker // are completely inlined.
603*635a8641SAndroid Build Coastguard Worker case Value::Type::DICTIONARY:
604*635a8641SAndroid Build Coastguard Worker return std::lexicographical_compare(
605*635a8641SAndroid Build Coastguard Worker std::begin(lhs.dict_), std::end(lhs.dict_), std::begin(rhs.dict_),
606*635a8641SAndroid Build Coastguard Worker std::end(rhs.dict_),
607*635a8641SAndroid Build Coastguard Worker [](const Value::DictStorage::value_type& u,
608*635a8641SAndroid Build Coastguard Worker const Value::DictStorage::value_type& v) {
609*635a8641SAndroid Build Coastguard Worker return std::tie(u.first, *u.second) < std::tie(v.first, *v.second);
610*635a8641SAndroid Build Coastguard Worker });
611*635a8641SAndroid Build Coastguard Worker case Value::Type::LIST:
612*635a8641SAndroid Build Coastguard Worker return lhs.list_ < rhs.list_;
613*635a8641SAndroid Build Coastguard Worker }
614*635a8641SAndroid Build Coastguard Worker
615*635a8641SAndroid Build Coastguard Worker NOTREACHED();
616*635a8641SAndroid Build Coastguard Worker return false;
617*635a8641SAndroid Build Coastguard Worker }
618*635a8641SAndroid Build Coastguard Worker
operator >(const Value & lhs,const Value & rhs)619*635a8641SAndroid Build Coastguard Worker bool operator>(const Value& lhs, const Value& rhs) {
620*635a8641SAndroid Build Coastguard Worker return rhs < lhs;
621*635a8641SAndroid Build Coastguard Worker }
622*635a8641SAndroid Build Coastguard Worker
operator <=(const Value & lhs,const Value & rhs)623*635a8641SAndroid Build Coastguard Worker bool operator<=(const Value& lhs, const Value& rhs) {
624*635a8641SAndroid Build Coastguard Worker return !(rhs < lhs);
625*635a8641SAndroid Build Coastguard Worker }
626*635a8641SAndroid Build Coastguard Worker
operator >=(const Value & lhs,const Value & rhs)627*635a8641SAndroid Build Coastguard Worker bool operator>=(const Value& lhs, const Value& rhs) {
628*635a8641SAndroid Build Coastguard Worker return !(lhs < rhs);
629*635a8641SAndroid Build Coastguard Worker }
630*635a8641SAndroid Build Coastguard Worker
Equals(const Value * other) const631*635a8641SAndroid Build Coastguard Worker bool Value::Equals(const Value* other) const {
632*635a8641SAndroid Build Coastguard Worker DCHECK(other);
633*635a8641SAndroid Build Coastguard Worker return *this == *other;
634*635a8641SAndroid Build Coastguard Worker }
635*635a8641SAndroid Build Coastguard Worker
636*635a8641SAndroid Build Coastguard Worker // Unsupported in libchrome
637*635a8641SAndroid Build Coastguard Worker // size_t Value::EstimateMemoryUsage() const {
638*635a8641SAndroid Build Coastguard Worker // switch (type_) {
639*635a8641SAndroid Build Coastguard Worker // case Type::STRING:
640*635a8641SAndroid Build Coastguard Worker // return base::trace_event::EstimateMemoryUsage(string_value_);
641*635a8641SAndroid Build Coastguard Worker // case Type::BINARY:
642*635a8641SAndroid Build Coastguard Worker // return base::trace_event::EstimateMemoryUsage(binary_value_);
643*635a8641SAndroid Build Coastguard Worker // case Type::DICTIONARY:
644*635a8641SAndroid Build Coastguard Worker // return base::trace_event::EstimateMemoryUsage(dict_);
645*635a8641SAndroid Build Coastguard Worker // case Type::LIST:
646*635a8641SAndroid Build Coastguard Worker // return base::trace_event::EstimateMemoryUsage(list_);
647*635a8641SAndroid Build Coastguard Worker // default:
648*635a8641SAndroid Build Coastguard Worker // return 0;
649*635a8641SAndroid Build Coastguard Worker // }
650*635a8641SAndroid Build Coastguard Worker // }
651*635a8641SAndroid Build Coastguard Worker
InternalMoveConstructFrom(Value && that)652*635a8641SAndroid Build Coastguard Worker void Value::InternalMoveConstructFrom(Value&& that) {
653*635a8641SAndroid Build Coastguard Worker type_ = that.type_;
654*635a8641SAndroid Build Coastguard Worker
655*635a8641SAndroid Build Coastguard Worker switch (type_) {
656*635a8641SAndroid Build Coastguard Worker case Type::NONE:
657*635a8641SAndroid Build Coastguard Worker return;
658*635a8641SAndroid Build Coastguard Worker case Type::BOOLEAN:
659*635a8641SAndroid Build Coastguard Worker bool_value_ = that.bool_value_;
660*635a8641SAndroid Build Coastguard Worker return;
661*635a8641SAndroid Build Coastguard Worker case Type::INTEGER:
662*635a8641SAndroid Build Coastguard Worker int_value_ = that.int_value_;
663*635a8641SAndroid Build Coastguard Worker return;
664*635a8641SAndroid Build Coastguard Worker case Type::DOUBLE:
665*635a8641SAndroid Build Coastguard Worker double_value_ = that.double_value_;
666*635a8641SAndroid Build Coastguard Worker return;
667*635a8641SAndroid Build Coastguard Worker case Type::STRING:
668*635a8641SAndroid Build Coastguard Worker new (&string_value_) std::string(std::move(that.string_value_));
669*635a8641SAndroid Build Coastguard Worker return;
670*635a8641SAndroid Build Coastguard Worker case Type::BINARY:
671*635a8641SAndroid Build Coastguard Worker new (&binary_value_) BlobStorage(std::move(that.binary_value_));
672*635a8641SAndroid Build Coastguard Worker return;
673*635a8641SAndroid Build Coastguard Worker case Type::DICTIONARY:
674*635a8641SAndroid Build Coastguard Worker new (&dict_) DictStorage(std::move(that.dict_));
675*635a8641SAndroid Build Coastguard Worker return;
676*635a8641SAndroid Build Coastguard Worker case Type::LIST:
677*635a8641SAndroid Build Coastguard Worker new (&list_) ListStorage(std::move(that.list_));
678*635a8641SAndroid Build Coastguard Worker return;
679*635a8641SAndroid Build Coastguard Worker }
680*635a8641SAndroid Build Coastguard Worker }
681*635a8641SAndroid Build Coastguard Worker
InternalCleanup()682*635a8641SAndroid Build Coastguard Worker void Value::InternalCleanup() {
683*635a8641SAndroid Build Coastguard Worker switch (type_) {
684*635a8641SAndroid Build Coastguard Worker case Type::NONE:
685*635a8641SAndroid Build Coastguard Worker case Type::BOOLEAN:
686*635a8641SAndroid Build Coastguard Worker case Type::INTEGER:
687*635a8641SAndroid Build Coastguard Worker case Type::DOUBLE:
688*635a8641SAndroid Build Coastguard Worker // Nothing to do
689*635a8641SAndroid Build Coastguard Worker return;
690*635a8641SAndroid Build Coastguard Worker
691*635a8641SAndroid Build Coastguard Worker case Type::STRING:
692*635a8641SAndroid Build Coastguard Worker string_value_.~basic_string();
693*635a8641SAndroid Build Coastguard Worker return;
694*635a8641SAndroid Build Coastguard Worker case Type::BINARY:
695*635a8641SAndroid Build Coastguard Worker binary_value_.~BlobStorage();
696*635a8641SAndroid Build Coastguard Worker return;
697*635a8641SAndroid Build Coastguard Worker case Type::DICTIONARY:
698*635a8641SAndroid Build Coastguard Worker dict_.~DictStorage();
699*635a8641SAndroid Build Coastguard Worker return;
700*635a8641SAndroid Build Coastguard Worker case Type::LIST:
701*635a8641SAndroid Build Coastguard Worker list_.~ListStorage();
702*635a8641SAndroid Build Coastguard Worker return;
703*635a8641SAndroid Build Coastguard Worker }
704*635a8641SAndroid Build Coastguard Worker }
705*635a8641SAndroid Build Coastguard Worker
706*635a8641SAndroid Build Coastguard Worker ///////////////////// DictionaryValue ////////////////////
707*635a8641SAndroid Build Coastguard Worker
708*635a8641SAndroid Build Coastguard Worker // static
From(std::unique_ptr<Value> value)709*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> DictionaryValue::From(
710*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> value) {
711*635a8641SAndroid Build Coastguard Worker DictionaryValue* out;
712*635a8641SAndroid Build Coastguard Worker if (value && value->GetAsDictionary(&out)) {
713*635a8641SAndroid Build Coastguard Worker ignore_result(value.release());
714*635a8641SAndroid Build Coastguard Worker return WrapUnique(out);
715*635a8641SAndroid Build Coastguard Worker }
716*635a8641SAndroid Build Coastguard Worker return nullptr;
717*635a8641SAndroid Build Coastguard Worker }
718*635a8641SAndroid Build Coastguard Worker
DictionaryValue()719*635a8641SAndroid Build Coastguard Worker DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {}
DictionaryValue(const DictStorage & in_dict)720*635a8641SAndroid Build Coastguard Worker DictionaryValue::DictionaryValue(const DictStorage& in_dict) : Value(in_dict) {}
DictionaryValue(DictStorage && in_dict)721*635a8641SAndroid Build Coastguard Worker DictionaryValue::DictionaryValue(DictStorage&& in_dict) noexcept
722*635a8641SAndroid Build Coastguard Worker : Value(std::move(in_dict)) {}
723*635a8641SAndroid Build Coastguard Worker
HasKey(StringPiece key) const724*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::HasKey(StringPiece key) const {
725*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(key));
726*635a8641SAndroid Build Coastguard Worker auto current_entry = dict_.find(key);
727*635a8641SAndroid Build Coastguard Worker DCHECK((current_entry == dict_.end()) || current_entry->second);
728*635a8641SAndroid Build Coastguard Worker return current_entry != dict_.end();
729*635a8641SAndroid Build Coastguard Worker }
730*635a8641SAndroid Build Coastguard Worker
Clear()731*635a8641SAndroid Build Coastguard Worker void DictionaryValue::Clear() {
732*635a8641SAndroid Build Coastguard Worker dict_.clear();
733*635a8641SAndroid Build Coastguard Worker }
734*635a8641SAndroid Build Coastguard Worker
Set(StringPiece path,std::unique_ptr<Value> in_value)735*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) {
736*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(path));
737*635a8641SAndroid Build Coastguard Worker DCHECK(in_value);
738*635a8641SAndroid Build Coastguard Worker
739*635a8641SAndroid Build Coastguard Worker StringPiece current_path(path);
740*635a8641SAndroid Build Coastguard Worker Value* current_dictionary = this;
741*635a8641SAndroid Build Coastguard Worker for (size_t delimiter_position = current_path.find('.');
742*635a8641SAndroid Build Coastguard Worker delimiter_position != StringPiece::npos;
743*635a8641SAndroid Build Coastguard Worker delimiter_position = current_path.find('.')) {
744*635a8641SAndroid Build Coastguard Worker // Assume that we're indexing into a dictionary.
745*635a8641SAndroid Build Coastguard Worker StringPiece key = current_path.substr(0, delimiter_position);
746*635a8641SAndroid Build Coastguard Worker Value* child_dictionary =
747*635a8641SAndroid Build Coastguard Worker current_dictionary->FindKeyOfType(key, Type::DICTIONARY);
748*635a8641SAndroid Build Coastguard Worker if (!child_dictionary) {
749*635a8641SAndroid Build Coastguard Worker child_dictionary =
750*635a8641SAndroid Build Coastguard Worker current_dictionary->SetKey(key, Value(Type::DICTIONARY));
751*635a8641SAndroid Build Coastguard Worker }
752*635a8641SAndroid Build Coastguard Worker
753*635a8641SAndroid Build Coastguard Worker current_dictionary = child_dictionary;
754*635a8641SAndroid Build Coastguard Worker current_path = current_path.substr(delimiter_position + 1);
755*635a8641SAndroid Build Coastguard Worker }
756*635a8641SAndroid Build Coastguard Worker
757*635a8641SAndroid Build Coastguard Worker return static_cast<DictionaryValue*>(current_dictionary)
758*635a8641SAndroid Build Coastguard Worker ->SetWithoutPathExpansion(current_path, std::move(in_value));
759*635a8641SAndroid Build Coastguard Worker }
760*635a8641SAndroid Build Coastguard Worker
SetBoolean(StringPiece path,bool in_value)761*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::SetBoolean(StringPiece path, bool in_value) {
762*635a8641SAndroid Build Coastguard Worker return Set(path, std::make_unique<Value>(in_value));
763*635a8641SAndroid Build Coastguard Worker }
764*635a8641SAndroid Build Coastguard Worker
SetInteger(StringPiece path,int in_value)765*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::SetInteger(StringPiece path, int in_value) {
766*635a8641SAndroid Build Coastguard Worker return Set(path, std::make_unique<Value>(in_value));
767*635a8641SAndroid Build Coastguard Worker }
768*635a8641SAndroid Build Coastguard Worker
SetDouble(StringPiece path,double in_value)769*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::SetDouble(StringPiece path, double in_value) {
770*635a8641SAndroid Build Coastguard Worker return Set(path, std::make_unique<Value>(in_value));
771*635a8641SAndroid Build Coastguard Worker }
772*635a8641SAndroid Build Coastguard Worker
SetString(StringPiece path,StringPiece in_value)773*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
774*635a8641SAndroid Build Coastguard Worker return Set(path, std::make_unique<Value>(in_value));
775*635a8641SAndroid Build Coastguard Worker }
776*635a8641SAndroid Build Coastguard Worker
SetString(StringPiece path,const string16 & in_value)777*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::SetString(StringPiece path, const string16& in_value) {
778*635a8641SAndroid Build Coastguard Worker return Set(path, std::make_unique<Value>(in_value));
779*635a8641SAndroid Build Coastguard Worker }
780*635a8641SAndroid Build Coastguard Worker
SetDictionary(StringPiece path,std::unique_ptr<DictionaryValue> in_value)781*635a8641SAndroid Build Coastguard Worker DictionaryValue* DictionaryValue::SetDictionary(
782*635a8641SAndroid Build Coastguard Worker StringPiece path,
783*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> in_value) {
784*635a8641SAndroid Build Coastguard Worker return static_cast<DictionaryValue*>(Set(path, std::move(in_value)));
785*635a8641SAndroid Build Coastguard Worker }
786*635a8641SAndroid Build Coastguard Worker
SetList(StringPiece path,std::unique_ptr<ListValue> in_value)787*635a8641SAndroid Build Coastguard Worker ListValue* DictionaryValue::SetList(StringPiece path,
788*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ListValue> in_value) {
789*635a8641SAndroid Build Coastguard Worker return static_cast<ListValue*>(Set(path, std::move(in_value)));
790*635a8641SAndroid Build Coastguard Worker }
791*635a8641SAndroid Build Coastguard Worker
SetWithoutPathExpansion(StringPiece key,std::unique_ptr<Value> in_value)792*635a8641SAndroid Build Coastguard Worker Value* DictionaryValue::SetWithoutPathExpansion(
793*635a8641SAndroid Build Coastguard Worker StringPiece key,
794*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> in_value) {
795*635a8641SAndroid Build Coastguard Worker // NOTE: We can't use |insert_or_assign| here, as only |try_emplace| does
796*635a8641SAndroid Build Coastguard Worker // an explicit conversion from StringPiece to std::string if necessary.
797*635a8641SAndroid Build Coastguard Worker auto result = dict_.try_emplace(key, std::move(in_value));
798*635a8641SAndroid Build Coastguard Worker if (!result.second) {
799*635a8641SAndroid Build Coastguard Worker // in_value is guaranteed to be still intact at this point.
800*635a8641SAndroid Build Coastguard Worker result.first->second = std::move(in_value);
801*635a8641SAndroid Build Coastguard Worker }
802*635a8641SAndroid Build Coastguard Worker return result.first->second.get();
803*635a8641SAndroid Build Coastguard Worker }
804*635a8641SAndroid Build Coastguard Worker
Get(StringPiece path,const Value ** out_value) const805*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::Get(StringPiece path,
806*635a8641SAndroid Build Coastguard Worker const Value** out_value) const {
807*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(path));
808*635a8641SAndroid Build Coastguard Worker StringPiece current_path(path);
809*635a8641SAndroid Build Coastguard Worker const DictionaryValue* current_dictionary = this;
810*635a8641SAndroid Build Coastguard Worker for (size_t delimiter_position = current_path.find('.');
811*635a8641SAndroid Build Coastguard Worker delimiter_position != std::string::npos;
812*635a8641SAndroid Build Coastguard Worker delimiter_position = current_path.find('.')) {
813*635a8641SAndroid Build Coastguard Worker const DictionaryValue* child_dictionary = nullptr;
814*635a8641SAndroid Build Coastguard Worker if (!current_dictionary->GetDictionaryWithoutPathExpansion(
815*635a8641SAndroid Build Coastguard Worker current_path.substr(0, delimiter_position), &child_dictionary)) {
816*635a8641SAndroid Build Coastguard Worker return false;
817*635a8641SAndroid Build Coastguard Worker }
818*635a8641SAndroid Build Coastguard Worker
819*635a8641SAndroid Build Coastguard Worker current_dictionary = child_dictionary;
820*635a8641SAndroid Build Coastguard Worker current_path = current_path.substr(delimiter_position + 1);
821*635a8641SAndroid Build Coastguard Worker }
822*635a8641SAndroid Build Coastguard Worker
823*635a8641SAndroid Build Coastguard Worker return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
824*635a8641SAndroid Build Coastguard Worker }
825*635a8641SAndroid Build Coastguard Worker
Get(StringPiece path,Value ** out_value)826*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::Get(StringPiece path, Value** out_value) {
827*635a8641SAndroid Build Coastguard Worker return static_cast<const DictionaryValue&>(*this).Get(
828*635a8641SAndroid Build Coastguard Worker path,
829*635a8641SAndroid Build Coastguard Worker const_cast<const Value**>(out_value));
830*635a8641SAndroid Build Coastguard Worker }
831*635a8641SAndroid Build Coastguard Worker
GetBoolean(StringPiece path,bool * bool_value) const832*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetBoolean(StringPiece path, bool* bool_value) const {
833*635a8641SAndroid Build Coastguard Worker const Value* value;
834*635a8641SAndroid Build Coastguard Worker if (!Get(path, &value))
835*635a8641SAndroid Build Coastguard Worker return false;
836*635a8641SAndroid Build Coastguard Worker
837*635a8641SAndroid Build Coastguard Worker return value->GetAsBoolean(bool_value);
838*635a8641SAndroid Build Coastguard Worker }
839*635a8641SAndroid Build Coastguard Worker
GetInteger(StringPiece path,int * out_value) const840*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetInteger(StringPiece path, int* out_value) const {
841*635a8641SAndroid Build Coastguard Worker const Value* value;
842*635a8641SAndroid Build Coastguard Worker if (!Get(path, &value))
843*635a8641SAndroid Build Coastguard Worker return false;
844*635a8641SAndroid Build Coastguard Worker
845*635a8641SAndroid Build Coastguard Worker return value->GetAsInteger(out_value);
846*635a8641SAndroid Build Coastguard Worker }
847*635a8641SAndroid Build Coastguard Worker
GetDouble(StringPiece path,double * out_value) const848*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetDouble(StringPiece path, double* out_value) const {
849*635a8641SAndroid Build Coastguard Worker const Value* value;
850*635a8641SAndroid Build Coastguard Worker if (!Get(path, &value))
851*635a8641SAndroid Build Coastguard Worker return false;
852*635a8641SAndroid Build Coastguard Worker
853*635a8641SAndroid Build Coastguard Worker return value->GetAsDouble(out_value);
854*635a8641SAndroid Build Coastguard Worker }
855*635a8641SAndroid Build Coastguard Worker
GetString(StringPiece path,std::string * out_value) const856*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetString(StringPiece path,
857*635a8641SAndroid Build Coastguard Worker std::string* out_value) const {
858*635a8641SAndroid Build Coastguard Worker const Value* value;
859*635a8641SAndroid Build Coastguard Worker if (!Get(path, &value))
860*635a8641SAndroid Build Coastguard Worker return false;
861*635a8641SAndroid Build Coastguard Worker
862*635a8641SAndroid Build Coastguard Worker return value->GetAsString(out_value);
863*635a8641SAndroid Build Coastguard Worker }
864*635a8641SAndroid Build Coastguard Worker
GetString(StringPiece path,string16 * out_value) const865*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetString(StringPiece path, string16* out_value) const {
866*635a8641SAndroid Build Coastguard Worker const Value* value;
867*635a8641SAndroid Build Coastguard Worker if (!Get(path, &value))
868*635a8641SAndroid Build Coastguard Worker return false;
869*635a8641SAndroid Build Coastguard Worker
870*635a8641SAndroid Build Coastguard Worker return value->GetAsString(out_value);
871*635a8641SAndroid Build Coastguard Worker }
872*635a8641SAndroid Build Coastguard Worker
GetStringASCII(StringPiece path,std::string * out_value) const873*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetStringASCII(StringPiece path,
874*635a8641SAndroid Build Coastguard Worker std::string* out_value) const {
875*635a8641SAndroid Build Coastguard Worker std::string out;
876*635a8641SAndroid Build Coastguard Worker if (!GetString(path, &out))
877*635a8641SAndroid Build Coastguard Worker return false;
878*635a8641SAndroid Build Coastguard Worker
879*635a8641SAndroid Build Coastguard Worker if (!IsStringASCII(out)) {
880*635a8641SAndroid Build Coastguard Worker NOTREACHED();
881*635a8641SAndroid Build Coastguard Worker return false;
882*635a8641SAndroid Build Coastguard Worker }
883*635a8641SAndroid Build Coastguard Worker
884*635a8641SAndroid Build Coastguard Worker out_value->assign(out);
885*635a8641SAndroid Build Coastguard Worker return true;
886*635a8641SAndroid Build Coastguard Worker }
887*635a8641SAndroid Build Coastguard Worker
GetBinary(StringPiece path,const Value ** out_value) const888*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetBinary(StringPiece path,
889*635a8641SAndroid Build Coastguard Worker const Value** out_value) const {
890*635a8641SAndroid Build Coastguard Worker const Value* value;
891*635a8641SAndroid Build Coastguard Worker bool result = Get(path, &value);
892*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_blob())
893*635a8641SAndroid Build Coastguard Worker return false;
894*635a8641SAndroid Build Coastguard Worker
895*635a8641SAndroid Build Coastguard Worker if (out_value)
896*635a8641SAndroid Build Coastguard Worker *out_value = value;
897*635a8641SAndroid Build Coastguard Worker
898*635a8641SAndroid Build Coastguard Worker return true;
899*635a8641SAndroid Build Coastguard Worker }
900*635a8641SAndroid Build Coastguard Worker
GetBinary(StringPiece path,Value ** out_value)901*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetBinary(StringPiece path, Value** out_value) {
902*635a8641SAndroid Build Coastguard Worker return static_cast<const DictionaryValue&>(*this).GetBinary(
903*635a8641SAndroid Build Coastguard Worker path, const_cast<const Value**>(out_value));
904*635a8641SAndroid Build Coastguard Worker }
905*635a8641SAndroid Build Coastguard Worker
GetDictionary(StringPiece path,const DictionaryValue ** out_value) const906*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetDictionary(StringPiece path,
907*635a8641SAndroid Build Coastguard Worker const DictionaryValue** out_value) const {
908*635a8641SAndroid Build Coastguard Worker const Value* value;
909*635a8641SAndroid Build Coastguard Worker bool result = Get(path, &value);
910*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_dict())
911*635a8641SAndroid Build Coastguard Worker return false;
912*635a8641SAndroid Build Coastguard Worker
913*635a8641SAndroid Build Coastguard Worker if (out_value)
914*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const DictionaryValue*>(value);
915*635a8641SAndroid Build Coastguard Worker
916*635a8641SAndroid Build Coastguard Worker return true;
917*635a8641SAndroid Build Coastguard Worker }
918*635a8641SAndroid Build Coastguard Worker
GetDictionary(StringPiece path,DictionaryValue ** out_value)919*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetDictionary(StringPiece path,
920*635a8641SAndroid Build Coastguard Worker DictionaryValue** out_value) {
921*635a8641SAndroid Build Coastguard Worker return static_cast<const DictionaryValue&>(*this).GetDictionary(
922*635a8641SAndroid Build Coastguard Worker path,
923*635a8641SAndroid Build Coastguard Worker const_cast<const DictionaryValue**>(out_value));
924*635a8641SAndroid Build Coastguard Worker }
925*635a8641SAndroid Build Coastguard Worker
GetList(StringPiece path,const ListValue ** out_value) const926*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetList(StringPiece path,
927*635a8641SAndroid Build Coastguard Worker const ListValue** out_value) const {
928*635a8641SAndroid Build Coastguard Worker const Value* value;
929*635a8641SAndroid Build Coastguard Worker bool result = Get(path, &value);
930*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_list())
931*635a8641SAndroid Build Coastguard Worker return false;
932*635a8641SAndroid Build Coastguard Worker
933*635a8641SAndroid Build Coastguard Worker if (out_value)
934*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const ListValue*>(value);
935*635a8641SAndroid Build Coastguard Worker
936*635a8641SAndroid Build Coastguard Worker return true;
937*635a8641SAndroid Build Coastguard Worker }
938*635a8641SAndroid Build Coastguard Worker
GetList(StringPiece path,ListValue ** out_value)939*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) {
940*635a8641SAndroid Build Coastguard Worker return static_cast<const DictionaryValue&>(*this).GetList(
941*635a8641SAndroid Build Coastguard Worker path,
942*635a8641SAndroid Build Coastguard Worker const_cast<const ListValue**>(out_value));
943*635a8641SAndroid Build Coastguard Worker }
944*635a8641SAndroid Build Coastguard Worker
GetWithoutPathExpansion(StringPiece key,const Value ** out_value) const945*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
946*635a8641SAndroid Build Coastguard Worker const Value** out_value) const {
947*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(key));
948*635a8641SAndroid Build Coastguard Worker auto entry_iterator = dict_.find(key);
949*635a8641SAndroid Build Coastguard Worker if (entry_iterator == dict_.end())
950*635a8641SAndroid Build Coastguard Worker return false;
951*635a8641SAndroid Build Coastguard Worker
952*635a8641SAndroid Build Coastguard Worker if (out_value)
953*635a8641SAndroid Build Coastguard Worker *out_value = entry_iterator->second.get();
954*635a8641SAndroid Build Coastguard Worker return true;
955*635a8641SAndroid Build Coastguard Worker }
956*635a8641SAndroid Build Coastguard Worker
GetWithoutPathExpansion(StringPiece key,Value ** out_value)957*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
958*635a8641SAndroid Build Coastguard Worker Value** out_value) {
959*635a8641SAndroid Build Coastguard Worker return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
960*635a8641SAndroid Build Coastguard Worker key,
961*635a8641SAndroid Build Coastguard Worker const_cast<const Value**>(out_value));
962*635a8641SAndroid Build Coastguard Worker }
963*635a8641SAndroid Build Coastguard Worker
GetBooleanWithoutPathExpansion(StringPiece key,bool * out_value) const964*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetBooleanWithoutPathExpansion(StringPiece key,
965*635a8641SAndroid Build Coastguard Worker bool* out_value) const {
966*635a8641SAndroid Build Coastguard Worker const Value* value;
967*635a8641SAndroid Build Coastguard Worker if (!GetWithoutPathExpansion(key, &value))
968*635a8641SAndroid Build Coastguard Worker return false;
969*635a8641SAndroid Build Coastguard Worker
970*635a8641SAndroid Build Coastguard Worker return value->GetAsBoolean(out_value);
971*635a8641SAndroid Build Coastguard Worker }
972*635a8641SAndroid Build Coastguard Worker
GetIntegerWithoutPathExpansion(StringPiece key,int * out_value) const973*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetIntegerWithoutPathExpansion(StringPiece key,
974*635a8641SAndroid Build Coastguard Worker int* out_value) const {
975*635a8641SAndroid Build Coastguard Worker const Value* value;
976*635a8641SAndroid Build Coastguard Worker if (!GetWithoutPathExpansion(key, &value))
977*635a8641SAndroid Build Coastguard Worker return false;
978*635a8641SAndroid Build Coastguard Worker
979*635a8641SAndroid Build Coastguard Worker return value->GetAsInteger(out_value);
980*635a8641SAndroid Build Coastguard Worker }
981*635a8641SAndroid Build Coastguard Worker
GetDoubleWithoutPathExpansion(StringPiece key,double * out_value) const982*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetDoubleWithoutPathExpansion(StringPiece key,
983*635a8641SAndroid Build Coastguard Worker double* out_value) const {
984*635a8641SAndroid Build Coastguard Worker const Value* value;
985*635a8641SAndroid Build Coastguard Worker if (!GetWithoutPathExpansion(key, &value))
986*635a8641SAndroid Build Coastguard Worker return false;
987*635a8641SAndroid Build Coastguard Worker
988*635a8641SAndroid Build Coastguard Worker return value->GetAsDouble(out_value);
989*635a8641SAndroid Build Coastguard Worker }
990*635a8641SAndroid Build Coastguard Worker
GetStringWithoutPathExpansion(StringPiece key,std::string * out_value) const991*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetStringWithoutPathExpansion(
992*635a8641SAndroid Build Coastguard Worker StringPiece key,
993*635a8641SAndroid Build Coastguard Worker std::string* out_value) const {
994*635a8641SAndroid Build Coastguard Worker const Value* value;
995*635a8641SAndroid Build Coastguard Worker if (!GetWithoutPathExpansion(key, &value))
996*635a8641SAndroid Build Coastguard Worker return false;
997*635a8641SAndroid Build Coastguard Worker
998*635a8641SAndroid Build Coastguard Worker return value->GetAsString(out_value);
999*635a8641SAndroid Build Coastguard Worker }
1000*635a8641SAndroid Build Coastguard Worker
GetStringWithoutPathExpansion(StringPiece key,string16 * out_value) const1001*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetStringWithoutPathExpansion(StringPiece key,
1002*635a8641SAndroid Build Coastguard Worker string16* out_value) const {
1003*635a8641SAndroid Build Coastguard Worker const Value* value;
1004*635a8641SAndroid Build Coastguard Worker if (!GetWithoutPathExpansion(key, &value))
1005*635a8641SAndroid Build Coastguard Worker return false;
1006*635a8641SAndroid Build Coastguard Worker
1007*635a8641SAndroid Build Coastguard Worker return value->GetAsString(out_value);
1008*635a8641SAndroid Build Coastguard Worker }
1009*635a8641SAndroid Build Coastguard Worker
GetDictionaryWithoutPathExpansion(StringPiece key,const DictionaryValue ** out_value) const1010*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetDictionaryWithoutPathExpansion(
1011*635a8641SAndroid Build Coastguard Worker StringPiece key,
1012*635a8641SAndroid Build Coastguard Worker const DictionaryValue** out_value) const {
1013*635a8641SAndroid Build Coastguard Worker const Value* value;
1014*635a8641SAndroid Build Coastguard Worker bool result = GetWithoutPathExpansion(key, &value);
1015*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_dict())
1016*635a8641SAndroid Build Coastguard Worker return false;
1017*635a8641SAndroid Build Coastguard Worker
1018*635a8641SAndroid Build Coastguard Worker if (out_value)
1019*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const DictionaryValue*>(value);
1020*635a8641SAndroid Build Coastguard Worker
1021*635a8641SAndroid Build Coastguard Worker return true;
1022*635a8641SAndroid Build Coastguard Worker }
1023*635a8641SAndroid Build Coastguard Worker
GetDictionaryWithoutPathExpansion(StringPiece key,DictionaryValue ** out_value)1024*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetDictionaryWithoutPathExpansion(
1025*635a8641SAndroid Build Coastguard Worker StringPiece key,
1026*635a8641SAndroid Build Coastguard Worker DictionaryValue** out_value) {
1027*635a8641SAndroid Build Coastguard Worker const DictionaryValue& const_this =
1028*635a8641SAndroid Build Coastguard Worker static_cast<const DictionaryValue&>(*this);
1029*635a8641SAndroid Build Coastguard Worker return const_this.GetDictionaryWithoutPathExpansion(
1030*635a8641SAndroid Build Coastguard Worker key,
1031*635a8641SAndroid Build Coastguard Worker const_cast<const DictionaryValue**>(out_value));
1032*635a8641SAndroid Build Coastguard Worker }
1033*635a8641SAndroid Build Coastguard Worker
GetListWithoutPathExpansion(StringPiece key,const ListValue ** out_value) const1034*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetListWithoutPathExpansion(
1035*635a8641SAndroid Build Coastguard Worker StringPiece key,
1036*635a8641SAndroid Build Coastguard Worker const ListValue** out_value) const {
1037*635a8641SAndroid Build Coastguard Worker const Value* value;
1038*635a8641SAndroid Build Coastguard Worker bool result = GetWithoutPathExpansion(key, &value);
1039*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_list())
1040*635a8641SAndroid Build Coastguard Worker return false;
1041*635a8641SAndroid Build Coastguard Worker
1042*635a8641SAndroid Build Coastguard Worker if (out_value)
1043*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const ListValue*>(value);
1044*635a8641SAndroid Build Coastguard Worker
1045*635a8641SAndroid Build Coastguard Worker return true;
1046*635a8641SAndroid Build Coastguard Worker }
1047*635a8641SAndroid Build Coastguard Worker
GetListWithoutPathExpansion(StringPiece key,ListValue ** out_value)1048*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::GetListWithoutPathExpansion(StringPiece key,
1049*635a8641SAndroid Build Coastguard Worker ListValue** out_value) {
1050*635a8641SAndroid Build Coastguard Worker return
1051*635a8641SAndroid Build Coastguard Worker static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
1052*635a8641SAndroid Build Coastguard Worker key,
1053*635a8641SAndroid Build Coastguard Worker const_cast<const ListValue**>(out_value));
1054*635a8641SAndroid Build Coastguard Worker }
1055*635a8641SAndroid Build Coastguard Worker
Remove(StringPiece path,std::unique_ptr<Value> * out_value)1056*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::Remove(StringPiece path,
1057*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value>* out_value) {
1058*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(path));
1059*635a8641SAndroid Build Coastguard Worker StringPiece current_path(path);
1060*635a8641SAndroid Build Coastguard Worker DictionaryValue* current_dictionary = this;
1061*635a8641SAndroid Build Coastguard Worker size_t delimiter_position = current_path.rfind('.');
1062*635a8641SAndroid Build Coastguard Worker if (delimiter_position != StringPiece::npos) {
1063*635a8641SAndroid Build Coastguard Worker if (!GetDictionary(current_path.substr(0, delimiter_position),
1064*635a8641SAndroid Build Coastguard Worker ¤t_dictionary))
1065*635a8641SAndroid Build Coastguard Worker return false;
1066*635a8641SAndroid Build Coastguard Worker current_path = current_path.substr(delimiter_position + 1);
1067*635a8641SAndroid Build Coastguard Worker }
1068*635a8641SAndroid Build Coastguard Worker
1069*635a8641SAndroid Build Coastguard Worker return current_dictionary->RemoveWithoutPathExpansion(current_path,
1070*635a8641SAndroid Build Coastguard Worker out_value);
1071*635a8641SAndroid Build Coastguard Worker }
1072*635a8641SAndroid Build Coastguard Worker
RemoveWithoutPathExpansion(StringPiece key,std::unique_ptr<Value> * out_value)1073*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::RemoveWithoutPathExpansion(
1074*635a8641SAndroid Build Coastguard Worker StringPiece key,
1075*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value>* out_value) {
1076*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringUTF8(key));
1077*635a8641SAndroid Build Coastguard Worker auto entry_iterator = dict_.find(key);
1078*635a8641SAndroid Build Coastguard Worker if (entry_iterator == dict_.end())
1079*635a8641SAndroid Build Coastguard Worker return false;
1080*635a8641SAndroid Build Coastguard Worker
1081*635a8641SAndroid Build Coastguard Worker if (out_value)
1082*635a8641SAndroid Build Coastguard Worker *out_value = std::move(entry_iterator->second);
1083*635a8641SAndroid Build Coastguard Worker dict_.erase(entry_iterator);
1084*635a8641SAndroid Build Coastguard Worker return true;
1085*635a8641SAndroid Build Coastguard Worker }
1086*635a8641SAndroid Build Coastguard Worker
RemovePath(StringPiece path,std::unique_ptr<Value> * out_value)1087*635a8641SAndroid Build Coastguard Worker bool DictionaryValue::RemovePath(StringPiece path,
1088*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value>* out_value) {
1089*635a8641SAndroid Build Coastguard Worker bool result = false;
1090*635a8641SAndroid Build Coastguard Worker size_t delimiter_position = path.find('.');
1091*635a8641SAndroid Build Coastguard Worker
1092*635a8641SAndroid Build Coastguard Worker if (delimiter_position == std::string::npos)
1093*635a8641SAndroid Build Coastguard Worker return RemoveWithoutPathExpansion(path, out_value);
1094*635a8641SAndroid Build Coastguard Worker
1095*635a8641SAndroid Build Coastguard Worker StringPiece subdict_path = path.substr(0, delimiter_position);
1096*635a8641SAndroid Build Coastguard Worker DictionaryValue* subdict = nullptr;
1097*635a8641SAndroid Build Coastguard Worker if (!GetDictionary(subdict_path, &subdict))
1098*635a8641SAndroid Build Coastguard Worker return false;
1099*635a8641SAndroid Build Coastguard Worker result = subdict->RemovePath(path.substr(delimiter_position + 1),
1100*635a8641SAndroid Build Coastguard Worker out_value);
1101*635a8641SAndroid Build Coastguard Worker if (result && subdict->empty())
1102*635a8641SAndroid Build Coastguard Worker RemoveWithoutPathExpansion(subdict_path, nullptr);
1103*635a8641SAndroid Build Coastguard Worker
1104*635a8641SAndroid Build Coastguard Worker return result;
1105*635a8641SAndroid Build Coastguard Worker }
1106*635a8641SAndroid Build Coastguard Worker
DeepCopyWithoutEmptyChildren() const1107*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren()
1108*635a8641SAndroid Build Coastguard Worker const {
1109*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> copy =
1110*635a8641SAndroid Build Coastguard Worker CopyDictionaryWithoutEmptyChildren(*this);
1111*635a8641SAndroid Build Coastguard Worker if (!copy)
1112*635a8641SAndroid Build Coastguard Worker copy = std::make_unique<DictionaryValue>();
1113*635a8641SAndroid Build Coastguard Worker return copy;
1114*635a8641SAndroid Build Coastguard Worker }
1115*635a8641SAndroid Build Coastguard Worker
MergeDictionary(const DictionaryValue * dictionary)1116*635a8641SAndroid Build Coastguard Worker void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
1117*635a8641SAndroid Build Coastguard Worker CHECK(dictionary->is_dict());
1118*635a8641SAndroid Build Coastguard Worker for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
1119*635a8641SAndroid Build Coastguard Worker const Value* merge_value = &it.value();
1120*635a8641SAndroid Build Coastguard Worker // Check whether we have to merge dictionaries.
1121*635a8641SAndroid Build Coastguard Worker if (merge_value->is_dict()) {
1122*635a8641SAndroid Build Coastguard Worker DictionaryValue* sub_dict;
1123*635a8641SAndroid Build Coastguard Worker if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
1124*635a8641SAndroid Build Coastguard Worker sub_dict->MergeDictionary(
1125*635a8641SAndroid Build Coastguard Worker static_cast<const DictionaryValue*>(merge_value));
1126*635a8641SAndroid Build Coastguard Worker continue;
1127*635a8641SAndroid Build Coastguard Worker }
1128*635a8641SAndroid Build Coastguard Worker }
1129*635a8641SAndroid Build Coastguard Worker // All other cases: Make a copy and hook it up.
1130*635a8641SAndroid Build Coastguard Worker SetKey(it.key(), merge_value->Clone());
1131*635a8641SAndroid Build Coastguard Worker }
1132*635a8641SAndroid Build Coastguard Worker }
1133*635a8641SAndroid Build Coastguard Worker
Swap(DictionaryValue * other)1134*635a8641SAndroid Build Coastguard Worker void DictionaryValue::Swap(DictionaryValue* other) {
1135*635a8641SAndroid Build Coastguard Worker CHECK(other->is_dict());
1136*635a8641SAndroid Build Coastguard Worker dict_.swap(other->dict_);
1137*635a8641SAndroid Build Coastguard Worker }
1138*635a8641SAndroid Build Coastguard Worker
Iterator(const DictionaryValue & target)1139*635a8641SAndroid Build Coastguard Worker DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
1140*635a8641SAndroid Build Coastguard Worker : target_(target), it_(target.dict_.begin()) {}
1141*635a8641SAndroid Build Coastguard Worker
1142*635a8641SAndroid Build Coastguard Worker DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
1143*635a8641SAndroid Build Coastguard Worker
1144*635a8641SAndroid Build Coastguard Worker DictionaryValue::Iterator::~Iterator() = default;
1145*635a8641SAndroid Build Coastguard Worker
DeepCopy() const1146*635a8641SAndroid Build Coastguard Worker DictionaryValue* DictionaryValue::DeepCopy() const {
1147*635a8641SAndroid Build Coastguard Worker return new DictionaryValue(dict_);
1148*635a8641SAndroid Build Coastguard Worker }
1149*635a8641SAndroid Build Coastguard Worker
CreateDeepCopy() const1150*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
1151*635a8641SAndroid Build Coastguard Worker return std::make_unique<DictionaryValue>(dict_);
1152*635a8641SAndroid Build Coastguard Worker }
1153*635a8641SAndroid Build Coastguard Worker
1154*635a8641SAndroid Build Coastguard Worker ///////////////////// ListValue ////////////////////
1155*635a8641SAndroid Build Coastguard Worker
1156*635a8641SAndroid Build Coastguard Worker // static
From(std::unique_ptr<Value> value)1157*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) {
1158*635a8641SAndroid Build Coastguard Worker ListValue* out;
1159*635a8641SAndroid Build Coastguard Worker if (value && value->GetAsList(&out)) {
1160*635a8641SAndroid Build Coastguard Worker ignore_result(value.release());
1161*635a8641SAndroid Build Coastguard Worker return WrapUnique(out);
1162*635a8641SAndroid Build Coastguard Worker }
1163*635a8641SAndroid Build Coastguard Worker return nullptr;
1164*635a8641SAndroid Build Coastguard Worker }
1165*635a8641SAndroid Build Coastguard Worker
ListValue()1166*635a8641SAndroid Build Coastguard Worker ListValue::ListValue() : Value(Type::LIST) {}
ListValue(const ListStorage & in_list)1167*635a8641SAndroid Build Coastguard Worker ListValue::ListValue(const ListStorage& in_list) : Value(in_list) {}
ListValue(ListStorage && in_list)1168*635a8641SAndroid Build Coastguard Worker ListValue::ListValue(ListStorage&& in_list) noexcept
1169*635a8641SAndroid Build Coastguard Worker : Value(std::move(in_list)) {}
1170*635a8641SAndroid Build Coastguard Worker
Clear()1171*635a8641SAndroid Build Coastguard Worker void ListValue::Clear() {
1172*635a8641SAndroid Build Coastguard Worker list_.clear();
1173*635a8641SAndroid Build Coastguard Worker }
1174*635a8641SAndroid Build Coastguard Worker
Reserve(size_t n)1175*635a8641SAndroid Build Coastguard Worker void ListValue::Reserve(size_t n) {
1176*635a8641SAndroid Build Coastguard Worker list_.reserve(n);
1177*635a8641SAndroid Build Coastguard Worker }
1178*635a8641SAndroid Build Coastguard Worker
Set(size_t index,std::unique_ptr<Value> in_value)1179*635a8641SAndroid Build Coastguard Worker bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
1180*635a8641SAndroid Build Coastguard Worker if (!in_value)
1181*635a8641SAndroid Build Coastguard Worker return false;
1182*635a8641SAndroid Build Coastguard Worker
1183*635a8641SAndroid Build Coastguard Worker if (index >= list_.size())
1184*635a8641SAndroid Build Coastguard Worker list_.resize(index + 1);
1185*635a8641SAndroid Build Coastguard Worker
1186*635a8641SAndroid Build Coastguard Worker list_[index] = std::move(*in_value);
1187*635a8641SAndroid Build Coastguard Worker return true;
1188*635a8641SAndroid Build Coastguard Worker }
1189*635a8641SAndroid Build Coastguard Worker
Get(size_t index,const Value ** out_value) const1190*635a8641SAndroid Build Coastguard Worker bool ListValue::Get(size_t index, const Value** out_value) const {
1191*635a8641SAndroid Build Coastguard Worker if (index >= list_.size())
1192*635a8641SAndroid Build Coastguard Worker return false;
1193*635a8641SAndroid Build Coastguard Worker
1194*635a8641SAndroid Build Coastguard Worker if (out_value)
1195*635a8641SAndroid Build Coastguard Worker *out_value = &list_[index];
1196*635a8641SAndroid Build Coastguard Worker
1197*635a8641SAndroid Build Coastguard Worker return true;
1198*635a8641SAndroid Build Coastguard Worker }
1199*635a8641SAndroid Build Coastguard Worker
Get(size_t index,Value ** out_value)1200*635a8641SAndroid Build Coastguard Worker bool ListValue::Get(size_t index, Value** out_value) {
1201*635a8641SAndroid Build Coastguard Worker return static_cast<const ListValue&>(*this).Get(
1202*635a8641SAndroid Build Coastguard Worker index,
1203*635a8641SAndroid Build Coastguard Worker const_cast<const Value**>(out_value));
1204*635a8641SAndroid Build Coastguard Worker }
1205*635a8641SAndroid Build Coastguard Worker
GetBoolean(size_t index,bool * bool_value) const1206*635a8641SAndroid Build Coastguard Worker bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
1207*635a8641SAndroid Build Coastguard Worker const Value* value;
1208*635a8641SAndroid Build Coastguard Worker if (!Get(index, &value))
1209*635a8641SAndroid Build Coastguard Worker return false;
1210*635a8641SAndroid Build Coastguard Worker
1211*635a8641SAndroid Build Coastguard Worker return value->GetAsBoolean(bool_value);
1212*635a8641SAndroid Build Coastguard Worker }
1213*635a8641SAndroid Build Coastguard Worker
GetInteger(size_t index,int * out_value) const1214*635a8641SAndroid Build Coastguard Worker bool ListValue::GetInteger(size_t index, int* out_value) const {
1215*635a8641SAndroid Build Coastguard Worker const Value* value;
1216*635a8641SAndroid Build Coastguard Worker if (!Get(index, &value))
1217*635a8641SAndroid Build Coastguard Worker return false;
1218*635a8641SAndroid Build Coastguard Worker
1219*635a8641SAndroid Build Coastguard Worker return value->GetAsInteger(out_value);
1220*635a8641SAndroid Build Coastguard Worker }
1221*635a8641SAndroid Build Coastguard Worker
GetDouble(size_t index,double * out_value) const1222*635a8641SAndroid Build Coastguard Worker bool ListValue::GetDouble(size_t index, double* out_value) const {
1223*635a8641SAndroid Build Coastguard Worker const Value* value;
1224*635a8641SAndroid Build Coastguard Worker if (!Get(index, &value))
1225*635a8641SAndroid Build Coastguard Worker return false;
1226*635a8641SAndroid Build Coastguard Worker
1227*635a8641SAndroid Build Coastguard Worker return value->GetAsDouble(out_value);
1228*635a8641SAndroid Build Coastguard Worker }
1229*635a8641SAndroid Build Coastguard Worker
GetString(size_t index,std::string * out_value) const1230*635a8641SAndroid Build Coastguard Worker bool ListValue::GetString(size_t index, std::string* out_value) const {
1231*635a8641SAndroid Build Coastguard Worker const Value* value;
1232*635a8641SAndroid Build Coastguard Worker if (!Get(index, &value))
1233*635a8641SAndroid Build Coastguard Worker return false;
1234*635a8641SAndroid Build Coastguard Worker
1235*635a8641SAndroid Build Coastguard Worker return value->GetAsString(out_value);
1236*635a8641SAndroid Build Coastguard Worker }
1237*635a8641SAndroid Build Coastguard Worker
GetString(size_t index,string16 * out_value) const1238*635a8641SAndroid Build Coastguard Worker bool ListValue::GetString(size_t index, string16* out_value) const {
1239*635a8641SAndroid Build Coastguard Worker const Value* value;
1240*635a8641SAndroid Build Coastguard Worker if (!Get(index, &value))
1241*635a8641SAndroid Build Coastguard Worker return false;
1242*635a8641SAndroid Build Coastguard Worker
1243*635a8641SAndroid Build Coastguard Worker return value->GetAsString(out_value);
1244*635a8641SAndroid Build Coastguard Worker }
1245*635a8641SAndroid Build Coastguard Worker
GetDictionary(size_t index,const DictionaryValue ** out_value) const1246*635a8641SAndroid Build Coastguard Worker bool ListValue::GetDictionary(size_t index,
1247*635a8641SAndroid Build Coastguard Worker const DictionaryValue** out_value) const {
1248*635a8641SAndroid Build Coastguard Worker const Value* value;
1249*635a8641SAndroid Build Coastguard Worker bool result = Get(index, &value);
1250*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_dict())
1251*635a8641SAndroid Build Coastguard Worker return false;
1252*635a8641SAndroid Build Coastguard Worker
1253*635a8641SAndroid Build Coastguard Worker if (out_value)
1254*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const DictionaryValue*>(value);
1255*635a8641SAndroid Build Coastguard Worker
1256*635a8641SAndroid Build Coastguard Worker return true;
1257*635a8641SAndroid Build Coastguard Worker }
1258*635a8641SAndroid Build Coastguard Worker
GetDictionary(size_t index,DictionaryValue ** out_value)1259*635a8641SAndroid Build Coastguard Worker bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
1260*635a8641SAndroid Build Coastguard Worker return static_cast<const ListValue&>(*this).GetDictionary(
1261*635a8641SAndroid Build Coastguard Worker index,
1262*635a8641SAndroid Build Coastguard Worker const_cast<const DictionaryValue**>(out_value));
1263*635a8641SAndroid Build Coastguard Worker }
1264*635a8641SAndroid Build Coastguard Worker
GetList(size_t index,const ListValue ** out_value) const1265*635a8641SAndroid Build Coastguard Worker bool ListValue::GetList(size_t index, const ListValue** out_value) const {
1266*635a8641SAndroid Build Coastguard Worker const Value* value;
1267*635a8641SAndroid Build Coastguard Worker bool result = Get(index, &value);
1268*635a8641SAndroid Build Coastguard Worker if (!result || !value->is_list())
1269*635a8641SAndroid Build Coastguard Worker return false;
1270*635a8641SAndroid Build Coastguard Worker
1271*635a8641SAndroid Build Coastguard Worker if (out_value)
1272*635a8641SAndroid Build Coastguard Worker *out_value = static_cast<const ListValue*>(value);
1273*635a8641SAndroid Build Coastguard Worker
1274*635a8641SAndroid Build Coastguard Worker return true;
1275*635a8641SAndroid Build Coastguard Worker }
1276*635a8641SAndroid Build Coastguard Worker
GetList(size_t index,ListValue ** out_value)1277*635a8641SAndroid Build Coastguard Worker bool ListValue::GetList(size_t index, ListValue** out_value) {
1278*635a8641SAndroid Build Coastguard Worker return static_cast<const ListValue&>(*this).GetList(
1279*635a8641SAndroid Build Coastguard Worker index,
1280*635a8641SAndroid Build Coastguard Worker const_cast<const ListValue**>(out_value));
1281*635a8641SAndroid Build Coastguard Worker }
1282*635a8641SAndroid Build Coastguard Worker
Remove(size_t index,std::unique_ptr<Value> * out_value)1283*635a8641SAndroid Build Coastguard Worker bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
1284*635a8641SAndroid Build Coastguard Worker if (index >= list_.size())
1285*635a8641SAndroid Build Coastguard Worker return false;
1286*635a8641SAndroid Build Coastguard Worker
1287*635a8641SAndroid Build Coastguard Worker if (out_value)
1288*635a8641SAndroid Build Coastguard Worker *out_value = std::make_unique<Value>(std::move(list_[index]));
1289*635a8641SAndroid Build Coastguard Worker
1290*635a8641SAndroid Build Coastguard Worker list_.erase(list_.begin() + index);
1291*635a8641SAndroid Build Coastguard Worker return true;
1292*635a8641SAndroid Build Coastguard Worker }
1293*635a8641SAndroid Build Coastguard Worker
Remove(const Value & value,size_t * index)1294*635a8641SAndroid Build Coastguard Worker bool ListValue::Remove(const Value& value, size_t* index) {
1295*635a8641SAndroid Build Coastguard Worker auto it = std::find(list_.begin(), list_.end(), value);
1296*635a8641SAndroid Build Coastguard Worker
1297*635a8641SAndroid Build Coastguard Worker if (it == list_.end())
1298*635a8641SAndroid Build Coastguard Worker return false;
1299*635a8641SAndroid Build Coastguard Worker
1300*635a8641SAndroid Build Coastguard Worker if (index)
1301*635a8641SAndroid Build Coastguard Worker *index = std::distance(list_.begin(), it);
1302*635a8641SAndroid Build Coastguard Worker
1303*635a8641SAndroid Build Coastguard Worker list_.erase(it);
1304*635a8641SAndroid Build Coastguard Worker return true;
1305*635a8641SAndroid Build Coastguard Worker }
1306*635a8641SAndroid Build Coastguard Worker
Erase(iterator iter,std::unique_ptr<Value> * out_value)1307*635a8641SAndroid Build Coastguard Worker ListValue::iterator ListValue::Erase(iterator iter,
1308*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value>* out_value) {
1309*635a8641SAndroid Build Coastguard Worker if (out_value)
1310*635a8641SAndroid Build Coastguard Worker *out_value = std::make_unique<Value>(std::move(*iter));
1311*635a8641SAndroid Build Coastguard Worker
1312*635a8641SAndroid Build Coastguard Worker return list_.erase(iter);
1313*635a8641SAndroid Build Coastguard Worker }
1314*635a8641SAndroid Build Coastguard Worker
Append(std::unique_ptr<Value> in_value)1315*635a8641SAndroid Build Coastguard Worker void ListValue::Append(std::unique_ptr<Value> in_value) {
1316*635a8641SAndroid Build Coastguard Worker list_.push_back(std::move(*in_value));
1317*635a8641SAndroid Build Coastguard Worker }
1318*635a8641SAndroid Build Coastguard Worker
AppendBoolean(bool in_value)1319*635a8641SAndroid Build Coastguard Worker void ListValue::AppendBoolean(bool in_value) {
1320*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1321*635a8641SAndroid Build Coastguard Worker }
1322*635a8641SAndroid Build Coastguard Worker
AppendInteger(int in_value)1323*635a8641SAndroid Build Coastguard Worker void ListValue::AppendInteger(int in_value) {
1324*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1325*635a8641SAndroid Build Coastguard Worker }
1326*635a8641SAndroid Build Coastguard Worker
AppendDouble(double in_value)1327*635a8641SAndroid Build Coastguard Worker void ListValue::AppendDouble(double in_value) {
1328*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1329*635a8641SAndroid Build Coastguard Worker }
1330*635a8641SAndroid Build Coastguard Worker
AppendString(StringPiece in_value)1331*635a8641SAndroid Build Coastguard Worker void ListValue::AppendString(StringPiece in_value) {
1332*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1333*635a8641SAndroid Build Coastguard Worker }
1334*635a8641SAndroid Build Coastguard Worker
AppendString(const string16 & in_value)1335*635a8641SAndroid Build Coastguard Worker void ListValue::AppendString(const string16& in_value) {
1336*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1337*635a8641SAndroid Build Coastguard Worker }
1338*635a8641SAndroid Build Coastguard Worker
AppendStrings(const std::vector<std::string> & in_values)1339*635a8641SAndroid Build Coastguard Worker void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1340*635a8641SAndroid Build Coastguard Worker list_.reserve(list_.size() + in_values.size());
1341*635a8641SAndroid Build Coastguard Worker for (const auto& in_value : in_values)
1342*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1343*635a8641SAndroid Build Coastguard Worker }
1344*635a8641SAndroid Build Coastguard Worker
AppendStrings(const std::vector<string16> & in_values)1345*635a8641SAndroid Build Coastguard Worker void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1346*635a8641SAndroid Build Coastguard Worker list_.reserve(list_.size() + in_values.size());
1347*635a8641SAndroid Build Coastguard Worker for (const auto& in_value : in_values)
1348*635a8641SAndroid Build Coastguard Worker list_.emplace_back(in_value);
1349*635a8641SAndroid Build Coastguard Worker }
1350*635a8641SAndroid Build Coastguard Worker
AppendIfNotPresent(std::unique_ptr<Value> in_value)1351*635a8641SAndroid Build Coastguard Worker bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
1352*635a8641SAndroid Build Coastguard Worker DCHECK(in_value);
1353*635a8641SAndroid Build Coastguard Worker if (ContainsValue(list_, *in_value))
1354*635a8641SAndroid Build Coastguard Worker return false;
1355*635a8641SAndroid Build Coastguard Worker
1356*635a8641SAndroid Build Coastguard Worker list_.push_back(std::move(*in_value));
1357*635a8641SAndroid Build Coastguard Worker return true;
1358*635a8641SAndroid Build Coastguard Worker }
1359*635a8641SAndroid Build Coastguard Worker
Insert(size_t index,std::unique_ptr<Value> in_value)1360*635a8641SAndroid Build Coastguard Worker bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
1361*635a8641SAndroid Build Coastguard Worker DCHECK(in_value);
1362*635a8641SAndroid Build Coastguard Worker if (index > list_.size())
1363*635a8641SAndroid Build Coastguard Worker return false;
1364*635a8641SAndroid Build Coastguard Worker
1365*635a8641SAndroid Build Coastguard Worker list_.insert(list_.begin() + index, std::move(*in_value));
1366*635a8641SAndroid Build Coastguard Worker return true;
1367*635a8641SAndroid Build Coastguard Worker }
1368*635a8641SAndroid Build Coastguard Worker
Find(const Value & value) const1369*635a8641SAndroid Build Coastguard Worker ListValue::const_iterator ListValue::Find(const Value& value) const {
1370*635a8641SAndroid Build Coastguard Worker return std::find(list_.begin(), list_.end(), value);
1371*635a8641SAndroid Build Coastguard Worker }
1372*635a8641SAndroid Build Coastguard Worker
Swap(ListValue * other)1373*635a8641SAndroid Build Coastguard Worker void ListValue::Swap(ListValue* other) {
1374*635a8641SAndroid Build Coastguard Worker CHECK(other->is_list());
1375*635a8641SAndroid Build Coastguard Worker list_.swap(other->list_);
1376*635a8641SAndroid Build Coastguard Worker }
1377*635a8641SAndroid Build Coastguard Worker
DeepCopy() const1378*635a8641SAndroid Build Coastguard Worker ListValue* ListValue::DeepCopy() const {
1379*635a8641SAndroid Build Coastguard Worker return new ListValue(list_);
1380*635a8641SAndroid Build Coastguard Worker }
1381*635a8641SAndroid Build Coastguard Worker
CreateDeepCopy() const1382*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
1383*635a8641SAndroid Build Coastguard Worker return std::make_unique<ListValue>(list_);
1384*635a8641SAndroid Build Coastguard Worker }
1385*635a8641SAndroid Build Coastguard Worker
1386*635a8641SAndroid Build Coastguard Worker ValueSerializer::~ValueSerializer() = default;
1387*635a8641SAndroid Build Coastguard Worker
1388*635a8641SAndroid Build Coastguard Worker ValueDeserializer::~ValueDeserializer() = default;
1389*635a8641SAndroid Build Coastguard Worker
operator <<(std::ostream & out,const Value & value)1390*635a8641SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const Value& value) {
1391*635a8641SAndroid Build Coastguard Worker std::string json;
1392*635a8641SAndroid Build Coastguard Worker JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
1393*635a8641SAndroid Build Coastguard Worker return out << json;
1394*635a8641SAndroid Build Coastguard Worker }
1395*635a8641SAndroid Build Coastguard Worker
operator <<(std::ostream & out,const Value::Type & type)1396*635a8641SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1397*635a8641SAndroid Build Coastguard Worker if (static_cast<int>(type) < 0 ||
1398*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(type) >= arraysize(kTypeNames))
1399*635a8641SAndroid Build Coastguard Worker return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1400*635a8641SAndroid Build Coastguard Worker return out << Value::GetTypeName(type);
1401*635a8641SAndroid Build Coastguard Worker }
1402*635a8641SAndroid Build Coastguard Worker
1403*635a8641SAndroid Build Coastguard Worker } // namespace base
1404