Chromium Code Reviews| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 return CopyDictionaryWithoutEmptyChildren( | 68 return CopyDictionaryWithoutEmptyChildren( |
| 69 static_cast<const DictionaryValue&>(node)); | 69 static_cast<const DictionaryValue&>(node)); |
| 70 | 70 |
| 71 default: | 71 default: |
| 72 return node.CreateDeepCopy(); | 72 return node.CreateDeepCopy(); |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 | 75 |
| 76 } // namespace | 76 } // namespace |
| 77 | 77 |
| 78 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} | |
| 79 | |
| 80 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} | |
| 81 | |
| 82 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { | |
| 83 if (!std::isfinite(double_value_)) { | |
| 84 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " | |
| 85 << "values cannot be represented in JSON"; | |
| 86 double_value_ = 0.0; | |
| 87 } | |
| 88 } | |
| 89 | |
| 78 Value::~Value() { | 90 Value::~Value() { |
| 79 } | 91 } |
| 80 | 92 |
| 93 void Value::InternalCopyFrom(const Value& that) { | |
| 94 type_ = that.type_; | |
| 95 switch (type_) { | |
| 96 case Type::NONE: | |
| 97 // Nothing to do | |
| 98 return; | |
| 99 | |
| 100 case Type::BOOLEAN: | |
| 101 bool_value_ = that.bool_value_; | |
| 102 return; | |
| 103 case Type::INTEGER: | |
| 104 int_value_ = that.int_value_; | |
| 105 return; | |
| 106 case Type::DOUBLE: | |
| 107 double_value_ = that.double_value_; | |
| 108 return; | |
| 109 | |
| 110 // TODO(crbug.com/646113): Implement these once the corresponding derived | |
| 111 // classes are removed. | |
| 112 case Type::STRING: | |
| 113 case Type::BINARY: | |
| 114 case Type::LIST: | |
| 115 case Type::DICTIONARY: | |
| 116 return; | |
| 117 } | |
| 118 } | |
| 119 | |
| 81 // static | 120 // static |
| 82 std::unique_ptr<Value> Value::CreateNullValue() { | 121 std::unique_ptr<Value> Value::CreateNullValue() { |
| 83 return WrapUnique(new Value(Type::NONE)); | 122 return WrapUnique(new Value(Type::NONE)); |
| 84 } | 123 } |
| 85 | 124 |
| 86 // static | 125 // static |
| 87 const char* Value::GetTypeName(Value::Type type) { | 126 const char* Value::GetTypeName(Value::Type type) { |
| 88 DCHECK_GE(static_cast<int>(type), 0); | 127 DCHECK_GE(static_cast<int>(type), 0); |
| 89 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); | 128 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); |
| 90 return kTypeNames[static_cast<size_t>(type)]; | 129 return kTypeNames[static_cast<size_t>(type)]; |
| 91 } | 130 } |
| 92 | 131 |
| 132 bool Value::GetBool() const { | |
| 133 CHECK(is_bool()); | |
| 134 return bool_value_; | |
| 135 } | |
| 136 | |
| 137 int Value::GetInt() const { | |
| 138 CHECK(is_int()); | |
| 139 return int_value_; | |
| 140 } | |
| 141 | |
| 142 double Value::GetDouble() const { | |
| 143 if (is_double()) | |
| 144 return double_value_; | |
| 145 if (is_int()) | |
| 146 return int_value_; | |
| 147 CHECK(false); | |
| 148 return 0.0; | |
| 149 } | |
| 150 | |
| 93 bool Value::GetAsBinary(const BinaryValue** out_value) const { | 151 bool Value::GetAsBinary(const BinaryValue** out_value) const { |
| 94 return false; | 152 return false; |
| 95 } | 153 } |
| 96 | 154 |
| 97 bool Value::GetAsBoolean(bool* out_value) const { | 155 bool Value::GetAsBoolean(bool* out_value) const { |
| 98 return false; | 156 if (out_value && is_bool()) { |
| 157 *out_value = bool_value_; | |
| 158 return true; | |
| 159 } | |
| 160 return is_bool(); | |
| 99 } | 161 } |
| 100 | 162 |
| 101 bool Value::GetAsInteger(int* out_value) const { | 163 bool Value::GetAsInteger(int* out_value) const { |
| 102 return false; | 164 if (out_value && is_int()) { |
| 165 *out_value = int_value_; | |
| 166 return true; | |
| 167 } | |
| 168 return is_int(); | |
| 103 } | 169 } |
| 104 | 170 |
| 105 bool Value::GetAsDouble(double* out_value) const { | 171 bool Value::GetAsDouble(double* out_value) const { |
| 106 return false; | 172 if (out_value && is_double()) { |
| 173 *out_value = double_value_; | |
| 174 return true; | |
| 175 } else if (out_value && is_int()) { | |
| 176 // Allow promotion from int to double. | |
| 177 *out_value = int_value_; | |
| 178 return true; | |
| 179 } | |
| 180 return is_double() || is_int(); | |
| 107 } | 181 } |
| 108 | 182 |
| 109 bool Value::GetAsString(std::string* out_value) const { | 183 bool Value::GetAsString(std::string* out_value) const { |
| 110 return false; | 184 return false; |
| 111 } | 185 } |
| 112 | 186 |
| 113 bool Value::GetAsString(string16* out_value) const { | 187 bool Value::GetAsString(string16* out_value) const { |
| 114 return false; | 188 return false; |
| 115 } | 189 } |
| 116 | 190 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 130 return false; | 204 return false; |
| 131 } | 205 } |
| 132 | 206 |
| 133 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { | 207 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { |
| 134 return false; | 208 return false; |
| 135 } | 209 } |
| 136 | 210 |
| 137 Value* Value::DeepCopy() const { | 211 Value* Value::DeepCopy() const { |
| 138 // This method should only be getting called for null Values--all subclasses | 212 // This method should only be getting called for null Values--all subclasses |
| 139 // need to provide their own implementation;. | 213 // need to provide their own implementation;. |
| 140 DCHECK(IsType(Type::NONE)); | 214 switch (type()) { |
| 141 return CreateNullValue().release(); | 215 case Type::NONE: |
| 216 return CreateNullValue().release(); | |
| 217 | |
| 218 // For now, make FundamentalValues for backward-compatibility. Convert to | |
| 219 // Value when that code is deleted. | |
| 220 case Type::BOOLEAN: | |
| 221 return new FundamentalValue(bool_value_); | |
| 222 case Type::INTEGER: | |
| 223 return new FundamentalValue(int_value_); | |
| 224 case Type::DOUBLE: | |
| 225 return new FundamentalValue(double_value_); | |
| 226 | |
| 227 default: | |
| 228 // All other types should be handled by subclasses. | |
| 229 NOTREACHED(); | |
| 230 return nullptr; | |
| 231 } | |
| 142 } | 232 } |
| 143 | 233 |
| 144 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 234 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
| 145 return WrapUnique(DeepCopy()); | 235 return WrapUnique(DeepCopy()); |
| 146 } | 236 } |
| 147 | 237 |
| 148 bool Value::Equals(const Value* other) const { | 238 bool Value::Equals(const Value* other) const { |
| 149 // This method should only be getting called for null Values--all subclasses | 239 if (other->type() != type()) |
| 150 // need to provide their own implementation;. | 240 return false; |
| 151 DCHECK(IsType(Type::NONE)); | 241 |
| 152 return other->IsType(Type::NONE); | 242 switch (type()) { |
| 243 case Type::NONE: | |
| 244 return true; | |
| 245 case Type::BOOLEAN: | |
| 246 return bool_value_ == other->bool_value_; | |
| 247 case Type::INTEGER: | |
| 248 return int_value_ == other->int_value_; | |
| 249 case Type::DOUBLE: | |
| 250 return double_value_ == other->double_value_; | |
| 251 default: | |
| 252 // This method should only be getting called for the above types -- all | |
| 253 // subclasses need to provide their own implementation;. | |
| 254 NOTREACHED(); | |
| 255 return false; | |
| 256 } | |
| 153 } | 257 } |
| 154 | 258 |
| 155 // static | 259 // static |
| 156 bool Value::Equals(const Value* a, const Value* b) { | 260 bool Value::Equals(const Value* a, const Value* b) { |
| 157 if ((a == NULL) && (b == NULL)) return true; | 261 if ((a == NULL) && (b == NULL)) return true; |
| 158 if ((a == NULL) ^ (b == NULL)) return false; | 262 if ((a == NULL) ^ (b == NULL)) return false; |
| 159 return a->Equals(b); | 263 return a->Equals(b); |
| 160 } | 264 } |
| 161 | 265 |
| 162 Value::Value(Type type) : type_(type) {} | 266 Value::Value(Type type) : type_(type) {} |
|
jdoerrie
2016/12/23 14:18:26
According to the proposal this constructor should
vabr (Chromium)
2016/12/23 21:34:22
Seems fine with me, done. brettw@ -- please let me
| |
| 163 | 267 |
| 164 Value::Value(const Value& that) : type_(that.type_) {} | 268 Value::Value(const Value& that) { |
| 269 InternalCopyFrom(that); | |
| 270 } | |
| 271 | |
| 272 Value::Value(Value&& that) { | |
| 273 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving | |
| 274 // and copying differ. | |
| 275 InternalCopyFrom(that); | |
| 276 } | |
| 165 | 277 |
| 166 Value& Value::operator=(const Value& that) { | 278 Value& Value::operator=(const Value& that) { |
| 167 type_ = that.type_; | 279 if (this != &that) |
| 280 InternalCopyFrom(that); | |
| 281 | |
| 282 return *this; | |
| 283 } | |
| 284 | |
| 285 Value& Value::operator=(Value&& that) { | |
| 286 if (this != &that) { | |
| 287 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving | |
| 288 // and copying differ. | |
| 289 InternalCopyFrom(that); | |
| 290 } | |
| 291 | |
| 168 return *this; | 292 return *this; |
| 169 } | 293 } |
| 170 | 294 |
| 171 ///////////////////// FundamentalValue //////////////////// | 295 ///////////////////// FundamentalValue //////////////////// |
| 172 | 296 |
| 173 FundamentalValue::FundamentalValue(bool in_value) | 297 FundamentalValue::FundamentalValue(bool in_value) : Value(in_value) {} |
| 174 : Value(Type::BOOLEAN), boolean_value_(in_value) {} | |
| 175 | 298 |
| 176 FundamentalValue::FundamentalValue(int in_value) | 299 FundamentalValue::FundamentalValue(int in_value) : Value(in_value) {} |
| 177 : Value(Type::INTEGER), integer_value_(in_value) {} | |
| 178 | 300 |
| 179 FundamentalValue::FundamentalValue(double in_value) | 301 FundamentalValue::FundamentalValue(double in_value) : Value(in_value) {} |
| 180 : Value(Type::DOUBLE), double_value_(in_value) { | |
| 181 if (!std::isfinite(double_value_)) { | |
| 182 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " | |
| 183 << "values cannot be represented in JSON"; | |
| 184 double_value_ = 0.0; | |
| 185 } | |
| 186 } | |
| 187 | 302 |
| 188 FundamentalValue::~FundamentalValue() { | 303 FundamentalValue::~FundamentalValue() {} |
| 189 } | |
| 190 | |
| 191 bool FundamentalValue::GetAsBoolean(bool* out_value) const { | |
| 192 if (out_value && IsType(Type::BOOLEAN)) | |
| 193 *out_value = boolean_value_; | |
| 194 return (IsType(Type::BOOLEAN)); | |
| 195 } | |
| 196 | |
| 197 bool FundamentalValue::GetAsInteger(int* out_value) const { | |
| 198 if (out_value && IsType(Type::INTEGER)) | |
| 199 *out_value = integer_value_; | |
| 200 return (IsType(Type::INTEGER)); | |
| 201 } | |
| 202 | |
| 203 bool FundamentalValue::GetAsDouble(double* out_value) const { | |
| 204 if (out_value && IsType(Type::DOUBLE)) | |
| 205 *out_value = double_value_; | |
| 206 else if (out_value && IsType(Type::INTEGER)) | |
| 207 *out_value = integer_value_; | |
| 208 return (IsType(Type::DOUBLE) || IsType(Type::INTEGER)); | |
| 209 } | |
| 210 | |
| 211 FundamentalValue* FundamentalValue::DeepCopy() const { | |
| 212 switch (GetType()) { | |
| 213 case Type::BOOLEAN: | |
| 214 return new FundamentalValue(boolean_value_); | |
| 215 | |
| 216 case Type::INTEGER: | |
| 217 return new FundamentalValue(integer_value_); | |
| 218 | |
| 219 case Type::DOUBLE: | |
| 220 return new FundamentalValue(double_value_); | |
| 221 | |
| 222 default: | |
| 223 NOTREACHED(); | |
| 224 return NULL; | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 bool FundamentalValue::Equals(const Value* other) const { | |
| 229 if (other->GetType() != GetType()) | |
| 230 return false; | |
| 231 | |
| 232 switch (GetType()) { | |
| 233 case Type::BOOLEAN: { | |
| 234 bool lhs, rhs; | |
| 235 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs; | |
| 236 } | |
| 237 case Type::INTEGER: { | |
| 238 int lhs, rhs; | |
| 239 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs; | |
| 240 } | |
| 241 case Type::DOUBLE: { | |
| 242 double lhs, rhs; | |
| 243 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs; | |
| 244 } | |
| 245 default: | |
| 246 NOTREACHED(); | |
| 247 return false; | |
| 248 } | |
| 249 } | |
| 250 | 304 |
| 251 ///////////////////// StringValue //////////////////// | 305 ///////////////////// StringValue //////////////////// |
| 252 | 306 |
| 253 StringValue::StringValue(StringPiece in_value) | 307 StringValue::StringValue(StringPiece in_value) |
| 254 : Value(Type::STRING), value_(in_value.as_string()) { | 308 : Value(Type::STRING), value_(in_value.as_string()) { |
| 255 DCHECK(IsStringUTF8(in_value)); | 309 DCHECK(IsStringUTF8(in_value)); |
| 256 } | 310 } |
| 257 | 311 |
| 258 StringValue::StringValue(const string16& in_value) | 312 StringValue::StringValue(const string16& in_value) |
| 259 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} | 313 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} |
| (...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1165 } | 1219 } |
| 1166 | 1220 |
| 1167 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1221 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
| 1168 if (static_cast<int>(type) < 0 || | 1222 if (static_cast<int>(type) < 0 || |
| 1169 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1223 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
| 1170 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1224 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
| 1171 return out << Value::GetTypeName(type); | 1225 return out << Value::GetTypeName(type); |
| 1172 } | 1226 } |
| 1173 | 1227 |
| 1174 } // namespace base | 1228 } // namespace base |
| OLD | NEW |