OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/values.h" | 5 #include "base/values.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} | 80 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} |
81 | 81 |
82 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { | 82 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { |
83 if (!std::isfinite(double_value_)) { | 83 if (!std::isfinite(double_value_)) { |
84 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " | 84 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " |
85 << "values cannot be represented in JSON"; | 85 << "values cannot be represented in JSON"; |
86 double_value_ = 0.0; | 86 double_value_ = 0.0; |
87 } | 87 } |
88 } | 88 } |
89 | 89 |
90 Value::Value(const char* in_string) : type_(Type::STRING) { | |
91 string_value_.Init(in_string); | |
92 DCHECK(IsStringUTF8(*string_value_)); | |
93 } | |
94 | |
95 Value::Value(StringPiece in_string) : type_(Type::STRING) { | |
96 string_value_.Init(in_string.as_string()); | |
97 DCHECK(IsStringUTF8(*string_value_)); | |
98 } | |
99 | |
100 Value::Value(const string16& in_string) : type_(Type::STRING) { | |
101 string_value_.Init(UTF16ToUTF8(in_string)); | |
102 } | |
103 | |
90 Value::~Value() { | 104 Value::~Value() { |
105 InternalCleanup(); | |
91 } | 106 } |
92 | 107 |
93 void Value::InternalCopyFrom(const Value& that) { | 108 void Value::InternalCopyFrom(const Value& that) { |
94 type_ = that.type_; | 109 type_ = that.type_; |
95 switch (type_) { | 110 switch (type_) { |
96 case Type::NONE: | 111 case Type::NONE: |
97 // Nothing to do | 112 // Nothing to do |
98 return; | 113 return; |
99 | 114 |
100 case Type::BOOLEAN: | 115 case Type::BOOLEAN: |
101 bool_value_ = that.bool_value_; | 116 bool_value_ = that.bool_value_; |
102 return; | 117 return; |
103 case Type::INTEGER: | 118 case Type::INTEGER: |
104 int_value_ = that.int_value_; | 119 int_value_ = that.int_value_; |
105 return; | 120 return; |
106 case Type::DOUBLE: | 121 case Type::DOUBLE: |
107 double_value_ = that.double_value_; | 122 double_value_ = that.double_value_; |
108 return; | 123 return; |
124 case Type::STRING: | |
125 string_value_.Init(*that.string_value_); | |
126 return; | |
109 | 127 |
110 // TODO(crbug.com/646113): Implement these once the corresponding derived | 128 // TODO(crbug.com/646113): Implement these once the corresponding derived |
111 // classes are removed. | 129 // classes are removed. |
112 case Type::STRING: | |
113 case Type::BINARY: | 130 case Type::BINARY: |
114 case Type::LIST: | 131 case Type::LIST: |
115 case Type::DICTIONARY: | 132 case Type::DICTIONARY: |
133 return; | |
134 } | |
135 } | |
136 | |
137 void Value::InternalMoveFrom(Value&& that) { | |
138 type_ = that.type_; | |
139 | |
140 switch (type_) { | |
141 case Type::NONE: | |
142 // Nothing to do | |
143 return; | |
144 | |
145 case Type::BOOLEAN: | |
146 bool_value_ = that.bool_value_; | |
147 return; | |
148 case Type::INTEGER: | |
149 int_value_ = that.int_value_; | |
150 return; | |
151 case Type::DOUBLE: | |
152 double_value_ = that.double_value_; | |
153 return; | |
154 case Type::STRING: | |
155 string_value_.InitFromMove(std::move(that.string_value_)); | |
156 that.type_ = Type::NONE; | |
jdoerrie
2016/12/19 11:54:09
I decided against setting the type to NONE here, s
vabr (Chromium)
2016/12/19 13:00:56
Acknowledged.
| |
157 return; | |
158 | |
159 // TODO(crbug.com/646113): Implement these once the corresponding derived | |
160 // classes are removed. | |
161 case Type::BINARY: | |
162 case Type::LIST: | |
163 case Type::DICTIONARY: | |
164 return; | |
165 } | |
166 } | |
167 | |
168 void Value::InternalCleanup() { | |
169 switch (type_) { | |
170 case Type::NONE: | |
171 case Type::BOOLEAN: | |
172 case Type::INTEGER: | |
173 case Type::DOUBLE: | |
174 // Nothing to do | |
175 return; | |
176 | |
177 case Type::STRING: | |
178 string_value_.Destroy(); | |
179 return; | |
180 | |
181 // TODO(crbug.com/646113): Implement these once the corresponding derived | |
182 // classes are removed. | |
183 case Type::BINARY: | |
184 case Type::LIST: | |
185 case Type::DICTIONARY: | |
116 return; | 186 return; |
117 } | 187 } |
118 } | 188 } |
119 | 189 |
120 // static | 190 // static |
121 std::unique_ptr<Value> Value::CreateNullValue() { | 191 std::unique_ptr<Value> Value::CreateNullValue() { |
122 return WrapUnique(new Value(Type::NONE)); | 192 return WrapUnique(new Value(Type::NONE)); |
123 } | 193 } |
124 | 194 |
125 // static | 195 // static |
(...skipping 15 matching lines...) Expand all Loading... | |
141 | 211 |
142 double Value::GetDouble() const { | 212 double Value::GetDouble() const { |
143 if (is_double()) | 213 if (is_double()) |
144 return double_value_; | 214 return double_value_; |
145 if (is_int()) | 215 if (is_int()) |
146 return int_value_; | 216 return int_value_; |
147 CHECK(false); | 217 CHECK(false); |
148 return 0.0; | 218 return 0.0; |
149 } | 219 } |
150 | 220 |
221 std::string& Value::GetString() { | |
222 CHECK(is_string()); | |
223 return *string_value_; | |
224 } | |
225 | |
226 const std::string& Value::GetString() const { | |
227 CHECK(is_string()); | |
228 return *string_value_; | |
229 } | |
230 | |
151 bool Value::GetAsBinary(const BinaryValue** out_value) const { | 231 bool Value::GetAsBinary(const BinaryValue** out_value) const { |
152 return false; | 232 return false; |
153 } | 233 } |
154 | 234 |
155 bool Value::GetAsBoolean(bool* out_value) const { | 235 bool Value::GetAsBoolean(bool* out_value) const { |
156 if (out_value && is_bool()) { | 236 if (out_value && is_bool()) { |
157 *out_value = bool_value_; | 237 *out_value = bool_value_; |
158 return true; | 238 return true; |
159 } | 239 } |
160 return is_bool(); | 240 return is_bool(); |
(...skipping 13 matching lines...) Expand all Loading... | |
174 return true; | 254 return true; |
175 } else if (out_value && is_int()) { | 255 } else if (out_value && is_int()) { |
176 // Allow promotion from int to double. | 256 // Allow promotion from int to double. |
177 *out_value = int_value_; | 257 *out_value = int_value_; |
178 return true; | 258 return true; |
179 } | 259 } |
180 return is_double() || is_int(); | 260 return is_double() || is_int(); |
181 } | 261 } |
182 | 262 |
183 bool Value::GetAsString(std::string* out_value) const { | 263 bool Value::GetAsString(std::string* out_value) const { |
184 return false; | 264 if (out_value && is_string()) { |
265 *out_value = *string_value_; | |
266 return true; | |
267 } | |
268 return is_string(); | |
185 } | 269 } |
186 | 270 |
187 bool Value::GetAsString(string16* out_value) const { | 271 bool Value::GetAsString(string16* out_value) const { |
188 return false; | 272 if (out_value && is_string()) { |
273 *out_value = UTF8ToUTF16(*string_value_); | |
274 return true; | |
275 } | |
276 return is_string(); | |
189 } | 277 } |
190 | 278 |
191 bool Value::GetAsString(const StringValue** out_value) const { | 279 bool Value::GetAsString(const StringValue** out_value) const { |
192 return false; | 280 if (out_value && is_string()) { |
281 *out_value = static_cast<const StringValue*>(this); | |
282 return true; | |
283 } | |
284 return is_string(); | |
193 } | 285 } |
194 | 286 |
195 bool Value::GetAsList(ListValue** out_value) { | 287 bool Value::GetAsList(ListValue** out_value) { |
196 return false; | 288 return false; |
197 } | 289 } |
198 | 290 |
199 bool Value::GetAsList(const ListValue** out_value) const { | 291 bool Value::GetAsList(const ListValue** out_value) const { |
200 return false; | 292 return false; |
201 } | 293 } |
202 | 294 |
(...skipping 13 matching lines...) Expand all Loading... | |
216 return CreateNullValue().release(); | 308 return CreateNullValue().release(); |
217 | 309 |
218 // For now, make FundamentalValues for backward-compatibility. Convert to | 310 // For now, make FundamentalValues for backward-compatibility. Convert to |
219 // Value when that code is deleted. | 311 // Value when that code is deleted. |
220 case Type::BOOLEAN: | 312 case Type::BOOLEAN: |
221 return new FundamentalValue(bool_value_); | 313 return new FundamentalValue(bool_value_); |
222 case Type::INTEGER: | 314 case Type::INTEGER: |
223 return new FundamentalValue(int_value_); | 315 return new FundamentalValue(int_value_); |
224 case Type::DOUBLE: | 316 case Type::DOUBLE: |
225 return new FundamentalValue(double_value_); | 317 return new FundamentalValue(double_value_); |
318 // For now, make StringValues for backward-compatibility. Convert to | |
319 // Value when that code is deleted. | |
320 case Type::STRING: | |
321 return new StringValue(*string_value_); | |
226 | 322 |
227 default: | 323 default: |
228 // All other types should be handled by subclasses. | 324 // All other types should be handled by subclasses. |
229 NOTREACHED(); | 325 NOTREACHED(); |
230 return nullptr; | 326 return nullptr; |
231 } | 327 } |
232 } | 328 } |
233 | 329 |
234 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 330 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
235 return WrapUnique(DeepCopy()); | 331 return WrapUnique(DeepCopy()); |
236 } | 332 } |
237 | 333 |
238 bool Value::Equals(const Value* other) const { | 334 bool Value::Equals(const Value* other) const { |
239 if (other->type() != type()) | 335 if (other->type() != type()) |
240 return false; | 336 return false; |
241 | 337 |
242 switch (type()) { | 338 switch (type()) { |
243 case Type::NONE: | 339 case Type::NONE: |
244 return true; | 340 return true; |
245 case Type::BOOLEAN: | 341 case Type::BOOLEAN: |
246 return bool_value_ == other->bool_value_; | 342 return bool_value_ == other->bool_value_; |
247 case Type::INTEGER: | 343 case Type::INTEGER: |
248 return int_value_ == other->int_value_; | 344 return int_value_ == other->int_value_; |
249 case Type::DOUBLE: | 345 case Type::DOUBLE: |
250 return double_value_ == other->double_value_; | 346 return double_value_ == other->double_value_; |
347 // TODO(crbug.com/646113): Simplify this once JSONStringValue is removed. | |
348 case Type::STRING: { | |
349 std::string lhs, rhs; | |
350 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; | |
351 } | |
251 default: | 352 default: |
252 // This method should only be getting called for the above types -- all | 353 // This method should only be getting called for the above types -- all |
253 // subclasses need to provide their own implementation;. | 354 // subclasses need to provide their own implementation;. |
254 NOTREACHED(); | 355 NOTREACHED(); |
255 return false; | 356 return false; |
256 } | 357 } |
257 } | 358 } |
258 | 359 |
259 // static | 360 // static |
260 bool Value::Equals(const Value* a, const Value* b) { | 361 bool Value::Equals(const Value* a, const Value* b) { |
261 if ((a == NULL) && (b == NULL)) return true; | 362 if ((a == NULL) && (b == NULL)) return true; |
262 if ((a == NULL) ^ (b == NULL)) return false; | 363 if ((a == NULL) ^ (b == NULL)) return false; |
263 return a->Equals(b); | 364 return a->Equals(b); |
264 } | 365 } |
265 | 366 |
266 Value::Value(Type type) : type_(type) {} | 367 Value::Value(Type type) : type_(type) {} |
267 | 368 |
268 Value::Value(const Value& that) { | 369 Value::Value(const Value& that) { |
269 InternalCopyFrom(that); | 370 InternalCopyFrom(that); |
270 } | 371 } |
271 | 372 |
272 Value::Value(Value&& that) { | 373 Value::Value(Value&& that) { |
273 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving | 374 InternalMoveFrom(std::move(that)); |
274 // and copying differ. | |
275 InternalCopyFrom(that); | |
276 } | 375 } |
277 | 376 |
278 Value& Value::operator=(const Value& that) { | 377 Value& Value::operator=(const Value& that) { |
279 if (this != &that) | 378 if (this != &that) { |
379 InternalCleanup(); | |
vabr (Chromium)
2016/12/16 17:00:55
Having the InternalCleanup here, and using Init in
jdoerrie
2016/12/19 11:54:09
I agree. Most likely we should act similarly with
| |
280 InternalCopyFrom(that); | 380 InternalCopyFrom(that); |
381 } | |
281 | 382 |
282 return *this; | 383 return *this; |
283 } | 384 } |
284 | 385 |
285 Value& Value::operator=(Value&& that) { | 386 Value& Value::operator=(Value&& that) { |
286 if (this != &that) { | 387 if (this != &that) { |
287 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving | 388 InternalCleanup(); |
288 // and copying differ. | 389 InternalMoveFrom(std::move(that)); |
vabr (Chromium)
2016/12/16 17:00:55
My comment from the const-ref operator= applies he
jdoerrie
2016/12/19 11:54:09
Acknowledged.
| |
289 InternalCopyFrom(that); | |
290 } | 390 } |
291 | 391 |
292 return *this; | 392 return *this; |
293 } | 393 } |
294 | 394 |
295 ///////////////////// FundamentalValue //////////////////// | 395 ///////////////////// FundamentalValue //////////////////// |
296 | 396 |
297 FundamentalValue::FundamentalValue(bool in_value) : Value(in_value) {} | 397 FundamentalValue::FundamentalValue(bool in_value) : Value(in_value) {} |
298 | 398 |
299 FundamentalValue::FundamentalValue(int in_value) : Value(in_value) {} | 399 FundamentalValue::FundamentalValue(int in_value) : Value(in_value) {} |
300 | 400 |
301 FundamentalValue::FundamentalValue(double in_value) : Value(in_value) {} | 401 FundamentalValue::FundamentalValue(double in_value) : Value(in_value) {} |
302 | 402 |
303 FundamentalValue::~FundamentalValue() {} | 403 FundamentalValue::~FundamentalValue() {} |
304 | 404 |
305 ///////////////////// StringValue //////////////////// | 405 ///////////////////// StringValue //////////////////// |
306 | 406 |
307 StringValue::StringValue(StringPiece in_value) | 407 StringValue::StringValue(StringPiece in_value) : Value(in_value) {} |
308 : Value(Type::STRING), value_(in_value.as_string()) { | |
309 DCHECK(IsStringUTF8(in_value)); | |
310 } | |
311 | 408 |
312 StringValue::StringValue(const string16& in_value) | 409 StringValue::StringValue(const string16& in_value) : Value(in_value) {} |
313 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} | |
314 | |
315 StringValue::~StringValue() { | |
316 } | |
317 | |
318 std::string* StringValue::GetString() { | |
319 return &value_; | |
320 } | |
321 | |
322 const std::string& StringValue::GetString() const { | |
323 return value_; | |
324 } | |
325 | |
326 bool StringValue::GetAsString(std::string* out_value) const { | |
327 if (out_value) | |
328 *out_value = value_; | |
329 return true; | |
330 } | |
331 | |
332 bool StringValue::GetAsString(string16* out_value) const { | |
333 if (out_value) | |
334 *out_value = UTF8ToUTF16(value_); | |
335 return true; | |
336 } | |
337 | |
338 bool StringValue::GetAsString(const StringValue** out_value) const { | |
339 if (out_value) | |
340 *out_value = this; | |
341 return true; | |
342 } | |
343 | |
344 StringValue* StringValue::DeepCopy() const { | |
345 return new StringValue(value_); | |
346 } | |
347 | |
348 bool StringValue::Equals(const Value* other) const { | |
349 if (other->GetType() != GetType()) | |
350 return false; | |
351 std::string lhs, rhs; | |
352 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; | |
353 } | |
354 | 410 |
355 ///////////////////// BinaryValue //////////////////// | 411 ///////////////////// BinaryValue //////////////////// |
356 | 412 |
357 BinaryValue::BinaryValue() : Value(Type::BINARY), size_(0) {} | 413 BinaryValue::BinaryValue() : Value(Type::BINARY), size_(0) {} |
358 | 414 |
359 BinaryValue::BinaryValue(std::unique_ptr<char[]> buffer, size_t size) | 415 BinaryValue::BinaryValue(std::unique_ptr<char[]> buffer, size_t size) |
360 : Value(Type::BINARY), buffer_(std::move(buffer)), size_(size) {} | 416 : Value(Type::BINARY), buffer_(std::move(buffer)), size_(size) {} |
361 | 417 |
362 BinaryValue::~BinaryValue() { | 418 BinaryValue::~BinaryValue() { |
363 } | 419 } |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1219 } | 1275 } |
1220 | 1276 |
1221 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1277 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
1222 if (static_cast<int>(type) < 0 || | 1278 if (static_cast<int>(type) < 0 || |
1223 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1279 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
1224 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1280 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
1225 return out << Value::GetTypeName(type); | 1281 return out << Value::GetTypeName(type); |
1226 } | 1282 } |
1227 | 1283 |
1228 } // namespace base | 1284 } // namespace base |
OLD | NEW |