| Index: base/values.cc
|
| diff --git a/base/values.cc b/base/values.cc
|
| index f00a03f8d3097896b7176052368cfdbb7fbfb8dd..3d2bb6c6e6a2b2ca3d7b7b3fd743ab1de521a10d 100644
|
| --- a/base/values.cc
|
| +++ b/base/values.cc
|
| @@ -74,6 +74,20 @@ std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
|
|
|
| } // namespace
|
|
|
| +Value::Value(bool in_bool) : type_(TYPE_BOOLEAN), bool_value_(in_bool) {
|
| +}
|
| +
|
| +Value::Value(int in_int) : type_(TYPE_INTEGER), int_value_(in_int) {
|
| +}
|
| +
|
| +Value::Value(double in_double) : type_(TYPE_DOUBLE), double_value_(in_double) {
|
| + if (!std::isfinite(double_value_)) {
|
| + NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
|
| + << "values cannot be represented in JSON";
|
| + double_value_ = 0.0;
|
| + }
|
| +}
|
| +
|
| Value::~Value() {
|
| }
|
|
|
| @@ -89,20 +103,55 @@ const char* Value::GetTypeName(Value::Type type) {
|
| return kTypeNames[type];
|
| }
|
|
|
| +bool Value::GetBool() const {
|
| + CHECK(is_bool());
|
| + return bool_value_;
|
| +}
|
| +
|
| +int Value::GetInt() const {
|
| + CHECK(is_int());
|
| + return int_value_;
|
| +}
|
| +
|
| +double Value::GetDouble() const {
|
| + if (is_double())
|
| + return double_value_;
|
| + if (is_int())
|
| + return int_value_;
|
| + CHECK(false);
|
| + return 0.0;
|
| +}
|
| +
|
| bool Value::GetAsBinary(const BinaryValue** out_value) const {
|
| return false;
|
| }
|
|
|
| bool Value::GetAsBoolean(bool* out_value) const {
|
| - return false;
|
| + if (out_value && is_bool()) {
|
| + *out_value = bool_value_;
|
| + return true;
|
| + }
|
| + return is_bool();
|
| }
|
|
|
| bool Value::GetAsInteger(int* out_value) const {
|
| - return false;
|
| + if (out_value && is_int()) {
|
| + *out_value = int_value_;
|
| + return true;
|
| + }
|
| + return is_int();
|
| }
|
|
|
| bool Value::GetAsDouble(double* out_value) const {
|
| - return false;
|
| + if (out_value && is_double()) {
|
| + *out_value = double_value_;
|
| + return true;
|
| + } else if (out_value && is_int()) {
|
| + // Allow promotion from int to double.
|
| + *out_value = int_value_;
|
| + return true;
|
| + }
|
| + return is_double() || is_int();
|
| }
|
|
|
| bool Value::GetAsString(std::string* out_value) const {
|
| @@ -136,8 +185,24 @@ bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
|
| Value* Value::DeepCopy() const {
|
| // This method should only be getting called for null Values--all subclasses
|
| // need to provide their own implementation;.
|
| - DCHECK(IsType(TYPE_NULL));
|
| - return CreateNullValue().release();
|
| + switch (type()) {
|
| + case TYPE_NULL:
|
| + return CreateNullValue().release();
|
| +
|
| + // For now, make FundamentalValues for backward-compatibility. Convert to
|
| + // Value when that code is deleted.
|
| + case TYPE_BOOLEAN:
|
| + return new FundamentalValue(bool_value_);
|
| + case TYPE_INTEGER:
|
| + return new FundamentalValue(int_value_);
|
| + case TYPE_DOUBLE:
|
| + return new FundamentalValue(double_value_);
|
| +
|
| + default:
|
| + // All other types should be handled by subclasses.
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| }
|
|
|
| std::unique_ptr<Value> Value::CreateDeepCopy() const {
|
| @@ -145,10 +210,24 @@ std::unique_ptr<Value> Value::CreateDeepCopy() const {
|
| }
|
|
|
| bool Value::Equals(const Value* other) const {
|
| - // This method should only be getting called for null Values--all subclasses
|
| - // need to provide their own implementation;.
|
| - DCHECK(IsType(TYPE_NULL));
|
| - return other->IsType(TYPE_NULL);
|
| + if (other->type() != type())
|
| + return false;
|
| +
|
| + switch (type()) {
|
| + case TYPE_NULL:
|
| + return true;
|
| + case TYPE_BOOLEAN:
|
| + return bool_value_ == other->bool_value_;
|
| + case TYPE_INTEGER:
|
| + return int_value_ == other->int_value_;
|
| + case TYPE_DOUBLE:
|
| + return double_value_ == other->double_value_;
|
| + default:
|
| + // This method should only be getting called for the above types -- all
|
| + // subclasses need to provide their own implementation;.
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| }
|
|
|
| // static
|
| @@ -170,85 +249,20 @@ Value& Value::operator=(const Value& that) {
|
| ///////////////////// FundamentalValue ////////////////////
|
|
|
| FundamentalValue::FundamentalValue(bool in_value)
|
| - : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
|
| + : Value(in_value) {
|
| }
|
|
|
| FundamentalValue::FundamentalValue(int in_value)
|
| - : Value(TYPE_INTEGER), integer_value_(in_value) {
|
| + : Value(in_value) {
|
| }
|
|
|
| FundamentalValue::FundamentalValue(double in_value)
|
| - : Value(TYPE_DOUBLE), double_value_(in_value) {
|
| - if (!std::isfinite(double_value_)) {
|
| - NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
|
| - << "values cannot be represented in JSON";
|
| - double_value_ = 0.0;
|
| - }
|
| + : Value(in_value) {
|
| }
|
|
|
| FundamentalValue::~FundamentalValue() {
|
| }
|
|
|
| -bool FundamentalValue::GetAsBoolean(bool* out_value) const {
|
| - if (out_value && IsType(TYPE_BOOLEAN))
|
| - *out_value = boolean_value_;
|
| - return (IsType(TYPE_BOOLEAN));
|
| -}
|
| -
|
| -bool FundamentalValue::GetAsInteger(int* out_value) const {
|
| - if (out_value && IsType(TYPE_INTEGER))
|
| - *out_value = integer_value_;
|
| - return (IsType(TYPE_INTEGER));
|
| -}
|
| -
|
| -bool FundamentalValue::GetAsDouble(double* out_value) const {
|
| - if (out_value && IsType(TYPE_DOUBLE))
|
| - *out_value = double_value_;
|
| - else if (out_value && IsType(TYPE_INTEGER))
|
| - *out_value = integer_value_;
|
| - return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
|
| -}
|
| -
|
| -FundamentalValue* FundamentalValue::DeepCopy() const {
|
| - switch (GetType()) {
|
| - case TYPE_BOOLEAN:
|
| - return new FundamentalValue(boolean_value_);
|
| -
|
| - case TYPE_INTEGER:
|
| - return new FundamentalValue(integer_value_);
|
| -
|
| - case TYPE_DOUBLE:
|
| - return new FundamentalValue(double_value_);
|
| -
|
| - default:
|
| - NOTREACHED();
|
| - return NULL;
|
| - }
|
| -}
|
| -
|
| -bool FundamentalValue::Equals(const Value* other) const {
|
| - if (other->GetType() != GetType())
|
| - return false;
|
| -
|
| - switch (GetType()) {
|
| - case TYPE_BOOLEAN: {
|
| - bool lhs, rhs;
|
| - return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
|
| - }
|
| - case TYPE_INTEGER: {
|
| - int lhs, rhs;
|
| - return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
|
| - }
|
| - case TYPE_DOUBLE: {
|
| - double lhs, rhs;
|
| - return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
|
| - }
|
| - default:
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| -}
|
| -
|
| ///////////////////// StringValue ////////////////////
|
|
|
| StringValue::StringValue(StringPiece in_value)
|
|
|