Chromium Code Reviews| 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 //////////////////// |