Index: base/values.cc |
diff --git a/base/values.cc b/base/values.cc |
index f697c5030250c0c74c1f80f49f4fff5274d89a62..537c1840177ac29a3d79b750d6c1ffed33cd2f89 100644 |
--- a/base/values.cc |
+++ b/base/values.cc |
@@ -87,7 +87,22 @@ Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { |
} |
} |
+Value::Value(const char* in_string) : type_(Type::STRING) { |
+ string_value_.Init(in_string); |
+ DCHECK(IsStringUTF8(*string_value_)); |
+} |
+ |
+Value::Value(StringPiece in_string) : type_(Type::STRING) { |
+ string_value_.Init(in_string.as_string()); |
+ DCHECK(IsStringUTF8(*string_value_)); |
+} |
+ |
+Value::Value(const string16& in_string) : type_(Type::STRING) { |
+ string_value_.Init(UTF16ToUTF8(in_string)); |
+} |
+ |
Value::~Value() { |
+ InternalCleanup(); |
} |
void Value::InternalCopyFrom(const Value& that) { |
@@ -106,10 +121,65 @@ void Value::InternalCopyFrom(const Value& that) { |
case Type::DOUBLE: |
double_value_ = that.double_value_; |
return; |
+ case Type::STRING: |
+ string_value_.Init(*that.string_value_); |
+ return; |
// TODO(crbug.com/646113): Implement these once the corresponding derived |
// classes are removed. |
+ case Type::BINARY: |
+ case Type::LIST: |
+ case Type::DICTIONARY: |
+ return; |
+ } |
+} |
+ |
+void Value::InternalMoveFrom(Value&& that) { |
+ type_ = that.type_; |
+ |
+ switch (type_) { |
+ case Type::NONE: |
+ // Nothing to do |
+ return; |
+ |
+ case Type::BOOLEAN: |
+ bool_value_ = that.bool_value_; |
+ return; |
+ case Type::INTEGER: |
+ int_value_ = that.int_value_; |
+ return; |
+ case Type::DOUBLE: |
+ double_value_ = that.double_value_; |
+ return; |
case Type::STRING: |
+ string_value_.InitFromMove(std::move(that.string_value_)); |
+ 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.
|
+ return; |
+ |
+ // TODO(crbug.com/646113): Implement these once the corresponding derived |
+ // classes are removed. |
+ case Type::BINARY: |
+ case Type::LIST: |
+ case Type::DICTIONARY: |
+ return; |
+ } |
+} |
+ |
+void Value::InternalCleanup() { |
+ switch (type_) { |
+ case Type::NONE: |
+ case Type::BOOLEAN: |
+ case Type::INTEGER: |
+ case Type::DOUBLE: |
+ // Nothing to do |
+ return; |
+ |
+ case Type::STRING: |
+ string_value_.Destroy(); |
+ return; |
+ |
+ // TODO(crbug.com/646113): Implement these once the corresponding derived |
+ // classes are removed. |
case Type::BINARY: |
case Type::LIST: |
case Type::DICTIONARY: |
@@ -148,6 +218,16 @@ double Value::GetDouble() const { |
return 0.0; |
} |
+std::string& Value::GetString() { |
+ CHECK(is_string()); |
+ return *string_value_; |
+} |
+ |
+const std::string& Value::GetString() const { |
+ CHECK(is_string()); |
+ return *string_value_; |
+} |
+ |
bool Value::GetAsBinary(const BinaryValue** out_value) const { |
return false; |
} |
@@ -181,15 +261,27 @@ bool Value::GetAsDouble(double* out_value) const { |
} |
bool Value::GetAsString(std::string* out_value) const { |
- return false; |
+ if (out_value && is_string()) { |
+ *out_value = *string_value_; |
+ return true; |
+ } |
+ return is_string(); |
} |
bool Value::GetAsString(string16* out_value) const { |
- return false; |
+ if (out_value && is_string()) { |
+ *out_value = UTF8ToUTF16(*string_value_); |
+ return true; |
+ } |
+ return is_string(); |
} |
bool Value::GetAsString(const StringValue** out_value) const { |
- return false; |
+ if (out_value && is_string()) { |
+ *out_value = static_cast<const StringValue*>(this); |
+ return true; |
+ } |
+ return is_string(); |
} |
bool Value::GetAsList(ListValue** out_value) { |
@@ -223,6 +315,10 @@ Value* Value::DeepCopy() const { |
return new FundamentalValue(int_value_); |
case Type::DOUBLE: |
return new FundamentalValue(double_value_); |
+ // For now, make StringValues for backward-compatibility. Convert to |
+ // Value when that code is deleted. |
+ case Type::STRING: |
+ return new StringValue(*string_value_); |
default: |
// All other types should be handled by subclasses. |
@@ -248,6 +344,11 @@ bool Value::Equals(const Value* other) const { |
return int_value_ == other->int_value_; |
case Type::DOUBLE: |
return double_value_ == other->double_value_; |
+ // TODO(crbug.com/646113): Simplify this once JSONStringValue is removed. |
+ case Type::STRING: { |
+ std::string lhs, rhs; |
+ return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; |
+ } |
default: |
// This method should only be getting called for the above types -- all |
// subclasses need to provide their own implementation;. |
@@ -270,23 +371,22 @@ Value::Value(const Value& that) { |
} |
Value::Value(Value&& that) { |
- // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving |
- // and copying differ. |
- InternalCopyFrom(that); |
+ InternalMoveFrom(std::move(that)); |
} |
Value& Value::operator=(const Value& that) { |
- if (this != &that) |
+ if (this != &that) { |
+ 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
|
InternalCopyFrom(that); |
+ } |
return *this; |
} |
Value& Value::operator=(Value&& that) { |
if (this != &that) { |
- // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving |
- // and copying differ. |
- InternalCopyFrom(that); |
+ InternalCleanup(); |
+ 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.
|
} |
return *this; |
@@ -304,53 +404,9 @@ FundamentalValue::~FundamentalValue() {} |
///////////////////// StringValue //////////////////// |
-StringValue::StringValue(StringPiece in_value) |
- : Value(Type::STRING), value_(in_value.as_string()) { |
- DCHECK(IsStringUTF8(in_value)); |
-} |
- |
-StringValue::StringValue(const string16& in_value) |
- : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} |
- |
-StringValue::~StringValue() { |
-} |
- |
-std::string* StringValue::GetString() { |
- return &value_; |
-} |
- |
-const std::string& StringValue::GetString() const { |
- return value_; |
-} |
+StringValue::StringValue(StringPiece in_value) : Value(in_value) {} |
-bool StringValue::GetAsString(std::string* out_value) const { |
- if (out_value) |
- *out_value = value_; |
- return true; |
-} |
- |
-bool StringValue::GetAsString(string16* out_value) const { |
- if (out_value) |
- *out_value = UTF8ToUTF16(value_); |
- return true; |
-} |
- |
-bool StringValue::GetAsString(const StringValue** out_value) const { |
- if (out_value) |
- *out_value = this; |
- return true; |
-} |
- |
-StringValue* StringValue::DeepCopy() const { |
- return new StringValue(value_); |
-} |
- |
-bool StringValue::Equals(const Value* other) const { |
- if (other->GetType() != GetType()) |
- return false; |
- std::string lhs, rhs; |
- return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; |
-} |
+StringValue::StringValue(const string16& in_value) : Value(in_value) {} |
///////////////////// BinaryValue //////////////////// |