blob: 74e83b9900f56008af6b7edbe5dbc50a90ac7d13 [file] [log] [blame]
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botf003cfe2008-08-24 09:55:55 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit3f4a7322008-07-27 06:49:38 +09004
tony@chromium.orge4948ab2009-12-02 09:20:32 +09005#include "base/values.h"
6
mostynb@opera.comf29dd612013-09-04 08:29:12 +09007#include <string.h>
8
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +09009#include <algorithm>
mateuszs8b1a88a2015-04-24 22:20:23 +090010#include <cmath>
kalman@chromium.org829cf752012-09-12 12:39:35 +090011#include <ostream>
danakj800d2ea2015-11-25 14:29:58 +090012#include <utility>
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +090013
kalman@chromium.org829cf752012-09-12 12:39:35 +090014#include "base/json/json_writer.h"
initial.commit3f4a7322008-07-27 06:49:38 +090015#include "base/logging.h"
dchengcc8e4d82016-04-05 06:25:51 +090016#include "base/memory/ptr_util.h"
avi@chromium.org68a745c2013-06-11 05:11:14 +090017#include "base/strings/string_util.h"
avi@chromium.org17f60622013-06-08 03:37:07 +090018#include "base/strings/utf_string_conversions.h"
tony@chromium.orge4948ab2009-12-02 09:20:32 +090019
brettw@chromium.org88aa6552013-06-15 02:56:08 +090020namespace base {
21
tony@chromium.orge4948ab2009-12-02 09:20:32 +090022namespace {
23
thestige44b9322016-07-19 09:39:30 +090024const char* const kTypeNames[] = {"null", "boolean", "integer", "double",
25 "string", "binary", "dictionary", "list"};
jdoerrie89ee31a2016-12-08 00:43:28 +090026static_assert(arraysize(kTypeNames) ==
27 static_cast<size_t>(Value::Type::LIST) + 1,
thestige44b9322016-07-19 09:39:30 +090028 "kTypeNames Has Wrong Size");
29
dchengcc8e4d82016-04-05 06:25:51 +090030std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
estade51a57ab2015-05-23 11:42:09 +090031
tony@chromium.orge4948ab2009-12-02 09:20:32 +090032// Make a deep copy of |node|, but don't include empty lists or dictionaries
33// in the copy. It's possible for this function to return NULL and it
34// expects |node| to always be non-NULL.
dchengcc8e4d82016-04-05 06:25:51 +090035std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
36 std::unique_ptr<ListValue> copy;
dcheng1fa44fb2016-05-26 03:30:47 +090037 for (const auto& entry : list) {
jdoerrie45184002017-04-12 03:09:14 +090038 std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(entry);
estade51a57ab2015-05-23 11:42:09 +090039 if (child_copy) {
40 if (!copy)
41 copy.reset(new ListValue);
danakj800d2ea2015-11-25 14:29:58 +090042 copy->Append(std::move(child_copy));
tony@chromium.orge4948ab2009-12-02 09:20:32 +090043 }
estade51a57ab2015-05-23 11:42:09 +090044 }
45 return copy;
46}
tony@chromium.orge4948ab2009-12-02 09:20:32 +090047
dchengcc8e4d82016-04-05 06:25:51 +090048std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
estade51a57ab2015-05-23 11:42:09 +090049 const DictionaryValue& dict) {
dchengcc8e4d82016-04-05 06:25:51 +090050 std::unique_ptr<DictionaryValue> copy;
estade51a57ab2015-05-23 11:42:09 +090051 for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
dchengcc8e4d82016-04-05 06:25:51 +090052 std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(it.value());
estade51a57ab2015-05-23 11:42:09 +090053 if (child_copy) {
54 if (!copy)
55 copy.reset(new DictionaryValue);
danakj800d2ea2015-11-25 14:29:58 +090056 copy->SetWithoutPathExpansion(it.key(), std::move(child_copy));
tony@chromium.orge4948ab2009-12-02 09:20:32 +090057 }
estade51a57ab2015-05-23 11:42:09 +090058 }
59 return copy;
60}
61
dchengcc8e4d82016-04-05 06:25:51 +090062std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
estade51a57ab2015-05-23 11:42:09 +090063 switch (node.GetType()) {
jdoerrie89ee31a2016-12-08 00:43:28 +090064 case Value::Type::LIST:
estade51a57ab2015-05-23 11:42:09 +090065 return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node));
66
jdoerrie89ee31a2016-12-08 00:43:28 +090067 case Value::Type::DICTIONARY:
estade51a57ab2015-05-23 11:42:09 +090068 return CopyDictionaryWithoutEmptyChildren(
69 static_cast<const DictionaryValue&>(node));
tony@chromium.orge4948ab2009-12-02 09:20:32 +090070
71 default:
jdoerrie751d7d72017-04-05 15:44:17 +090072 return MakeUnique<Value>(node);
tony@chromium.orge4948ab2009-12-02 09:20:32 +090073 }
74}
75
jdoerrie93a0cf32017-02-01 19:36:56 +090076} // namespace
77
initial.commit3f4a7322008-07-27 06:49:38 +090078// static
jdoerriec56cc7f2017-04-11 16:45:50 +090079std::unique_ptr<Value> Value::CreateWithCopiedBuffer(const char* buffer,
80 size_t size) {
81 return MakeUnique<Value>(std::vector<char>(buffer, buffer + size));
jdoerrie58325a42017-02-15 17:42:14 +090082}
83
jdoerrie93a0cf32017-02-01 19:36:56 +090084Value::Value(const Value& that) {
jdoerrie31299132017-02-01 23:38:32 +090085 InternalCopyConstructFrom(that);
jdoerrie93a0cf32017-02-01 19:36:56 +090086}
87
brettwce38c192017-03-25 01:36:42 +090088Value::Value(Value&& that) noexcept {
jdoerrie31299132017-02-01 23:38:32 +090089 InternalMoveConstructFrom(std::move(that));
jdoerrie93a0cf32017-02-01 19:36:56 +090090}
91
jdoerrie74f76802017-03-30 15:40:29 +090092Value::Value() noexcept : type_(Type::NONE) {}
jdoerrie93a0cf32017-02-01 19:36:56 +090093
94Value::Value(Type type) : type_(type) {
95 // Initialize with the default value.
96 switch (type_) {
97 case Type::NONE:
98 return;
99
100 case Type::BOOLEAN:
101 bool_value_ = false;
102 return;
103 case Type::INTEGER:
104 int_value_ = 0;
105 return;
106 case Type::DOUBLE:
107 double_value_ = 0.0;
108 return;
jdoerrie31299132017-02-01 23:38:32 +0900109 case Type::STRING:
110 string_value_.Init();
111 return;
jdoerrie58325a42017-02-15 17:42:14 +0900112 case Type::BINARY:
113 binary_value_.Init();
114 return;
jdoerrie93a0cf32017-02-01 19:36:56 +0900115 case Type::DICTIONARY:
jdoerrie1d5b3482017-02-17 22:54:49 +0900116 dict_ptr_.Init(MakeUnique<DictStorage>());
117 return;
118 case Type::LIST:
119 list_.Init();
jdoerrie93a0cf32017-02-01 19:36:56 +0900120 return;
121 }
122}
123
124Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
125
126Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
127
128Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
129 if (!std::isfinite(double_value_)) {
130 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
131 << "values cannot be represented in JSON";
132 double_value_ = 0.0;
133 }
134}
135
jdoerrie31299132017-02-01 23:38:32 +0900136Value::Value(const char* in_string) : type_(Type::STRING) {
137 string_value_.Init(in_string);
138 DCHECK(IsStringUTF8(*string_value_));
139}
140
141Value::Value(const std::string& in_string) : type_(Type::STRING) {
142 string_value_.Init(in_string);
143 DCHECK(IsStringUTF8(*string_value_));
144}
145
jdoerrie74f76802017-03-30 15:40:29 +0900146Value::Value(std::string&& in_string) noexcept : type_(Type::STRING) {
jdoerrie31299132017-02-01 23:38:32 +0900147 string_value_.Init(std::move(in_string));
148 DCHECK(IsStringUTF8(*string_value_));
149}
150
151Value::Value(const char16* in_string) : type_(Type::STRING) {
152 string_value_.Init(UTF16ToUTF8(in_string));
153}
154
155Value::Value(const string16& in_string) : type_(Type::STRING) {
156 string_value_.Init(UTF16ToUTF8(in_string));
157}
158
159Value::Value(StringPiece in_string) : Value(in_string.as_string()) {}
160
jdoerrie58325a42017-02-15 17:42:14 +0900161Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) {
162 binary_value_.Init(in_blob);
163}
164
jdoerrie74f76802017-03-30 15:40:29 +0900165Value::Value(std::vector<char>&& in_blob) noexcept : type_(Type::BINARY) {
jdoerrie58325a42017-02-15 17:42:14 +0900166 binary_value_.Init(std::move(in_blob));
167}
168
mkwst62e159c2017-04-11 15:52:21 +0900169Value::Value(DictStorage&& in_dict) noexcept : type_(Type::DICTIONARY) {
170 dict_ptr_.Init(MakeUnique<DictStorage>(std::move(in_dict)));
171}
172
jdoerrie93a0cf32017-02-01 19:36:56 +0900173Value& Value::operator=(const Value& that) {
dyaroshev798c5ef2017-03-21 02:04:27 +0900174 if (type_ == that.type_) {
175 InternalCopyAssignFromSameType(that);
176 } else {
177 // This is not a self assignment because the type_ doesn't match.
178 InternalCleanup();
179 InternalCopyConstructFrom(that);
jdoerrie93a0cf32017-02-01 19:36:56 +0900180 }
181
182 return *this;
183}
184
jdoerrie74f76802017-03-30 15:40:29 +0900185Value& Value::operator=(Value&& that) noexcept {
dyaroshev798c5ef2017-03-21 02:04:27 +0900186 InternalCleanup();
187 InternalMoveConstructFrom(std::move(that));
jdoerrie93a0cf32017-02-01 19:36:56 +0900188
189 return *this;
190}
191
jdoerrie31299132017-02-01 23:38:32 +0900192Value::~Value() {
193 InternalCleanup();
194}
jdoerrie93a0cf32017-02-01 19:36:56 +0900195
thestige44b9322016-07-19 09:39:30 +0900196// static
197const char* Value::GetTypeName(Value::Type type) {
jdoerrie89ee31a2016-12-08 00:43:28 +0900198 DCHECK_GE(static_cast<int>(type), 0);
thestige44b9322016-07-19 09:39:30 +0900199 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames));
jdoerrie89ee31a2016-12-08 00:43:28 +0900200 return kTypeNames[static_cast<size_t>(type)];
thestige44b9322016-07-19 09:39:30 +0900201}
202
jdoerrie93a0cf32017-02-01 19:36:56 +0900203bool Value::GetBool() const {
204 CHECK(is_bool());
205 return bool_value_;
206}
207
208int Value::GetInt() const {
209 CHECK(is_int());
210 return int_value_;
211}
212
213double Value::GetDouble() const {
214 if (is_double())
215 return double_value_;
216 if (is_int())
217 return int_value_;
218 CHECK(false);
219 return 0.0;
pneubeckb57f3f52015-01-20 20:26:36 +0900220}
221
jdoerrie31299132017-02-01 23:38:32 +0900222const std::string& Value::GetString() const {
223 CHECK(is_string());
224 return *string_value_;
225}
226
jdoerrie58325a42017-02-15 17:42:14 +0900227const std::vector<char>& Value::GetBlob() const {
228 CHECK(is_blob());
229 return *binary_value_;
230}
231
232size_t Value::GetSize() const {
233 return GetBlob().size();
234}
235
236const char* Value::GetBuffer() const {
237 return GetBlob().data();
238}
239
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900240bool Value::GetAsBoolean(bool* out_value) const {
jdoerrie93a0cf32017-02-01 19:36:56 +0900241 if (out_value && is_bool()) {
242 *out_value = bool_value_;
243 return true;
244 }
245 return is_bool();
initial.commit3f4a7322008-07-27 06:49:38 +0900246}
247
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900248bool Value::GetAsInteger(int* out_value) const {
jdoerrie93a0cf32017-02-01 19:36:56 +0900249 if (out_value && is_int()) {
250 *out_value = int_value_;
251 return true;
252 }
253 return is_int();
initial.commit3f4a7322008-07-27 06:49:38 +0900254}
255
arv@chromium.org13413eb2011-02-01 10:02:07 +0900256bool Value::GetAsDouble(double* out_value) const {
jdoerrie93a0cf32017-02-01 19:36:56 +0900257 if (out_value && is_double()) {
258 *out_value = double_value_;
259 return true;
260 } else if (out_value && is_int()) {
261 // Allow promotion from int to double.
262 *out_value = int_value_;
263 return true;
264 }
265 return is_double() || is_int();
initial.commit3f4a7322008-07-27 06:49:38 +0900266}
267
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900268bool Value::GetAsString(std::string* out_value) const {
jdoerrie31299132017-02-01 23:38:32 +0900269 if (out_value && is_string()) {
270 *out_value = *string_value_;
271 return true;
272 }
273 return is_string();
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900274}
275
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900276bool Value::GetAsString(string16* out_value) const {
jdoerrie31299132017-02-01 23:38:32 +0900277 if (out_value && is_string()) {
278 *out_value = UTF8ToUTF16(*string_value_);
279 return true;
280 }
281 return is_string();
initial.commit3f4a7322008-07-27 06:49:38 +0900282}
283
jdoerrie0d1295b2017-03-06 20:12:04 +0900284bool Value::GetAsString(const Value** out_value) const {
jdoerrie31299132017-02-01 23:38:32 +0900285 if (out_value && is_string()) {
jdoerrie0d1295b2017-03-06 20:12:04 +0900286 *out_value = static_cast<const Value*>(this);
jdoerrie31299132017-02-01 23:38:32 +0900287 return true;
288 }
289 return is_string();
estade@chromium.org0fd309d2014-02-06 05:42:06 +0900290}
291
sammc94ef7962016-12-21 17:55:41 +0900292bool Value::GetAsString(StringPiece* out_value) const {
jdoerrie31299132017-02-01 23:38:32 +0900293 if (out_value && is_string()) {
294 *out_value = *string_value_;
295 return true;
296 }
297 return is_string();
sammc94ef7962016-12-21 17:55:41 +0900298}
299
jdoerriec56cc7f2017-04-11 16:45:50 +0900300bool Value::GetAsBinary(const Value** out_value) const {
jdoerrie58325a42017-02-15 17:42:14 +0900301 if (out_value && is_blob()) {
302 *out_value = this;
303 return true;
304 }
305 return is_blob();
jdoerrie93a0cf32017-02-01 19:36:56 +0900306}
307
scottbyer@google.com673b8762010-12-07 09:35:29 +0900308bool Value::GetAsList(ListValue** out_value) {
jdoerrie1d5b3482017-02-17 22:54:49 +0900309 if (out_value && is_list()) {
310 *out_value = static_cast<ListValue*>(this);
311 return true;
312 }
313 return is_list();
scottbyer@google.com673b8762010-12-07 09:35:29 +0900314}
315
bauerb@chromium.org6878e502011-07-12 18:04:38 +0900316bool Value::GetAsList(const ListValue** out_value) const {
jdoerrie1d5b3482017-02-17 22:54:49 +0900317 if (out_value && is_list()) {
318 *out_value = static_cast<const ListValue*>(this);
319 return true;
320 }
321 return is_list();
bauerb@chromium.org6878e502011-07-12 18:04:38 +0900322}
323
battre@chromium.org29eaa252011-11-26 10:11:44 +0900324bool Value::GetAsDictionary(DictionaryValue** out_value) {
jdoerrie1d5b3482017-02-17 22:54:49 +0900325 if (out_value && is_dict()) {
326 *out_value = static_cast<DictionaryValue*>(this);
327 return true;
328 }
329 return is_dict();
battre@chromium.org29eaa252011-11-26 10:11:44 +0900330}
331
332bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
jdoerrie1d5b3482017-02-17 22:54:49 +0900333 if (out_value && is_dict()) {
334 *out_value = static_cast<const DictionaryValue*>(this);
335 return true;
336 }
337 return is_dict();
battre@chromium.org29eaa252011-11-26 10:11:44 +0900338}
339
initial.commit3f4a7322008-07-27 06:49:38 +0900340Value* Value::DeepCopy() const {
jdoerrie751d7d72017-04-05 15:44:17 +0900341 return new Value(*this);
initial.commit3f4a7322008-07-27 06:49:38 +0900342}
343
dchengcc8e4d82016-04-05 06:25:51 +0900344std::unique_ptr<Value> Value::CreateDeepCopy() const {
jdoerrie751d7d72017-04-05 15:44:17 +0900345 return MakeUnique<Value>(*this);
estade77a018f2015-05-07 10:53:08 +0900346}
347
jdoerrie046caee2017-03-29 02:52:00 +0900348bool operator==(const Value& lhs, const Value& rhs) {
349 if (lhs.type_ != rhs.type_)
jdoerrie93a0cf32017-02-01 19:36:56 +0900350 return false;
351
jdoerrie046caee2017-03-29 02:52:00 +0900352 switch (lhs.type_) {
353 case Value::Type::NONE:
jdoerrie93a0cf32017-02-01 19:36:56 +0900354 return true;
jdoerrie046caee2017-03-29 02:52:00 +0900355 case Value::Type::BOOLEAN:
356 return lhs.bool_value_ == rhs.bool_value_;
357 case Value::Type::INTEGER:
358 return lhs.int_value_ == rhs.int_value_;
359 case Value::Type::DOUBLE:
360 return lhs.double_value_ == rhs.double_value_;
361 case Value::Type::STRING:
362 return *lhs.string_value_ == *rhs.string_value_;
363 case Value::Type::BINARY:
364 return *lhs.binary_value_ == *rhs.binary_value_;
jdoerrie1d5b3482017-02-17 22:54:49 +0900365 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
366 // are completely inlined.
jdoerrie046caee2017-03-29 02:52:00 +0900367 case Value::Type::DICTIONARY:
368 if ((*lhs.dict_ptr_)->size() != (*rhs.dict_ptr_)->size())
jdoerrie1d5b3482017-02-17 22:54:49 +0900369 return false;
jdoerrie046caee2017-03-29 02:52:00 +0900370 return std::equal(std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_),
371 std::begin(**rhs.dict_ptr_),
372 [](const Value::DictStorage::value_type& u,
373 const Value::DictStorage::value_type& v) {
374 return std::tie(u.first, *u.second) ==
375 std::tie(v.first, *v.second);
jdoerrie1d5b3482017-02-17 22:54:49 +0900376 });
jdoerrie046caee2017-03-29 02:52:00 +0900377 case Value::Type::LIST:
jdoerrie45184002017-04-12 03:09:14 +0900378 return *lhs.list_ == *rhs.list_;
jdoerrie93a0cf32017-02-01 19:36:56 +0900379 }
jdoerrie1d5b3482017-02-17 22:54:49 +0900380
381 NOTREACHED();
382 return false;
initial.commit3f4a7322008-07-27 06:49:38 +0900383}
384
jdoerrie046caee2017-03-29 02:52:00 +0900385bool operator!=(const Value& lhs, const Value& rhs) {
386 return !(lhs == rhs);
387}
388
389bool operator<(const Value& lhs, const Value& rhs) {
390 if (lhs.type_ != rhs.type_)
391 return lhs.type_ < rhs.type_;
392
393 switch (lhs.type_) {
394 case Value::Type::NONE:
395 return false;
396 case Value::Type::BOOLEAN:
397 return lhs.bool_value_ < rhs.bool_value_;
398 case Value::Type::INTEGER:
399 return lhs.int_value_ < rhs.int_value_;
400 case Value::Type::DOUBLE:
401 return lhs.double_value_ < rhs.double_value_;
402 case Value::Type::STRING:
403 return *lhs.string_value_ < *rhs.string_value_;
404 case Value::Type::BINARY:
405 return *lhs.binary_value_ < *rhs.binary_value_;
406 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
407 // are completely inlined.
408 case Value::Type::DICTIONARY:
409 return std::lexicographical_compare(
410 std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_),
411 std::begin(**rhs.dict_ptr_), std::end(**rhs.dict_ptr_),
412 [](const Value::DictStorage::value_type& u,
413 const Value::DictStorage::value_type& v) {
414 return std::tie(u.first, *u.second) < std::tie(v.first, *v.second);
415 });
416 case Value::Type::LIST:
jdoerrie45184002017-04-12 03:09:14 +0900417 return *lhs.list_ < *rhs.list_;
jdoerrie046caee2017-03-29 02:52:00 +0900418 }
419
420 NOTREACHED();
421 return false;
422}
423
424bool operator>(const Value& lhs, const Value& rhs) {
425 return rhs < lhs;
426}
427
428bool operator<=(const Value& lhs, const Value& rhs) {
429 return !(rhs < lhs);
430}
431
432bool operator>=(const Value& lhs, const Value& rhs) {
433 return !(lhs < rhs);
434}
435
436bool Value::Equals(const Value* other) const {
437 DCHECK(other);
438 return *this == *other;
439}
440
bauerb@chromium.orgfbd55e12010-12-07 03:13:43 +0900441// static
442bool Value::Equals(const Value* a, const Value* b) {
jdoerrie046caee2017-03-29 02:52:00 +0900443 if ((a == NULL) && (b == NULL))
444 return true;
445 if ((a == NULL) ^ (b == NULL))
446 return false;
447 return *a == *b;
bauerb@chromium.orgfbd55e12010-12-07 03:13:43 +0900448}
449
jdoerrie31299132017-02-01 23:38:32 +0900450void Value::InternalCopyFundamentalValue(const Value& that) {
jdoerrie93a0cf32017-02-01 19:36:56 +0900451 switch (type_) {
452 case Type::NONE:
453 // Nothing to do.
454 return;
erg@chromium.org493f5f62010-07-16 06:03:54 +0900455
jdoerrie89ee31a2016-12-08 00:43:28 +0900456 case Type::BOOLEAN:
jdoerrie93a0cf32017-02-01 19:36:56 +0900457 bool_value_ = that.bool_value_;
458 return;
jdoerrie89ee31a2016-12-08 00:43:28 +0900459 case Type::INTEGER:
jdoerrie93a0cf32017-02-01 19:36:56 +0900460 int_value_ = that.int_value_;
461 return;
jdoerrie89ee31a2016-12-08 00:43:28 +0900462 case Type::DOUBLE:
jdoerrie93a0cf32017-02-01 19:36:56 +0900463 double_value_ = that.double_value_;
464 return;
initial.commit3f4a7322008-07-27 06:49:38 +0900465
jdoerrie31299132017-02-01 23:38:32 +0900466 default:
467 NOTREACHED();
468 }
469}
470
471void Value::InternalCopyConstructFrom(const Value& that) {
472 type_ = that.type_;
473
474 switch (type_) {
475 case Type::NONE:
476 case Type::BOOLEAN:
477 case Type::INTEGER:
478 case Type::DOUBLE:
479 InternalCopyFundamentalValue(that);
480 return;
481
482 case Type::STRING:
483 string_value_.Init(*that.string_value_);
484 return;
jdoerrie58325a42017-02-15 17:42:14 +0900485 case Type::BINARY:
486 binary_value_.Init(*that.binary_value_);
487 return;
jdoerrie45184002017-04-12 03:09:14 +0900488 // DictStorage is a move-only type due to the presence of unique_ptrs. This
489 // is why the explicit copy of every element is necessary here.
490 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
491 // directly.
jdoerrie93a0cf32017-02-01 19:36:56 +0900492 case Type::DICTIONARY:
jdoerrie751d7d72017-04-05 15:44:17 +0900493 dict_ptr_.Init(MakeUnique<DictStorage>());
494 for (const auto& it : **that.dict_ptr_) {
495 (*dict_ptr_)
496 ->emplace_hint((*dict_ptr_)->end(), it.first,
497 MakeUnique<Value>(*it.second));
498 }
jdoerrie1d5b3482017-02-17 22:54:49 +0900499 return;
500 case Type::LIST:
jdoerrie45184002017-04-12 03:09:14 +0900501 list_.Init(*that.list_);
jdoerrie93a0cf32017-02-01 19:36:56 +0900502 return;
initial.commit3f4a7322008-07-27 06:49:38 +0900503 }
504}
505
jdoerrie31299132017-02-01 23:38:32 +0900506void Value::InternalMoveConstructFrom(Value&& that) {
507 type_ = that.type_;
initial.commit3f4a7322008-07-27 06:49:38 +0900508
jdoerrie31299132017-02-01 23:38:32 +0900509 switch (type_) {
510 case Type::NONE:
511 case Type::BOOLEAN:
512 case Type::INTEGER:
513 case Type::DOUBLE:
514 InternalCopyFundamentalValue(that);
515 return;
516
517 case Type::STRING:
518 string_value_.InitFromMove(std::move(that.string_value_));
519 return;
jdoerrie58325a42017-02-15 17:42:14 +0900520 case Type::BINARY:
521 binary_value_.InitFromMove(std::move(that.binary_value_));
522 return;
jdoerrie31299132017-02-01 23:38:32 +0900523 case Type::DICTIONARY:
jdoerrie1d5b3482017-02-17 22:54:49 +0900524 dict_ptr_.InitFromMove(std::move(that.dict_ptr_));
525 return;
526 case Type::LIST:
527 list_.InitFromMove(std::move(that.list_));
jdoerrie31299132017-02-01 23:38:32 +0900528 return;
529 }
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900530}
531
vabr7eac8352017-03-08 08:34:30 +0900532void Value::InternalCopyAssignFromSameType(const Value& that) {
dyaroshev798c5ef2017-03-21 02:04:27 +0900533 // TODO(crbug.com/646113): make this a DCHECK once base::Value does not have
534 // subclasses.
vabr7eac8352017-03-08 08:34:30 +0900535 CHECK_EQ(type_, that.type_);
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900536
jdoerrie31299132017-02-01 23:38:32 +0900537 switch (type_) {
538 case Type::NONE:
539 case Type::BOOLEAN:
540 case Type::INTEGER:
541 case Type::DOUBLE:
542 InternalCopyFundamentalValue(that);
543 return;
544
545 case Type::STRING:
546 *string_value_ = *that.string_value_;
547 return;
jdoerrie58325a42017-02-15 17:42:14 +0900548 case Type::BINARY:
549 *binary_value_ = *that.binary_value_;
550 return;
jdoerrie45184002017-04-12 03:09:14 +0900551 // DictStorage is a move-only type due to the presence of unique_ptrs. This
552 // is why the explicit call to the copy constructor is necessary here.
553 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
554 // directly.
555 case Type::DICTIONARY: {
556 Value copy = that;
557 *dict_ptr_ = std::move(*copy.dict_ptr_);
jdoerrie1d5b3482017-02-17 22:54:49 +0900558 return;
jdoerrie45184002017-04-12 03:09:14 +0900559 }
jdoerrie1d5b3482017-02-17 22:54:49 +0900560 case Type::LIST:
jdoerrie45184002017-04-12 03:09:14 +0900561 *list_ = *that.list_;
jdoerrie31299132017-02-01 23:38:32 +0900562 return;
563 }
initial.commit3f4a7322008-07-27 06:49:38 +0900564}
565
jdoerrie31299132017-02-01 23:38:32 +0900566void Value::InternalCleanup() {
567 switch (type_) {
568 case Type::NONE:
569 case Type::BOOLEAN:
570 case Type::INTEGER:
571 case Type::DOUBLE:
572 // Nothing to do
573 return;
estade@chromium.org0fd309d2014-02-06 05:42:06 +0900574
jdoerrie31299132017-02-01 23:38:32 +0900575 case Type::STRING:
576 string_value_.Destroy();
577 return;
jdoerrie58325a42017-02-15 17:42:14 +0900578 case Type::BINARY:
579 binary_value_.Destroy();
580 return;
jdoerrie31299132017-02-01 23:38:32 +0900581 case Type::DICTIONARY:
jdoerrie1d5b3482017-02-17 22:54:49 +0900582 dict_ptr_.Destroy();
583 return;
584 case Type::LIST:
585 list_.Destroy();
jdoerrie31299132017-02-01 23:38:32 +0900586 return;
587 }
initial.commit3f4a7322008-07-27 06:49:38 +0900588}
589
initial.commit3f4a7322008-07-27 06:49:38 +0900590///////////////////// DictionaryValue ////////////////////
591
reillygd39049b2015-09-11 09:25:54 +0900592// static
dchengcc8e4d82016-04-05 06:25:51 +0900593std::unique_ptr<DictionaryValue> DictionaryValue::From(
594 std::unique_ptr<Value> value) {
reillygd39049b2015-09-11 09:25:54 +0900595 DictionaryValue* out;
596 if (value && value->GetAsDictionary(&out)) {
597 ignore_result(value.release());
dchengcc8e4d82016-04-05 06:25:51 +0900598 return WrapUnique(out);
reillygd39049b2015-09-11 09:25:54 +0900599 }
600 return nullptr;
601}
602
jdoerrie89ee31a2016-12-08 00:43:28 +0900603DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {}
erg@chromium.org493f5f62010-07-16 06:03:54 +0900604
dchengae1c2d62016-08-26 01:07:11 +0900605bool DictionaryValue::HasKey(StringPiece key) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900606 DCHECK(IsStringUTF8(key));
jdoerrie1d5b3482017-02-17 22:54:49 +0900607 auto current_entry = (*dict_ptr_)->find(key.as_string());
608 DCHECK((current_entry == (*dict_ptr_)->end()) || current_entry->second);
609 return current_entry != (*dict_ptr_)->end();
tony@chromium.orge4948ab2009-12-02 09:20:32 +0900610}
611
initial.commit3f4a7322008-07-27 06:49:38 +0900612void DictionaryValue::Clear() {
jdoerrie1d5b3482017-02-17 22:54:49 +0900613 (*dict_ptr_)->clear();
initial.commit3f4a7322008-07-27 06:49:38 +0900614}
615
dchengae1c2d62016-08-26 01:07:11 +0900616void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900617 DCHECK(IsStringUTF8(path));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900618 DCHECK(in_value);
619
lazyboya6030462016-10-04 09:18:57 +0900620 StringPiece current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900621 DictionaryValue* current_dictionary = this;
622 for (size_t delimiter_position = current_path.find('.');
lazyboya6030462016-10-04 09:18:57 +0900623 delimiter_position != StringPiece::npos;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900624 delimiter_position = current_path.find('.')) {
625 // Assume that we're indexing into a dictionary.
lazyboya6030462016-10-04 09:18:57 +0900626 StringPiece key = current_path.substr(0, delimiter_position);
corona1050a617b2016-10-07 21:53:36 +0900627 DictionaryValue* child_dictionary = nullptr;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900628 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
629 child_dictionary = new DictionaryValue;
corona1050a617b2016-10-07 21:53:36 +0900630 current_dictionary->SetWithoutPathExpansion(
631 key, base::WrapUnique(child_dictionary));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900632 }
633
634 current_dictionary = child_dictionary;
lazyboya6030462016-10-04 09:18:57 +0900635 current_path = current_path.substr(delimiter_position + 1);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900636 }
637
danakj800d2ea2015-11-25 14:29:58 +0900638 current_dictionary->SetWithoutPathExpansion(current_path,
639 std::move(in_value));
estade948395d2015-01-07 05:06:50 +0900640}
641
dchengae1c2d62016-08-26 01:07:11 +0900642void DictionaryValue::Set(StringPiece path, Value* in_value) {
dchengcc8e4d82016-04-05 06:25:51 +0900643 Set(path, WrapUnique(in_value));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900644}
645
dchengae1c2d62016-08-26 01:07:11 +0900646void DictionaryValue::SetBoolean(StringPiece path, bool in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +0900647 Set(path, new Value(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900648}
649
dchengae1c2d62016-08-26 01:07:11 +0900650void DictionaryValue::SetInteger(StringPiece path, int in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +0900651 Set(path, new Value(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900652}
653
dchengae1c2d62016-08-26 01:07:11 +0900654void DictionaryValue::SetDouble(StringPiece path, double in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +0900655 Set(path, new Value(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900656}
657
dchengae1c2d62016-08-26 01:07:11 +0900658void DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
jdoerrie0d1295b2017-03-06 20:12:04 +0900659 Set(path, new Value(in_value));
dchengae1c2d62016-08-26 01:07:11 +0900660}
661
662void DictionaryValue::SetString(StringPiece path, const string16& in_value) {
jdoerrie0d1295b2017-03-06 20:12:04 +0900663 Set(path, new Value(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900664}
665
dchengae1c2d62016-08-26 01:07:11 +0900666void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
dchengcc8e4d82016-04-05 06:25:51 +0900667 std::unique_ptr<Value> in_value) {
jdoerrie1d5b3482017-02-17 22:54:49 +0900668 (**dict_ptr_)[key.as_string()] = std::move(in_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900669}
670
dchengae1c2d62016-08-26 01:07:11 +0900671void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
estade948395d2015-01-07 05:06:50 +0900672 Value* in_value) {
dchengcc8e4d82016-04-05 06:25:51 +0900673 SetWithoutPathExpansion(key, WrapUnique(in_value));
estade948395d2015-01-07 05:06:50 +0900674}
675
dchengae1c2d62016-08-26 01:07:11 +0900676void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path,
677 bool in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +0900678 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +0900679}
680
dchengae1c2d62016-08-26 01:07:11 +0900681void DictionaryValue::SetIntegerWithoutPathExpansion(StringPiece path,
682 int in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +0900683 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +0900684}
685
dchengae1c2d62016-08-26 01:07:11 +0900686void DictionaryValue::SetDoubleWithoutPathExpansion(StringPiece path,
687 double in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +0900688 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +0900689}
690
dchengae1c2d62016-08-26 01:07:11 +0900691void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
692 StringPiece in_value) {
jdoerrie0d1295b2017-03-06 20:12:04 +0900693 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +0900694}
695
dchengae1c2d62016-08-26 01:07:11 +0900696void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
697 const string16& in_value) {
jdoerrie0d1295b2017-03-06 20:12:04 +0900698 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +0900699}
700
asvitkine22632bf2015-06-24 03:22:52 +0900701bool DictionaryValue::Get(StringPiece path,
gab@chromium.org903d5c92013-11-27 10:38:24 +0900702 const Value** out_value) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900703 DCHECK(IsStringUTF8(path));
asvitkine22632bf2015-06-24 03:22:52 +0900704 StringPiece current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900705 const DictionaryValue* current_dictionary = this;
706 for (size_t delimiter_position = current_path.find('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900707 delimiter_position != std::string::npos;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900708 delimiter_position = current_path.find('.')) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900709 const DictionaryValue* child_dictionary = NULL;
asvitkinec568efe2015-07-15 12:10:12 +0900710 if (!current_dictionary->GetDictionaryWithoutPathExpansion(
lazyboya6030462016-10-04 09:18:57 +0900711 current_path.substr(0, delimiter_position), &child_dictionary)) {
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900712 return false;
asvitkine22632bf2015-06-24 03:22:52 +0900713 }
initial.commit3f4a7322008-07-27 06:49:38 +0900714
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900715 current_dictionary = child_dictionary;
asvitkine22632bf2015-06-24 03:22:52 +0900716 current_path = current_path.substr(delimiter_position + 1);
initial.commit3f4a7322008-07-27 06:49:38 +0900717 }
718
lazyboya6030462016-10-04 09:18:57 +0900719 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900720}
721
asvitkine22632bf2015-06-24 03:22:52 +0900722bool DictionaryValue::Get(StringPiece path, Value** out_value) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900723 return static_cast<const DictionaryValue&>(*this).Get(
724 path,
725 const_cast<const Value**>(out_value));
726}
727
dchengae1c2d62016-08-26 01:07:11 +0900728bool DictionaryValue::GetBoolean(StringPiece path, bool* bool_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900729 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900730 if (!Get(path, &value))
731 return false;
732
733 return value->GetAsBoolean(bool_value);
734}
735
dchengae1c2d62016-08-26 01:07:11 +0900736bool DictionaryValue::GetInteger(StringPiece path, int* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900737 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900738 if (!Get(path, &value))
739 return false;
740
741 return value->GetAsInteger(out_value);
742}
743
dchengae1c2d62016-08-26 01:07:11 +0900744bool DictionaryValue::GetDouble(StringPiece path, double* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900745 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900746 if (!Get(path, &value))
747 return false;
748
arv@chromium.org13413eb2011-02-01 10:02:07 +0900749 return value->GetAsDouble(out_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900750}
751
dchengae1c2d62016-08-26 01:07:11 +0900752bool DictionaryValue::GetString(StringPiece path,
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900753 std::string* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900754 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900755 if (!Get(path, &value))
756 return false;
757
758 return value->GetAsString(out_value);
759}
760
dchengae1c2d62016-08-26 01:07:11 +0900761bool DictionaryValue::GetString(StringPiece path, string16* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900762 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900763 if (!Get(path, &value))
764 return false;
765
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900766 return value->GetAsString(out_value);
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900767}
768
dchengae1c2d62016-08-26 01:07:11 +0900769bool DictionaryValue::GetStringASCII(StringPiece path,
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900770 std::string* out_value) const {
771 std::string out;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900772 if (!GetString(path, &out))
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900773 return false;
774
775 if (!IsStringASCII(out)) {
776 NOTREACHED();
777 return false;
778 }
779
780 out_value->assign(out);
781 return true;
782}
783
dchengae1c2d62016-08-26 01:07:11 +0900784bool DictionaryValue::GetBinary(StringPiece path,
jdoerriec56cc7f2017-04-11 16:45:50 +0900785 const Value** out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900786 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900787 bool result = Get(path, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +0900788 if (!result || !value->IsType(Type::BINARY))
initial.commit3f4a7322008-07-27 06:49:38 +0900789 return false;
790
791 if (out_value)
jdoerrie58325a42017-02-15 17:42:14 +0900792 *out_value = value;
initial.commit3f4a7322008-07-27 06:49:38 +0900793
794 return true;
795}
796
jdoerriec56cc7f2017-04-11 16:45:50 +0900797bool DictionaryValue::GetBinary(StringPiece path, Value** out_value) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900798 return static_cast<const DictionaryValue&>(*this).GetBinary(
jdoerriec56cc7f2017-04-11 16:45:50 +0900799 path, const_cast<const Value**>(out_value));
vabr@chromium.org74562432012-07-28 07:27:11 +0900800}
801
asvitkine22632bf2015-06-24 03:22:52 +0900802bool DictionaryValue::GetDictionary(StringPiece path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900803 const DictionaryValue** out_value) const {
804 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900805 bool result = Get(path, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +0900806 if (!result || !value->IsType(Type::DICTIONARY))
initial.commit3f4a7322008-07-27 06:49:38 +0900807 return false;
808
809 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900810 *out_value = static_cast<const DictionaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900811
812 return true;
813}
814
asvitkine22632bf2015-06-24 03:22:52 +0900815bool DictionaryValue::GetDictionary(StringPiece path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900816 DictionaryValue** out_value) {
817 return static_cast<const DictionaryValue&>(*this).GetDictionary(
818 path,
819 const_cast<const DictionaryValue**>(out_value));
820}
821
dchengae1c2d62016-08-26 01:07:11 +0900822bool DictionaryValue::GetList(StringPiece path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900823 const ListValue** out_value) const {
824 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900825 bool result = Get(path, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +0900826 if (!result || !value->IsType(Type::LIST))
initial.commit3f4a7322008-07-27 06:49:38 +0900827 return false;
828
829 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900830 *out_value = static_cast<const ListValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900831
832 return true;
833}
834
dchengae1c2d62016-08-26 01:07:11 +0900835bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900836 return static_cast<const DictionaryValue&>(*this).GetList(
837 path,
838 const_cast<const ListValue**>(out_value));
839}
840
dchengae1c2d62016-08-26 01:07:11 +0900841bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900842 const Value** out_value) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900843 DCHECK(IsStringUTF8(key));
jdoerrie1d5b3482017-02-17 22:54:49 +0900844 auto entry_iterator = (*dict_ptr_)->find(key.as_string());
845 if (entry_iterator == (*dict_ptr_)->end())
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900846 return false;
initial.commit3f4a7322008-07-27 06:49:38 +0900847
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900848 if (out_value)
dcheng1fa44fb2016-05-26 03:30:47 +0900849 *out_value = entry_iterator->second.get();
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900850 return true;
851}
852
dchengae1c2d62016-08-26 01:07:11 +0900853bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900854 Value** out_value) {
855 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
856 key,
857 const_cast<const Value**>(out_value));
858}
859
dchengae1c2d62016-08-26 01:07:11 +0900860bool DictionaryValue::GetBooleanWithoutPathExpansion(StringPiece key,
pneubeck@chromium.org3b600542012-11-07 01:46:55 +0900861 bool* out_value) const {
862 const Value* value;
863 if (!GetWithoutPathExpansion(key, &value))
864 return false;
865
866 return value->GetAsBoolean(out_value);
867}
868
dchengae1c2d62016-08-26 01:07:11 +0900869bool DictionaryValue::GetIntegerWithoutPathExpansion(StringPiece key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900870 int* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900871 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900872 if (!GetWithoutPathExpansion(key, &value))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900873 return false;
874
875 return value->GetAsInteger(out_value);
876}
877
dchengae1c2d62016-08-26 01:07:11 +0900878bool DictionaryValue::GetDoubleWithoutPathExpansion(StringPiece key,
arv@chromium.org13413eb2011-02-01 10:02:07 +0900879 double* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900880 const Value* value;
jam@chromium.org5bd53922010-10-01 16:28:25 +0900881 if (!GetWithoutPathExpansion(key, &value))
882 return false;
883
arv@chromium.org13413eb2011-02-01 10:02:07 +0900884 return value->GetAsDouble(out_value);
jam@chromium.org5bd53922010-10-01 16:28:25 +0900885}
886
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900887bool DictionaryValue::GetStringWithoutPathExpansion(
dchengae1c2d62016-08-26 01:07:11 +0900888 StringPiece key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900889 std::string* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900890 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900891 if (!GetWithoutPathExpansion(key, &value))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900892 return false;
893
894 return value->GetAsString(out_value);
895}
896
dchengae1c2d62016-08-26 01:07:11 +0900897bool DictionaryValue::GetStringWithoutPathExpansion(StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900898 string16* out_value) const {
899 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900900 if (!GetWithoutPathExpansion(key, &value))
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900901 return false;
902
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900903 return value->GetAsString(out_value);
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900904}
905
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900906bool DictionaryValue::GetDictionaryWithoutPathExpansion(
dchengae1c2d62016-08-26 01:07:11 +0900907 StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900908 const DictionaryValue** out_value) const {
909 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900910 bool result = GetWithoutPathExpansion(key, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +0900911 if (!result || !value->IsType(Type::DICTIONARY))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900912 return false;
913
914 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900915 *out_value = static_cast<const DictionaryValue*>(value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900916
917 return true;
918}
919
vabr@chromium.org74562432012-07-28 07:27:11 +0900920bool DictionaryValue::GetDictionaryWithoutPathExpansion(
dchengae1c2d62016-08-26 01:07:11 +0900921 StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900922 DictionaryValue** out_value) {
923 const DictionaryValue& const_this =
924 static_cast<const DictionaryValue&>(*this);
925 return const_this.GetDictionaryWithoutPathExpansion(
926 key,
927 const_cast<const DictionaryValue**>(out_value));
928}
929
930bool DictionaryValue::GetListWithoutPathExpansion(
dchengae1c2d62016-08-26 01:07:11 +0900931 StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900932 const ListValue** out_value) const {
933 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900934 bool result = GetWithoutPathExpansion(key, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +0900935 if (!result || !value->IsType(Type::LIST))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900936 return false;
937
938 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900939 *out_value = static_cast<const ListValue*>(value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900940
941 return true;
942}
943
dchengae1c2d62016-08-26 01:07:11 +0900944bool DictionaryValue::GetListWithoutPathExpansion(StringPiece key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900945 ListValue** out_value) {
946 return
947 static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
948 key,
949 const_cast<const ListValue**>(out_value));
950}
951
dchengae1c2d62016-08-26 01:07:11 +0900952bool DictionaryValue::Remove(StringPiece path,
dchengcc8e4d82016-04-05 06:25:51 +0900953 std::unique_ptr<Value>* out_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900954 DCHECK(IsStringUTF8(path));
lazyboya6030462016-10-04 09:18:57 +0900955 StringPiece current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900956 DictionaryValue* current_dictionary = this;
957 size_t delimiter_position = current_path.rfind('.');
lazyboya6030462016-10-04 09:18:57 +0900958 if (delimiter_position != StringPiece::npos) {
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900959 if (!GetDictionary(current_path.substr(0, delimiter_position),
960 &current_dictionary))
961 return false;
lazyboya6030462016-10-04 09:18:57 +0900962 current_path = current_path.substr(delimiter_position + 1);
initial.commit3f4a7322008-07-27 06:49:38 +0900963 }
964
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900965 return current_dictionary->RemoveWithoutPathExpansion(current_path,
966 out_value);
967}
968
dchengcc8e4d82016-04-05 06:25:51 +0900969bool DictionaryValue::RemoveWithoutPathExpansion(
dchengae1c2d62016-08-26 01:07:11 +0900970 StringPiece key,
dchengcc8e4d82016-04-05 06:25:51 +0900971 std::unique_ptr<Value>* out_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900972 DCHECK(IsStringUTF8(key));
jdoerrie1d5b3482017-02-17 22:54:49 +0900973 auto entry_iterator = (*dict_ptr_)->find(key.as_string());
974 if (entry_iterator == (*dict_ptr_)->end())
initial.commit3f4a7322008-07-27 06:49:38 +0900975 return false;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900976
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900977 if (out_value)
dcheng1fa44fb2016-05-26 03:30:47 +0900978 *out_value = std::move(entry_iterator->second);
jdoerrie1d5b3482017-02-17 22:54:49 +0900979 (*dict_ptr_)->erase(entry_iterator);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900980 return true;
initial.commit3f4a7322008-07-27 06:49:38 +0900981}
982
dchengae1c2d62016-08-26 01:07:11 +0900983bool DictionaryValue::RemovePath(StringPiece path,
dchengcc8e4d82016-04-05 06:25:51 +0900984 std::unique_ptr<Value>* out_value) {
gab@chromium.org903d5c92013-11-27 10:38:24 +0900985 bool result = false;
986 size_t delimiter_position = path.find('.');
987
988 if (delimiter_position == std::string::npos)
989 return RemoveWithoutPathExpansion(path, out_value);
990
dchengae1c2d62016-08-26 01:07:11 +0900991 StringPiece subdict_path = path.substr(0, delimiter_position);
gab@chromium.org903d5c92013-11-27 10:38:24 +0900992 DictionaryValue* subdict = NULL;
993 if (!GetDictionary(subdict_path, &subdict))
994 return false;
995 result = subdict->RemovePath(path.substr(delimiter_position + 1),
996 out_value);
997 if (result && subdict->empty())
998 RemoveWithoutPathExpansion(subdict_path, NULL);
999
1000 return result;
1001}
1002
dchengcc8e4d82016-04-05 06:25:51 +09001003std::unique_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren()
estade51a57ab2015-05-23 11:42:09 +09001004 const {
dchengcc8e4d82016-04-05 06:25:51 +09001005 std::unique_ptr<DictionaryValue> copy =
1006 CopyDictionaryWithoutEmptyChildren(*this);
estade51a57ab2015-05-23 11:42:09 +09001007 if (!copy)
1008 copy.reset(new DictionaryValue);
1009 return copy;
initial.commit3f4a7322008-07-27 06:49:38 +09001010}
1011
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +09001012void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
vabr7eac8352017-03-08 08:34:30 +09001013 CHECK(dictionary->is_dict());
pneubeck@chromium.org03ed8622013-03-10 20:32:49 +09001014 for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
1015 const Value* merge_value = &it.value();
1016 // Check whether we have to merge dictionaries.
jdoerrie89ee31a2016-12-08 00:43:28 +09001017 if (merge_value->IsType(Value::Type::DICTIONARY)) {
pneubeck@chromium.org03ed8622013-03-10 20:32:49 +09001018 DictionaryValue* sub_dict;
1019 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
1020 sub_dict->MergeDictionary(
1021 static_cast<const DictionaryValue*>(merge_value));
1022 continue;
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +09001023 }
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +09001024 }
pneubeck@chromium.org03ed8622013-03-10 20:32:49 +09001025 // All other cases: Make a copy and hook it up.
jdoerrie751d7d72017-04-05 15:44:17 +09001026 SetWithoutPathExpansion(it.key(), MakeUnique<Value>(*merge_value));
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +09001027 }
1028}
1029
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001030void DictionaryValue::Swap(DictionaryValue* other) {
vabr7eac8352017-03-08 08:34:30 +09001031 CHECK(other->is_dict());
jdoerrie1d5b3482017-02-17 22:54:49 +09001032 dict_ptr_->swap(*(other->dict_ptr_));
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001033}
1034
hans@chromium.orgd5d38e32012-08-10 21:45:35 +09001035DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
jdoerrie1d5b3482017-02-17 22:54:49 +09001036 : target_(target), it_((*target.dict_ptr_)->begin()) {}
hans@chromium.orgd5d38e32012-08-10 21:45:35 +09001037
vmpstrc8651bf2016-02-25 09:50:31 +09001038DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
1039
phajdan.jr@chromium.org8e2b2082013-12-11 03:52:22 +09001040DictionaryValue::Iterator::~Iterator() {}
1041
akalin@chromium.org810f92f2011-01-18 11:16:59 +09001042DictionaryValue* DictionaryValue::DeepCopy() const {
jdoerrie751d7d72017-04-05 15:44:17 +09001043 return new DictionaryValue(*this);
erg@google.com67a25432011-01-08 05:23:43 +09001044}
1045
dchengcc8e4d82016-04-05 06:25:51 +09001046std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
jdoerrie751d7d72017-04-05 15:44:17 +09001047 return MakeUnique<DictionaryValue>(*this);
estade77a018f2015-05-07 10:53:08 +09001048}
1049
initial.commit3f4a7322008-07-27 06:49:38 +09001050///////////////////// ListValue ////////////////////
1051
reillygd39049b2015-09-11 09:25:54 +09001052// static
dchengcc8e4d82016-04-05 06:25:51 +09001053std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) {
reillygd39049b2015-09-11 09:25:54 +09001054 ListValue* out;
1055 if (value && value->GetAsList(&out)) {
1056 ignore_result(value.release());
dchengcc8e4d82016-04-05 06:25:51 +09001057 return WrapUnique(out);
reillygd39049b2015-09-11 09:25:54 +09001058 }
1059 return nullptr;
1060}
1061
jdoerrie89ee31a2016-12-08 00:43:28 +09001062ListValue::ListValue() : Value(Type::LIST) {}
erg@chromium.org493f5f62010-07-16 06:03:54 +09001063
initial.commit3f4a7322008-07-27 06:49:38 +09001064void ListValue::Clear() {
jdoerrie1d5b3482017-02-17 22:54:49 +09001065 list_->clear();
initial.commit3f4a7322008-07-27 06:49:38 +09001066}
1067
jdoerrie45184002017-04-12 03:09:14 +09001068void ListValue::Reserve(size_t n) {
1069 list_->reserve(n);
1070}
1071
initial.commit3f4a7322008-07-27 06:49:38 +09001072bool ListValue::Set(size_t index, Value* in_value) {
dcheng1fa44fb2016-05-26 03:30:47 +09001073 return Set(index, WrapUnique(in_value));
1074}
1075
1076bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +09001077 if (!in_value)
1078 return false;
1079
jdoerrie1d5b3482017-02-17 22:54:49 +09001080 if (index >= list_->size()) {
initial.commit3f4a7322008-07-27 06:49:38 +09001081 // Pad out any intermediate indexes with null settings
jdoerrie1d5b3482017-02-17 22:54:49 +09001082 while (index > list_->size())
jdoerriefcdbae72017-04-07 15:39:00 +09001083 Append(MakeUnique<Value>());
dcheng1fa44fb2016-05-26 03:30:47 +09001084 Append(std::move(in_value));
initial.commit3f4a7322008-07-27 06:49:38 +09001085 } else {
jdoerrie45184002017-04-12 03:09:14 +09001086 (*list_)[index] = std::move(*in_value);
initial.commit3f4a7322008-07-27 06:49:38 +09001087 }
1088 return true;
1089}
1090
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001091bool ListValue::Get(size_t index, const Value** out_value) const {
jdoerrie1d5b3482017-02-17 22:54:49 +09001092 if (index >= list_->size())
initial.commit3f4a7322008-07-27 06:49:38 +09001093 return false;
1094
1095 if (out_value)
jdoerrie45184002017-04-12 03:09:14 +09001096 *out_value = &(*list_)[index];
initial.commit3f4a7322008-07-27 06:49:38 +09001097
1098 return true;
1099}
1100
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001101bool ListValue::Get(size_t index, Value** out_value) {
1102 return static_cast<const ListValue&>(*this).Get(
1103 index,
1104 const_cast<const Value**>(out_value));
1105}
1106
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001107bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001108 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001109 if (!Get(index, &value))
1110 return false;
1111
1112 return value->GetAsBoolean(bool_value);
1113}
1114
1115bool ListValue::GetInteger(size_t index, int* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001116 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001117 if (!Get(index, &value))
1118 return false;
1119
1120 return value->GetAsInteger(out_value);
1121}
1122
arv@chromium.org13413eb2011-02-01 10:02:07 +09001123bool ListValue::GetDouble(size_t index, double* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001124 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001125 if (!Get(index, &value))
1126 return false;
1127
arv@chromium.org13413eb2011-02-01 10:02:07 +09001128 return value->GetAsDouble(out_value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001129}
1130
1131bool ListValue::GetString(size_t index, std::string* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001132 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001133 if (!Get(index, &value))
1134 return false;
1135
1136 return value->GetAsString(out_value);
1137}
1138
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +09001139bool ListValue::GetString(size_t index, string16* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001140 const Value* value;
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +09001141 if (!Get(index, &value))
1142 return false;
1143
1144 return value->GetAsString(out_value);
1145}
1146
jdoerriec56cc7f2017-04-11 16:45:50 +09001147bool ListValue::GetBinary(size_t index, const Value** out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001148 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001149 bool result = Get(index, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +09001150 if (!result || !value->IsType(Type::BINARY))
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001151 return false;
1152
1153 if (out_value)
jdoerrie58325a42017-02-15 17:42:14 +09001154 *out_value = value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001155
1156 return true;
1157}
1158
jdoerriec56cc7f2017-04-11 16:45:50 +09001159bool ListValue::GetBinary(size_t index, Value** out_value) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001160 return static_cast<const ListValue&>(*this).GetBinary(
jdoerriec56cc7f2017-04-11 16:45:50 +09001161 index, const_cast<const Value**>(out_value));
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001162}
1163
1164bool ListValue::GetDictionary(size_t index,
1165 const DictionaryValue** out_value) const {
1166 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +09001167 bool result = Get(index, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +09001168 if (!result || !value->IsType(Type::DICTIONARY))
initial.commit3f4a7322008-07-27 06:49:38 +09001169 return false;
1170
1171 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001172 *out_value = static_cast<const DictionaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +09001173
1174 return true;
1175}
1176
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001177bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
1178 return static_cast<const ListValue&>(*this).GetDictionary(
1179 index,
1180 const_cast<const DictionaryValue**>(out_value));
1181}
1182
1183bool ListValue::GetList(size_t index, const ListValue** out_value) const {
1184 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001185 bool result = Get(index, &value);
jdoerrie89ee31a2016-12-08 00:43:28 +09001186 if (!result || !value->IsType(Type::LIST))
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001187 return false;
1188
1189 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001190 *out_value = static_cast<const ListValue*>(value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +09001191
1192 return true;
1193}
1194
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001195bool ListValue::GetList(size_t index, ListValue** out_value) {
1196 return static_cast<const ListValue&>(*this).GetList(
1197 index,
1198 const_cast<const ListValue**>(out_value));
1199}
1200
dchengcc8e4d82016-04-05 06:25:51 +09001201bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
jdoerrie1d5b3482017-02-17 22:54:49 +09001202 if (index >= list_->size())
initial.commit3f4a7322008-07-27 06:49:38 +09001203 return false;
1204
1205 if (out_value)
jdoerrie45184002017-04-12 03:09:14 +09001206 *out_value = MakeUnique<Value>(std::move((*list_)[index]));
initial.commit3f4a7322008-07-27 06:49:38 +09001207
jdoerrie1d5b3482017-02-17 22:54:49 +09001208 list_->erase(list_->begin() + index);
initial.commit3f4a7322008-07-27 06:49:38 +09001209 return true;
1210}
1211
tfarina@chromium.org09cf4342011-08-14 02:34:31 +09001212bool ListValue::Remove(const Value& value, size_t* index) {
jdoerrie45184002017-04-12 03:09:14 +09001213 auto it = std::find(list_->begin(), list_->end(), value);
robertshield@chromium.org9fb9e372010-03-23 05:12:50 +09001214
jdoerrie45184002017-04-12 03:09:14 +09001215 if (it == list_->end())
1216 return false;
1217
1218 if (index)
1219 *index = std::distance(list_->begin(), it);
1220
1221 list_->erase(it);
1222 return true;
pkasting@chromium.org727139c2009-05-09 09:33:04 +09001223}
1224
bauerb@chromium.orgae43e0a2013-08-06 22:33:04 +09001225ListValue::iterator ListValue::Erase(iterator iter,
dchengcc8e4d82016-04-05 06:25:51 +09001226 std::unique_ptr<Value>* out_value) {
estade@chromium.org52852d52012-07-03 11:51:43 +09001227 if (out_value)
jdoerrie45184002017-04-12 03:09:14 +09001228 *out_value = MakeUnique<Value>(std::move(*iter));
estade@chromium.org52852d52012-07-03 11:51:43 +09001229
jdoerrie1d5b3482017-02-17 22:54:49 +09001230 return list_->erase(iter);
estade@chromium.org52852d52012-07-03 11:51:43 +09001231}
1232
dchengcc8e4d82016-04-05 06:25:51 +09001233void ListValue::Append(std::unique_ptr<Value> in_value) {
jdoerrie45184002017-04-12 03:09:14 +09001234 list_->push_back(std::move(*in_value));
estade77a018f2015-05-07 10:53:08 +09001235}
1236
dchengd66aba82016-10-17 11:19:00 +09001237#if !defined(OS_LINUX)
initial.commit3f4a7322008-07-27 06:49:38 +09001238void ListValue::Append(Value* in_value) {
1239 DCHECK(in_value);
dcheng1fa44fb2016-05-26 03:30:47 +09001240 Append(WrapUnique(in_value));
initial.commit3f4a7322008-07-27 06:49:38 +09001241}
dcheng17f21de2016-09-17 10:30:15 +09001242#endif
initial.commit3f4a7322008-07-27 06:49:38 +09001243
kalman@chromium.org5081d8e2012-09-14 11:14:01 +09001244void ListValue::AppendBoolean(bool in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +09001245 Append(MakeUnique<Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +09001246}
1247
1248void ListValue::AppendInteger(int in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +09001249 Append(MakeUnique<Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +09001250}
1251
1252void ListValue::AppendDouble(double in_value) {
jdoerriebfe825e2017-03-02 21:09:19 +09001253 Append(MakeUnique<Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +09001254}
1255
dchengae1c2d62016-08-26 01:07:11 +09001256void ListValue::AppendString(StringPiece in_value) {
jdoerrie0d1295b2017-03-06 20:12:04 +09001257 Append(MakeUnique<Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +09001258}
1259
1260void ListValue::AppendString(const string16& in_value) {
jdoerrie0d1295b2017-03-06 20:12:04 +09001261 Append(MakeUnique<Value>(in_value));
kalman@chromium.org5081d8e2012-09-14 11:14:01 +09001262}
1263
1264void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1265 for (std::vector<std::string>::const_iterator it = in_values.begin();
1266 it != in_values.end(); ++it) {
1267 AppendString(*it);
1268 }
1269}
1270
1271void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1272 for (std::vector<string16>::const_iterator it = in_values.begin();
1273 it != in_values.end(); ++it) {
1274 AppendString(*it);
1275 }
1276}
1277
dcheng46cc6ec2016-09-14 14:49:58 +09001278bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
zork@chromium.orgb5f742b2010-04-13 06:48:10 +09001279 DCHECK(in_value);
jdoerrie45184002017-04-12 03:09:14 +09001280 if (std::find(list_->begin(), list_->end(), *in_value) != list_->end())
1281 return false;
1282
1283 list_->push_back(std::move(*in_value));
zork@chromium.orgb5f742b2010-04-13 06:48:10 +09001284 return true;
1285}
1286
dcheng46cc6ec2016-09-14 14:49:58 +09001287bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
erikkay@chromium.org9034a232009-08-29 05:26:05 +09001288 DCHECK(in_value);
jdoerrie1d5b3482017-02-17 22:54:49 +09001289 if (index > list_->size())
erikkay@chromium.org9034a232009-08-29 05:26:05 +09001290 return false;
1291
jdoerrie45184002017-04-12 03:09:14 +09001292 list_->insert(list_->begin() + index, std::move(*in_value));
erikkay@chromium.org9034a232009-08-29 05:26:05 +09001293 return true;
1294}
1295
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +09001296ListValue::const_iterator ListValue::Find(const Value& value) const {
jdoerrie45184002017-04-12 03:09:14 +09001297 return std::find(list_->begin(), list_->end(), value);
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +09001298}
1299
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001300void ListValue::Swap(ListValue* other) {
vabr7eac8352017-03-08 08:34:30 +09001301 CHECK(other->is_list());
jdoerrie1d5b3482017-02-17 22:54:49 +09001302 list_->swap(*(other->list_));
bauerb@chromium.org6878e502011-07-12 18:04:38 +09001303}
1304
akalin@chromium.org810f92f2011-01-18 11:16:59 +09001305ListValue* ListValue::DeepCopy() const {
jdoerrie751d7d72017-04-05 15:44:17 +09001306 return new ListValue(*this);
initial.commit3f4a7322008-07-27 06:49:38 +09001307}
1308
dchengcc8e4d82016-04-05 06:25:51 +09001309std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
jdoerrie751d7d72017-04-05 15:44:17 +09001310 return MakeUnique<ListValue>(*this);
estade033e61e2015-05-13 03:11:50 +09001311}
1312
erg@chromium.org493f5f62010-07-16 06:03:54 +09001313ValueSerializer::~ValueSerializer() {
1314}
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +09001315
prashhir58322f42015-03-05 18:30:57 +09001316ValueDeserializer::~ValueDeserializer() {
1317}
1318
kalman@chromium.org829cf752012-09-12 12:39:35 +09001319std::ostream& operator<<(std::ostream& out, const Value& value) {
1320 std::string json;
estadeb5f30dd2015-05-16 10:02:34 +09001321 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
kalman@chromium.org829cf752012-09-12 12:39:35 +09001322 return out << json;
1323}
1324
jdoerrie89ee31a2016-12-08 00:43:28 +09001325std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1326 if (static_cast<int>(type) < 0 ||
1327 static_cast<size_t>(type) >= arraysize(kTypeNames))
1328 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1329 return out << Value::GetTypeName(type);
1330}
1331
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +09001332} // namespace base