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 17 matching lines...) Expand all Loading... | |
134 return false; | 208 return false; |
135 } | 209 } |
136 | 210 |
137 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { | 211 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { |
138 return false; | 212 return false; |
139 } | 213 } |
140 | 214 |
141 Value* Value::DeepCopy() const { | 215 Value* Value::DeepCopy() const { |
142 // This method should only be getting called for null Values--all subclasses | 216 // This method should only be getting called for null Values--all subclasses |
143 // need to provide their own implementation;. | 217 // need to provide their own implementation;. |
144 DCHECK(IsType(Type::NONE)); | 218 switch (type()) { |
145 return CreateNullValue().release(); | 219 case Type::NONE: |
220 return CreateNullValue().release(); | |
221 | |
222 // For now, make FundamentalValues for backward-compatibility. Convert to | |
223 // Value when that code is deleted. | |
224 case Type::BOOLEAN: | |
225 return new FundamentalValue(bool_value_); | |
226 case Type::INTEGER: | |
227 return new FundamentalValue(int_value_); | |
228 case Type::DOUBLE: | |
229 return new FundamentalValue(double_value_); | |
230 | |
231 default: | |
232 // All other types should be handled by subclasses. | |
233 NOTREACHED(); | |
234 return nullptr; | |
235 } | |
146 } | 236 } |
147 | 237 |
148 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 238 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
149 return WrapUnique(DeepCopy()); | 239 return WrapUnique(DeepCopy()); |
150 } | 240 } |
151 | 241 |
152 bool Value::Equals(const Value* other) const { | 242 bool Value::Equals(const Value* other) const { |
153 // This method should only be getting called for null Values--all subclasses | 243 if (other->type() != type()) |
154 // need to provide their own implementation;. | 244 return false; |
155 DCHECK(IsType(Type::NONE)); | 245 |
156 return other->IsType(Type::NONE); | 246 switch (type()) { |
247 case Type::NONE: | |
248 return true; | |
249 case Type::BOOLEAN: | |
250 return bool_value_ == other->bool_value_; | |
251 case Type::INTEGER: | |
252 return int_value_ == other->int_value_; | |
253 case Type::DOUBLE: | |
254 return double_value_ == other->double_value_; | |
255 default: | |
256 // This method should only be getting called for the above types -- all | |
257 // subclasses need to provide their own implementation;. | |
258 NOTREACHED(); | |
259 return false; | |
260 } | |
157 } | 261 } |
158 | 262 |
159 // static | 263 // static |
160 bool Value::Equals(const Value* a, const Value* b) { | 264 bool Value::Equals(const Value* a, const Value* b) { |
161 if ((a == NULL) && (b == NULL)) return true; | 265 if ((a == NULL) && (b == NULL)) return true; |
162 if ((a == NULL) ^ (b == NULL)) return false; | 266 if ((a == NULL) ^ (b == NULL)) return false; |
163 return a->Equals(b); | 267 return a->Equals(b); |
164 } | 268 } |
165 | 269 |
166 Value::Value(Type type) : type_(type) {} | 270 Value::Value(Type type) : type_(type) { |
271 // Initialize with the default value. | |
272 switch (type_) { | |
273 case Type::NONE: | |
274 return; | |
167 | 275 |
168 Value::Value(const Value& that) : type_(that.type_) {} | 276 case Type::BOOLEAN: |
277 bool_value_ = bool(); | |
278 return; | |
279 case Type::INTEGER: | |
280 int_value_ = int(); | |
281 return; | |
282 case Type::DOUBLE: | |
283 double_value_ = double(); | |
284 return; | |
285 | |
286 // TODO(crbug.com/646113): Implement these once the corresponding derived | |
287 // classes are removed. | |
288 case Type::STRING: | |
289 case Type::BINARY: | |
290 case Type::LIST: | |
291 case Type::DICTIONARY: | |
292 return; | |
293 } | |
294 NOTREACHED(); | |
295 return; | |
jdoerrie
2017/01/02 09:55:10
Since the compiler already enforces that we cover
| |
296 } | |
297 | |
298 Value::Value(const Value& that) { | |
299 InternalCopyFrom(that); | |
300 } | |
301 | |
302 Value::Value(Value&& that) { | |
303 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving | |
304 // and copying differ. | |
305 InternalCopyFrom(that); | |
306 } | |
169 | 307 |
170 Value& Value::operator=(const Value& that) { | 308 Value& Value::operator=(const Value& that) { |
171 type_ = that.type_; | 309 if (this != &that) |
310 InternalCopyFrom(that); | |
311 | |
312 return *this; | |
313 } | |
314 | |
315 Value& Value::operator=(Value&& that) { | |
316 if (this != &that) { | |
317 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving | |
318 // and copying differ. | |
319 InternalCopyFrom(that); | |
320 } | |
321 | |
172 return *this; | 322 return *this; |
173 } | 323 } |
174 | 324 |
175 ///////////////////// FundamentalValue //////////////////// | 325 ///////////////////// FundamentalValue //////////////////// |
176 | 326 |
177 FundamentalValue::FundamentalValue(bool in_value) | 327 FundamentalValue::FundamentalValue(bool in_value) : Value(in_value) {} |
178 : Value(Type::BOOLEAN), boolean_value_(in_value) {} | |
179 | 328 |
180 FundamentalValue::FundamentalValue(int in_value) | 329 FundamentalValue::FundamentalValue(int in_value) : Value(in_value) {} |
181 : Value(Type::INTEGER), integer_value_(in_value) {} | |
182 | 330 |
183 FundamentalValue::FundamentalValue(double in_value) | 331 FundamentalValue::FundamentalValue(double in_value) : Value(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 } | |
190 } | |
191 | 332 |
192 FundamentalValue::~FundamentalValue() { | 333 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 | 334 |
255 ///////////////////// StringValue //////////////////// | 335 ///////////////////// StringValue //////////////////// |
256 | 336 |
257 StringValue::StringValue(StringPiece in_value) | 337 StringValue::StringValue(StringPiece in_value) |
258 : Value(Type::STRING), value_(in_value.as_string()) { | 338 : Value(Type::STRING), value_(in_value.as_string()) { |
259 DCHECK(IsStringUTF8(in_value)); | 339 DCHECK(IsStringUTF8(in_value)); |
260 } | 340 } |
261 | 341 |
262 StringValue::StringValue(const string16& in_value) | 342 StringValue::StringValue(const string16& in_value) |
263 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} | 343 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} |
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1175 } | 1255 } |
1176 | 1256 |
1177 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1257 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
1178 if (static_cast<int>(type) < 0 || | 1258 if (static_cast<int>(type) < 0 || |
1179 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1259 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
1180 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1260 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
1181 return out << Value::GetTypeName(type); | 1261 return out << Value::GetTypeName(type); |
1182 } | 1262 } |
1183 | 1263 |
1184 } // namespace base | 1264 } // namespace base |
OLD | NEW |