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) |