Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: base/values.cc

Issue 441008: Many changes to DictionaryValues:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/logging.h" 5 #include "base/logging.h"
6 #include "base/string_util.h" 6 #include "base/string_util.h"
7 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 9
10 ///////////////////// Value //////////////////// 10 ///////////////////// Value ////////////////////
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 246
247 dictionary_.clear(); 247 dictionary_.clear();
248 } 248 }
249 249
250 bool DictionaryValue::HasKey(const std::wstring& key) const { 250 bool DictionaryValue::HasKey(const std::wstring& key) const {
251 ValueMap::const_iterator current_entry = dictionary_.find(key); 251 ValueMap::const_iterator current_entry = dictionary_.find(key);
252 DCHECK((current_entry == dictionary_.end()) || current_entry->second); 252 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
253 return current_entry != dictionary_.end(); 253 return current_entry != dictionary_.end();
254 } 254 }
255 255
256 void DictionaryValue::SetInCurrentNode(const std::wstring& key, 256 void DictionaryValue::Set(const std::wstring& path, Value* in_value) {
257 Value* in_value) { 257 DCHECK(in_value);
258
259 std::wstring current_path(path);
260 DictionaryValue* current_dictionary = this;
261 for (size_t delimiter_position = current_path.find('.');
262 delimiter_position != std::wstring::npos;
263 delimiter_position = current_path.find('.')) {
264 // Assume that we're indexing into a dictionary.
265 std::wstring key(current_path, 0, delimiter_position);
266 DictionaryValue* child_dictionary;
267 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
268 child_dictionary = new DictionaryValue;
269 current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
270 }
271
272 current_dictionary = child_dictionary;
273 current_path.erase(0, delimiter_position + 1);
274 }
275
276 current_dictionary->SetWithoutPathExpansion(current_path, in_value);
277 }
278
279 void DictionaryValue::SetBoolean(const std::wstring& path, bool in_value) {
280 Set(path, CreateBooleanValue(in_value));
281 }
282
283 void DictionaryValue::SetInteger(const std::wstring& path, int in_value) {
284 Set(path, CreateIntegerValue(in_value));
285 }
286
287 void DictionaryValue::SetReal(const std::wstring& path, double in_value) {
288 Set(path, CreateRealValue(in_value));
289 }
290
291 void DictionaryValue::SetString(const std::wstring& path,
292 const std::string& in_value) {
293 Set(path, CreateStringValue(in_value));
294 }
295
296 void DictionaryValue::SetString(const std::wstring& path,
297 const std::wstring& in_value) {
298 Set(path, CreateStringValue(in_value));
299 }
300
301 void DictionaryValue::SetWithoutPathExpansion(const std::wstring& key,
302 Value* in_value) {
258 // If there's an existing value here, we need to delete it, because 303 // If there's an existing value here, we need to delete it, because
259 // we own all our children. 304 // we own all our children.
260 if (HasKey(key)) { 305 if (HasKey(key)) {
261 DCHECK(dictionary_[key] != in_value); // This would be bogus 306 DCHECK(dictionary_[key] != in_value); // This would be bogus
262 delete dictionary_[key]; 307 delete dictionary_[key];
263 } 308 }
264 309
265 dictionary_[key] = in_value; 310 dictionary_[key] = in_value;
266 } 311 }
267 312
268 bool DictionaryValue::Set(const std::wstring& path, Value* in_value) { 313 bool DictionaryValue::Get(const std::wstring& path, Value** out_value) const {
269 DCHECK(in_value); 314 std::wstring current_path(path);
315 const DictionaryValue* current_dictionary = this;
316 for (size_t delimiter_position = current_path.find('.');
317 delimiter_position != std::wstring::npos;
318 delimiter_position = current_path.find('.')) {
319 DictionaryValue* child_dictionary;
320 if (!current_dictionary->GetDictionary(
321 current_path.substr(0, delimiter_position), &child_dictionary))
322 return false;
270 323
271 std::wstring key = path; 324 current_dictionary = child_dictionary;
272 325 current_path.erase(0, delimiter_position + 1);
273 size_t delimiter_position = path.find_first_of(L".", 0);
274 // If there isn't a dictionary delimiter in the path, we're done.
275 if (delimiter_position == std::wstring::npos) {
276 SetInCurrentNode(key, in_value);
277 return true;
278 } else {
279 key = path.substr(0, delimiter_position);
280 } 326 }
281 327
282 // Assume that we're indexing into a dictionary. 328 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
283 DictionaryValue* entry = NULL;
284 if (!HasKey(key) || (dictionary_[key]->GetType() != TYPE_DICTIONARY)) {
285 entry = new DictionaryValue;
286 SetInCurrentNode(key, entry);
287 } else {
288 entry = static_cast<DictionaryValue*>(dictionary_[key]);
289 }
290
291 std::wstring remaining_path = path.substr(delimiter_position + 1);
292 return entry->Set(remaining_path, in_value);
293 }
294
295 bool DictionaryValue::SetBoolean(const std::wstring& path, bool in_value) {
296 return Set(path, CreateBooleanValue(in_value));
297 }
298
299 bool DictionaryValue::SetInteger(const std::wstring& path, int in_value) {
300 return Set(path, CreateIntegerValue(in_value));
301 }
302
303 bool DictionaryValue::SetReal(const std::wstring& path, double in_value) {
304 return Set(path, CreateRealValue(in_value));
305 }
306
307 bool DictionaryValue::SetString(const std::wstring& path,
308 const std::string& in_value) {
309 return Set(path, CreateStringValue(in_value));
310 }
311
312 bool DictionaryValue::SetString(const std::wstring& path,
313 const std::wstring& in_value) {
314 return Set(path, CreateStringValue(in_value));
315 }
316
317 bool DictionaryValue::Get(const std::wstring& path, Value** out_value) const {
318 std::wstring key = path;
319
320 size_t delimiter_position = path.find_first_of(L".", 0);
321 if (delimiter_position != std::wstring::npos) {
322 key = path.substr(0, delimiter_position);
323 }
324
325 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
326 if (entry_iterator == dictionary_.end())
327 return false;
328 Value* entry = entry_iterator->second;
329
330 if (delimiter_position == std::wstring::npos) {
331 if (out_value)
332 *out_value = entry;
333 return true;
334 }
335
336 if (entry->IsType(TYPE_DICTIONARY)) {
337 DictionaryValue* dictionary = static_cast<DictionaryValue*>(entry);
338 return dictionary->Get(path.substr(delimiter_position + 1), out_value);
339 }
340
341 return false;
342 } 329 }
343 330
344 bool DictionaryValue::GetBoolean(const std::wstring& path, 331 bool DictionaryValue::GetBoolean(const std::wstring& path,
345 bool* bool_value) const { 332 bool* bool_value) const {
346 Value* value; 333 Value* value;
347 if (!Get(path, &value)) 334 if (!Get(path, &value))
348 return false; 335 return false;
349 336
350 return value->GetAsBoolean(bool_value); 337 return value->GetAsBoolean(bool_value);
351 } 338 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 bool result = Get(path, &value); 405 bool result = Get(path, &value);
419 if (!result || !value->IsType(TYPE_LIST)) 406 if (!result || !value->IsType(TYPE_LIST))
420 return false; 407 return false;
421 408
422 if (out_value) 409 if (out_value)
423 *out_value = static_cast<ListValue*>(value); 410 *out_value = static_cast<ListValue*>(value);
424 411
425 return true; 412 return true;
426 } 413 }
427 414
415 bool DictionaryValue::GetWithoutPathExpansion(const std::wstring& key,
416 Value** out_value) const {
417 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
418 if (entry_iterator == dictionary_.end())
419 return false;
420
421 Value* entry = entry_iterator->second;
422 if (out_value)
423 *out_value = entry;
424 return true;
425 }
426
427 bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::wstring& path,
428 int* out_value) const {
429 Value* value;
430 if (!GetWithoutPathExpansion(path, &value))
431 return false;
432
433 return value->GetAsInteger(out_value);
434 }
435
436 bool DictionaryValue::GetStringWithoutPathExpansion(
437 const std::wstring& path,
438 std::string* out_value) const {
439 Value* value;
440 if (!GetWithoutPathExpansion(path, &value))
441 return false;
442
443 return value->GetAsString(out_value);
444 }
445
446 bool DictionaryValue::GetStringWithoutPathExpansion(
447 const std::wstring& path,
448 std::wstring* out_value) const {
449 Value* value;
450 if (!GetWithoutPathExpansion(path, &value))
451 return false;
452
453 return value->GetAsString(out_value);
454 }
455
456 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
457 const std::wstring& path,
458 DictionaryValue** out_value) const {
459 Value* value;
460 bool result = GetWithoutPathExpansion(path, &value);
461 if (!result || !value->IsType(TYPE_DICTIONARY))
462 return false;
463
464 if (out_value)
465 *out_value = static_cast<DictionaryValue*>(value);
466
467 return true;
468 }
469
470 bool DictionaryValue::GetListWithoutPathExpansion(const std::wstring& path,
471 ListValue** out_value) const {
472 Value* value;
473 bool result = GetWithoutPathExpansion(path, &value);
474 if (!result || !value->IsType(TYPE_LIST))
475 return false;
476
477 if (out_value)
478 *out_value = static_cast<ListValue*>(value);
479
480 return true;
481 }
482
428 bool DictionaryValue::Remove(const std::wstring& path, Value** out_value) { 483 bool DictionaryValue::Remove(const std::wstring& path, Value** out_value) {
429 std::wstring key = path; 484 std::wstring current_path(path);
430 485 DictionaryValue* current_dictionary = this;
431 size_t delimiter_position = path.find_first_of(L".", 0); 486 size_t delimiter_position = current_path.rfind('.');
432 if (delimiter_position != std::wstring::npos) { 487 if (delimiter_position != std::wstring::npos) {
433 key = path.substr(0, delimiter_position); 488 if (!GetDictionary(current_path.substr(0, delimiter_position),
489 &current_dictionary))
490 return false;
491 current_path.erase(0, delimiter_position + 1);
434 } 492 }
435 493
494 return current_dictionary->RemoveWithoutPathExpansion(current_path, out_value) ;
tony 2009/11/25 19:30:13 Nit: 80 cols
495 }
496
497 bool DictionaryValue::RemoveWithoutPathExpansion(const std::wstring& key,
498 Value** out_value) {
436 ValueMap::iterator entry_iterator = dictionary_.find(key); 499 ValueMap::iterator entry_iterator = dictionary_.find(key);
437 if (entry_iterator == dictionary_.end()) 500 if (entry_iterator == dictionary_.end())
438 return false; 501 return false;
502
439 Value* entry = entry_iterator->second; 503 Value* entry = entry_iterator->second;
440 504 if (out_value)
441 if (delimiter_position == std::wstring::npos) { 505 *out_value = entry;
442 if (out_value) 506 else
443 *out_value = entry; 507 delete entry;
444 else 508 dictionary_.erase(entry_iterator);
445 delete entry; 509 return true;
446
447 dictionary_.erase(entry_iterator);
448 return true;
449 }
450
451 if (entry->IsType(TYPE_DICTIONARY)) {
452 DictionaryValue* dictionary = static_cast<DictionaryValue*>(entry);
453 return dictionary->Remove(path.substr(delimiter_position + 1), out_value);
454 }
455
456 return false;
457 } 510 }
458 511
459 Value* DictionaryValue::DeepCopy() const { 512 Value* DictionaryValue::DeepCopy() const {
460 DictionaryValue* result = new DictionaryValue; 513 DictionaryValue* result = new DictionaryValue;
461 514
462 ValueMap::const_iterator current_entry = dictionary_.begin(); 515 for (ValueMap::const_iterator current_entry(dictionary_.begin());
463 while (current_entry != dictionary_.end()) { 516 current_entry != dictionary_.end(); ++current_entry) {
464 result->Set(current_entry->first, current_entry->second->DeepCopy()); 517 result->SetWithoutPathExpansion(current_entry->first,
465 ++current_entry; 518 current_entry->second->DeepCopy());
466 } 519 }
467 520
468 return result; 521 return result;
469 } 522 }
470 523
471 bool DictionaryValue::Equals(const Value* other) const { 524 bool DictionaryValue::Equals(const Value* other) const {
472 if (other->GetType() != GetType()) 525 if (other->GetType() != GetType())
473 return false; 526 return false;
474 527
475 const DictionaryValue* other_dict = 528 const DictionaryValue* other_dict =
476 static_cast<const DictionaryValue*>(other); 529 static_cast<const DictionaryValue*>(other);
477 key_iterator lhs_it(begin_keys()); 530 key_iterator lhs_it(begin_keys());
478 key_iterator rhs_it(other_dict->begin_keys()); 531 key_iterator rhs_it(other_dict->begin_keys());
479 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) { 532 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
480 Value* lhs; 533 Value* lhs;
481 Value* rhs; 534 Value* rhs;
482 if (!Get(*lhs_it, &lhs) || !other_dict->Get(*rhs_it, &rhs) || 535 if (!GetWithoutPathExpansion(*lhs_it, &lhs) ||
536 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
483 !lhs->Equals(rhs)) { 537 !lhs->Equals(rhs)) {
484 return false; 538 return false;
485 } 539 }
486 ++lhs_it; 540 ++lhs_it;
487 ++rhs_it; 541 ++rhs_it;
488 } 542 }
489 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys()) 543 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
490 return false; 544 return false;
491 545
492 return true; 546 return true;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 lhs_it != end() && rhs_it != other_list->end(); 711 lhs_it != end() && rhs_it != other_list->end();
658 ++lhs_it, ++rhs_it) { 712 ++lhs_it, ++rhs_it) {
659 if (!(*lhs_it)->Equals(*rhs_it)) 713 if (!(*lhs_it)->Equals(*rhs_it))
660 return false; 714 return false;
661 } 715 }
662 if (lhs_it != end() || rhs_it != other_list->end()) 716 if (lhs_it != end() || rhs_it != other_list->end())
663 return false; 717 return false;
664 718
665 return true; 719 return true;
666 } 720 }
OLDNEW
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698