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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 default: | 71 default: |
72 return node.CreateDeepCopy(); | 72 return node.CreateDeepCopy(); |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 // TODO(crbug.com/646113): Remove this once all types are implemented. | 76 // TODO(crbug.com/646113): Remove this once all types are implemented. |
77 bool IsAssignmentSafe(Value::Type lhs, Value::Type rhs) { | 77 bool IsAssignmentSafe(Value::Type lhs, Value::Type rhs) { |
78 auto IsImplemented = [](Value::Type type) { | 78 auto IsImplemented = [](Value::Type type) { |
79 return type == Value::Type::NONE || type == Value::Type::BOOLEAN || | 79 return type == Value::Type::NONE || type == Value::Type::BOOLEAN || |
80 type == Value::Type::INTEGER || type == Value::Type::DOUBLE || | 80 type == Value::Type::INTEGER || type == Value::Type::DOUBLE || |
81 type == Value::Type::STRING; | 81 type == Value::Type::STRING || type == Value::Type::BINARY; |
82 }; | 82 }; |
83 | 83 |
84 return lhs == rhs || (IsImplemented(lhs) && IsImplemented(rhs)); | 84 return lhs == rhs || (IsImplemented(lhs) && IsImplemented(rhs)); |
85 } | 85 } |
86 | 86 |
87 } // namespace | 87 } // namespace |
88 | 88 |
89 // static | 89 // static |
90 std::unique_ptr<Value> Value::CreateNullValue() { | 90 std::unique_ptr<Value> Value::CreateNullValue() { |
91 return WrapUnique(new Value(Type::NONE)); | 91 return WrapUnique(new Value(Type::NONE)); |
92 } | 92 } |
93 | 93 |
| 94 // static |
| 95 std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer( |
| 96 const char* buffer, |
| 97 size_t size) { |
| 98 return MakeUnique<BinaryValue>(std::vector<char>(buffer, buffer + size)); |
| 99 } |
| 100 |
94 Value::Value(const Value& that) { | 101 Value::Value(const Value& that) { |
95 InternalCopyConstructFrom(that); | 102 InternalCopyConstructFrom(that); |
96 } | 103 } |
97 | 104 |
98 Value::Value(Value&& that) { | 105 Value::Value(Value&& that) { |
99 InternalMoveConstructFrom(std::move(that)); | 106 InternalMoveConstructFrom(std::move(that)); |
100 } | 107 } |
101 | 108 |
102 Value::Value() : type_(Type::NONE) {} | 109 Value::Value() : type_(Type::NONE) {} |
103 | 110 |
104 Value::Value(Type type) : type_(type) { | 111 Value::Value(Type type) : type_(type) { |
105 // Initialize with the default value. | 112 // Initialize with the default value. |
106 switch (type_) { | 113 switch (type_) { |
107 case Type::NONE: | 114 case Type::NONE: |
108 return; | 115 return; |
109 | 116 |
110 case Type::BOOLEAN: | 117 case Type::BOOLEAN: |
111 bool_value_ = false; | 118 bool_value_ = false; |
112 return; | 119 return; |
113 case Type::INTEGER: | 120 case Type::INTEGER: |
114 int_value_ = 0; | 121 int_value_ = 0; |
115 return; | 122 return; |
116 case Type::DOUBLE: | 123 case Type::DOUBLE: |
117 double_value_ = 0.0; | 124 double_value_ = 0.0; |
118 return; | 125 return; |
119 case Type::STRING: | 126 case Type::STRING: |
120 string_value_.Init(); | 127 string_value_.Init(); |
121 return; | 128 return; |
| 129 case Type::BINARY: |
| 130 binary_value_.Init(); |
| 131 return; |
122 | 132 |
123 // TODO(crbug.com/646113): Implement these once the corresponding derived | 133 // TODO(crbug.com/646113): Implement these once the corresponding derived |
124 // classes are removed. | 134 // classes are removed. |
125 case Type::BINARY: | |
126 case Type::LIST: | 135 case Type::LIST: |
127 case Type::DICTIONARY: | 136 case Type::DICTIONARY: |
128 return; | 137 return; |
129 } | 138 } |
130 } | 139 } |
131 | 140 |
132 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} | 141 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} |
133 | 142 |
134 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} | 143 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} |
135 | 144 |
(...skipping 23 matching lines...) Expand all Loading... |
159 Value::Value(const char16* in_string) : type_(Type::STRING) { | 168 Value::Value(const char16* in_string) : type_(Type::STRING) { |
160 string_value_.Init(UTF16ToUTF8(in_string)); | 169 string_value_.Init(UTF16ToUTF8(in_string)); |
161 } | 170 } |
162 | 171 |
163 Value::Value(const string16& in_string) : type_(Type::STRING) { | 172 Value::Value(const string16& in_string) : type_(Type::STRING) { |
164 string_value_.Init(UTF16ToUTF8(in_string)); | 173 string_value_.Init(UTF16ToUTF8(in_string)); |
165 } | 174 } |
166 | 175 |
167 Value::Value(StringPiece in_string) : Value(in_string.as_string()) {} | 176 Value::Value(StringPiece in_string) : Value(in_string.as_string()) {} |
168 | 177 |
| 178 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) { |
| 179 binary_value_.Init(in_blob); |
| 180 } |
| 181 |
| 182 Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) { |
| 183 binary_value_.Init(std::move(in_blob)); |
| 184 } |
| 185 |
169 Value& Value::operator=(const Value& that) { | 186 Value& Value::operator=(const Value& that) { |
170 if (this != &that) { | 187 if (this != &that) { |
171 DCHECK(IsAssignmentSafe(type_, that.type_)); | 188 DCHECK(IsAssignmentSafe(type_, that.type_)); |
172 if (type_ == that.type_) { | 189 if (type_ == that.type_) { |
173 InternalCopyAssignFrom(that); | 190 InternalCopyAssignFrom(that); |
174 } else { | 191 } else { |
175 InternalCleanup(); | 192 InternalCleanup(); |
176 InternalCopyConstructFrom(that); | 193 InternalCopyConstructFrom(that); |
177 } | 194 } |
178 } | 195 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 return int_value_; | 239 return int_value_; |
223 CHECK(false); | 240 CHECK(false); |
224 return 0.0; | 241 return 0.0; |
225 } | 242 } |
226 | 243 |
227 const std::string& Value::GetString() const { | 244 const std::string& Value::GetString() const { |
228 CHECK(is_string()); | 245 CHECK(is_string()); |
229 return *string_value_; | 246 return *string_value_; |
230 } | 247 } |
231 | 248 |
| 249 const std::vector<char>& Value::GetBlob() const { |
| 250 CHECK(is_blob()); |
| 251 return *binary_value_; |
| 252 } |
| 253 |
| 254 size_t Value::GetSize() const { |
| 255 return GetBlob().size(); |
| 256 } |
| 257 |
| 258 const char* Value::GetBuffer() const { |
| 259 return GetBlob().data(); |
| 260 } |
| 261 |
232 bool Value::GetAsBoolean(bool* out_value) const { | 262 bool Value::GetAsBoolean(bool* out_value) const { |
233 if (out_value && is_bool()) { | 263 if (out_value && is_bool()) { |
234 *out_value = bool_value_; | 264 *out_value = bool_value_; |
235 return true; | 265 return true; |
236 } | 266 } |
237 return is_bool(); | 267 return is_bool(); |
238 } | 268 } |
239 | 269 |
240 bool Value::GetAsInteger(int* out_value) const { | 270 bool Value::GetAsInteger(int* out_value) const { |
241 if (out_value && is_int()) { | 271 if (out_value && is_int()) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 313 |
284 bool Value::GetAsString(StringPiece* out_value) const { | 314 bool Value::GetAsString(StringPiece* out_value) const { |
285 if (out_value && is_string()) { | 315 if (out_value && is_string()) { |
286 *out_value = *string_value_; | 316 *out_value = *string_value_; |
287 return true; | 317 return true; |
288 } | 318 } |
289 return is_string(); | 319 return is_string(); |
290 } | 320 } |
291 | 321 |
292 bool Value::GetAsBinary(const BinaryValue** out_value) const { | 322 bool Value::GetAsBinary(const BinaryValue** out_value) const { |
293 return false; | 323 if (out_value && is_blob()) { |
| 324 *out_value = this; |
| 325 return true; |
| 326 } |
| 327 return is_blob(); |
294 } | 328 } |
295 | 329 |
296 bool Value::GetAsList(ListValue** out_value) { | 330 bool Value::GetAsList(ListValue** out_value) { |
297 return false; | 331 return false; |
298 } | 332 } |
299 | 333 |
300 bool Value::GetAsList(const ListValue** out_value) const { | 334 bool Value::GetAsList(const ListValue** out_value) const { |
301 return false; | 335 return false; |
302 } | 336 } |
303 | 337 |
(...skipping 17 matching lines...) Expand all Loading... |
321 case Type::BOOLEAN: | 355 case Type::BOOLEAN: |
322 return new FundamentalValue(bool_value_); | 356 return new FundamentalValue(bool_value_); |
323 case Type::INTEGER: | 357 case Type::INTEGER: |
324 return new FundamentalValue(int_value_); | 358 return new FundamentalValue(int_value_); |
325 case Type::DOUBLE: | 359 case Type::DOUBLE: |
326 return new FundamentalValue(double_value_); | 360 return new FundamentalValue(double_value_); |
327 // For now, make StringValues for backward-compatibility. Convert to | 361 // For now, make StringValues for backward-compatibility. Convert to |
328 // Value when that code is deleted. | 362 // Value when that code is deleted. |
329 case Type::STRING: | 363 case Type::STRING: |
330 return new StringValue(*string_value_); | 364 return new StringValue(*string_value_); |
| 365 // For now, make BinaryValues for backward-compatibility. Convert to |
| 366 // Value when that code is deleted. |
| 367 case Type::BINARY: |
| 368 return new BinaryValue(*binary_value_); |
331 | 369 |
332 default: | 370 default: |
333 // All other types should be handled by subclasses. | 371 // All other types should be handled by subclasses. |
334 NOTREACHED(); | 372 NOTREACHED(); |
335 return nullptr; | 373 return nullptr; |
336 } | 374 } |
337 } | 375 } |
338 | 376 |
339 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 377 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
340 return WrapUnique(DeepCopy()); | 378 return WrapUnique(DeepCopy()); |
341 } | 379 } |
342 | 380 |
343 bool Value::Equals(const Value* other) const { | 381 bool Value::Equals(const Value* other) const { |
344 if (other->type() != type()) | 382 if (other->type() != type()) |
345 return false; | 383 return false; |
346 | 384 |
347 switch (type()) { | 385 switch (type()) { |
348 case Type::NONE: | 386 case Type::NONE: |
349 return true; | 387 return true; |
350 case Type::BOOLEAN: | 388 case Type::BOOLEAN: |
351 return bool_value_ == other->bool_value_; | 389 return bool_value_ == other->bool_value_; |
352 case Type::INTEGER: | 390 case Type::INTEGER: |
353 return int_value_ == other->int_value_; | 391 return int_value_ == other->int_value_; |
354 case Type::DOUBLE: | 392 case Type::DOUBLE: |
355 return double_value_ == other->double_value_; | 393 return double_value_ == other->double_value_; |
356 case Type::STRING: | 394 case Type::STRING: |
357 return *string_value_ == *(other->string_value_); | 395 return *string_value_ == *(other->string_value_); |
| 396 case Type::BINARY: |
| 397 return *binary_value_ == *(other->binary_value_); |
358 default: | 398 default: |
359 // This method should only be getting called for the above types -- all | 399 // This method should only be getting called for the above types -- all |
360 // subclasses need to provide their own implementation;. | 400 // subclasses need to provide their own implementation;. |
361 NOTREACHED(); | 401 NOTREACHED(); |
362 return false; | 402 return false; |
363 } | 403 } |
364 } | 404 } |
365 | 405 |
366 // static | 406 // static |
367 bool Value::Equals(const Value* a, const Value* b) { | 407 bool Value::Equals(const Value* a, const Value* b) { |
(...skipping 30 matching lines...) Expand all Loading... |
398 case Type::NONE: | 438 case Type::NONE: |
399 case Type::BOOLEAN: | 439 case Type::BOOLEAN: |
400 case Type::INTEGER: | 440 case Type::INTEGER: |
401 case Type::DOUBLE: | 441 case Type::DOUBLE: |
402 InternalCopyFundamentalValue(that); | 442 InternalCopyFundamentalValue(that); |
403 return; | 443 return; |
404 | 444 |
405 case Type::STRING: | 445 case Type::STRING: |
406 string_value_.Init(*that.string_value_); | 446 string_value_.Init(*that.string_value_); |
407 return; | 447 return; |
| 448 case Type::BINARY: |
| 449 binary_value_.Init(*that.binary_value_); |
| 450 return; |
408 | 451 |
409 // TODO(crbug.com/646113): Implement these once the corresponding derived | 452 // TODO(crbug.com/646113): Implement these once the corresponding derived |
410 // classes are removed. | 453 // classes are removed. |
411 case Type::BINARY: | |
412 case Type::LIST: | 454 case Type::LIST: |
413 case Type::DICTIONARY: | 455 case Type::DICTIONARY: |
414 return; | 456 return; |
415 } | 457 } |
416 } | 458 } |
417 | 459 |
418 void Value::InternalMoveConstructFrom(Value&& that) { | 460 void Value::InternalMoveConstructFrom(Value&& that) { |
419 type_ = that.type_; | 461 type_ = that.type_; |
420 | 462 |
421 switch (type_) { | 463 switch (type_) { |
422 case Type::NONE: | 464 case Type::NONE: |
423 case Type::BOOLEAN: | 465 case Type::BOOLEAN: |
424 case Type::INTEGER: | 466 case Type::INTEGER: |
425 case Type::DOUBLE: | 467 case Type::DOUBLE: |
426 InternalCopyFundamentalValue(that); | 468 InternalCopyFundamentalValue(that); |
427 return; | 469 return; |
428 | 470 |
429 case Type::STRING: | 471 case Type::STRING: |
430 string_value_.InitFromMove(std::move(that.string_value_)); | 472 string_value_.InitFromMove(std::move(that.string_value_)); |
431 return; | 473 return; |
| 474 case Type::BINARY: |
| 475 binary_value_.InitFromMove(std::move(that.binary_value_)); |
| 476 return; |
432 | 477 |
433 // TODO(crbug.com/646113): Implement these once the corresponding derived | 478 // TODO(crbug.com/646113): Implement these once the corresponding derived |
434 // classes are removed. | 479 // classes are removed. |
435 case Type::BINARY: | |
436 case Type::LIST: | 480 case Type::LIST: |
437 case Type::DICTIONARY: | 481 case Type::DICTIONARY: |
438 return; | 482 return; |
439 } | 483 } |
440 } | 484 } |
441 | 485 |
442 void Value::InternalCopyAssignFrom(const Value& that) { | 486 void Value::InternalCopyAssignFrom(const Value& that) { |
443 type_ = that.type_; | 487 type_ = that.type_; |
444 | 488 |
445 switch (type_) { | 489 switch (type_) { |
446 case Type::NONE: | 490 case Type::NONE: |
447 case Type::BOOLEAN: | 491 case Type::BOOLEAN: |
448 case Type::INTEGER: | 492 case Type::INTEGER: |
449 case Type::DOUBLE: | 493 case Type::DOUBLE: |
450 InternalCopyFundamentalValue(that); | 494 InternalCopyFundamentalValue(that); |
451 return; | 495 return; |
452 | 496 |
453 case Type::STRING: | 497 case Type::STRING: |
454 *string_value_ = *that.string_value_; | 498 *string_value_ = *that.string_value_; |
455 return; | 499 return; |
| 500 case Type::BINARY: |
| 501 *binary_value_ = *that.binary_value_; |
| 502 return; |
456 | 503 |
457 // TODO(crbug.com/646113): Implement these once the corresponding derived | 504 // TODO(crbug.com/646113): Implement these once the corresponding derived |
458 // classes are removed. | 505 // classes are removed. |
459 case Type::BINARY: | |
460 case Type::LIST: | 506 case Type::LIST: |
461 case Type::DICTIONARY: | 507 case Type::DICTIONARY: |
462 return; | 508 return; |
463 } | 509 } |
464 } | 510 } |
465 | 511 |
466 void Value::InternalMoveAssignFrom(Value&& that) { | 512 void Value::InternalMoveAssignFrom(Value&& that) { |
467 type_ = that.type_; | 513 type_ = that.type_; |
468 | 514 |
469 switch (type_) { | 515 switch (type_) { |
470 case Type::NONE: | 516 case Type::NONE: |
471 case Type::BOOLEAN: | 517 case Type::BOOLEAN: |
472 case Type::INTEGER: | 518 case Type::INTEGER: |
473 case Type::DOUBLE: | 519 case Type::DOUBLE: |
474 InternalCopyFundamentalValue(that); | 520 InternalCopyFundamentalValue(that); |
475 return; | 521 return; |
476 | 522 |
477 case Type::STRING: | 523 case Type::STRING: |
478 *string_value_ = std::move(*that.string_value_); | 524 *string_value_ = std::move(*that.string_value_); |
479 return; | 525 return; |
| 526 case Type::BINARY: |
| 527 *binary_value_ = std::move(*that.binary_value_); |
| 528 return; |
480 | 529 |
481 // TODO(crbug.com/646113): Implement these once the corresponding derived | 530 // TODO(crbug.com/646113): Implement these once the corresponding derived |
482 // classes are removed. | 531 // classes are removed. |
483 case Type::BINARY: | |
484 case Type::LIST: | 532 case Type::LIST: |
485 case Type::DICTIONARY: | 533 case Type::DICTIONARY: |
486 return; | 534 return; |
487 } | 535 } |
488 } | 536 } |
489 | 537 |
490 void Value::InternalCleanup() { | 538 void Value::InternalCleanup() { |
491 switch (type_) { | 539 switch (type_) { |
492 case Type::NONE: | 540 case Type::NONE: |
493 case Type::BOOLEAN: | 541 case Type::BOOLEAN: |
494 case Type::INTEGER: | 542 case Type::INTEGER: |
495 case Type::DOUBLE: | 543 case Type::DOUBLE: |
496 // Nothing to do | 544 // Nothing to do |
497 return; | 545 return; |
498 | 546 |
499 case Type::STRING: | 547 case Type::STRING: |
500 string_value_.Destroy(); | 548 string_value_.Destroy(); |
501 return; | 549 return; |
| 550 case Type::BINARY: |
| 551 binary_value_.Destroy(); |
| 552 return; |
502 | 553 |
503 // TODO(crbug.com/646113): Implement these once the corresponding derived | 554 // TODO(crbug.com/646113): Implement these once the corresponding derived |
504 // classes are removed. | 555 // classes are removed. |
505 case Type::BINARY: | |
506 case Type::LIST: | 556 case Type::LIST: |
507 case Type::DICTIONARY: | 557 case Type::DICTIONARY: |
508 return; | 558 return; |
509 } | 559 } |
510 } | 560 } |
511 | 561 |
512 ///////////////////// BinaryValue //////////////////// | |
513 | |
514 BinaryValue::BinaryValue() : Value(Type::BINARY), size_(0) {} | |
515 | |
516 BinaryValue::BinaryValue(std::unique_ptr<char[]> buffer, size_t size) | |
517 : Value(Type::BINARY), buffer_(std::move(buffer)), size_(size) {} | |
518 | |
519 BinaryValue::~BinaryValue() { | |
520 } | |
521 | |
522 // static | |
523 std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer( | |
524 const char* buffer, | |
525 size_t size) { | |
526 std::unique_ptr<char[]> buffer_copy(new char[size]); | |
527 memcpy(buffer_copy.get(), buffer, size); | |
528 return MakeUnique<BinaryValue>(std::move(buffer_copy), size); | |
529 } | |
530 | |
531 bool BinaryValue::GetAsBinary(const BinaryValue** out_value) const { | |
532 if (out_value) | |
533 *out_value = this; | |
534 return true; | |
535 } | |
536 | |
537 BinaryValue* BinaryValue::DeepCopy() const { | |
538 return CreateWithCopiedBuffer(buffer_.get(), size_).release(); | |
539 } | |
540 | |
541 bool BinaryValue::Equals(const Value* other) const { | |
542 if (other->GetType() != GetType()) | |
543 return false; | |
544 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other); | |
545 if (other_binary->size_ != size_) | |
546 return false; | |
547 return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_); | |
548 } | |
549 | |
550 ///////////////////// DictionaryValue //////////////////// | 562 ///////////////////// DictionaryValue //////////////////// |
551 | 563 |
552 // static | 564 // static |
553 std::unique_ptr<DictionaryValue> DictionaryValue::From( | 565 std::unique_ptr<DictionaryValue> DictionaryValue::From( |
554 std::unique_ptr<Value> value) { | 566 std::unique_ptr<Value> value) { |
555 DictionaryValue* out; | 567 DictionaryValue* out; |
556 if (value && value->GetAsDictionary(&out)) { | 568 if (value && value->GetAsDictionary(&out)) { |
557 ignore_result(value.release()); | 569 ignore_result(value.release()); |
558 return WrapUnique(out); | 570 return WrapUnique(out); |
559 } | 571 } |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 } | 773 } |
762 | 774 |
763 bool DictionaryValue::GetBinary(StringPiece path, | 775 bool DictionaryValue::GetBinary(StringPiece path, |
764 const BinaryValue** out_value) const { | 776 const BinaryValue** out_value) const { |
765 const Value* value; | 777 const Value* value; |
766 bool result = Get(path, &value); | 778 bool result = Get(path, &value); |
767 if (!result || !value->IsType(Type::BINARY)) | 779 if (!result || !value->IsType(Type::BINARY)) |
768 return false; | 780 return false; |
769 | 781 |
770 if (out_value) | 782 if (out_value) |
771 *out_value = static_cast<const BinaryValue*>(value); | 783 *out_value = value; |
772 | 784 |
773 return true; | 785 return true; |
774 } | 786 } |
775 | 787 |
776 bool DictionaryValue::GetBinary(StringPiece path, BinaryValue** out_value) { | 788 bool DictionaryValue::GetBinary(StringPiece path, BinaryValue** out_value) { |
777 return static_cast<const DictionaryValue&>(*this).GetBinary( | 789 return static_cast<const DictionaryValue&>(*this).GetBinary( |
778 path, | 790 path, |
779 const_cast<const BinaryValue**>(out_value)); | 791 const_cast<const BinaryValue**>(out_value)); |
780 } | 792 } |
781 | 793 |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 return value->GetAsString(out_value); | 1167 return value->GetAsString(out_value); |
1156 } | 1168 } |
1157 | 1169 |
1158 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const { | 1170 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const { |
1159 const Value* value; | 1171 const Value* value; |
1160 bool result = Get(index, &value); | 1172 bool result = Get(index, &value); |
1161 if (!result || !value->IsType(Type::BINARY)) | 1173 if (!result || !value->IsType(Type::BINARY)) |
1162 return false; | 1174 return false; |
1163 | 1175 |
1164 if (out_value) | 1176 if (out_value) |
1165 *out_value = static_cast<const BinaryValue*>(value); | 1177 *out_value = value; |
1166 | 1178 |
1167 return true; | 1179 return true; |
1168 } | 1180 } |
1169 | 1181 |
1170 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) { | 1182 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) { |
1171 return static_cast<const ListValue&>(*this).GetBinary( | 1183 return static_cast<const ListValue&>(*this).GetBinary( |
1172 index, | 1184 index, |
1173 const_cast<const BinaryValue**>(out_value)); | 1185 const_cast<const BinaryValue**>(out_value)); |
1174 } | 1186 } |
1175 | 1187 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 } | 1388 } |
1377 | 1389 |
1378 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1390 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
1379 if (static_cast<int>(type) < 0 || | 1391 if (static_cast<int>(type) < 0 || |
1380 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1392 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
1381 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1393 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
1382 return out << Value::GetTypeName(type); | 1394 return out << Value::GetTypeName(type); |
1383 } | 1395 } |
1384 | 1396 |
1385 } // namespace base | 1397 } // namespace base |
OLD | NEW |