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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 return CopyDictionaryWithoutEmptyChildren( | 67 return CopyDictionaryWithoutEmptyChildren( |
68 static_cast<const DictionaryValue&>(node)); | 68 static_cast<const DictionaryValue&>(node)); |
69 | 69 |
70 default: | 70 default: |
71 return node.CreateDeepCopy(); | 71 return node.CreateDeepCopy(); |
72 } | 72 } |
73 } | 73 } |
74 | 74 |
75 } // namespace | 75 } // namespace |
76 | 76 |
| 77 Value::Value(bool in_bool) : type_(TYPE_BOOLEAN), bool_value_(in_bool) { |
| 78 } |
| 79 |
| 80 Value::Value(int in_int) : type_(TYPE_INTEGER), int_value_(in_int) { |
| 81 } |
| 82 |
| 83 Value::Value(double in_double) : type_(TYPE_DOUBLE), double_value_(in_double) { |
| 84 if (!std::isfinite(double_value_)) { |
| 85 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " |
| 86 << "values cannot be represented in JSON"; |
| 87 double_value_ = 0.0; |
| 88 } |
| 89 } |
| 90 |
77 Value::~Value() { | 91 Value::~Value() { |
78 } | 92 } |
79 | 93 |
80 // static | 94 // static |
81 std::unique_ptr<Value> Value::CreateNullValue() { | 95 std::unique_ptr<Value> Value::CreateNullValue() { |
82 return WrapUnique(new Value(TYPE_NULL)); | 96 return WrapUnique(new Value(TYPE_NULL)); |
83 } | 97 } |
84 | 98 |
85 // static | 99 // static |
86 const char* Value::GetTypeName(Value::Type type) { | 100 const char* Value::GetTypeName(Value::Type type) { |
87 DCHECK_GE(type, 0); | 101 DCHECK_GE(type, 0); |
88 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); | 102 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); |
89 return kTypeNames[type]; | 103 return kTypeNames[type]; |
90 } | 104 } |
91 | 105 |
| 106 bool Value::GetBool() const { |
| 107 CHECK(is_bool()); |
| 108 return bool_value_; |
| 109 } |
| 110 |
| 111 int Value::GetInt() const { |
| 112 CHECK(is_int()); |
| 113 return int_value_; |
| 114 } |
| 115 |
| 116 double Value::GetDouble() const { |
| 117 if (is_double()) |
| 118 return double_value_; |
| 119 if (is_int()) |
| 120 return int_value_; |
| 121 CHECK(false); |
| 122 return 0.0; |
| 123 } |
| 124 |
92 bool Value::GetAsBinary(const BinaryValue** out_value) const { | 125 bool Value::GetAsBinary(const BinaryValue** out_value) const { |
93 return false; | 126 return false; |
94 } | 127 } |
95 | 128 |
96 bool Value::GetAsBoolean(bool* out_value) const { | 129 bool Value::GetAsBoolean(bool* out_value) const { |
97 return false; | 130 if (out_value && is_bool()) { |
| 131 *out_value = bool_value_; |
| 132 return true; |
| 133 } |
| 134 return is_bool(); |
98 } | 135 } |
99 | 136 |
100 bool Value::GetAsInteger(int* out_value) const { | 137 bool Value::GetAsInteger(int* out_value) const { |
101 return false; | 138 if (out_value && is_int()) { |
| 139 *out_value = int_value_; |
| 140 return true; |
| 141 } |
| 142 return is_int(); |
102 } | 143 } |
103 | 144 |
104 bool Value::GetAsDouble(double* out_value) const { | 145 bool Value::GetAsDouble(double* out_value) const { |
105 return false; | 146 if (out_value && is_double()) { |
| 147 *out_value = double_value_; |
| 148 return true; |
| 149 } else if (out_value && is_int()) { |
| 150 // Allow promotion from int to double. |
| 151 *out_value = int_value_; |
| 152 return true; |
| 153 } |
| 154 return is_double() || is_int(); |
106 } | 155 } |
107 | 156 |
108 bool Value::GetAsString(std::string* out_value) const { | 157 bool Value::GetAsString(std::string* out_value) const { |
109 return false; | 158 return false; |
110 } | 159 } |
111 | 160 |
112 bool Value::GetAsString(string16* out_value) const { | 161 bool Value::GetAsString(string16* out_value) const { |
113 return false; | 162 return false; |
114 } | 163 } |
115 | 164 |
(...skipping 13 matching lines...) Expand all Loading... |
129 return false; | 178 return false; |
130 } | 179 } |
131 | 180 |
132 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { | 181 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { |
133 return false; | 182 return false; |
134 } | 183 } |
135 | 184 |
136 Value* Value::DeepCopy() const { | 185 Value* Value::DeepCopy() const { |
137 // This method should only be getting called for null Values--all subclasses | 186 // This method should only be getting called for null Values--all subclasses |
138 // need to provide their own implementation;. | 187 // need to provide their own implementation;. |
139 DCHECK(IsType(TYPE_NULL)); | 188 switch (type()) { |
140 return CreateNullValue().release(); | 189 case TYPE_NULL: |
| 190 return CreateNullValue().release(); |
| 191 |
| 192 // For now, make FundamentalValues for backward-compatibility. Convert to |
| 193 // Value when that code is deleted. |
| 194 case TYPE_BOOLEAN: |
| 195 return new FundamentalValue(bool_value_); |
| 196 case TYPE_INTEGER: |
| 197 return new FundamentalValue(int_value_); |
| 198 case TYPE_DOUBLE: |
| 199 return new FundamentalValue(double_value_); |
| 200 |
| 201 default: |
| 202 // All other types should be handled by subclasses. |
| 203 NOTREACHED(); |
| 204 return nullptr; |
| 205 } |
141 } | 206 } |
142 | 207 |
143 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 208 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
144 return WrapUnique(DeepCopy()); | 209 return WrapUnique(DeepCopy()); |
145 } | 210 } |
146 | 211 |
147 bool Value::Equals(const Value* other) const { | 212 bool Value::Equals(const Value* other) const { |
148 // This method should only be getting called for null Values--all subclasses | 213 if (other->type() != type()) |
149 // need to provide their own implementation;. | 214 return false; |
150 DCHECK(IsType(TYPE_NULL)); | 215 |
151 return other->IsType(TYPE_NULL); | 216 switch (type()) { |
| 217 case TYPE_NULL: |
| 218 return true; |
| 219 case TYPE_BOOLEAN: |
| 220 return bool_value_ == other->bool_value_; |
| 221 case TYPE_INTEGER: |
| 222 return int_value_ == other->int_value_; |
| 223 case TYPE_DOUBLE: |
| 224 return double_value_ == other->double_value_; |
| 225 default: |
| 226 // This method should only be getting called for the above types -- all |
| 227 // subclasses need to provide their own implementation;. |
| 228 NOTREACHED(); |
| 229 return false; |
| 230 } |
152 } | 231 } |
153 | 232 |
154 // static | 233 // static |
155 bool Value::Equals(const Value* a, const Value* b) { | 234 bool Value::Equals(const Value* a, const Value* b) { |
156 if ((a == NULL) && (b == NULL)) return true; | 235 if ((a == NULL) && (b == NULL)) return true; |
157 if ((a == NULL) ^ (b == NULL)) return false; | 236 if ((a == NULL) ^ (b == NULL)) return false; |
158 return a->Equals(b); | 237 return a->Equals(b); |
159 } | 238 } |
160 | 239 |
161 Value::Value(Type type) : type_(type) {} | 240 Value::Value(Type type) : type_(type) {} |
162 | 241 |
163 Value::Value(const Value& that) : type_(that.type_) {} | 242 Value::Value(const Value& that) : type_(that.type_) {} |
164 | 243 |
165 Value& Value::operator=(const Value& that) { | 244 Value& Value::operator=(const Value& that) { |
166 type_ = that.type_; | 245 type_ = that.type_; |
167 return *this; | 246 return *this; |
168 } | 247 } |
169 | 248 |
170 ///////////////////// FundamentalValue //////////////////// | 249 ///////////////////// FundamentalValue //////////////////// |
171 | 250 |
172 FundamentalValue::FundamentalValue(bool in_value) | 251 FundamentalValue::FundamentalValue(bool in_value) |
173 : Value(TYPE_BOOLEAN), boolean_value_(in_value) { | 252 : Value(in_value) { |
174 } | 253 } |
175 | 254 |
176 FundamentalValue::FundamentalValue(int in_value) | 255 FundamentalValue::FundamentalValue(int in_value) |
177 : Value(TYPE_INTEGER), integer_value_(in_value) { | 256 : Value(in_value) { |
178 } | 257 } |
179 | 258 |
180 FundamentalValue::FundamentalValue(double in_value) | 259 FundamentalValue::FundamentalValue(double in_value) |
181 : Value(TYPE_DOUBLE), double_value_(in_value) { | 260 : Value(in_value) { |
182 if (!std::isfinite(double_value_)) { | |
183 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " | |
184 << "values cannot be represented in JSON"; | |
185 double_value_ = 0.0; | |
186 } | |
187 } | 261 } |
188 | 262 |
189 FundamentalValue::~FundamentalValue() { | 263 FundamentalValue::~FundamentalValue() { |
190 } | 264 } |
191 | 265 |
192 bool FundamentalValue::GetAsBoolean(bool* out_value) const { | |
193 if (out_value && IsType(TYPE_BOOLEAN)) | |
194 *out_value = boolean_value_; | |
195 return (IsType(TYPE_BOOLEAN)); | |
196 } | |
197 | |
198 bool FundamentalValue::GetAsInteger(int* out_value) const { | |
199 if (out_value && IsType(TYPE_INTEGER)) | |
200 *out_value = integer_value_; | |
201 return (IsType(TYPE_INTEGER)); | |
202 } | |
203 | |
204 bool FundamentalValue::GetAsDouble(double* out_value) const { | |
205 if (out_value && IsType(TYPE_DOUBLE)) | |
206 *out_value = double_value_; | |
207 else if (out_value && IsType(TYPE_INTEGER)) | |
208 *out_value = integer_value_; | |
209 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER)); | |
210 } | |
211 | |
212 FundamentalValue* FundamentalValue::DeepCopy() const { | |
213 switch (GetType()) { | |
214 case TYPE_BOOLEAN: | |
215 return new FundamentalValue(boolean_value_); | |
216 | |
217 case TYPE_INTEGER: | |
218 return new FundamentalValue(integer_value_); | |
219 | |
220 case TYPE_DOUBLE: | |
221 return new FundamentalValue(double_value_); | |
222 | |
223 default: | |
224 NOTREACHED(); | |
225 return NULL; | |
226 } | |
227 } | |
228 | |
229 bool FundamentalValue::Equals(const Value* other) const { | |
230 if (other->GetType() != GetType()) | |
231 return false; | |
232 | |
233 switch (GetType()) { | |
234 case TYPE_BOOLEAN: { | |
235 bool lhs, rhs; | |
236 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs; | |
237 } | |
238 case TYPE_INTEGER: { | |
239 int lhs, rhs; | |
240 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs; | |
241 } | |
242 case TYPE_DOUBLE: { | |
243 double lhs, rhs; | |
244 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs; | |
245 } | |
246 default: | |
247 NOTREACHED(); | |
248 return false; | |
249 } | |
250 } | |
251 | |
252 ///////////////////// StringValue //////////////////// | 266 ///////////////////// StringValue //////////////////// |
253 | 267 |
254 StringValue::StringValue(StringPiece in_value) | 268 StringValue::StringValue(StringPiece in_value) |
255 : Value(TYPE_STRING), value_(in_value.as_string()) { | 269 : Value(TYPE_STRING), value_(in_value.as_string()) { |
256 DCHECK(IsStringUTF8(in_value)); | 270 DCHECK(IsStringUTF8(in_value)); |
257 } | 271 } |
258 | 272 |
259 StringValue::StringValue(const string16& in_value) | 273 StringValue::StringValue(const string16& in_value) |
260 : Value(TYPE_STRING), | 274 : Value(TYPE_STRING), |
261 value_(UTF16ToUTF8(in_value)) { | 275 value_(UTF16ToUTF8(in_value)) { |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 ValueDeserializer::~ValueDeserializer() { | 1181 ValueDeserializer::~ValueDeserializer() { |
1168 } | 1182 } |
1169 | 1183 |
1170 std::ostream& operator<<(std::ostream& out, const Value& value) { | 1184 std::ostream& operator<<(std::ostream& out, const Value& value) { |
1171 std::string json; | 1185 std::string json; |
1172 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); | 1186 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
1173 return out << json; | 1187 return out << json; |
1174 } | 1188 } |
1175 | 1189 |
1176 } // namespace base | 1190 } // namespace base |
OLD | NEW |