| 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 <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "chrome/browser/chromeos/gdata/find_entry_delegate.h" |
| 13 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 14 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
| 14 #include "chrome/browser/chromeos/gdata/gdata_parser.h" | 15 #include "chrome/browser/chromeos/gdata/gdata_parser.h" |
| 15 #include "net/base/escape.h" | 16 #include "net/base/escape.h" |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 // Content refresh time. | 20 // Content refresh time. |
| 20 #ifndef NDEBUG | 21 #ifndef NDEBUG |
| 21 const int kRefreshTimeInSec = 10; | 22 const int kRefreshTimeInSec = 10; |
| 22 #else | 23 #else |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 72 } |
| 72 | 73 |
| 73 GDataDirectory* GDataEntry::AsGDataDirectory() { | 74 GDataDirectory* GDataEntry::AsGDataDirectory() { |
| 74 return NULL; | 75 return NULL; |
| 75 } | 76 } |
| 76 | 77 |
| 77 GDataRootDirectory* GDataEntry::AsGDataRootDirectory() { | 78 GDataRootDirectory* GDataEntry::AsGDataRootDirectory() { |
| 78 return NULL; | 79 return NULL; |
| 79 } | 80 } |
| 80 | 81 |
| 81 FilePath GDataEntry::GetFilePath() { | 82 const GDataFile* GDataEntry::AsGDataFileConst() const { |
| 83 // cast away const and call the non-const version. This is safe. |
| 84 return const_cast<GDataEntry*>(this)->AsGDataFile(); |
| 85 } |
| 86 |
| 87 const GDataDirectory* GDataEntry::AsGDataDirectoryConst() const { |
| 88 // cast away const and call the non-const version. This is safe. |
| 89 return const_cast<GDataEntry*>(this)->AsGDataDirectory(); |
| 90 } |
| 91 |
| 92 FilePath GDataEntry::GetFilePath() const { |
| 82 FilePath path; | 93 FilePath path; |
| 83 std::vector<FilePath::StringType> parts; | 94 std::vector<FilePath::StringType> parts; |
| 84 for (GDataEntry* entry = this; entry != NULL; entry = entry->parent()) | 95 for (const GDataEntry* entry = this; entry != NULL; entry = entry->parent_) |
| 85 parts.push_back(entry->file_name()); | 96 parts.push_back(entry->file_name()); |
| 86 | 97 |
| 87 // Paste paths parts back together in reverse order from upward tree | 98 // Paste paths parts back together in reverse order from upward tree |
| 88 // traversal. | 99 // traversal. |
| 89 for (std::vector<FilePath::StringType>::reverse_iterator iter = | 100 for (std::vector<FilePath::StringType>::reverse_iterator iter = |
| 90 parts.rbegin(); | 101 parts.rbegin(); |
| 91 iter != parts.rend(); ++iter) { | 102 iter != parts.rend(); ++iter) { |
| 92 path = path.Append(*iter); | 103 path = path.Append(*iter); |
| 93 } | 104 } |
| 94 return path; | 105 return path; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 ReplaceSubstringsAfterOffset(&output, 0, std::string(kEscapedSlash), kSlash); | 137 ReplaceSubstringsAfterOffset(&output, 0, std::string(kEscapedSlash), kSlash); |
| 127 return output; | 138 return output; |
| 128 } | 139 } |
| 129 | 140 |
| 130 // GDataFile class implementation. | 141 // GDataFile class implementation. |
| 131 | 142 |
| 132 GDataFile::GDataFile(GDataDirectory* parent, GDataRootDirectory* root) | 143 GDataFile::GDataFile(GDataDirectory* parent, GDataRootDirectory* root) |
| 133 : GDataEntry(parent, root), | 144 : GDataEntry(parent, root), |
| 134 kind_(gdata::DocumentEntry::UNKNOWN), | 145 kind_(gdata::DocumentEntry::UNKNOWN), |
| 135 is_hosted_document_(false) { | 146 is_hosted_document_(false) { |
| 147 file_info_.is_directory = false; |
| 136 } | 148 } |
| 137 | 149 |
| 138 GDataFile::~GDataFile() { | 150 GDataFile::~GDataFile() { |
| 139 } | 151 } |
| 140 | 152 |
| 141 GDataFile* GDataFile::AsGDataFile() { | 153 GDataFile* GDataFile::AsGDataFile() { |
| 142 return this; | 154 return this; |
| 143 } | 155 } |
| 144 | 156 |
| 145 void GDataFile::SetFileNameFromTitle() { | 157 void GDataFile::SetFileNameFromTitle() { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 STLDeleteValues(&cache_map_); | 414 STLDeleteValues(&cache_map_); |
| 403 cache_map_.clear(); | 415 cache_map_.clear(); |
| 404 | 416 |
| 405 resource_map_.clear(); | 417 resource_map_.clear(); |
| 406 } | 418 } |
| 407 | 419 |
| 408 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { | 420 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { |
| 409 return this; | 421 return this; |
| 410 } | 422 } |
| 411 | 423 |
| 424 void GDataRootDirectory::FindEntryByPath(const FilePath& file_path, |
| 425 FindEntryDelegate* delegate) { |
| 426 // GDataFileSystem has already locked. |
| 427 DCHECK(delegate); |
| 428 std::vector<FilePath::StringType> components; |
| 429 file_path.GetComponents(&components); |
| 430 |
| 431 GDataDirectory* current_dir = this; |
| 432 FilePath directory_path; |
| 433 for (size_t i = 0; i < components.size() && current_dir; i++) { |
| 434 directory_path = directory_path.Append(current_dir->file_name()); |
| 435 |
| 436 // Last element must match, if not last then it must be a directory. |
| 437 if (i == components.size() - 1) { |
| 438 if (current_dir->file_name() == components[i]) |
| 439 delegate->OnDone(base::PLATFORM_FILE_OK, directory_path, current_dir); |
| 440 else |
| 441 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
| 442 |
| 443 return; |
| 444 } |
| 445 |
| 446 // Not the last part of the path, search for the next segment. |
| 447 GDataFileCollection::const_iterator file_iter = |
| 448 current_dir->children().find(components[i + 1]); |
| 449 if (file_iter == current_dir->children().end()) { |
| 450 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
| 451 return; |
| 452 } |
| 453 |
| 454 // Found file, must be the last segment. |
| 455 if (file_iter->second->file_info().is_directory) { |
| 456 // Found directory, continue traversal. |
| 457 current_dir = file_iter->second->AsGDataDirectory(); |
| 458 } else { |
| 459 if ((i + 1) == (components.size() - 1)) { |
| 460 delegate->OnDone(base::PLATFORM_FILE_OK, |
| 461 directory_path, |
| 462 file_iter->second); |
| 463 } else { |
| 464 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
| 465 } |
| 466 |
| 467 return; |
| 468 } |
| 469 } |
| 470 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
| 471 } |
| 472 |
| 412 void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) { | 473 void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) { |
| 413 // GDataFileSystem has already locked. | 474 // GDataFileSystem has already locked. |
| 414 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 475 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
| 415 } | 476 } |
| 416 | 477 |
| 417 void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { | 478 void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { |
| 418 // GDataFileSystem has already locked. | 479 // GDataFileSystem has already locked. |
| 419 resource_map_.erase(entry->resource_id()); | 480 resource_map_.erase(entry->resource_id()); |
| 420 } | 481 } |
| 421 | 482 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 file_info_.creation_time.ToInternalValue()); | 635 file_info_.creation_time.ToInternalValue()); |
| 575 | 636 |
| 576 proto->set_file_name(file_name_); | 637 proto->set_file_name(file_name_); |
| 577 proto->set_title(title_); | 638 proto->set_title(title_); |
| 578 proto->set_resource_id(resource_id_); | 639 proto->set_resource_id(resource_id_); |
| 579 proto->set_edit_url(edit_url_.spec()); | 640 proto->set_edit_url(edit_url_.spec()); |
| 580 proto->set_content_url(content_url_.spec()); | 641 proto->set_content_url(content_url_.spec()); |
| 581 } | 642 } |
| 582 | 643 |
| 583 void GDataFile::FromProto(const GDataFileProto& proto) { | 644 void GDataFile::FromProto(const GDataFileProto& proto) { |
| 645 DCHECK(!proto.gdata_entry().file_info().is_directory()); |
| 584 GDataEntry::FromProto(proto.gdata_entry()); | 646 GDataEntry::FromProto(proto.gdata_entry()); |
| 585 kind_ = DocumentEntry::EntryKind(proto.kind()); | 647 kind_ = DocumentEntry::EntryKind(proto.kind()); |
| 586 thumbnail_url_ = GURL(proto.thumbnail_url()); | 648 thumbnail_url_ = GURL(proto.thumbnail_url()); |
| 587 alternate_url_ = GURL(proto.alternate_url()); | 649 alternate_url_ = GURL(proto.alternate_url()); |
| 588 content_mime_type_ = proto.content_mime_type(); | 650 content_mime_type_ = proto.content_mime_type(); |
| 589 etag_ = proto.etag(); | 651 etag_ = proto.etag(); |
| 590 id_ = proto.id(); | 652 id_ = proto.id(); |
| 591 file_md5_ = proto.file_md5(); | 653 file_md5_ = proto.file_md5(); |
| 592 document_extension_ = proto.document_extension(); | 654 document_extension_ = proto.document_extension(); |
| 593 is_hosted_document_ = proto.is_hosted_document(); | 655 is_hosted_document_ = proto.is_hosted_document(); |
| 594 } | 656 } |
| 595 | 657 |
| 596 void GDataFile::ToProto(GDataFileProto* proto) const { | 658 void GDataFile::ToProto(GDataFileProto* proto) const { |
| 597 GDataEntry::ToProto(proto->mutable_gdata_entry()); | 659 GDataEntry::ToProto(proto->mutable_gdata_entry()); |
| 660 DCHECK(!proto->gdata_entry().file_info().is_directory()); |
| 598 proto->set_kind(kind_); | 661 proto->set_kind(kind_); |
| 599 proto->set_thumbnail_url(thumbnail_url_.spec()); | 662 proto->set_thumbnail_url(thumbnail_url_.spec()); |
| 600 proto->set_alternate_url(alternate_url_.spec()); | 663 proto->set_alternate_url(alternate_url_.spec()); |
| 601 proto->set_content_mime_type(content_mime_type_); | 664 proto->set_content_mime_type(content_mime_type_); |
| 602 proto->set_etag(etag_); | 665 proto->set_etag(etag_); |
| 603 proto->set_id(id_); | 666 proto->set_id(id_); |
| 604 proto->set_file_md5(file_md5_); | 667 proto->set_file_md5(file_md5_); |
| 605 proto->set_document_extension(document_extension_); | 668 proto->set_document_extension(document_extension_); |
| 606 proto->set_is_hosted_document(is_hosted_document_); | 669 proto->set_is_hosted_document(is_hosted_document_); |
| 607 } | 670 } |
| 608 | 671 |
| 609 void GDataDirectory::FromProto(const GDataDirectoryProto& proto) { | 672 void GDataDirectory::FromProto(const GDataDirectoryProto& proto) { |
| 673 DCHECK(proto.gdata_entry().file_info().is_directory()); |
| 610 GDataEntry::FromProto(proto.gdata_entry()); | 674 GDataEntry::FromProto(proto.gdata_entry()); |
| 611 refresh_time_ = base::Time::FromInternalValue(proto.refresh_time()); | 675 refresh_time_ = base::Time::FromInternalValue(proto.refresh_time()); |
| 612 start_feed_url_ = GURL(proto.start_feed_url()); | 676 start_feed_url_ = GURL(proto.start_feed_url()); |
| 613 next_feed_url_ = GURL(proto.next_feed_url()); | 677 next_feed_url_ = GURL(proto.next_feed_url()); |
| 614 upload_url_ = GURL(proto.upload_url()); | 678 upload_url_ = GURL(proto.upload_url()); |
| 615 origin_ = ContentOrigin(proto.origin()); | 679 origin_ = ContentOrigin(proto.origin()); |
| 616 for (int i = 0; i < proto.child_files_size(); ++i) { | 680 for (int i = 0; i < proto.child_files_size(); ++i) { |
| 617 scoped_ptr<GDataFile> file(new GDataFile(this, root_)); | 681 scoped_ptr<GDataFile> file(new GDataFile(this, root_)); |
| 618 file->FromProto(proto.child_files(i)); | 682 file->FromProto(proto.child_files(i)); |
| 619 AddEntry(file.release()); | 683 AddEntry(file.release()); |
| 620 } | 684 } |
| 621 for (int i = 0; i < proto.child_directories_size(); ++i) { | 685 for (int i = 0; i < proto.child_directories_size(); ++i) { |
| 622 scoped_ptr<GDataDirectory> dir(new GDataDirectory(this, root_)); | 686 scoped_ptr<GDataDirectory> dir(new GDataDirectory(this, root_)); |
| 623 dir->FromProto(proto.child_directories(i)); | 687 dir->FromProto(proto.child_directories(i)); |
| 624 AddEntry(dir.release()); | 688 AddEntry(dir.release()); |
| 625 } | 689 } |
| 626 } | 690 } |
| 627 | 691 |
| 628 void GDataDirectory::ToProto(GDataDirectoryProto* proto) const { | 692 void GDataDirectory::ToProto(GDataDirectoryProto* proto) const { |
| 629 GDataEntry::ToProto(proto->mutable_gdata_entry()); | 693 GDataEntry::ToProto(proto->mutable_gdata_entry()); |
| 694 DCHECK(proto->gdata_entry().file_info().is_directory()); |
| 630 proto->set_refresh_time(refresh_time_.ToInternalValue()); | 695 proto->set_refresh_time(refresh_time_.ToInternalValue()); |
| 631 proto->set_start_feed_url(start_feed_url_.spec()); | 696 proto->set_start_feed_url(start_feed_url_.spec()); |
| 632 proto->set_next_feed_url(next_feed_url_.spec()); | 697 proto->set_next_feed_url(next_feed_url_.spec()); |
| 633 proto->set_upload_url(upload_url_.spec()); | 698 proto->set_upload_url(upload_url_.spec()); |
| 634 proto->set_origin(origin_); | 699 proto->set_origin(origin_); |
| 635 for (GDataFileCollection::const_iterator iter = children_.begin(); | 700 for (GDataFileCollection::const_iterator iter = children_.begin(); |
| 636 iter != children_.end(); ++iter) { | 701 iter != children_.end(); ++iter) { |
| 637 GDataFile* file = iter->second->AsGDataFile(); | 702 GDataFile* file = iter->second->AsGDataFile(); |
| 638 GDataDirectory* dir = iter->second->AsGDataDirectory(); | 703 GDataDirectory* dir = iter->second->AsGDataDirectory(); |
| 639 if (file) | 704 if (file) |
| 640 file->ToProto(proto->add_child_files()); | 705 file->ToProto(proto->add_child_files()); |
| 641 if (dir) | 706 if (dir) |
| 642 dir->ToProto(proto->add_child_directories()); | 707 dir->ToProto(proto->add_child_directories()); |
| 643 } | 708 } |
| 644 } | 709 } |
| 645 | 710 |
| 646 void GDataRootDirectory::FromProto(const GDataRootDirectoryProto& proto) { | 711 void GDataRootDirectory::FromProto(const GDataRootDirectoryProto& proto) { |
| 647 root_ = this; | 712 root_ = this; |
| 648 GDataDirectory::FromProto(proto.gdata_directory()); | 713 GDataDirectory::FromProto(proto.gdata_directory()); |
| 649 largest_changestamp_ = proto.largest_changestamp(); | 714 largest_changestamp_ = proto.largest_changestamp(); |
| 650 } | 715 } |
| 651 | 716 |
| 652 void GDataRootDirectory::ToProto(GDataRootDirectoryProto* proto) const { | 717 void GDataRootDirectory::ToProto(GDataRootDirectoryProto* proto) const { |
| 653 GDataDirectory::ToProto(proto->mutable_gdata_directory()); | 718 GDataDirectory::ToProto(proto->mutable_gdata_directory()); |
| 654 proto->set_largest_changestamp(largest_changestamp_); | 719 proto->set_largest_changestamp(largest_changestamp_); |
| 655 } | 720 } |
| 656 | 721 |
| 657 void GDataRootDirectory::SerializeToString(std::string* proto_string) const { | 722 void GDataEntry::SerializeToString(std::string* serialized_proto) const { |
| 723 const GDataFile* file = AsGDataFileConst(); |
| 724 const GDataDirectory* dir = AsGDataDirectoryConst(); |
| 725 |
| 726 if (file) { |
| 727 scoped_ptr<GDataFileProto> proto(new GDataFileProto()); |
| 728 file->ToProto(proto.get()); |
| 729 const bool ok = proto->SerializeToString(serialized_proto); |
| 730 DCHECK(ok); |
| 731 } else if (dir) { |
| 732 scoped_ptr<GDataDirectoryProto> proto(new GDataDirectoryProto()); |
| 733 dir->ToProto(proto.get()); |
| 734 const bool ok = proto->SerializeToString(serialized_proto); |
| 735 DCHECK(ok); |
| 736 } |
| 737 } |
| 738 |
| 739 // static |
| 740 scoped_ptr<GDataEntry> GDataEntry::FromProtoString( |
| 741 const std::string& serialized_proto) { |
| 742 // First try to parse as GDataDirectoryProto. Note that this can succeed for |
| 743 // a serialized_proto that's really a GDataFileProto - we have to check |
| 744 // is_directory to be sure. |
| 745 scoped_ptr<GDataDirectoryProto> dir_proto(new GDataDirectoryProto()); |
| 746 bool ok = dir_proto->ParseFromString(serialized_proto); |
| 747 if (ok && dir_proto->gdata_entry().file_info().is_directory()) { |
| 748 GDataDirectory* dir = new GDataDirectory(NULL, NULL); |
| 749 dir->FromProto(*dir_proto); |
| 750 return scoped_ptr<GDataEntry>(dir); |
| 751 } |
| 752 |
| 753 scoped_ptr<GDataFileProto> file_proto(new GDataFileProto()); |
| 754 ok = file_proto->ParseFromString(serialized_proto); |
| 755 if (ok) { |
| 756 DCHECK(!file_proto->gdata_entry().file_info().is_directory()); |
| 757 GDataFile* file = new GDataFile(NULL, NULL); |
| 758 file->FromProto(*file_proto); |
| 759 return scoped_ptr<GDataEntry>(file); |
| 760 } |
| 761 return scoped_ptr<GDataEntry>(NULL); |
| 762 } |
| 763 |
| 764 void GDataRootDirectory::SerializeToString( |
| 765 std::string* serialized_proto) const { |
| 658 scoped_ptr<GDataRootDirectoryProto> proto( | 766 scoped_ptr<GDataRootDirectoryProto> proto( |
| 659 new GDataRootDirectoryProto()); | 767 new GDataRootDirectoryProto()); |
| 660 ToProto(proto.get()); | 768 ToProto(proto.get()); |
| 661 const bool ok = proto->SerializeToString(proto_string); | 769 const bool ok = proto->SerializeToString(serialized_proto); |
| 662 DCHECK(ok); | 770 DCHECK(ok); |
| 663 } | 771 } |
| 664 | 772 |
| 665 bool GDataRootDirectory::ParseFromString(const std::string& proto_string) { | 773 bool GDataRootDirectory::ParseFromString(const std::string& serialized_proto) { |
| 666 scoped_ptr<GDataRootDirectoryProto> proto( | 774 scoped_ptr<GDataRootDirectoryProto> proto( |
| 667 new GDataRootDirectoryProto()); | 775 new GDataRootDirectoryProto()); |
| 668 bool ok = proto->ParseFromString(proto_string); | 776 bool ok = proto->ParseFromString(serialized_proto); |
| 669 if (ok) { | 777 if (ok) { |
| 670 FromProto(*proto.get()); | 778 FromProto(*proto.get()); |
| 671 set_origin(FROM_CACHE); | 779 set_origin(FROM_CACHE); |
| 672 set_refresh_time(base::Time::Now()); | 780 set_refresh_time(base::Time::Now()); |
| 673 } | 781 } |
| 674 return ok; | 782 return ok; |
| 675 } | 783 } |
| 676 | 784 |
| 677 } // namespace gdata | 785 } // namespace gdata |
| OLD | NEW |