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 d48a11c12c36b4b931429842d403a082b9b67c06..750f19429ac25c7b1f972773efd3b5cf9f59faa3 100644 |
--- a/chrome/browser/chromeos/gdata/gdata_files.cc |
+++ b/chrome/browser/chromeos/gdata/gdata_files.cc |
@@ -4,8 +4,6 @@ |
#include "chrome/browser/chromeos/gdata/gdata_files.h" |
-#include <vector> |
- |
#include "base/utf_string_conversions.h" |
#include "base/platform_file.h" |
#include "base/stringprintf.h" |
@@ -13,6 +11,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 { |
@@ -295,7 +294,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); |
@@ -374,7 +375,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); |
@@ -387,7 +389,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(); |
@@ -397,7 +400,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(); |
@@ -424,6 +428,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(); |
@@ -451,6 +456,54 @@ void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { |
resource_map_.erase(entry->resource_id()); |
} |
+bool GDataRootDirectory::ModifyFindEntryParamsForSearchPath( |
+ const FilePath& file_path, |
+ std::vector<FilePath::StringType>* components, |
+ GDataDirectory** current_dir, |
+ FilePath* directory_path) { |
+ DCHECK(current_dir); |
+ DCHECK(components); |
+ // |components| should contain at least 4 members. |
+ // "gdata", ".search", query_name and query_result_name. Additionally, |
+ // if query result is a directory, it may contain subdirectories and files, |
+ // in which case the number of components may be bigger than 4. |
+ DCHECK_GT(components->size(), 3u); |
+ DCHECK(components->at(0) == "gdata" && components->at(1) == ".search"); |
+ |
+ FilePath::StringType resource_id; |
+ FilePath::StringType file_name; |
+ if (!util::ParseSearchFileName((*components)[3], &resource_id, &file_name)) |
+ return false; |
+ |
+ GDataEntry* file_entry = GetEntryByResourceId(resource_id); |
+ if (!file_entry) |
+ return false; |
+ |
+ // We should continue search from the entry's parent dir (|current_dir|), so |
+ // we have to ammend |components| to be relative to the |current_dir| |
+ // (including the dir itself). |
+ // We continue the search with the entry's parent instead of the entry itself |
+ // to make sure that the returned file really has the name |file_name|. Note |
+ // that we may end up with finding an entry even if entry with |resource_id| |
+ // has a name different from |file_name|. This is intended, and enables us to |
+ // test that new file name is unique (in file manager) when renaming the |
+ // entry. |
+ 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) { |
@@ -462,16 +515,37 @@ 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) { |
+ 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 (!ModifyFindEntryParamsForSearchPath(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; |
} |