Index: chrome/browser/chromeos/gdata/gdata_files.cc |
diff --git a/chrome/browser/chromeos/gdata/gdata_files.cc b/chrome/browser/chromeos/gdata/gdata_files.cc |
index 183329223afd36a686c8e7ac9883c6709fb2111a..cd671facbbe3aa0356242bbf55759d6e064a9b1f 100644 |
--- a/chrome/browser/chromeos/gdata/gdata_files.cc |
+++ b/chrome/browser/chromeos/gdata/gdata_files.cc |
@@ -13,6 +13,7 @@ |
#include "chrome/browser/chromeos/gdata/find_entry_delegate.h" |
#include "chrome/browser/chromeos/gdata/gdata.pb.h" |
#include "chrome/browser/chromeos/gdata/gdata_parser.h" |
+#include "chrome/browser/chromeos/gdata/gdata_util.h" |
#include "net/base/escape.h" |
namespace gdata { |
@@ -318,7 +319,9 @@ void GDataDirectory::AddEntry(GDataEntry* entry) { |
// Add entry to resource map. |
- root_->AddEntryToResourceMap(entry); |
+ if (root_) |
+ root_->AddEntryToResourceMap(entry); |
+ |
// Setup child and parent links. |
AddChild(entry); |
entry->SetParent(this); |
@@ -397,7 +400,8 @@ bool GDataDirectory::RemoveChild(GDataEntry* entry) { |
DCHECK_EQ(entry, found_entry); |
// Remove entry from resource map first. |
- root_->RemoveEntryFromResourceMap(entry); |
+ if (root_) |
+ root_->RemoveEntryFromResourceMap(entry); |
// Then delete it from tree. |
child_files_.erase(file_name); |
@@ -410,7 +414,8 @@ void GDataDirectory::RemoveChildren() { |
// Remove child files first. |
for (GDataFileCollection::const_iterator iter = child_files_.begin(); |
iter != child_files_.end(); ++iter) { |
- root_->RemoveEntryFromResourceMap(iter->second); |
+ if (root_) |
+ root_->RemoveEntryFromResourceMap(iter->second); |
} |
STLDeleteValues(&child_files_); |
child_files_.clear(); |
@@ -420,7 +425,8 @@ void GDataDirectory::RemoveChildren() { |
GDataDirectory* dir = iter->second; |
// Remove directories recursively. |
dir->RemoveChildren(); |
- root_->RemoveEntryFromResourceMap(dir); |
+ if (root_) |
+ root_->RemoveEntryFromResourceMap(dir); |
} |
STLDeleteValues(&child_directories_); |
child_directories_.clear(); |
@@ -447,6 +453,7 @@ std::string GDataRootDirectory::CacheEntry::ToString() const { |
GDataRootDirectory::GDataRootDirectory() |
: ALLOW_THIS_IN_INITIALIZER_LIST(GDataDirectory(NULL, this)), |
+ fake_search_directory_(new GDataDirectory(NULL, NULL)), |
largest_changestamp_(0), serialized_size_(0) { |
title_ = kGDataRootDirectory; |
SetFileNameFromTitle(); |
@@ -474,6 +481,47 @@ void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { |
resource_map_.erase(entry->resource_id()); |
} |
+bool GDataRootDirectory::ModifyFindEntryParamsIfSearchPath( |
+ const FilePath& file_path, |
+ std::vector<FilePath::StringType>* components, |
+ GDataDirectory** current_dir, |
+ FilePath* directory_path) { |
+ DCHECK(current_dir); |
+ DCHECK(components); |
+ DCHECK(components->size() > 3); |
+ |
+ FilePath::StringType resource_id; |
+ FilePath::StringType file_name; |
+ util::ParseSearchFileName((*components)[3], &resource_id, &file_name); |
zel
2012/05/03 22:57:56
DCHECK that |components| starts with [ "gdata", "s
tbarzic
2012/05/03 23:56:17
Done.
|
+ if (resource_id.empty() || file_name.empty()) |
+ return false; |
+ |
+ GDataEntry* file_entry = GetEntryByResourceId(resource_id); |
+ if (!file_entry) |
+ return false; |
+ |
+ // If |file_path| is indeed search file path, we should continue search from |
+ // its parent directory. We have to ammend |components| to be relative to |
+ // the |current_dir| (including the dir itself). |
+ // We continue the search with the entrie's parent instead of the entry itself |
+ // to make sure that the file with id |resource_id| really has the name |
+ // |file_name|. |
+ DCHECK(file_entry->parent()); |
+ *current_dir = file_entry->parent(); |
+ |
+ if ((*current_dir)->parent()) { |
+ *directory_path = (*current_dir)->parent()->GetFilePath(); |
+ } else { |
+ *directory_path = FilePath(); |
+ } |
+ |
+ // Remove "gdata/.search" from path. |
+ components->erase(components->begin(), components->begin() + 2); |
+ (*components)[0] = (*current_dir)->file_name(); |
+ (*components)[1] = file_name; |
+ return true; |
+} |
+ |
void GDataRootDirectory::FindEntryByPath( |
const FilePath& file_path, |
FindEntryDelegate* delegate) { |
@@ -485,16 +533,39 @@ void GDataRootDirectory::FindEntryByPath( |
GDataDirectory* current_dir = this; |
FilePath directory_path; |
+ |
+ util::GDataSearchPathType path_type = |
+ util::GetSearchPathStatusForPathComponents(components); |
+ |
+ if (path_type == util::GDATA_SEARCH_PATH_ROOT || |
+ path_type == util::GDATA_SEARCH_PATH_QUERY) { |
+ fake_search_directory_->set_file_name(file_path.BaseName().value()); |
tbarzic
2012/05/03 23:56:17
don't really need this
|
+ delegate->OnDone(base::PLATFORM_FILE_OK, file_path.DirName(), |
+ fake_search_directory_.get()); |
+ return; |
+ |
+ } |
+ |
+ // If the path is under search path, we have to modify paremeters for finding |
+ // the entry. |
+ if (path_type != util::GDATA_SEARCH_PATH_INVALID) { |
+ if (!ModifyFindEntryParamsIfSearchPath(file_path, &components, ¤t_dir, |
+ &directory_path)) { |
+ delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
+ return; |
+ } |
+ } |
+ |
for (size_t i = 0; i < components.size() && current_dir; i++) { |
directory_path = directory_path.Append(current_dir->file_name()); |
// Last element must match, if not last then it must be a directory. |
if (i == components.size() - 1) { |
- if (current_dir->file_name() == components[i]) |
+ if (current_dir->file_name() == components[i]) { |
delegate->OnDone(base::PLATFORM_FILE_OK, directory_path, current_dir); |
- else |
+ } else { |
delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
- |
+ } |
return; |
} |