rsesek@chromium.org | c2d2b20 | 2012-05-17 00:23:30 +0900 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 4 | |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 5 | #include "base/values.h" |
| 6 | |
mostynb@opera.com | f29dd61 | 2013-09-04 08:29:12 +0900 | [diff] [blame] | 7 | #include <string.h> |
| 8 | |
pastarmovj@chromium.org | 1602a47 | 2011-09-20 00:23:10 +0900 | [diff] [blame] | 9 | #include <algorithm> |
mateuszs | 8b1a88a | 2015-04-24 22:20:23 +0900 | [diff] [blame] | 10 | #include <cmath> |
kalman@chromium.org | 829cf75 | 2012-09-12 12:39:35 +0900 | [diff] [blame] | 11 | #include <ostream> |
danakj | 800d2ea | 2015-11-25 14:29:58 +0900 | [diff] [blame] | 12 | #include <utility> |
pastarmovj@chromium.org | 1602a47 | 2011-09-20 00:23:10 +0900 | [diff] [blame] | 13 | |
kalman@chromium.org | 829cf75 | 2012-09-12 12:39:35 +0900 | [diff] [blame] | 14 | #include "base/json/json_writer.h" |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 15 | #include "base/logging.h" |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 16 | #include "base/memory/ptr_util.h" |
avi@chromium.org | 68a745c | 2013-06-11 05:11:14 +0900 | [diff] [blame] | 17 | #include "base/strings/string_util.h" |
avi@chromium.org | 17f6062 | 2013-06-08 03:37:07 +0900 | [diff] [blame] | 18 | #include "base/strings/utf_string_conversions.h" |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 19 | |
brettw@chromium.org | 88aa655 | 2013-06-15 02:56:08 +0900 | [diff] [blame] | 20 | namespace base { |
| 21 | |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 22 | namespace { |
| 23 | |
thestig | e44b932 | 2016-07-19 09:39:30 +0900 | [diff] [blame] | 24 | const char* const kTypeNames[] = {"null", "boolean", "integer", "double", |
| 25 | "string", "binary", "dictionary", "list"}; |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 26 | static_assert(arraysize(kTypeNames) == |
| 27 | static_cast<size_t>(Value::Type::LIST) + 1, |
thestig | e44b932 | 2016-07-19 09:39:30 +0900 | [diff] [blame] | 28 | "kTypeNames Has Wrong Size"); |
| 29 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 30 | std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node); |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 31 | |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 32 | // 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. |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 35 | std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) { |
| 36 | std::unique_ptr<ListValue> copy; |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 37 | for (const auto& entry : list) { |
| 38 | std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(*entry); |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 39 | if (child_copy) { |
| 40 | if (!copy) |
| 41 | copy.reset(new ListValue); |
danakj | 800d2ea | 2015-11-25 14:29:58 +0900 | [diff] [blame] | 42 | copy->Append(std::move(child_copy)); |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 43 | } |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 44 | } |
| 45 | return copy; |
| 46 | } |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 47 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 48 | std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren( |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 49 | const DictionaryValue& dict) { |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 50 | std::unique_ptr<DictionaryValue> copy; |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 51 | for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 52 | std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(it.value()); |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 53 | if (child_copy) { |
| 54 | if (!copy) |
| 55 | copy.reset(new DictionaryValue); |
danakj | 800d2ea | 2015-11-25 14:29:58 +0900 | [diff] [blame] | 56 | copy->SetWithoutPathExpansion(it.key(), std::move(child_copy)); |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 57 | } |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 58 | } |
| 59 | return copy; |
| 60 | } |
| 61 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 62 | std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) { |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 63 | switch (node.GetType()) { |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 64 | case Value::Type::LIST: |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 65 | return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node)); |
| 66 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 67 | case Value::Type::DICTIONARY: |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 68 | return CopyDictionaryWithoutEmptyChildren( |
| 69 | static_cast<const DictionaryValue&>(node)); |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 70 | |
| 71 | default: |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 72 | return node.CreateDeepCopy(); |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 73 | } |
| 74 | } |
| 75 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 76 | } // namespace |
| 77 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 78 | // static |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 79 | std::unique_ptr<Value> Value::CreateNullValue() { |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 80 | return WrapUnique(new Value(Type::NONE)); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 81 | } |
| 82 | |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 83 | // static |
| 84 | std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer( |
| 85 | const char* buffer, |
| 86 | size_t size) { |
| 87 | return MakeUnique<BinaryValue>(std::vector<char>(buffer, buffer + size)); |
| 88 | } |
| 89 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 90 | Value::Value(const Value& that) { |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 91 | InternalCopyConstructFrom(that); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | Value::Value(Value&& that) { |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 95 | InternalMoveConstructFrom(std::move(that)); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 96 | } |
| 97 | |
| 98 | Value::Value() : type_(Type::NONE) {} |
| 99 | |
| 100 | Value::Value(Type type) : type_(type) { |
| 101 | // Initialize with the default value. |
| 102 | switch (type_) { |
| 103 | case Type::NONE: |
| 104 | return; |
| 105 | |
| 106 | case Type::BOOLEAN: |
| 107 | bool_value_ = false; |
| 108 | return; |
| 109 | case Type::INTEGER: |
| 110 | int_value_ = 0; |
| 111 | return; |
| 112 | case Type::DOUBLE: |
| 113 | double_value_ = 0.0; |
| 114 | return; |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 115 | case Type::STRING: |
| 116 | string_value_.Init(); |
| 117 | return; |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 118 | case Type::BINARY: |
| 119 | binary_value_.Init(); |
| 120 | return; |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 121 | case Type::DICTIONARY: |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 122 | dict_ptr_.Init(MakeUnique<DictStorage>()); |
| 123 | return; |
| 124 | case Type::LIST: |
| 125 | list_.Init(); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 126 | return; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} |
| 131 | |
| 132 | Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} |
| 133 | |
| 134 | Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { |
| 135 | if (!std::isfinite(double_value_)) { |
| 136 | NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " |
| 137 | << "values cannot be represented in JSON"; |
| 138 | double_value_ = 0.0; |
| 139 | } |
| 140 | } |
| 141 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 142 | Value::Value(const char* in_string) : type_(Type::STRING) { |
| 143 | string_value_.Init(in_string); |
| 144 | DCHECK(IsStringUTF8(*string_value_)); |
| 145 | } |
| 146 | |
| 147 | Value::Value(const std::string& in_string) : type_(Type::STRING) { |
| 148 | string_value_.Init(in_string); |
| 149 | DCHECK(IsStringUTF8(*string_value_)); |
| 150 | } |
| 151 | |
| 152 | Value::Value(std::string&& in_string) : type_(Type::STRING) { |
| 153 | string_value_.Init(std::move(in_string)); |
| 154 | DCHECK(IsStringUTF8(*string_value_)); |
| 155 | } |
| 156 | |
| 157 | Value::Value(const char16* in_string) : type_(Type::STRING) { |
| 158 | string_value_.Init(UTF16ToUTF8(in_string)); |
| 159 | } |
| 160 | |
| 161 | Value::Value(const string16& in_string) : type_(Type::STRING) { |
| 162 | string_value_.Init(UTF16ToUTF8(in_string)); |
| 163 | } |
| 164 | |
| 165 | Value::Value(StringPiece in_string) : Value(in_string.as_string()) {} |
| 166 | |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 167 | Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) { |
| 168 | binary_value_.Init(in_blob); |
| 169 | } |
| 170 | |
| 171 | Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) { |
| 172 | binary_value_.Init(std::move(in_blob)); |
| 173 | } |
| 174 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 175 | Value& Value::operator=(const Value& that) { |
dyaroshev | 798c5ef | 2017-03-21 02:04:27 +0900 | [diff] [blame^] | 176 | if (type_ == that.type_) { |
| 177 | InternalCopyAssignFromSameType(that); |
| 178 | } else { |
| 179 | // This is not a self assignment because the type_ doesn't match. |
| 180 | InternalCleanup(); |
| 181 | InternalCopyConstructFrom(that); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | return *this; |
| 185 | } |
| 186 | |
| 187 | Value& Value::operator=(Value&& that) { |
dyaroshev | 798c5ef | 2017-03-21 02:04:27 +0900 | [diff] [blame^] | 188 | DCHECK(this != &that) << "attempt to self move assign."; |
| 189 | InternalCleanup(); |
| 190 | InternalMoveConstructFrom(std::move(that)); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 191 | |
| 192 | return *this; |
| 193 | } |
| 194 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 195 | Value::~Value() { |
| 196 | InternalCleanup(); |
vabr | 3f090ed | 2017-03-15 05:06:11 +0900 | [diff] [blame] | 197 | alive_ = false; |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 198 | } |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 199 | |
thestig | e44b932 | 2016-07-19 09:39:30 +0900 | [diff] [blame] | 200 | // static |
| 201 | const char* Value::GetTypeName(Value::Type type) { |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 202 | DCHECK_GE(static_cast<int>(type), 0); |
thestig | e44b932 | 2016-07-19 09:39:30 +0900 | [diff] [blame] | 203 | DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 204 | return kTypeNames[static_cast<size_t>(type)]; |
thestig | e44b932 | 2016-07-19 09:39:30 +0900 | [diff] [blame] | 205 | } |
| 206 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 207 | bool Value::GetBool() const { |
| 208 | CHECK(is_bool()); |
| 209 | return bool_value_; |
| 210 | } |
| 211 | |
| 212 | int Value::GetInt() const { |
| 213 | CHECK(is_int()); |
| 214 | return int_value_; |
| 215 | } |
| 216 | |
| 217 | double Value::GetDouble() const { |
| 218 | if (is_double()) |
| 219 | return double_value_; |
| 220 | if (is_int()) |
| 221 | return int_value_; |
| 222 | CHECK(false); |
| 223 | return 0.0; |
pneubeck | b57f3f5 | 2015-01-20 20:26:36 +0900 | [diff] [blame] | 224 | } |
| 225 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 226 | const std::string& Value::GetString() const { |
| 227 | CHECK(is_string()); |
| 228 | return *string_value_; |
| 229 | } |
| 230 | |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 231 | const std::vector<char>& Value::GetBlob() const { |
| 232 | CHECK(is_blob()); |
| 233 | return *binary_value_; |
| 234 | } |
| 235 | |
| 236 | size_t Value::GetSize() const { |
| 237 | return GetBlob().size(); |
| 238 | } |
| 239 | |
| 240 | const char* Value::GetBuffer() const { |
| 241 | return GetBlob().data(); |
| 242 | } |
| 243 | |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 244 | bool Value::GetAsBoolean(bool* out_value) const { |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 245 | if (out_value && is_bool()) { |
| 246 | *out_value = bool_value_; |
| 247 | return true; |
| 248 | } |
| 249 | return is_bool(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 250 | } |
| 251 | |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 252 | bool Value::GetAsInteger(int* out_value) const { |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 253 | if (out_value && is_int()) { |
| 254 | *out_value = int_value_; |
| 255 | return true; |
| 256 | } |
| 257 | return is_int(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 258 | } |
| 259 | |
arv@chromium.org | 13413eb | 2011-02-01 10:02:07 +0900 | [diff] [blame] | 260 | bool Value::GetAsDouble(double* out_value) const { |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 261 | if (out_value && is_double()) { |
| 262 | *out_value = double_value_; |
| 263 | return true; |
| 264 | } else if (out_value && is_int()) { |
| 265 | // Allow promotion from int to double. |
| 266 | *out_value = int_value_; |
| 267 | return true; |
| 268 | } |
| 269 | return is_double() || is_int(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 270 | } |
| 271 | |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 272 | bool Value::GetAsString(std::string* out_value) const { |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 273 | if (out_value && is_string()) { |
| 274 | *out_value = *string_value_; |
| 275 | return true; |
| 276 | } |
| 277 | return is_string(); |
scherkus@chromium.org | 2b923e7 | 2008-12-11 10:23:17 +0900 | [diff] [blame] | 278 | } |
| 279 | |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 280 | bool Value::GetAsString(string16* out_value) const { |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 281 | if (out_value && is_string()) { |
| 282 | *out_value = UTF8ToUTF16(*string_value_); |
| 283 | return true; |
| 284 | } |
| 285 | return is_string(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 286 | } |
| 287 | |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 288 | bool Value::GetAsString(const Value** out_value) const { |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 289 | if (out_value && is_string()) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 290 | *out_value = static_cast<const Value*>(this); |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 291 | return true; |
| 292 | } |
| 293 | return is_string(); |
estade@chromium.org | 0fd309d | 2014-02-06 05:42:06 +0900 | [diff] [blame] | 294 | } |
| 295 | |
sammc | 94ef796 | 2016-12-21 17:55:41 +0900 | [diff] [blame] | 296 | bool Value::GetAsString(StringPiece* out_value) const { |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 297 | if (out_value && is_string()) { |
| 298 | *out_value = *string_value_; |
| 299 | return true; |
| 300 | } |
| 301 | return is_string(); |
sammc | 94ef796 | 2016-12-21 17:55:41 +0900 | [diff] [blame] | 302 | } |
| 303 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 304 | bool Value::GetAsBinary(const BinaryValue** out_value) const { |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 305 | if (out_value && is_blob()) { |
| 306 | *out_value = this; |
| 307 | return true; |
| 308 | } |
| 309 | return is_blob(); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 310 | } |
| 311 | |
scottbyer@google.com | 673b876 | 2010-12-07 09:35:29 +0900 | [diff] [blame] | 312 | bool Value::GetAsList(ListValue** out_value) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 313 | if (out_value && is_list()) { |
| 314 | *out_value = static_cast<ListValue*>(this); |
| 315 | return true; |
| 316 | } |
| 317 | return is_list(); |
scottbyer@google.com | 673b876 | 2010-12-07 09:35:29 +0900 | [diff] [blame] | 318 | } |
| 319 | |
bauerb@chromium.org | 6878e50 | 2011-07-12 18:04:38 +0900 | [diff] [blame] | 320 | bool Value::GetAsList(const ListValue** out_value) const { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 321 | if (out_value && is_list()) { |
| 322 | *out_value = static_cast<const ListValue*>(this); |
| 323 | return true; |
| 324 | } |
| 325 | return is_list(); |
bauerb@chromium.org | 6878e50 | 2011-07-12 18:04:38 +0900 | [diff] [blame] | 326 | } |
| 327 | |
battre@chromium.org | 29eaa25 | 2011-11-26 10:11:44 +0900 | [diff] [blame] | 328 | bool Value::GetAsDictionary(DictionaryValue** out_value) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 329 | if (out_value && is_dict()) { |
| 330 | *out_value = static_cast<DictionaryValue*>(this); |
| 331 | return true; |
| 332 | } |
| 333 | return is_dict(); |
battre@chromium.org | 29eaa25 | 2011-11-26 10:11:44 +0900 | [diff] [blame] | 334 | } |
| 335 | |
| 336 | bool Value::GetAsDictionary(const DictionaryValue** out_value) const { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 337 | if (out_value && is_dict()) { |
| 338 | *out_value = static_cast<const DictionaryValue*>(this); |
| 339 | return true; |
| 340 | } |
| 341 | return is_dict(); |
battre@chromium.org | 29eaa25 | 2011-11-26 10:11:44 +0900 | [diff] [blame] | 342 | } |
| 343 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 344 | Value* Value::DeepCopy() const { |
| 345 | // This method should only be getting called for null Values--all subclasses |
| 346 | // need to provide their own implementation;. |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 347 | switch (type()) { |
| 348 | case Type::NONE: |
| 349 | return CreateNullValue().release(); |
| 350 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 351 | case Type::BOOLEAN: |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 352 | return new Value(bool_value_); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 353 | case Type::INTEGER: |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 354 | return new Value(int_value_); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 355 | case Type::DOUBLE: |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 356 | return new Value(double_value_); |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 357 | case Type::STRING: |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 358 | return new Value(*string_value_); |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 359 | // For now, make BinaryValues for backward-compatibility. Convert to |
| 360 | // Value when that code is deleted. |
| 361 | case Type::BINARY: |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 362 | return new Value(*binary_value_); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 363 | |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 364 | // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue |
| 365 | // are completely inlined. |
| 366 | case Type::DICTIONARY: { |
| 367 | DictionaryValue* result = new DictionaryValue; |
| 368 | |
| 369 | for (const auto& current_entry : **dict_ptr_) { |
| 370 | result->SetWithoutPathExpansion(current_entry.first, |
| 371 | current_entry.second->CreateDeepCopy()); |
| 372 | } |
| 373 | |
| 374 | return result; |
| 375 | } |
| 376 | |
| 377 | case Type::LIST: { |
| 378 | ListValue* result = new ListValue; |
| 379 | |
| 380 | for (const auto& entry : *list_) |
| 381 | result->Append(entry->CreateDeepCopy()); |
| 382 | |
| 383 | return result; |
| 384 | } |
| 385 | |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 386 | default: |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 387 | NOTREACHED(); |
| 388 | return nullptr; |
| 389 | } |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 390 | } |
| 391 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 392 | std::unique_ptr<Value> Value::CreateDeepCopy() const { |
| 393 | return WrapUnique(DeepCopy()); |
estade | 77a018f | 2015-05-07 10:53:08 +0900 | [diff] [blame] | 394 | } |
| 395 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 396 | bool Value::Equals(const Value* other) const { |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 397 | if (other->type() != type()) |
| 398 | return false; |
| 399 | |
| 400 | switch (type()) { |
| 401 | case Type::NONE: |
| 402 | return true; |
| 403 | case Type::BOOLEAN: |
| 404 | return bool_value_ == other->bool_value_; |
| 405 | case Type::INTEGER: |
| 406 | return int_value_ == other->int_value_; |
| 407 | case Type::DOUBLE: |
| 408 | return double_value_ == other->double_value_; |
jdoerrie | 34ee9f6 | 2017-02-02 19:56:03 +0900 | [diff] [blame] | 409 | case Type::STRING: |
| 410 | return *string_value_ == *(other->string_value_); |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 411 | case Type::BINARY: |
| 412 | return *binary_value_ == *(other->binary_value_); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 413 | // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue |
| 414 | // are completely inlined. |
| 415 | case Type::DICTIONARY: { |
| 416 | if ((*dict_ptr_)->size() != (*other->dict_ptr_)->size()) |
| 417 | return false; |
| 418 | |
| 419 | return std::equal(std::begin(**dict_ptr_), std::end(**dict_ptr_), |
| 420 | std::begin(**(other->dict_ptr_)), |
| 421 | [](const DictStorage::value_type& lhs, |
| 422 | const DictStorage::value_type& rhs) { |
| 423 | if (lhs.first != rhs.first) |
| 424 | return false; |
| 425 | |
| 426 | return lhs.second->Equals(rhs.second.get()); |
| 427 | }); |
| 428 | } |
| 429 | case Type::LIST: { |
| 430 | if (list_->size() != other->list_->size()) |
| 431 | return false; |
| 432 | |
| 433 | return std::equal(std::begin(*list_), std::end(*list_), |
| 434 | std::begin(*(other->list_)), |
| 435 | [](const ListStorage::value_type& lhs, |
| 436 | const ListStorage::value_type& rhs) { |
| 437 | return lhs->Equals(rhs.get()); |
| 438 | }); |
| 439 | } |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 440 | } |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 441 | |
| 442 | NOTREACHED(); |
| 443 | return false; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 444 | } |
| 445 | |
bauerb@chromium.org | fbd55e1 | 2010-12-07 03:13:43 +0900 | [diff] [blame] | 446 | // static |
| 447 | bool Value::Equals(const Value* a, const Value* b) { |
| 448 | if ((a == NULL) && (b == NULL)) return true; |
| 449 | if ((a == NULL) ^ (b == NULL)) return false; |
| 450 | return a->Equals(b); |
| 451 | } |
| 452 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 453 | void Value::InternalCopyFundamentalValue(const Value& that) { |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 454 | switch (type_) { |
| 455 | case Type::NONE: |
| 456 | // Nothing to do. |
| 457 | return; |
erg@chromium.org | 493f5f6 | 2010-07-16 06:03:54 +0900 | [diff] [blame] | 458 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 459 | case Type::BOOLEAN: |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 460 | bool_value_ = that.bool_value_; |
| 461 | return; |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 462 | case Type::INTEGER: |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 463 | int_value_ = that.int_value_; |
| 464 | return; |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 465 | case Type::DOUBLE: |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 466 | double_value_ = that.double_value_; |
| 467 | return; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 468 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 469 | default: |
| 470 | NOTREACHED(); |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | void Value::InternalCopyConstructFrom(const Value& that) { |
| 475 | type_ = that.type_; |
| 476 | |
| 477 | switch (type_) { |
| 478 | case Type::NONE: |
| 479 | case Type::BOOLEAN: |
| 480 | case Type::INTEGER: |
| 481 | case Type::DOUBLE: |
| 482 | InternalCopyFundamentalValue(that); |
| 483 | return; |
| 484 | |
| 485 | case Type::STRING: |
| 486 | string_value_.Init(*that.string_value_); |
| 487 | return; |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 488 | case Type::BINARY: |
| 489 | binary_value_.Init(*that.binary_value_); |
| 490 | return; |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 491 | // DictStorage and ListStorage are move-only types due to the presence of |
| 492 | // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. |
| 493 | // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage |
| 494 | // can be copied directly. |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 495 | case Type::DICTIONARY: |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 496 | dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_)); |
| 497 | return; |
| 498 | case Type::LIST: |
| 499 | list_.Init(std::move(*that.CreateDeepCopy()->list_)); |
jdoerrie | 93a0cf3 | 2017-02-01 19:36:56 +0900 | [diff] [blame] | 500 | return; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 501 | } |
| 502 | } |
| 503 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 504 | void Value::InternalMoveConstructFrom(Value&& that) { |
| 505 | type_ = that.type_; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 506 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 507 | switch (type_) { |
| 508 | case Type::NONE: |
| 509 | case Type::BOOLEAN: |
| 510 | case Type::INTEGER: |
| 511 | case Type::DOUBLE: |
| 512 | InternalCopyFundamentalValue(that); |
| 513 | return; |
| 514 | |
| 515 | case Type::STRING: |
| 516 | string_value_.InitFromMove(std::move(that.string_value_)); |
| 517 | return; |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 518 | case Type::BINARY: |
| 519 | binary_value_.InitFromMove(std::move(that.binary_value_)); |
| 520 | return; |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 521 | case Type::DICTIONARY: |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 522 | dict_ptr_.InitFromMove(std::move(that.dict_ptr_)); |
| 523 | return; |
| 524 | case Type::LIST: |
| 525 | list_.InitFromMove(std::move(that.list_)); |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 526 | return; |
| 527 | } |
scherkus@chromium.org | 2b923e7 | 2008-12-11 10:23:17 +0900 | [diff] [blame] | 528 | } |
| 529 | |
vabr | 7eac835 | 2017-03-08 08:34:30 +0900 | [diff] [blame] | 530 | void Value::InternalCopyAssignFromSameType(const Value& that) { |
dyaroshev | 798c5ef | 2017-03-21 02:04:27 +0900 | [diff] [blame^] | 531 | // TODO(crbug.com/646113): make this a DCHECK once base::Value does not have |
| 532 | // subclasses. |
vabr | 7eac835 | 2017-03-08 08:34:30 +0900 | [diff] [blame] | 533 | CHECK_EQ(type_, that.type_); |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 534 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 535 | switch (type_) { |
| 536 | case Type::NONE: |
| 537 | case Type::BOOLEAN: |
| 538 | case Type::INTEGER: |
| 539 | case Type::DOUBLE: |
| 540 | InternalCopyFundamentalValue(that); |
| 541 | return; |
| 542 | |
| 543 | case Type::STRING: |
| 544 | *string_value_ = *that.string_value_; |
| 545 | return; |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 546 | case Type::BINARY: |
| 547 | *binary_value_ = *that.binary_value_; |
| 548 | return; |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 549 | // DictStorage and ListStorage are move-only types due to the presence of |
| 550 | // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. |
| 551 | // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage |
| 552 | // can be copied directly. |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 553 | case Type::DICTIONARY: |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 554 | *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); |
| 555 | return; |
| 556 | case Type::LIST: |
| 557 | *list_ = std::move(*that.CreateDeepCopy()->list_); |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 558 | return; |
| 559 | } |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 560 | } |
| 561 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 562 | void Value::InternalCleanup() { |
vabr | 3f090ed | 2017-03-15 05:06:11 +0900 | [diff] [blame] | 563 | CHECK(alive_); |
| 564 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 565 | switch (type_) { |
| 566 | case Type::NONE: |
| 567 | case Type::BOOLEAN: |
| 568 | case Type::INTEGER: |
| 569 | case Type::DOUBLE: |
| 570 | // Nothing to do |
| 571 | return; |
estade@chromium.org | 0fd309d | 2014-02-06 05:42:06 +0900 | [diff] [blame] | 572 | |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 573 | case Type::STRING: |
| 574 | string_value_.Destroy(); |
| 575 | return; |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 576 | case Type::BINARY: |
| 577 | binary_value_.Destroy(); |
| 578 | return; |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 579 | case Type::DICTIONARY: |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 580 | dict_ptr_.Destroy(); |
| 581 | return; |
| 582 | case Type::LIST: |
| 583 | list_.Destroy(); |
jdoerrie | 3129913 | 2017-02-01 23:38:32 +0900 | [diff] [blame] | 584 | return; |
| 585 | } |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 586 | } |
| 587 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 588 | ///////////////////// DictionaryValue //////////////////// |
| 589 | |
reillyg | d39049b | 2015-09-11 09:25:54 +0900 | [diff] [blame] | 590 | // static |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 591 | std::unique_ptr<DictionaryValue> DictionaryValue::From( |
| 592 | std::unique_ptr<Value> value) { |
reillyg | d39049b | 2015-09-11 09:25:54 +0900 | [diff] [blame] | 593 | DictionaryValue* out; |
| 594 | if (value && value->GetAsDictionary(&out)) { |
| 595 | ignore_result(value.release()); |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 596 | return WrapUnique(out); |
reillyg | d39049b | 2015-09-11 09:25:54 +0900 | [diff] [blame] | 597 | } |
| 598 | return nullptr; |
| 599 | } |
| 600 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 601 | DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {} |
erg@chromium.org | 493f5f6 | 2010-07-16 06:03:54 +0900 | [diff] [blame] | 602 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 603 | bool DictionaryValue::HasKey(StringPiece key) const { |
viettrungluu@chromium.org | 4c86b85 | 2010-08-06 15:03:25 +0900 | [diff] [blame] | 604 | DCHECK(IsStringUTF8(key)); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 605 | auto current_entry = (*dict_ptr_)->find(key.as_string()); |
| 606 | DCHECK((current_entry == (*dict_ptr_)->end()) || current_entry->second); |
| 607 | return current_entry != (*dict_ptr_)->end(); |
tony@chromium.org | e4948ab | 2009-12-02 09:20:32 +0900 | [diff] [blame] | 608 | } |
| 609 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 610 | void DictionaryValue::Clear() { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 611 | (*dict_ptr_)->clear(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 612 | } |
| 613 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 614 | void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) { |
viettrungluu@chromium.org | 4c86b85 | 2010-08-06 15:03:25 +0900 | [diff] [blame] | 615 | DCHECK(IsStringUTF8(path)); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 616 | DCHECK(in_value); |
| 617 | |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 618 | StringPiece current_path(path); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 619 | DictionaryValue* current_dictionary = this; |
| 620 | for (size_t delimiter_position = current_path.find('.'); |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 621 | delimiter_position != StringPiece::npos; |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 622 | delimiter_position = current_path.find('.')) { |
| 623 | // Assume that we're indexing into a dictionary. |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 624 | StringPiece key = current_path.substr(0, delimiter_position); |
corona10 | 50a617b | 2016-10-07 21:53:36 +0900 | [diff] [blame] | 625 | DictionaryValue* child_dictionary = nullptr; |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 626 | if (!current_dictionary->GetDictionary(key, &child_dictionary)) { |
| 627 | child_dictionary = new DictionaryValue; |
corona10 | 50a617b | 2016-10-07 21:53:36 +0900 | [diff] [blame] | 628 | current_dictionary->SetWithoutPathExpansion( |
| 629 | key, base::WrapUnique(child_dictionary)); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 630 | } |
| 631 | |
| 632 | current_dictionary = child_dictionary; |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 633 | current_path = current_path.substr(delimiter_position + 1); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 634 | } |
| 635 | |
danakj | 800d2ea | 2015-11-25 14:29:58 +0900 | [diff] [blame] | 636 | current_dictionary->SetWithoutPathExpansion(current_path, |
| 637 | std::move(in_value)); |
estade | 948395d | 2015-01-07 05:06:50 +0900 | [diff] [blame] | 638 | } |
| 639 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 640 | void DictionaryValue::Set(StringPiece path, Value* in_value) { |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 641 | Set(path, WrapUnique(in_value)); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 642 | } |
| 643 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 644 | void DictionaryValue::SetBoolean(StringPiece path, bool in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 645 | Set(path, new Value(in_value)); |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 646 | } |
| 647 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 648 | void DictionaryValue::SetInteger(StringPiece path, int in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 649 | Set(path, new Value(in_value)); |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 650 | } |
| 651 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 652 | void DictionaryValue::SetDouble(StringPiece path, double in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 653 | Set(path, new Value(in_value)); |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 654 | } |
| 655 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 656 | void DictionaryValue::SetString(StringPiece path, StringPiece in_value) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 657 | Set(path, new Value(in_value)); |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 658 | } |
| 659 | |
| 660 | void DictionaryValue::SetString(StringPiece path, const string16& in_value) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 661 | Set(path, new Value(in_value)); |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 662 | } |
| 663 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 664 | void DictionaryValue::SetWithoutPathExpansion(StringPiece key, |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 665 | std::unique_ptr<Value> in_value) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 666 | (**dict_ptr_)[key.as_string()] = std::move(in_value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 667 | } |
| 668 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 669 | void DictionaryValue::SetWithoutPathExpansion(StringPiece key, |
estade | 948395d | 2015-01-07 05:06:50 +0900 | [diff] [blame] | 670 | Value* in_value) { |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 671 | SetWithoutPathExpansion(key, WrapUnique(in_value)); |
estade | 948395d | 2015-01-07 05:06:50 +0900 | [diff] [blame] | 672 | } |
| 673 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 674 | void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path, |
| 675 | bool in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 676 | SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 677 | } |
| 678 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 679 | void DictionaryValue::SetIntegerWithoutPathExpansion(StringPiece path, |
| 680 | int in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 681 | SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 682 | } |
| 683 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 684 | void DictionaryValue::SetDoubleWithoutPathExpansion(StringPiece path, |
| 685 | double in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 686 | SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 687 | } |
| 688 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 689 | void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path, |
| 690 | StringPiece in_value) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 691 | SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 692 | } |
| 693 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 694 | void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path, |
| 695 | const string16& in_value) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 696 | SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 697 | } |
| 698 | |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 699 | bool DictionaryValue::Get(StringPiece path, |
gab@chromium.org | 903d5c9 | 2013-11-27 10:38:24 +0900 | [diff] [blame] | 700 | const Value** out_value) const { |
viettrungluu@chromium.org | 4c86b85 | 2010-08-06 15:03:25 +0900 | [diff] [blame] | 701 | DCHECK(IsStringUTF8(path)); |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 702 | StringPiece current_path(path); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 703 | const DictionaryValue* current_dictionary = this; |
| 704 | for (size_t delimiter_position = current_path.find('.'); |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 705 | delimiter_position != std::string::npos; |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 706 | delimiter_position = current_path.find('.')) { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 707 | const DictionaryValue* child_dictionary = NULL; |
asvitkine | c568efe | 2015-07-15 12:10:12 +0900 | [diff] [blame] | 708 | if (!current_dictionary->GetDictionaryWithoutPathExpansion( |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 709 | current_path.substr(0, delimiter_position), &child_dictionary)) { |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 710 | return false; |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 711 | } |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 712 | |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 713 | current_dictionary = child_dictionary; |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 714 | current_path = current_path.substr(delimiter_position + 1); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 715 | } |
| 716 | |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 717 | return current_dictionary->GetWithoutPathExpansion(current_path, out_value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 718 | } |
| 719 | |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 720 | bool DictionaryValue::Get(StringPiece path, Value** out_value) { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 721 | return static_cast<const DictionaryValue&>(*this).Get( |
| 722 | path, |
| 723 | const_cast<const Value**>(out_value)); |
| 724 | } |
| 725 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 726 | bool DictionaryValue::GetBoolean(StringPiece path, bool* bool_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 727 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 728 | if (!Get(path, &value)) |
| 729 | return false; |
| 730 | |
| 731 | return value->GetAsBoolean(bool_value); |
| 732 | } |
| 733 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 734 | bool DictionaryValue::GetInteger(StringPiece path, int* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 735 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 736 | if (!Get(path, &value)) |
| 737 | return false; |
| 738 | |
| 739 | return value->GetAsInteger(out_value); |
| 740 | } |
| 741 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 742 | bool DictionaryValue::GetDouble(StringPiece path, double* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 743 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 744 | if (!Get(path, &value)) |
| 745 | return false; |
| 746 | |
arv@chromium.org | 13413eb | 2011-02-01 10:02:07 +0900 | [diff] [blame] | 747 | return value->GetAsDouble(out_value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 748 | } |
| 749 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 750 | bool DictionaryValue::GetString(StringPiece path, |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 751 | std::string* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 752 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 753 | if (!Get(path, &value)) |
| 754 | return false; |
| 755 | |
| 756 | return value->GetAsString(out_value); |
| 757 | } |
| 758 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 759 | bool DictionaryValue::GetString(StringPiece path, string16* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 760 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 761 | if (!Get(path, &value)) |
| 762 | return false; |
| 763 | |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 764 | return value->GetAsString(out_value); |
evan@chromium.org | d9ab8de | 2010-02-19 22:32:16 +0900 | [diff] [blame] | 765 | } |
| 766 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 767 | bool DictionaryValue::GetStringASCII(StringPiece path, |
evan@chromium.org | d9ab8de | 2010-02-19 22:32:16 +0900 | [diff] [blame] | 768 | std::string* out_value) const { |
| 769 | std::string out; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 770 | if (!GetString(path, &out)) |
evan@chromium.org | d9ab8de | 2010-02-19 22:32:16 +0900 | [diff] [blame] | 771 | return false; |
| 772 | |
| 773 | if (!IsStringASCII(out)) { |
| 774 | NOTREACHED(); |
| 775 | return false; |
| 776 | } |
| 777 | |
| 778 | out_value->assign(out); |
| 779 | return true; |
| 780 | } |
| 781 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 782 | bool DictionaryValue::GetBinary(StringPiece path, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 783 | const BinaryValue** out_value) const { |
| 784 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 785 | bool result = Get(path, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 786 | if (!result || !value->IsType(Type::BINARY)) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 787 | return false; |
| 788 | |
| 789 | if (out_value) |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 790 | *out_value = value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 791 | |
| 792 | return true; |
| 793 | } |
| 794 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 795 | bool DictionaryValue::GetBinary(StringPiece path, BinaryValue** out_value) { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 796 | return static_cast<const DictionaryValue&>(*this).GetBinary( |
| 797 | path, |
| 798 | const_cast<const BinaryValue**>(out_value)); |
| 799 | } |
| 800 | |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 801 | bool DictionaryValue::GetDictionary(StringPiece path, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 802 | const DictionaryValue** out_value) const { |
| 803 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 804 | bool result = Get(path, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 805 | if (!result || !value->IsType(Type::DICTIONARY)) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 806 | return false; |
| 807 | |
| 808 | if (out_value) |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 809 | *out_value = static_cast<const DictionaryValue*>(value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 810 | |
| 811 | return true; |
| 812 | } |
| 813 | |
asvitkine | 22632bf | 2015-06-24 03:22:52 +0900 | [diff] [blame] | 814 | bool DictionaryValue::GetDictionary(StringPiece path, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 815 | DictionaryValue** out_value) { |
| 816 | return static_cast<const DictionaryValue&>(*this).GetDictionary( |
| 817 | path, |
| 818 | const_cast<const DictionaryValue**>(out_value)); |
| 819 | } |
| 820 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 821 | bool DictionaryValue::GetList(StringPiece path, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 822 | const ListValue** out_value) const { |
| 823 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 824 | bool result = Get(path, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 825 | if (!result || !value->IsType(Type::LIST)) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 826 | return false; |
| 827 | |
| 828 | if (out_value) |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 829 | *out_value = static_cast<const ListValue*>(value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 830 | |
| 831 | return true; |
| 832 | } |
| 833 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 834 | bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 835 | return static_cast<const DictionaryValue&>(*this).GetList( |
| 836 | path, |
| 837 | const_cast<const ListValue**>(out_value)); |
| 838 | } |
| 839 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 840 | bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 841 | const Value** out_value) const { |
viettrungluu@chromium.org | 4c86b85 | 2010-08-06 15:03:25 +0900 | [diff] [blame] | 842 | DCHECK(IsStringUTF8(key)); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 843 | auto entry_iterator = (*dict_ptr_)->find(key.as_string()); |
| 844 | if (entry_iterator == (*dict_ptr_)->end()) |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 845 | return false; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 846 | |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 847 | if (out_value) |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 848 | *out_value = entry_iterator->second.get(); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 849 | return true; |
| 850 | } |
| 851 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 852 | bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 853 | Value** out_value) { |
| 854 | return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion( |
| 855 | key, |
| 856 | const_cast<const Value**>(out_value)); |
| 857 | } |
| 858 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 859 | bool DictionaryValue::GetBooleanWithoutPathExpansion(StringPiece key, |
pneubeck@chromium.org | 3b60054 | 2012-11-07 01:46:55 +0900 | [diff] [blame] | 860 | bool* out_value) const { |
| 861 | const Value* value; |
| 862 | if (!GetWithoutPathExpansion(key, &value)) |
| 863 | return false; |
| 864 | |
| 865 | return value->GetAsBoolean(out_value); |
| 866 | } |
| 867 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 868 | bool DictionaryValue::GetIntegerWithoutPathExpansion(StringPiece key, |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 869 | int* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 870 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 871 | if (!GetWithoutPathExpansion(key, &value)) |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 872 | return false; |
| 873 | |
| 874 | return value->GetAsInteger(out_value); |
| 875 | } |
| 876 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 877 | bool DictionaryValue::GetDoubleWithoutPathExpansion(StringPiece key, |
arv@chromium.org | 13413eb | 2011-02-01 10:02:07 +0900 | [diff] [blame] | 878 | double* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 879 | const Value* value; |
jam@chromium.org | 5bd5392 | 2010-10-01 16:28:25 +0900 | [diff] [blame] | 880 | if (!GetWithoutPathExpansion(key, &value)) |
| 881 | return false; |
| 882 | |
arv@chromium.org | 13413eb | 2011-02-01 10:02:07 +0900 | [diff] [blame] | 883 | return value->GetAsDouble(out_value); |
jam@chromium.org | 5bd5392 | 2010-10-01 16:28:25 +0900 | [diff] [blame] | 884 | } |
| 885 | |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 886 | bool DictionaryValue::GetStringWithoutPathExpansion( |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 887 | StringPiece key, |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 888 | std::string* out_value) const { |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 889 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 890 | if (!GetWithoutPathExpansion(key, &value)) |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 891 | return false; |
| 892 | |
| 893 | return value->GetAsString(out_value); |
| 894 | } |
| 895 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 896 | bool DictionaryValue::GetStringWithoutPathExpansion(StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 897 | string16* out_value) const { |
| 898 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 899 | if (!GetWithoutPathExpansion(key, &value)) |
munjal@chromium.org | 3b2d3a4 | 2010-01-16 05:09:03 +0900 | [diff] [blame] | 900 | return false; |
| 901 | |
viettrungluu@chromium.org | 31b80ba | 2010-08-04 00:42:58 +0900 | [diff] [blame] | 902 | return value->GetAsString(out_value); |
munjal@chromium.org | 3b2d3a4 | 2010-01-16 05:09:03 +0900 | [diff] [blame] | 903 | } |
| 904 | |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 905 | bool DictionaryValue::GetDictionaryWithoutPathExpansion( |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 906 | StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 907 | const DictionaryValue** out_value) const { |
| 908 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 909 | bool result = GetWithoutPathExpansion(key, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 910 | if (!result || !value->IsType(Type::DICTIONARY)) |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 911 | return false; |
| 912 | |
| 913 | if (out_value) |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 914 | *out_value = static_cast<const DictionaryValue*>(value); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 915 | |
| 916 | return true; |
| 917 | } |
| 918 | |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 919 | bool DictionaryValue::GetDictionaryWithoutPathExpansion( |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 920 | StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 921 | DictionaryValue** out_value) { |
| 922 | const DictionaryValue& const_this = |
| 923 | static_cast<const DictionaryValue&>(*this); |
| 924 | return const_this.GetDictionaryWithoutPathExpansion( |
| 925 | key, |
| 926 | const_cast<const DictionaryValue**>(out_value)); |
| 927 | } |
| 928 | |
| 929 | bool DictionaryValue::GetListWithoutPathExpansion( |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 930 | StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 931 | const ListValue** out_value) const { |
| 932 | const Value* value; |
viettrungluu@chromium.org | 178423d | 2010-07-31 04:47:47 +0900 | [diff] [blame] | 933 | bool result = GetWithoutPathExpansion(key, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 934 | if (!result || !value->IsType(Type::LIST)) |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 935 | return false; |
| 936 | |
| 937 | if (out_value) |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 938 | *out_value = static_cast<const ListValue*>(value); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 939 | |
| 940 | return true; |
| 941 | } |
| 942 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 943 | bool DictionaryValue::GetListWithoutPathExpansion(StringPiece key, |
vabr@chromium.org | 7456243 | 2012-07-28 07:27:11 +0900 | [diff] [blame] | 944 | ListValue** out_value) { |
| 945 | return |
| 946 | static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion( |
| 947 | key, |
| 948 | const_cast<const ListValue**>(out_value)); |
| 949 | } |
| 950 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 951 | bool DictionaryValue::Remove(StringPiece path, |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 952 | std::unique_ptr<Value>* out_value) { |
viettrungluu@chromium.org | 4c86b85 | 2010-08-06 15:03:25 +0900 | [diff] [blame] | 953 | DCHECK(IsStringUTF8(path)); |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 954 | StringPiece current_path(path); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 955 | DictionaryValue* current_dictionary = this; |
| 956 | size_t delimiter_position = current_path.rfind('.'); |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 957 | if (delimiter_position != StringPiece::npos) { |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 958 | if (!GetDictionary(current_path.substr(0, delimiter_position), |
| 959 | ¤t_dictionary)) |
| 960 | return false; |
lazyboy | a603046 | 2016-10-04 09:18:57 +0900 | [diff] [blame] | 961 | current_path = current_path.substr(delimiter_position + 1); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 962 | } |
| 963 | |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 964 | return current_dictionary->RemoveWithoutPathExpansion(current_path, |
| 965 | out_value); |
| 966 | } |
| 967 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 968 | bool DictionaryValue::RemoveWithoutPathExpansion( |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 969 | StringPiece key, |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 970 | std::unique_ptr<Value>* out_value) { |
viettrungluu@chromium.org | 4c86b85 | 2010-08-06 15:03:25 +0900 | [diff] [blame] | 971 | DCHECK(IsStringUTF8(key)); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 972 | auto entry_iterator = (*dict_ptr_)->find(key.as_string()); |
| 973 | if (entry_iterator == (*dict_ptr_)->end()) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 974 | return false; |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 975 | |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 976 | if (out_value) |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 977 | *out_value = std::move(entry_iterator->second); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 978 | (*dict_ptr_)->erase(entry_iterator); |
pkasting@chromium.org | 36515db | 2009-11-26 05:47:52 +0900 | [diff] [blame] | 979 | return true; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 980 | } |
| 981 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 982 | bool DictionaryValue::RemovePath(StringPiece path, |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 983 | std::unique_ptr<Value>* out_value) { |
gab@chromium.org | 903d5c9 | 2013-11-27 10:38:24 +0900 | [diff] [blame] | 984 | bool result = false; |
| 985 | size_t delimiter_position = path.find('.'); |
| 986 | |
| 987 | if (delimiter_position == std::string::npos) |
| 988 | return RemoveWithoutPathExpansion(path, out_value); |
| 989 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 990 | StringPiece subdict_path = path.substr(0, delimiter_position); |
gab@chromium.org | 903d5c9 | 2013-11-27 10:38:24 +0900 | [diff] [blame] | 991 | DictionaryValue* subdict = NULL; |
| 992 | if (!GetDictionary(subdict_path, &subdict)) |
| 993 | return false; |
| 994 | result = subdict->RemovePath(path.substr(delimiter_position + 1), |
| 995 | out_value); |
| 996 | if (result && subdict->empty()) |
| 997 | RemoveWithoutPathExpansion(subdict_path, NULL); |
| 998 | |
| 999 | return result; |
| 1000 | } |
| 1001 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1002 | std::unique_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren() |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 1003 | const { |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1004 | std::unique_ptr<DictionaryValue> copy = |
| 1005 | CopyDictionaryWithoutEmptyChildren(*this); |
estade | 51a57ab | 2015-05-23 11:42:09 +0900 | [diff] [blame] | 1006 | if (!copy) |
| 1007 | copy.reset(new DictionaryValue); |
| 1008 | return copy; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1009 | } |
| 1010 | |
mnissler@chromium.org | 17cee0e | 2010-05-14 22:17:40 +0900 | [diff] [blame] | 1011 | void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) { |
vabr | 7eac835 | 2017-03-08 08:34:30 +0900 | [diff] [blame] | 1012 | CHECK(dictionary->is_dict()); |
pneubeck@chromium.org | 03ed862 | 2013-03-10 20:32:49 +0900 | [diff] [blame] | 1013 | for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) { |
| 1014 | const Value* merge_value = &it.value(); |
| 1015 | // Check whether we have to merge dictionaries. |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 1016 | if (merge_value->IsType(Value::Type::DICTIONARY)) { |
pneubeck@chromium.org | 03ed862 | 2013-03-10 20:32:49 +0900 | [diff] [blame] | 1017 | DictionaryValue* sub_dict; |
| 1018 | if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { |
| 1019 | sub_dict->MergeDictionary( |
| 1020 | static_cast<const DictionaryValue*>(merge_value)); |
| 1021 | continue; |
mnissler@chromium.org | 17cee0e | 2010-05-14 22:17:40 +0900 | [diff] [blame] | 1022 | } |
mnissler@chromium.org | 17cee0e | 2010-05-14 22:17:40 +0900 | [diff] [blame] | 1023 | } |
pneubeck@chromium.org | 03ed862 | 2013-03-10 20:32:49 +0900 | [diff] [blame] | 1024 | // All other cases: Make a copy and hook it up. |
corona10 | 50a617b | 2016-10-07 21:53:36 +0900 | [diff] [blame] | 1025 | SetWithoutPathExpansion(it.key(), |
| 1026 | base::WrapUnique(merge_value->DeepCopy())); |
mnissler@chromium.org | 17cee0e | 2010-05-14 22:17:40 +0900 | [diff] [blame] | 1027 | } |
| 1028 | } |
| 1029 | |
rsesek@chromium.org | c2d2b20 | 2012-05-17 00:23:30 +0900 | [diff] [blame] | 1030 | void DictionaryValue::Swap(DictionaryValue* other) { |
vabr | 7eac835 | 2017-03-08 08:34:30 +0900 | [diff] [blame] | 1031 | CHECK(other->is_dict()); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1032 | dict_ptr_->swap(*(other->dict_ptr_)); |
rsesek@chromium.org | c2d2b20 | 2012-05-17 00:23:30 +0900 | [diff] [blame] | 1033 | } |
| 1034 | |
hans@chromium.org | d5d38e3 | 2012-08-10 21:45:35 +0900 | [diff] [blame] | 1035 | DictionaryValue::Iterator::Iterator(const DictionaryValue& target) |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1036 | : target_(target), it_((*target.dict_ptr_)->begin()) {} |
hans@chromium.org | d5d38e3 | 2012-08-10 21:45:35 +0900 | [diff] [blame] | 1037 | |
vmpstr | c8651bf | 2016-02-25 09:50:31 +0900 | [diff] [blame] | 1038 | DictionaryValue::Iterator::Iterator(const Iterator& other) = default; |
| 1039 | |
phajdan.jr@chromium.org | 8e2b208 | 2013-12-11 03:52:22 +0900 | [diff] [blame] | 1040 | DictionaryValue::Iterator::~Iterator() {} |
| 1041 | |
akalin@chromium.org | 810f92f | 2011-01-18 11:16:59 +0900 | [diff] [blame] | 1042 | DictionaryValue* DictionaryValue::DeepCopy() const { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1043 | return static_cast<DictionaryValue*>(Value::DeepCopy()); |
erg@google.com | 67a2543 | 2011-01-08 05:23:43 +0900 | [diff] [blame] | 1044 | } |
| 1045 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1046 | std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { |
| 1047 | return WrapUnique(DeepCopy()); |
estade | 77a018f | 2015-05-07 10:53:08 +0900 | [diff] [blame] | 1048 | } |
| 1049 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1050 | ///////////////////// ListValue //////////////////// |
| 1051 | |
reillyg | d39049b | 2015-09-11 09:25:54 +0900 | [diff] [blame] | 1052 | // static |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1053 | std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { |
reillyg | d39049b | 2015-09-11 09:25:54 +0900 | [diff] [blame] | 1054 | ListValue* out; |
| 1055 | if (value && value->GetAsList(&out)) { |
| 1056 | ignore_result(value.release()); |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1057 | return WrapUnique(out); |
reillyg | d39049b | 2015-09-11 09:25:54 +0900 | [diff] [blame] | 1058 | } |
| 1059 | return nullptr; |
| 1060 | } |
| 1061 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 1062 | ListValue::ListValue() : Value(Type::LIST) {} |
erg@chromium.org | 493f5f6 | 2010-07-16 06:03:54 +0900 | [diff] [blame] | 1063 | |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1064 | void ListValue::Clear() { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1065 | list_->clear(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1066 | } |
| 1067 | |
| 1068 | bool ListValue::Set(size_t index, Value* in_value) { |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 1069 | return Set(index, WrapUnique(in_value)); |
| 1070 | } |
| 1071 | |
| 1072 | bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) { |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1073 | if (!in_value) |
| 1074 | return false; |
| 1075 | |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1076 | if (index >= list_->size()) { |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1077 | // Pad out any intermediate indexes with null settings |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1078 | while (index > list_->size()) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1079 | Append(CreateNullValue()); |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 1080 | Append(std::move(in_value)); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1081 | } else { |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 1082 | // TODO(dcheng): remove this DCHECK once the raw pointer version is removed? |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1083 | DCHECK((*list_)[index] != in_value); |
| 1084 | (*list_)[index] = std::move(in_value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1085 | } |
| 1086 | return true; |
| 1087 | } |
| 1088 | |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1089 | bool ListValue::Get(size_t index, const Value** out_value) const { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1090 | if (index >= list_->size()) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1091 | return false; |
| 1092 | |
| 1093 | if (out_value) |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1094 | *out_value = (*list_)[index].get(); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1095 | |
| 1096 | return true; |
| 1097 | } |
| 1098 | |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1099 | bool ListValue::Get(size_t index, Value** out_value) { |
| 1100 | return static_cast<const ListValue&>(*this).Get( |
| 1101 | index, |
| 1102 | const_cast<const Value**>(out_value)); |
| 1103 | } |
| 1104 | |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1105 | bool ListValue::GetBoolean(size_t index, bool* bool_value) const { |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1106 | const Value* value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1107 | if (!Get(index, &value)) |
| 1108 | return false; |
| 1109 | |
| 1110 | return value->GetAsBoolean(bool_value); |
| 1111 | } |
| 1112 | |
| 1113 | bool ListValue::GetInteger(size_t index, int* out_value) const { |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1114 | const Value* value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1115 | if (!Get(index, &value)) |
| 1116 | return false; |
| 1117 | |
| 1118 | return value->GetAsInteger(out_value); |
| 1119 | } |
| 1120 | |
arv@chromium.org | 13413eb | 2011-02-01 10:02:07 +0900 | [diff] [blame] | 1121 | bool ListValue::GetDouble(size_t index, double* out_value) const { |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1122 | const Value* value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1123 | if (!Get(index, &value)) |
| 1124 | return false; |
| 1125 | |
arv@chromium.org | 13413eb | 2011-02-01 10:02:07 +0900 | [diff] [blame] | 1126 | return value->GetAsDouble(out_value); |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1127 | } |
| 1128 | |
| 1129 | bool ListValue::GetString(size_t index, std::string* out_value) const { |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1130 | const Value* value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1131 | if (!Get(index, &value)) |
| 1132 | return false; |
| 1133 | |
| 1134 | return value->GetAsString(out_value); |
| 1135 | } |
| 1136 | |
viettrungluu@chromium.org | 58767ef | 2010-08-05 04:35:33 +0900 | [diff] [blame] | 1137 | bool ListValue::GetString(size_t index, string16* out_value) const { |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1138 | const Value* value; |
viettrungluu@chromium.org | 58767ef | 2010-08-05 04:35:33 +0900 | [diff] [blame] | 1139 | if (!Get(index, &value)) |
| 1140 | return false; |
| 1141 | |
| 1142 | return value->GetAsString(out_value); |
| 1143 | } |
| 1144 | |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1145 | bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const { |
| 1146 | const Value* value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1147 | bool result = Get(index, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 1148 | if (!result || !value->IsType(Type::BINARY)) |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1149 | return false; |
| 1150 | |
| 1151 | if (out_value) |
jdoerrie | 58325a4 | 2017-02-15 17:42:14 +0900 | [diff] [blame] | 1152 | *out_value = value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1153 | |
| 1154 | return true; |
| 1155 | } |
| 1156 | |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1157 | bool ListValue::GetBinary(size_t index, BinaryValue** out_value) { |
| 1158 | return static_cast<const ListValue&>(*this).GetBinary( |
| 1159 | index, |
| 1160 | const_cast<const BinaryValue**>(out_value)); |
| 1161 | } |
| 1162 | |
| 1163 | bool ListValue::GetDictionary(size_t index, |
| 1164 | const DictionaryValue** out_value) const { |
| 1165 | const Value* value; |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1166 | bool result = Get(index, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 1167 | if (!result || !value->IsType(Type::DICTIONARY)) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1168 | return false; |
| 1169 | |
| 1170 | if (out_value) |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1171 | *out_value = static_cast<const DictionaryValue*>(value); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1172 | |
| 1173 | return true; |
| 1174 | } |
| 1175 | |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1176 | bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) { |
| 1177 | return static_cast<const ListValue&>(*this).GetDictionary( |
| 1178 | index, |
| 1179 | const_cast<const DictionaryValue**>(out_value)); |
| 1180 | } |
| 1181 | |
| 1182 | bool ListValue::GetList(size_t index, const ListValue** out_value) const { |
| 1183 | const Value* value; |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1184 | bool result = Get(index, &value); |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 1185 | if (!result || !value->IsType(Type::LIST)) |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1186 | return false; |
| 1187 | |
| 1188 | if (out_value) |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1189 | *out_value = static_cast<const ListValue*>(value); |
aa@chromium.org | c93b02f | 2009-01-21 06:05:32 +0900 | [diff] [blame] | 1190 | |
| 1191 | return true; |
| 1192 | } |
| 1193 | |
vabr@chromium.org | a8ca4fd | 2012-08-03 17:43:37 +0900 | [diff] [blame] | 1194 | bool ListValue::GetList(size_t index, ListValue** out_value) { |
| 1195 | return static_cast<const ListValue&>(*this).GetList( |
| 1196 | index, |
| 1197 | const_cast<const ListValue**>(out_value)); |
| 1198 | } |
| 1199 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1200 | bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1201 | if (index >= list_->size()) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1202 | return false; |
| 1203 | |
| 1204 | if (out_value) |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1205 | *out_value = std::move((*list_)[index]); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1206 | |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1207 | list_->erase(list_->begin() + index); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1208 | return true; |
| 1209 | } |
| 1210 | |
tfarina@chromium.org | 09cf434 | 2011-08-14 02:34:31 +0900 | [diff] [blame] | 1211 | bool ListValue::Remove(const Value& value, size_t* index) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1212 | for (auto it = list_->begin(); it != list_->end(); ++it) { |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 1213 | if ((*it)->Equals(&value)) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1214 | size_t previous_index = it - list_->begin(); |
| 1215 | list_->erase(it); |
robertshield@chromium.org | 9fb9e37 | 2010-03-23 05:12:50 +0900 | [diff] [blame] | 1216 | |
tfarina@chromium.org | 09cf434 | 2011-08-14 02:34:31 +0900 | [diff] [blame] | 1217 | if (index) |
| 1218 | *index = previous_index; |
| 1219 | return true; |
pkasting@chromium.org | 727139c | 2009-05-09 09:33:04 +0900 | [diff] [blame] | 1220 | } |
| 1221 | } |
tfarina@chromium.org | 09cf434 | 2011-08-14 02:34:31 +0900 | [diff] [blame] | 1222 | return false; |
pkasting@chromium.org | 727139c | 2009-05-09 09:33:04 +0900 | [diff] [blame] | 1223 | } |
| 1224 | |
bauerb@chromium.org | ae43e0a | 2013-08-06 22:33:04 +0900 | [diff] [blame] | 1225 | ListValue::iterator ListValue::Erase(iterator iter, |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1226 | std::unique_ptr<Value>* out_value) { |
estade@chromium.org | 52852d5 | 2012-07-03 11:51:43 +0900 | [diff] [blame] | 1227 | if (out_value) |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1228 | *out_value = std::move(*ListStorage::iterator(iter)); |
estade@chromium.org | 52852d5 | 2012-07-03 11:51:43 +0900 | [diff] [blame] | 1229 | |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1230 | return list_->erase(iter); |
estade@chromium.org | 52852d5 | 2012-07-03 11:51:43 +0900 | [diff] [blame] | 1231 | } |
| 1232 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1233 | void ListValue::Append(std::unique_ptr<Value> in_value) { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1234 | list_->push_back(std::move(in_value)); |
estade | 77a018f | 2015-05-07 10:53:08 +0900 | [diff] [blame] | 1235 | } |
| 1236 | |
dcheng | d66aba8 | 2016-10-17 11:19:00 +0900 | [diff] [blame] | 1237 | #if !defined(OS_LINUX) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1238 | void ListValue::Append(Value* in_value) { |
| 1239 | DCHECK(in_value); |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 1240 | Append(WrapUnique(in_value)); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1241 | } |
dcheng | 17f21de | 2016-09-17 10:30:15 +0900 | [diff] [blame] | 1242 | #endif |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1243 | |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 1244 | void ListValue::AppendBoolean(bool in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 1245 | Append(MakeUnique<Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 1246 | } |
| 1247 | |
| 1248 | void ListValue::AppendInteger(int in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 1249 | Append(MakeUnique<Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 1250 | } |
| 1251 | |
| 1252 | void ListValue::AppendDouble(double in_value) { |
jdoerrie | bfe825e | 2017-03-02 21:09:19 +0900 | [diff] [blame] | 1253 | Append(MakeUnique<Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 1254 | } |
| 1255 | |
dcheng | ae1c2d6 | 2016-08-26 01:07:11 +0900 | [diff] [blame] | 1256 | void ListValue::AppendString(StringPiece in_value) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 1257 | Append(MakeUnique<Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 1258 | } |
| 1259 | |
| 1260 | void ListValue::AppendString(const string16& in_value) { |
jdoerrie | 0d1295b | 2017-03-06 20:12:04 +0900 | [diff] [blame] | 1261 | Append(MakeUnique<Value>(in_value)); |
kalman@chromium.org | 5081d8e | 2012-09-14 11:14:01 +0900 | [diff] [blame] | 1262 | } |
| 1263 | |
| 1264 | void 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 | |
| 1271 | void 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 | |
dcheng | 46cc6ec | 2016-09-14 14:49:58 +0900 | [diff] [blame] | 1278 | bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { |
zork@chromium.org | b5f742b | 2010-04-13 06:48:10 +0900 | [diff] [blame] | 1279 | DCHECK(in_value); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1280 | for (const auto& entry : *list_) { |
dcheng | 46cc6ec | 2016-09-14 14:49:58 +0900 | [diff] [blame] | 1281 | if (entry->Equals(in_value.get())) { |
zork@chromium.org | b5f742b | 2010-04-13 06:48:10 +0900 | [diff] [blame] | 1282 | return false; |
markusheintz@chromium.org | 7862187 | 2011-03-18 22:56:38 +0900 | [diff] [blame] | 1283 | } |
zork@chromium.org | b5f742b | 2010-04-13 06:48:10 +0900 | [diff] [blame] | 1284 | } |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1285 | list_->push_back(std::move(in_value)); |
zork@chromium.org | b5f742b | 2010-04-13 06:48:10 +0900 | [diff] [blame] | 1286 | return true; |
| 1287 | } |
| 1288 | |
dcheng | 46cc6ec | 2016-09-14 14:49:58 +0900 | [diff] [blame] | 1289 | bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { |
erikkay@chromium.org | 9034a23 | 2009-08-29 05:26:05 +0900 | [diff] [blame] | 1290 | DCHECK(in_value); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1291 | if (index > list_->size()) |
erikkay@chromium.org | 9034a23 | 2009-08-29 05:26:05 +0900 | [diff] [blame] | 1292 | return false; |
| 1293 | |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1294 | list_->insert(list_->begin() + index, std::move(in_value)); |
erikkay@chromium.org | 9034a23 | 2009-08-29 05:26:05 +0900 | [diff] [blame] | 1295 | return true; |
| 1296 | } |
| 1297 | |
pastarmovj@chromium.org | 1602a47 | 2011-09-20 00:23:10 +0900 | [diff] [blame] | 1298 | ListValue::const_iterator ListValue::Find(const Value& value) const { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1299 | return std::find_if(list_->begin(), list_->end(), |
dcheng | 1fa44fb | 2016-05-26 03:30:47 +0900 | [diff] [blame] | 1300 | [&value](const std::unique_ptr<Value>& entry) { |
| 1301 | return entry->Equals(&value); |
| 1302 | }); |
pastarmovj@chromium.org | 1602a47 | 2011-09-20 00:23:10 +0900 | [diff] [blame] | 1303 | } |
| 1304 | |
rsesek@chromium.org | c2d2b20 | 2012-05-17 00:23:30 +0900 | [diff] [blame] | 1305 | void ListValue::Swap(ListValue* other) { |
vabr | 7eac835 | 2017-03-08 08:34:30 +0900 | [diff] [blame] | 1306 | CHECK(other->is_list()); |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1307 | list_->swap(*(other->list_)); |
bauerb@chromium.org | 6878e50 | 2011-07-12 18:04:38 +0900 | [diff] [blame] | 1308 | } |
| 1309 | |
akalin@chromium.org | 810f92f | 2011-01-18 11:16:59 +0900 | [diff] [blame] | 1310 | ListValue* ListValue::DeepCopy() const { |
jdoerrie | 1d5b348 | 2017-02-17 22:54:49 +0900 | [diff] [blame] | 1311 | return static_cast<ListValue*>(Value::DeepCopy()); |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 1312 | } |
| 1313 | |
dcheng | cc8e4d8 | 2016-04-05 06:25:51 +0900 | [diff] [blame] | 1314 | std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const { |
| 1315 | return WrapUnique(DeepCopy()); |
estade | 033e61e | 2015-05-13 03:11:50 +0900 | [diff] [blame] | 1316 | } |
| 1317 | |
erg@chromium.org | 493f5f6 | 2010-07-16 06:03:54 +0900 | [diff] [blame] | 1318 | ValueSerializer::~ValueSerializer() { |
| 1319 | } |
tfarina@chromium.org | de3ef41 | 2011-08-05 08:51:10 +0900 | [diff] [blame] | 1320 | |
prashhir | 58322f4 | 2015-03-05 18:30:57 +0900 | [diff] [blame] | 1321 | ValueDeserializer::~ValueDeserializer() { |
| 1322 | } |
| 1323 | |
kalman@chromium.org | 829cf75 | 2012-09-12 12:39:35 +0900 | [diff] [blame] | 1324 | std::ostream& operator<<(std::ostream& out, const Value& value) { |
| 1325 | std::string json; |
estade | b5f30dd | 2015-05-16 10:02:34 +0900 | [diff] [blame] | 1326 | JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
kalman@chromium.org | 829cf75 | 2012-09-12 12:39:35 +0900 | [diff] [blame] | 1327 | return out << json; |
| 1328 | } |
| 1329 | |
jdoerrie | 89ee31a | 2016-12-08 00:43:28 +0900 | [diff] [blame] | 1330 | std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
| 1331 | if (static_cast<int>(type) < 0 || |
| 1332 | static_cast<size_t>(type) >= arraysize(kTypeNames)) |
| 1333 | return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
| 1334 | return out << Value::GetTypeName(type); |
| 1335 | } |
| 1336 | |
tfarina@chromium.org | de3ef41 | 2011-08-05 08:51:10 +0900 | [diff] [blame] | 1337 | } // namespace base |