| 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() { | |
| 79 } | |
| 80 | |
| 81 // static | 78 // static |
| 82 std::unique_ptr<Value> Value::CreateNullValue() { | 79 std::unique_ptr<Value> Value::CreateNullValue() { |
| 83 return WrapUnique(new Value(Type::NONE)); | 80 return WrapUnique(new Value(Type::NONE)); |
| 84 } | 81 } |
| 85 | 82 |
| 83 Value::Value(const Value& that) { |
| 84 InternalCopyFrom(that); |
| 85 } |
| 86 |
| 87 Value::Value(Value&& that) { |
| 88 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving |
| 89 // and copying differ. |
| 90 InternalCopyFrom(that); |
| 91 } |
| 92 |
| 93 Value::Value() : type_(Type::NONE) {} |
| 94 |
| 95 Value::Value(Type type) : type_(type) { |
| 96 // Initialize with the default value. |
| 97 switch (type_) { |
| 98 case Type::NONE: |
| 99 return; |
| 100 |
| 101 case Type::BOOLEAN: |
| 102 bool_value_ = bool(); |
| 103 return; |
| 104 case Type::INTEGER: |
| 105 int_value_ = int(); |
| 106 return; |
| 107 case Type::DOUBLE: |
| 108 double_value_ = double(); |
| 109 return; |
| 110 |
| 111 // TODO(crbug.com/646113): Implement these once the corresponding derived |
| 112 // classes are removed. |
| 113 case Type::STRING: |
| 114 case Type::BINARY: |
| 115 case Type::LIST: |
| 116 case Type::DICTIONARY: |
| 117 return; |
| 118 } |
| 119 NOTREACHED(); |
| 120 return; |
| 121 } |
| 122 |
| 123 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} |
| 124 |
| 125 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} |
| 126 |
| 127 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { |
| 128 if (!std::isfinite(double_value_)) { |
| 129 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " |
| 130 << "values cannot be represented in JSON"; |
| 131 double_value_ = 0.0; |
| 132 } |
| 133 } |
| 134 |
| 135 Value& Value::operator=(const Value& that) { |
| 136 if (this != &that) |
| 137 InternalCopyFrom(that); |
| 138 |
| 139 return *this; |
| 140 } |
| 141 |
| 142 Value& Value::operator=(Value&& that) { |
| 143 if (this != &that) { |
| 144 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving |
| 145 // and copying differ. |
| 146 InternalCopyFrom(that); |
| 147 } |
| 148 |
| 149 return *this; |
| 150 } |
| 151 |
| 152 Value::~Value() {} |
| 153 |
| 86 // static | 154 // static |
| 87 const char* Value::GetTypeName(Value::Type type) { | 155 const char* Value::GetTypeName(Value::Type type) { |
| 88 DCHECK_GE(static_cast<int>(type), 0); | 156 DCHECK_GE(static_cast<int>(type), 0); |
| 89 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); | 157 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); |
| 90 return kTypeNames[static_cast<size_t>(type)]; | 158 return kTypeNames[static_cast<size_t>(type)]; |
| 91 } | 159 } |
| 92 | 160 |
| 93 bool Value::GetAsBinary(const BinaryValue** out_value) const { | 161 bool Value::GetBool() const { |
| 94 return false; | 162 CHECK(is_bool()); |
| 163 return bool_value_; |
| 164 } |
| 165 |
| 166 int Value::GetInt() const { |
| 167 CHECK(is_int()); |
| 168 return int_value_; |
| 169 } |
| 170 |
| 171 double Value::GetDouble() const { |
| 172 if (is_double()) |
| 173 return double_value_; |
| 174 if (is_int()) |
| 175 return int_value_; |
| 176 CHECK(false); |
| 177 return 0.0; |
| 95 } | 178 } |
| 96 | 179 |
| 97 bool Value::GetAsBoolean(bool* out_value) const { | 180 bool Value::GetAsBoolean(bool* out_value) const { |
| 98 return false; | 181 if (out_value && is_bool()) { |
| 182 *out_value = bool_value_; |
| 183 return true; |
| 184 } |
| 185 return is_bool(); |
| 99 } | 186 } |
| 100 | 187 |
| 101 bool Value::GetAsInteger(int* out_value) const { | 188 bool Value::GetAsInteger(int* out_value) const { |
| 102 return false; | 189 if (out_value && is_int()) { |
| 190 *out_value = int_value_; |
| 191 return true; |
| 192 } |
| 193 return is_int(); |
| 103 } | 194 } |
| 104 | 195 |
| 105 bool Value::GetAsDouble(double* out_value) const { | 196 bool Value::GetAsDouble(double* out_value) const { |
| 106 return false; | 197 if (out_value && is_double()) { |
| 198 *out_value = double_value_; |
| 199 return true; |
| 200 } else if (out_value && is_int()) { |
| 201 // Allow promotion from int to double. |
| 202 *out_value = int_value_; |
| 203 return true; |
| 204 } |
| 205 return is_double() || is_int(); |
| 107 } | 206 } |
| 108 | 207 |
| 109 bool Value::GetAsString(std::string* out_value) const { | 208 bool Value::GetAsString(std::string* out_value) const { |
| 110 return false; | 209 return false; |
| 111 } | 210 } |
| 112 | 211 |
| 113 bool Value::GetAsString(string16* out_value) const { | 212 bool Value::GetAsString(string16* out_value) const { |
| 114 return false; | 213 return false; |
| 115 } | 214 } |
| 116 | 215 |
| 117 bool Value::GetAsString(const StringValue** out_value) const { | 216 bool Value::GetAsString(const StringValue** out_value) const { |
| 118 return false; | 217 return false; |
| 119 } | 218 } |
| 120 | 219 |
| 121 bool Value::GetAsString(StringPiece* out_value) const { | 220 bool Value::GetAsString(StringPiece* out_value) const { |
| 122 return false; | 221 return false; |
| 123 } | 222 } |
| 124 | 223 |
| 224 bool Value::GetAsBinary(const BinaryValue** out_value) const { |
| 225 return false; |
| 226 } |
| 227 |
| 125 bool Value::GetAsList(ListValue** out_value) { | 228 bool Value::GetAsList(ListValue** out_value) { |
| 126 return false; | 229 return false; |
| 127 } | 230 } |
| 128 | 231 |
| 129 bool Value::GetAsList(const ListValue** out_value) const { | 232 bool Value::GetAsList(const ListValue** out_value) const { |
| 130 return false; | 233 return false; |
| 131 } | 234 } |
| 132 | 235 |
| 133 bool Value::GetAsDictionary(DictionaryValue** out_value) { | 236 bool Value::GetAsDictionary(DictionaryValue** out_value) { |
| 134 return false; | 237 return false; |
| 135 } | 238 } |
| 136 | 239 |
| 137 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { | 240 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { |
| 138 return false; | 241 return false; |
| 139 } | 242 } |
| 140 | 243 |
| 141 Value* Value::DeepCopy() const { | 244 Value* Value::DeepCopy() const { |
| 142 // This method should only be getting called for null Values--all subclasses | 245 // This method should only be getting called for null Values--all subclasses |
| 143 // need to provide their own implementation;. | 246 // need to provide their own implementation;. |
| 144 DCHECK(IsType(Type::NONE)); | 247 switch (type()) { |
| 145 return CreateNullValue().release(); | 248 case Type::NONE: |
| 249 return CreateNullValue().release(); |
| 250 |
| 251 // For now, make FundamentalValues for backward-compatibility. Convert to |
| 252 // Value when that code is deleted. |
| 253 case Type::BOOLEAN: |
| 254 return new FundamentalValue(bool_value_); |
| 255 case Type::INTEGER: |
| 256 return new FundamentalValue(int_value_); |
| 257 case Type::DOUBLE: |
| 258 return new FundamentalValue(double_value_); |
| 259 |
| 260 default: |
| 261 // All other types should be handled by subclasses. |
| 262 NOTREACHED(); |
| 263 return nullptr; |
| 264 } |
| 146 } | 265 } |
| 147 | 266 |
| 148 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 267 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
| 149 return WrapUnique(DeepCopy()); | 268 return WrapUnique(DeepCopy()); |
| 150 } | 269 } |
| 151 | 270 |
| 152 bool Value::Equals(const Value* other) const { | 271 bool Value::Equals(const Value* other) const { |
| 153 // This method should only be getting called for null Values--all subclasses | 272 if (other->type() != type()) |
| 154 // need to provide their own implementation;. | 273 return false; |
| 155 DCHECK(IsType(Type::NONE)); | 274 |
| 156 return other->IsType(Type::NONE); | 275 switch (type()) { |
| 276 case Type::NONE: |
| 277 return true; |
| 278 case Type::BOOLEAN: |
| 279 return bool_value_ == other->bool_value_; |
| 280 case Type::INTEGER: |
| 281 return int_value_ == other->int_value_; |
| 282 case Type::DOUBLE: |
| 283 return double_value_ == other->double_value_; |
| 284 default: |
| 285 // This method should only be getting called for the above types -- all |
| 286 // subclasses need to provide their own implementation;. |
| 287 NOTREACHED(); |
| 288 return false; |
| 289 } |
| 157 } | 290 } |
| 158 | 291 |
| 159 // static | 292 // static |
| 160 bool Value::Equals(const Value* a, const Value* b) { | 293 bool Value::Equals(const Value* a, const Value* b) { |
| 161 if ((a == NULL) && (b == NULL)) return true; | 294 if ((a == NULL) && (b == NULL)) return true; |
| 162 if ((a == NULL) ^ (b == NULL)) return false; | 295 if ((a == NULL) ^ (b == NULL)) return false; |
| 163 return a->Equals(b); | 296 return a->Equals(b); |
| 164 } | 297 } |
| 165 | 298 |
| 166 Value::Value(Type type) : type_(type) {} | 299 void Value::InternalCopyFrom(const Value& that) { |
| 300 type_ = that.type_; |
| 301 switch (type_) { |
| 302 case Type::NONE: |
| 303 // Nothing to do. |
| 304 return; |
| 167 | 305 |
| 168 Value::Value(const Value& that) : type_(that.type_) {} | 306 case Type::BOOLEAN: |
| 307 bool_value_ = that.bool_value_; |
| 308 return; |
| 309 case Type::INTEGER: |
| 310 int_value_ = that.int_value_; |
| 311 return; |
| 312 case Type::DOUBLE: |
| 313 double_value_ = that.double_value_; |
| 314 return; |
| 169 | 315 |
| 170 Value& Value::operator=(const Value& that) { | 316 // Currently it is not safe to copy from these types. |
| 171 type_ = that.type_; | 317 // TODO(crbug.com/646113): Implement these once the corresponding derived |
| 172 return *this; | 318 // classes are removed. |
| 173 } | 319 case Type::STRING: |
| 174 | 320 case Type::BINARY: |
| 175 ///////////////////// FundamentalValue //////////////////// | 321 case Type::LIST: |
| 176 | 322 case Type::DICTIONARY: |
| 177 FundamentalValue::FundamentalValue(bool in_value) | 323 NOTREACHED(); |
| 178 : Value(Type::BOOLEAN), boolean_value_(in_value) {} | 324 return; |
| 179 | |
| 180 FundamentalValue::FundamentalValue(int in_value) | |
| 181 : Value(Type::INTEGER), integer_value_(in_value) {} | |
| 182 | |
| 183 FundamentalValue::FundamentalValue(double in_value) | |
| 184 : Value(Type::DOUBLE), double_value_(in_value) { | |
| 185 if (!std::isfinite(double_value_)) { | |
| 186 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " | |
| 187 << "values cannot be represented in JSON"; | |
| 188 double_value_ = 0.0; | |
| 189 } | 325 } |
| 190 } | 326 } |
| 191 | 327 |
| 192 FundamentalValue::~FundamentalValue() { | |
| 193 } | |
| 194 | |
| 195 bool FundamentalValue::GetAsBoolean(bool* out_value) const { | |
| 196 if (out_value && IsType(Type::BOOLEAN)) | |
| 197 *out_value = boolean_value_; | |
| 198 return (IsType(Type::BOOLEAN)); | |
| 199 } | |
| 200 | |
| 201 bool FundamentalValue::GetAsInteger(int* out_value) const { | |
| 202 if (out_value && IsType(Type::INTEGER)) | |
| 203 *out_value = integer_value_; | |
| 204 return (IsType(Type::INTEGER)); | |
| 205 } | |
| 206 | |
| 207 bool FundamentalValue::GetAsDouble(double* out_value) const { | |
| 208 if (out_value && IsType(Type::DOUBLE)) | |
| 209 *out_value = double_value_; | |
| 210 else if (out_value && IsType(Type::INTEGER)) | |
| 211 *out_value = integer_value_; | |
| 212 return (IsType(Type::DOUBLE) || IsType(Type::INTEGER)); | |
| 213 } | |
| 214 | |
| 215 FundamentalValue* FundamentalValue::DeepCopy() const { | |
| 216 switch (GetType()) { | |
| 217 case Type::BOOLEAN: | |
| 218 return new FundamentalValue(boolean_value_); | |
| 219 | |
| 220 case Type::INTEGER: | |
| 221 return new FundamentalValue(integer_value_); | |
| 222 | |
| 223 case Type::DOUBLE: | |
| 224 return new FundamentalValue(double_value_); | |
| 225 | |
| 226 default: | |
| 227 NOTREACHED(); | |
| 228 return NULL; | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 bool FundamentalValue::Equals(const Value* other) const { | |
| 233 if (other->GetType() != GetType()) | |
| 234 return false; | |
| 235 | |
| 236 switch (GetType()) { | |
| 237 case Type::BOOLEAN: { | |
| 238 bool lhs, rhs; | |
| 239 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs; | |
| 240 } | |
| 241 case Type::INTEGER: { | |
| 242 int lhs, rhs; | |
| 243 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs; | |
| 244 } | |
| 245 case Type::DOUBLE: { | |
| 246 double lhs, rhs; | |
| 247 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs; | |
| 248 } | |
| 249 default: | |
| 250 NOTREACHED(); | |
| 251 return false; | |
| 252 } | |
| 253 } | |
| 254 | |
| 255 ///////////////////// StringValue //////////////////// | 328 ///////////////////// StringValue //////////////////// |
| 256 | 329 |
| 257 StringValue::StringValue(StringPiece in_value) | 330 StringValue::StringValue(StringPiece in_value) |
| 258 : Value(Type::STRING), value_(in_value.as_string()) { | 331 : Value(Type::STRING), value_(in_value.as_string()) { |
| 259 DCHECK(IsStringUTF8(in_value)); | 332 DCHECK(IsStringUTF8(in_value)); |
| 260 } | 333 } |
| 261 | 334 |
| 262 StringValue::StringValue(const string16& in_value) | 335 StringValue::StringValue(const string16& in_value) |
| 263 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} | 336 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} |
| 264 | 337 |
| (...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 } | 1248 } |
| 1176 | 1249 |
| 1177 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1250 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
| 1178 if (static_cast<int>(type) < 0 || | 1251 if (static_cast<int>(type) < 0 || |
| 1179 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1252 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
| 1180 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1253 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
| 1181 return out << Value::GetTypeName(type); | 1254 return out << Value::GetTypeName(type); |
| 1182 } | 1255 } |
| 1183 | 1256 |
| 1184 } // namespace base | 1257 } // namespace base |
| OLD | NEW |