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 |