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 "chrome/browser/chromeos/gdata/gdata_files.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_files.h" |
| 6 | 6 |
| 7 #include <leveldb/db.h> | 7 #include <leveldb/db.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 // the proto data if the older format is detected. | 57 // the proto data if the older format is detected. |
| 58 if (entry_proto.resource_id() != kGDataRootDirectoryResourceId) { | 58 if (entry_proto.resource_id() != kGDataRootDirectoryResourceId) { |
| 59 LOG(ERROR) << "Incompatible proto detected (bad resource ID): " | 59 LOG(ERROR) << "Incompatible proto detected (bad resource ID): " |
| 60 << entry_proto.resource_id(); | 60 << entry_proto.resource_id(); |
| 61 return false; | 61 return false; |
| 62 } | 62 } |
| 63 | 63 |
| 64 return true; | 64 return true; |
| 65 } | 65 } |
| 66 | 66 |
| 67 void FindNextComponent(std::vector<FilePath::StringType> components, | |
|
satorux1
2012/08/07 10:43:46
function comment is missing.
| |
| 68 const FindEntryCallback& callback, | |
| 69 GDataFileError error, | |
| 70 GDataEntry* entry) { | |
| 71 if (components.size() == 0 || !entry) { | |
| 72 callback.Run(error, entry); | |
| 73 return; | |
| 74 } | |
| 75 | |
| 76 GDataDirectory* current_dir = entry->AsGDataDirectory(); | |
| 77 if (!current_dir) { | |
| 78 callback.Run(GDATA_FILE_ERROR_NOT_FOUND, NULL); | |
| 79 return; | |
| 80 } | |
| 81 | |
| 82 FilePath::StringType file_name = components.back(); | |
| 83 components.pop_back(); | |
| 84 current_dir->FindChildAsync(file_name, | |
| 85 base::Bind(&FindNextComponent, components, callback)); | |
| 86 } | |
| 87 | |
| 67 } // namespace | 88 } // namespace |
| 68 | 89 |
| 69 // GDataEntry class. | 90 // GDataEntry class. |
| 70 | 91 |
| 71 GDataEntry::GDataEntry(GDataDirectory* parent, | 92 GDataEntry::GDataEntry(GDataDirectory* parent, |
| 72 GDataDirectoryService* directory_service) | 93 GDataDirectoryService* directory_service) |
| 73 : directory_service_(directory_service), | 94 : directory_service_(directory_service), |
| 74 deleted_(false) { | 95 deleted_(false) { |
| 75 SetParent(parent); | 96 SetParent(parent); |
| 76 } | 97 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 | 364 |
| 344 for (GDataDirectoryCollection::iterator iter = | 365 for (GDataDirectoryCollection::iterator iter = |
| 345 dir->child_directories_.begin(); | 366 dir->child_directories_.begin(); |
| 346 iter != dir->child_directories_.end(); ++iter) { | 367 iter != dir->child_directories_.end(); ++iter) { |
| 347 AddEntry(iter->second); | 368 AddEntry(iter->second); |
| 348 } | 369 } |
| 349 dir->child_directories_.clear(); | 370 dir->child_directories_.clear(); |
| 350 return true; | 371 return true; |
| 351 } | 372 } |
| 352 | 373 |
| 353 bool GDataDirectory::RemoveEntry(GDataEntry* entry) { | 374 void GDataDirectory::RemoveEntry(GDataEntry* entry) { |
| 354 DCHECK(entry); | 375 DCHECK(entry); |
| 355 | 376 |
| 356 if (!RemoveChild(entry)) | 377 RemoveChild(entry); |
| 357 return false; | |
| 358 | |
| 359 delete entry; | 378 delete entry; |
| 360 return true; | |
| 361 } | 379 } |
| 362 | 380 |
| 363 GDataEntry* GDataDirectory::FindChild( | 381 GDataEntry* GDataDirectory::FindChild( |
| 364 const FilePath::StringType& file_name) const { | 382 const FilePath::StringType& file_name) const { |
| 365 GDataFileCollection::const_iterator it = child_files_.find(file_name); | 383 GDataFileCollection::const_iterator it = child_files_.find(file_name); |
| 366 if (it != child_files_.end()) | 384 if (it != child_files_.end()) |
| 367 return it->second; | 385 return it->second; |
| 368 | 386 |
| 369 GDataDirectoryCollection::const_iterator itd = | 387 GDataDirectoryCollection::const_iterator itd = |
| 370 child_directories_.find(file_name); | 388 child_directories_.find(file_name); |
| 371 if (itd != child_directories_.end()) | 389 if (itd != child_directories_.end()) |
| 372 return itd->second; | 390 return itd->second; |
| 373 | 391 |
| 374 return NULL; | 392 return NULL; |
| 375 } | 393 } |
| 376 | 394 |
| 395 void GDataDirectory::FindChildAsync( | |
| 396 const FilePath::StringType& file_name, | |
| 397 const FindEntryCallback& callback) const { | |
| 398 GDataEntry* entry = FindChild(file_name); | |
| 399 callback.Run(entry ? GDATA_FILE_OK : GDATA_FILE_ERROR_NOT_FOUND, entry); | |
|
satorux1
2012/08/07 10:43:46
To make it more asynchronous, can you post the cal
| |
| 400 } | |
| 401 | |
| 377 void GDataDirectory::AddChild(GDataEntry* entry) { | 402 void GDataDirectory::AddChild(GDataEntry* entry) { |
| 378 DCHECK(entry); | 403 DCHECK(entry); |
| 379 | 404 |
| 380 GDataFile* file = entry->AsGDataFile(); | 405 GDataFile* file = entry->AsGDataFile(); |
| 381 if (file) | 406 if (file) |
| 382 child_files_.insert(std::make_pair(entry->base_name(), file)); | 407 child_files_.insert(std::make_pair(entry->base_name(), file)); |
| 383 | 408 |
| 384 GDataDirectory* directory = entry->AsGDataDirectory(); | 409 GDataDirectory* directory = entry->AsGDataDirectory(); |
| 385 if (directory) | 410 if (directory) |
| 386 child_directories_.insert(std::make_pair(entry->base_name(), directory)); | 411 child_directories_.insert(std::make_pair(entry->base_name(), directory)); |
| 387 } | 412 } |
| 388 | 413 |
| 389 bool GDataDirectory::RemoveChild(GDataEntry* entry) { | 414 void GDataDirectory::RemoveChild(GDataEntry* entry) { |
| 390 DCHECK(entry); | 415 DCHECK(entry); |
| 391 | 416 |
| 392 const std::string file_name(entry->base_name()); | 417 const std::string& file_name(entry->base_name()); |
| 393 GDataEntry* found_entry = FindChild(file_name); | |
| 394 if (!found_entry) | |
| 395 return false; | |
| 396 | |
| 397 DCHECK_EQ(entry, found_entry); | |
| 398 | |
| 399 // Remove entry from resource map first. | 418 // Remove entry from resource map first. |
| 400 if (directory_service_) | 419 if (directory_service_) |
| 401 directory_service_->RemoveEntryFromResourceMap(entry); | 420 directory_service_->RemoveEntryFromResourceMap(entry); |
| 402 | 421 |
| 403 // Then delete it from tree. | 422 // Then delete it from tree. |
| 404 child_files_.erase(file_name); | 423 child_files_.erase(file_name); |
| 405 child_directories_.erase(file_name); | 424 child_directories_.erase(file_name); |
| 406 | |
| 407 return true; | |
| 408 } | 425 } |
| 409 | 426 |
| 410 void GDataDirectory::RemoveChildren() { | 427 void GDataDirectory::RemoveChildren() { |
| 411 RemoveChildFiles(); | 428 RemoveChildFiles(); |
| 412 RemoveChildDirectories(); | 429 RemoveChildDirectories(); |
| 413 } | 430 } |
| 414 | 431 |
| 415 void GDataDirectory::RemoveChildFiles() { | 432 void GDataDirectory::RemoveChildFiles() { |
| 416 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 433 for (GDataFileCollection::const_iterator iter = child_files_.begin(); |
| 417 iter != child_files_.end(); ++iter) { | 434 iter != child_files_.end(); ++iter) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 612 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 629 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
| 613 } | 630 } |
| 614 | 631 |
| 615 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { | 632 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { |
| 616 // GDataFileSystem has already locked. | 633 // GDataFileSystem has already locked. |
| 617 resource_map_.erase(entry->resource_id()); | 634 resource_map_.erase(entry->resource_id()); |
| 618 } | 635 } |
| 619 | 636 |
| 620 GDataEntry* GDataDirectoryService::FindEntryByPathSync( | 637 GDataEntry* GDataDirectoryService::FindEntryByPathSync( |
| 621 const FilePath& file_path) { | 638 const FilePath& file_path) { |
| 639 if (file_path == root_->GetFilePath()) | |
| 640 return root_.get(); | |
| 641 | |
| 622 std::vector<FilePath::StringType> components; | 642 std::vector<FilePath::StringType> components; |
| 623 file_path.GetComponents(&components); | 643 file_path.GetComponents(&components); |
| 644 GDataDirectory* current_dir = root_.get(); | |
| 624 | 645 |
| 625 GDataDirectory* current_dir = root_.get(); | 646 for (size_t i = 1; i < components.size() && current_dir; ++i) { |
| 626 FilePath directory_path; | 647 GDataEntry* entry = current_dir->FindChild(components[i]); |
| 648 if (!entry) | |
| 649 return NULL; | |
| 627 | 650 |
| 628 for (size_t i = 0; i < components.size() && current_dir; i++) { | 651 if (i == components.size() - 1) // Last component. |
| 629 directory_path = directory_path.Append(current_dir->base_name()); | 652 return entry; |
| 630 | 653 else |
|
satorux1
2012/08/07 10:43:46
I'm rather confused. Simplifying the FindEntryByPa
| |
| 631 // Last element must match, if not last then it must be a directory. | |
| 632 if (i == components.size() - 1) { | |
| 633 if (current_dir->base_name() == components[i]) | |
| 634 return current_dir; | |
| 635 else | |
| 636 return NULL; | |
| 637 } | |
| 638 | |
| 639 // Not the last part of the path, search for the next segment. | |
| 640 GDataEntry* entry = current_dir->FindChild(components[i + 1]); | |
| 641 if (!entry) { | |
| 642 return NULL; | |
| 643 } | |
| 644 | |
| 645 // Found file, must be the last segment. | |
| 646 if (entry->file_info().is_directory) { | |
| 647 // Found directory, continue traversal. | |
| 648 current_dir = entry->AsGDataDirectory(); | 654 current_dir = entry->AsGDataDirectory(); |
| 649 } else { | |
| 650 if ((i + 1) == (components.size() - 1)) | |
| 651 return entry; | |
| 652 else | |
| 653 return NULL; | |
| 654 } | |
| 655 } | 655 } |
| 656 return NULL; | 656 return NULL; |
| 657 } | 657 } |
| 658 | 658 |
| 659 void GDataDirectoryService::FindEntryByPathAndRunSync( | 659 void GDataDirectoryService::FindEntryByPathAndRunSync( |
| 660 const FilePath& search_file_path, | 660 const FilePath& search_file_path, |
| 661 const FindEntryCallback& callback) { | 661 const FindEntryCallback& callback) { |
| 662 GDataEntry* entry = FindEntryByPathSync(search_file_path); | 662 if (search_file_path == root_->GetFilePath()) { |
| 663 callback.Run(entry ? GDATA_FILE_OK : GDATA_FILE_ERROR_NOT_FOUND, entry); | 663 callback.Run(GDATA_FILE_OK, root_.get()); |
| 664 return; | |
| 665 } | |
| 666 | |
| 667 std::vector<FilePath::StringType> components; | |
| 668 search_file_path.GetComponents(&components); | |
| 669 std::reverse(components.begin(), components.end()); | |
| 670 components.pop_back(); // Pop root. | |
| 671 FindNextComponent(components, callback, GDATA_FILE_OK, root_.get()); | |
| 664 } | 672 } |
| 665 | 673 |
| 666 GDataEntry* GDataDirectoryService::GetEntryByResourceId( | 674 GDataEntry* GDataDirectoryService::GetEntryByResourceId( |
| 667 const std::string& resource) { | 675 const std::string& resource) { |
| 668 // GDataFileSystem has already locked. | 676 // GDataFileSystem has already locked. |
| 669 ResourceMap::const_iterator iter = resource_map_.find(resource); | 677 ResourceMap::const_iterator iter = resource_map_.find(resource); |
| 670 return iter == resource_map_.end() ? NULL : iter->second; | 678 return iter == resource_map_.end() ? NULL : iter->second; |
| 671 } | 679 } |
| 672 | 680 |
| 673 void GDataDirectoryService::GetEntryByResourceIdAsync( | 681 void GDataDirectoryService::GetEntryByResourceIdAsync( |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1097 if (file->FromProto(entry_proto)) { | 1105 if (file->FromProto(entry_proto)) { |
| 1098 entry.reset(file.release()); | 1106 entry.reset(file.release()); |
| 1099 } else { | 1107 } else { |
| 1100 NOTREACHED() << "FromProto (file) failed"; | 1108 NOTREACHED() << "FromProto (file) failed"; |
| 1101 } | 1109 } |
| 1102 } | 1110 } |
| 1103 return entry.Pass(); | 1111 return entry.Pass(); |
| 1104 } | 1112 } |
| 1105 | 1113 |
| 1106 } // namespace gdata | 1114 } // namespace gdata |
| OLD | NEW |