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

Unified Diff: chrome/browser/chromeos/gdata/gdata_files.cc

Issue 10258004: Parent/child fixes. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: rebase Created 8 years, 8 months 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/gdata/gdata_files.cc
===================================================================
--- chrome/browser/chromeos/gdata/gdata_files.cc (revision 134375)
+++ chrome/browser/chromeos/gdata/gdata_files.cc (working copy)
@@ -15,6 +15,7 @@
#include "chrome/browser/chromeos/gdata/gdata_parser.h"
#include "net/base/escape.h"
+namespace gdata {
namespace {
// Content refresh time.
@@ -26,20 +27,21 @@
const char kSlash[] = "/";
const char kEscapedSlash[] = "\xE2\x88\x95";
+const FilePath::CharType kGDataRootDirectory[] = FILE_PATH_LITERAL("gdata");
std::string CacheSubDirectoryTypeToString(
- gdata::GDataRootDirectory::CacheSubDirectoryType subdir) {
+ GDataRootDirectory::CacheSubDirectoryType subdir) {
switch (subdir) {
- case gdata::GDataRootDirectory::CACHE_TYPE_META: return "meta";
- case gdata::GDataRootDirectory::CACHE_TYPE_PINNED: return "pinned";
- case gdata::GDataRootDirectory::CACHE_TYPE_OUTGOING: return "outgoing";
- case gdata::GDataRootDirectory::CACHE_TYPE_PERSISTENT: return "persistent";
- case gdata::GDataRootDirectory::CACHE_TYPE_TMP: return "tmp";
- case gdata::GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS:
+ case GDataRootDirectory::CACHE_TYPE_META: return "meta";
+ case GDataRootDirectory::CACHE_TYPE_PINNED: return "pinned";
+ case GDataRootDirectory::CACHE_TYPE_OUTGOING: return "outgoing";
+ case GDataRootDirectory::CACHE_TYPE_PERSISTENT: return "persistent";
+ case GDataRootDirectory::CACHE_TYPE_TMP: return "tmp";
+ case GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS:
return "tmp_downloads";
- case gdata::GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS:
+ case GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS:
return "tmp_documents";
- case gdata::GDataRootDirectory::NUM_CACHE_TYPES:
+ case GDataRootDirectory::NUM_CACHE_TYPES:
NOTREACHED();
}
NOTREACHED();
@@ -54,14 +56,12 @@
} // namespace
-namespace gdata {
-
// GDataEntry class.
GDataEntry::GDataEntry(GDataDirectory* parent, GDataRootDirectory* root)
- : parent_(parent),
- root_(root),
+ : root_(root),
deleted_(false) {
+ SetParent(parent);
}
GDataEntry::~GDataEntry() {
@@ -91,28 +91,25 @@
FilePath GDataEntry::GetFilePath() const {
FilePath path;
- std::vector<FilePath::StringType> parts;
- for (const GDataEntry* entry = this; entry != NULL; entry = entry->parent_)
- parts.push_back(entry->file_name());
-
- // Paste paths parts back together in reverse order from upward tree
- // traversal.
- for (std::vector<FilePath::StringType>::reverse_iterator iter =
- parts.rbegin();
- iter != parts.rend(); ++iter) {
- path = path.Append(*iter);
- }
+ if (parent())
+ path = parent()->GetFilePath();
+ path = path.Append(file_name());
return path;
}
+void GDataEntry::SetParent(GDataDirectory* parent) {
+ parent_ = parent;
+ parent_resource_id_ = parent ? parent->resource_id() : "";
+}
+
void GDataEntry::SetFileNameFromTitle() {
file_name_ = EscapeUtf8FileName(title_);
}
// static.
GDataEntry* GDataEntry::FromDocumentEntry(GDataDirectory* parent,
- DocumentEntry* doc,
- GDataRootDirectory* root) {
+ DocumentEntry* doc,
+ GDataRootDirectory* root) {
DCHECK(doc);
if (doc->is_folder())
return GDataDirectory::FromDocumentEntry(parent, doc, root);
@@ -142,7 +139,7 @@
GDataFile::GDataFile(GDataDirectory* parent, GDataRootDirectory* root)
: GDataEntry(parent, root),
- kind_(gdata::DocumentEntry::UNKNOWN),
+ kind_(DocumentEntry::UNKNOWN),
is_hosted_document_(false) {
file_info_.is_directory = false;
}
@@ -164,8 +161,8 @@
// static.
GDataEntry* GDataFile::FromDocumentEntry(GDataDirectory* parent,
- DocumentEntry* doc,
- GDataRootDirectory* root) {
+ DocumentEntry* doc,
+ GDataRootDirectory* root) {
DCHECK(doc->is_hosted_document() || doc->is_file());
GDataFile* file = new GDataFile(parent, root);
@@ -241,8 +238,8 @@
// static
GDataEntry* GDataDirectory::FromDocumentEntry(GDataDirectory* parent,
- DocumentEntry* doc,
- GDataRootDirectory* root) {
+ DocumentEntry* doc,
+ GDataRootDirectory* root) {
DCHECK(doc->is_folder());
GDataDirectory* dir = new GDataDirectory(parent, root);
dir->title_ = UTF16ToUTF8(doc->title());
@@ -273,15 +270,6 @@
return dir;
}
-void GDataDirectory::RemoveChildren() {
- // Remove children from resource map first.
- root_->RemoveEntriesFromResourceMap(children_);
-
- // Then delete and remove the children from tree.
- STLDeleteValues(&children_);
- children_.clear();
-}
-
bool GDataDirectory::NeedsRefresh() const {
// Already refreshing by someone else.
if (origin_ == REFRESHING)
@@ -298,13 +286,18 @@
}
void GDataDirectory::AddEntry(GDataEntry* entry) {
+ // The entry name may have been changed due to prior name de-duplication.
+ // We need to first restore the file name based on the title before going
+ // through name de-duplication again when it is added to another directory.
+ entry->SetFileNameFromTitle();
+
// Do file name de-duplication - find files with the same name and
// append a name modifier to the name.
int max_modifier = 1;
FilePath full_file_name(entry->file_name());
- std::string extension = full_file_name.Extension();
- std::string file_name = full_file_name.RemoveExtension().value();
- while (children_.find(full_file_name.value()) != children_.end()) {
+ const std::string extension = full_file_name.Extension();
+ const std::string file_name = full_file_name.RemoveExtension().value();
+ while (FindChild(full_file_name.value())) {
if (!extension.empty()) {
full_file_name = FilePath(base::StringPrintf("%s (%d)%s",
file_name.c_str(),
@@ -316,76 +309,123 @@
++max_modifier));
}
}
- if (full_file_name.value() != entry->file_name())
- entry->set_file_name(full_file_name.value());
- children_.insert(std::make_pair(entry->file_name(), entry));
- DVLOG(1) << "Adding: "
- << this->GetFilePath().value()
- << "/" + entry->file_name()
- << ", resource " << entry->parent_resource_id()
- << "/" + entry->resource_id();
+ entry->set_file_name(full_file_name.value());
+ DVLOG(1) << "AddEntry: dir = " << GetFilePath().value()
+ << ", file = " + entry->file_name()
+ << ", parent resource = " << entry->parent_resource_id()
+ << ", resource = " + entry->resource_id();
+
+
// Add entry to resource map.
root_->AddEntryToResourceMap(entry);
-
- entry->set_parent(this);
+ // Setup child and parent links.
+ AddChild(entry);
+ entry->SetParent(this);
}
bool GDataDirectory::TakeEntry(GDataEntry* entry) {
DCHECK(entry);
DCHECK(entry->parent());
- entry->parent()->RemoveEntryFromChildrenList(entry);
-
- // The entry name may have been changed due to prior name de-duplication.
- // We need to first restore the file name based on the title before going
- // through name de-duplication again when it is added to another directory.
- entry->SetFileNameFromTitle();
+ entry->parent()->RemoveChild(entry);
AddEntry(entry);
return true;
}
bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) {
- for (GDataFileCollection::iterator iter = dir->children_.begin();
- iter != dir->children_.end(); ++iter) {
- GDataEntry* entry = iter->second;
- entry->SetFileNameFromTitle();
- AddEntry(entry);
+ for (GDataFileCollection::iterator iter = dir->child_files_.begin();
+ iter != dir->child_files_.end(); ++iter) {
+ AddEntry(iter->second);
}
- dir->children_.clear();
+ dir->child_files_.clear();
+
+ for (GDataDirectoryCollection::iterator iter =
+ dir->child_directories_.begin();
+ iter != dir->child_directories_.end(); ++iter) {
+ AddEntry(iter->second);
+ }
+ dir->child_directories_.clear();
return true;
}
bool GDataDirectory::RemoveEntry(GDataEntry* entry) {
DCHECK(entry);
- if (!RemoveEntryFromChildrenList(entry))
+ if (!RemoveChild(entry))
return false;
delete entry;
return true;
}
-bool GDataDirectory::RemoveEntryFromChildrenList(GDataEntry* entry) {
+GDataEntry* GDataDirectory::FindChild(
+ const FilePath::StringType& file_name) const {
+ GDataFileCollection::const_iterator it = child_files_.find(file_name);
+ if (it != child_files_.end())
+ return it->second;
+
+ GDataDirectoryCollection::const_iterator itd =
+ child_directories_.find(file_name);
+ if (itd != child_directories_.end())
+ return itd->second;
+
+ return NULL;
+}
+
+void GDataDirectory::AddChild(GDataEntry* entry) {
DCHECK(entry);
- GDataFileCollection::iterator iter = children_.find(entry->file_name());
- if (iter == children_.end())
+ GDataFile* file = entry->AsGDataFile();
+ if (file)
+ child_files_.insert(std::make_pair(entry->file_name(), file));
+
+ GDataDirectory* directory = entry->AsGDataDirectory();
+ if (directory)
+ child_directories_.insert(std::make_pair(entry->file_name(), directory));
+}
+
+bool GDataDirectory::RemoveChild(GDataEntry* entry) {
+ DCHECK(entry);
+
+ const std::string file_name(entry->file_name());
+ GDataEntry* found_entry = FindChild(file_name);
+ if (!found_entry)
return false;
- DCHECK(iter->second);
- DCHECK_EQ(entry, iter->second);
+ DCHECK_EQ(entry, found_entry);
// Remove entry from resource map first.
root_->RemoveEntryFromResourceMap(entry);
// Then delete it from tree.
- children_.erase(iter);
+ child_files_.erase(file_name);
+ child_directories_.erase(file_name);
return true;
}
+void GDataDirectory::RemoveChildren() {
+ // Remove child files first.
+ for (GDataFileCollection::const_iterator iter = child_files_.begin();
+ iter != child_files_.end(); ++iter) {
+ root_->RemoveEntryFromResourceMap(iter->second);
+ }
+ STLDeleteValues(&child_files_);
+ child_files_.clear();
+
+ for (GDataDirectoryCollection::iterator iter = child_directories_.begin();
+ iter != child_directories_.end(); ++iter) {
+ GDataDirectory* dir = iter->second;
+ // Remove directories recursively.
+ dir->RemoveChildren();
+ root_->RemoveEntryFromResourceMap(dir);
+ }
+ STLDeleteValues(&child_directories_);
+ child_directories_.clear();
+}
+
// GDataRootDirectory::CacheEntry struct implementation.
std::string GDataRootDirectory::CacheEntry::ToString() const {
@@ -408,6 +448,8 @@
GDataRootDirectory::GDataRootDirectory()
: ALLOW_THIS_IN_INITIALIZER_LIST(GDataDirectory(NULL, this)),
largest_changestamp_(0), serialized_size_(0) {
+ title_ = kGDataRootDirectory;
+ SetFileNameFromTitle();
}
GDataRootDirectory::~GDataRootDirectory() {
@@ -423,6 +465,7 @@
void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) {
// GDataFileSystem has already locked.
+ DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id();
resource_map_.insert(std::make_pair(entry->resource_id(), entry));
}
@@ -431,22 +474,6 @@
resource_map_.erase(entry->resource_id());
}
-void GDataRootDirectory::RemoveEntriesFromResourceMap(
- const GDataFileCollection& children) {
- // GDataFileSystem has already locked.
- for (GDataFileCollection::const_iterator iter = children.begin();
- iter != children.end(); ++iter) {
- // Recursively call RemoveEntrysFromResourceMap for each directory.
- if (iter->second->AsGDataDirectory()) {
- RemoveEntriesFromResourceMap(
- iter->second->AsGDataDirectory()->children());
- continue;
- }
-
- resource_map_.erase(iter->second->resource_id());
- }
-}
-
void GDataRootDirectory::FindEntryByPath(
const FilePath& file_path,
FindEntryDelegate* delegate) {
@@ -472,22 +499,21 @@
}
// Not the last part of the path, search for the next segment.
- GDataFileCollection::const_iterator file_iter =
- current_dir->children().find(components[i + 1]);
- if (file_iter == current_dir->children().end()) {
+ GDataEntry* entry = current_dir->FindChild(components[i + 1]);
+ if (!entry) {
delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL);
return;
}
// Found file, must be the last segment.
- if (file_iter->second->file_info().is_directory) {
+ if (entry->file_info().is_directory) {
// Found directory, continue traversal.
- current_dir = file_iter->second->AsGDataDirectory();
+ current_dir = entry->AsGDataDirectory();
} else {
if ((i + 1) == (components.size() - 1)) {
delegate->OnDone(base::PLATFORM_FILE_OK,
directory_path,
- file_iter->second);
+ entry);
} else {
delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL);
}
@@ -617,11 +643,12 @@
file_info_.creation_time = base::Time::FromInternalValue(
proto.file_info().creation_time());
- file_name_ = proto.file_name();
title_ = proto.title();
resource_id_ = proto.resource_id();
+ parent_resource_id_ = proto.parent_resource_id();
edit_url_ = GURL(proto.edit_url());
content_url_ = GURL(proto.content_url());
+ SetFileNameFromTitle();
}
void GDataEntry::ToProto(GDataEntryProto* proto) const {
@@ -636,9 +663,9 @@
proto_file_info->set_creation_time(
file_info_.creation_time.ToInternalValue());
- proto->set_file_name(file_name_);
proto->set_title(title_);
proto->set_resource_id(resource_id_);
+ proto->set_parent_resource_id(parent_resource_id_);
proto->set_edit_url(edit_url_.spec());
proto->set_content_url(content_url_.spec());
}
@@ -699,15 +726,17 @@
proto->set_next_feed_url(next_feed_url_.spec());
proto->set_upload_url(upload_url_.spec());
proto->set_origin(origin_);
- for (GDataFileCollection::const_iterator iter = children_.begin();
- iter != children_.end(); ++iter) {
- GDataFile* file = iter->second->AsGDataFile();
- GDataDirectory* dir = iter->second->AsGDataDirectory();
- if (file)
- file->ToProto(proto->add_child_files());
- if (dir)
- dir->ToProto(proto->add_child_directories());
+ for (GDataFileCollection::const_iterator iter = child_files_.begin();
+ iter != child_files_.end(); ++iter) {
+ GDataFile* file = iter->second;
+ file->ToProto(proto->add_child_files());
}
+ for (GDataDirectoryCollection::const_iterator iter =
+ child_directories_.begin();
+ iter != child_directories_.end(); ++iter) {
+ GDataDirectory* dir = iter->second;
+ dir->ToProto(proto->add_child_directories());
+ }
}
void GDataRootDirectory::FromProto(const GDataRootDirectoryProto& proto) {
« chrome/browser/chromeos/gdata/gdata_files.h ('K') | « chrome/browser/chromeos/gdata/gdata_files.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698