Index: webkit/fileapi/isolated_context.cc |
diff --git a/webkit/fileapi/isolated_context.cc b/webkit/fileapi/isolated_context.cc |
index d590f442b010facdf51b823d288e86f7dba6fa32..d57b8737612de894da11e8f4c10dda4077a705e1 100644 |
--- a/webkit/fileapi/isolated_context.cc |
+++ b/webkit/fileapi/isolated_context.cc |
@@ -8,6 +8,7 @@ |
#include "base/basictypes.h" |
#include "base/logging.h" |
#include "base/rand_util.h" |
+#include "base/stl_util.h" |
#include "base/string_number_conversions.h" |
#include "base/string_util.h" |
#include "base/stringprintf.h" |
@@ -51,11 +52,15 @@ IsolatedContext::FileInfo::FileInfo( |
IsolatedContext::FileInfoSet::FileInfoSet() {} |
IsolatedContext::FileInfoSet::~FileInfoSet() {} |
-std::string IsolatedContext::FileInfoSet::AddPath( |
- const FilePath& path) { |
+bool IsolatedContext::FileInfoSet::AddPath( |
+ const FilePath& path, std::string* registered_name) { |
+ // The given path should not contain any '..' and should be absolute. |
+ if (path.ReferencesParent() || !path.IsAbsolute()) |
+ return false; |
FilePath::StringType name = GetRegisterNameForPath(path); |
std::string utf8name = FilePath(name).AsUTF8Unsafe(); |
- bool inserted = fileset_.insert(FileInfo(utf8name, path)).second; |
+ FilePath normalized_path = path.NormalizePathSeparators(); |
+ bool inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; |
if (!inserted) { |
int suffix = 1; |
std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe(); |
@@ -64,98 +69,120 @@ std::string IsolatedContext::FileInfoSet::AddPath( |
utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++); |
if (!ext.empty()) |
utf8name.append(ext); |
- inserted = fileset_.insert(FileInfo(utf8name, path)).second; |
+ inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; |
} |
} |
- return utf8name; |
+ if (registered_name) |
+ *registered_name = utf8name; |
+ return true; |
} |
bool IsolatedContext::FileInfoSet::AddPathWithName( |
const FilePath& path, const std::string& name) { |
- return fileset_.insert(FileInfo(name, path)).second; |
+ // The given path should not contain any '..' and should be absolute. |
+ if (path.ReferencesParent() || !path.IsAbsolute()) |
+ return false; |
+ return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; |
} |
+//-------------------------------------------------------------------------- |
+ |
+IsolatedContext::Instance::Instance(FileSystemType type, |
+ const FileInfo& file_info) |
+ : type_(type), |
+ file_info_(file_info), |
+ ref_counts_(0) {} |
+ |
+IsolatedContext::Instance::Instance(const std::set<FileInfo>& dragged_files) |
+ : type_(kFileSystemTypeDragged), |
+ dragged_files_(dragged_files), |
+ ref_counts_(0) {} |
+ |
+bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, |
+ FilePath* path) { |
+ if (type_ != kFileSystemTypeDragged) { |
+ *path = file_info_.path; |
+ return (file_info_.name == name); |
+ } |
+ std::set<FileInfo>::const_iterator found = dragged_files_.find( |
+ FileInfo(name, FilePath())); |
+ if (found == dragged_files_.end()) |
+ return false; |
+ *path = found->path; |
+ return true; |
+} |
+ |
+//-------------------------------------------------------------------------- |
+ |
// static |
IsolatedContext* IsolatedContext::GetInstance() { |
return g_isolated_context.Pointer(); |
} |
-std::string IsolatedContext::RegisterFileSystem(const FileInfoSet& files) { |
+std::string IsolatedContext::RegisterDraggedFileSystem( |
+ const FileInfoSet& files) { |
base::AutoLock locker(lock_); |
std::string filesystem_id = GetNewFileSystemId(); |
- // Stores name to fullpath map, as we store the name as a key in |
- // the filesystem's toplevel entries. |
- FileSet toplevels; |
- for (std::set<FileInfo>::const_iterator iter = files.fileset().begin(); |
- iter != files.fileset().end(); |
- ++iter) { |
- const FileInfo& info = *iter; |
- // The given path should not contain any '..' and should be absolute. |
- if (info.path.ReferencesParent() || !info.path.IsAbsolute()) |
- continue; |
- |
- // Register the basename -> fullpath map. (We only expose the basename |
- // part to the user scripts) |
- FilePath fullpath = info.path.NormalizePathSeparators(); |
- const bool inserted = toplevels.insert( |
- FileInfo(info.name, fullpath)).second; |
- DCHECK(inserted); |
- } |
- |
- // TODO(kinuko): we may not want to register the file system if there're |
- // no valid paths in the given file set. |
- |
- toplevel_map_[filesystem_id] = toplevels; |
- |
- // Each file system is created with refcount == 0. |
- ref_counts_[filesystem_id] = 0; |
- |
+ instance_map_[filesystem_id] = new Instance(files.fileset()); |
return filesystem_id; |
} |
-std::string IsolatedContext::RegisterFileSystemForFile( |
+std::string IsolatedContext::RegisterFileSystemForPath( |
+ FileSystemType type, |
const FilePath& path, |
std::string* register_name) { |
- FileInfoSet files; |
+ DCHECK(!path.ReferencesParent() && path.IsAbsolute()); |
+ std::string name; |
if (register_name && !register_name->empty()) { |
- const bool added = files.AddPathWithName(path, *register_name); |
- DCHECK(added); |
+ name = *register_name; |
} else { |
- std::string name = files.AddPath(path); |
+ name = GetRegisterNameForPath(path); |
if (register_name) |
register_name->assign(name); |
} |
- return RegisterFileSystem(files); |
+ |
+ base::AutoLock locker(lock_); |
+ std::string filesystem_id = GetNewFileSystemId(); |
+ instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); |
+ return filesystem_id; |
} |
void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { |
base::AutoLock locker(lock_); |
- RevokeWithoutLocking(filesystem_id); |
+ IDToInstance::iterator found = instance_map_.find(filesystem_id); |
+ if (found == instance_map_.end()) |
+ return; |
+ delete found->second; |
+ instance_map_.erase(found); |
} |
void IsolatedContext::AddReference(const std::string& filesystem_id) { |
base::AutoLock locker(lock_); |
- DCHECK(ref_counts_.find(filesystem_id) != ref_counts_.end()); |
- ref_counts_[filesystem_id]++; |
+ DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); |
+ instance_map_[filesystem_id]->AddRef(); |
} |
void IsolatedContext::RemoveReference(const std::string& filesystem_id) { |
base::AutoLock locker(lock_); |
// This could get called for non-existent filesystem if it has been |
// already deleted by RevokeFileSystem. |
- if (ref_counts_.find(filesystem_id) == ref_counts_.end()) |
+ IDToInstance::iterator found = instance_map_.find(filesystem_id); |
+ if (found == instance_map_.end()) |
return; |
- DCHECK(ref_counts_[filesystem_id] > 0); |
- if (--ref_counts_[filesystem_id] == 0) |
- RevokeWithoutLocking(filesystem_id); |
+ DCHECK(found->second->ref_counts() > 0); |
+ found->second->RemoveRef(); |
+ if (found->second->ref_counts() == 0) { |
+ delete found->second; |
+ instance_map_.erase(found); |
+ } |
} |
bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
std::string* filesystem_id, |
FileInfo* root_info, |
- FilePath* platform_path) const { |
+ FilePath* path) const { |
DCHECK(filesystem_id); |
- DCHECK(platform_path); |
+ DCHECK(path); |
// This should not contain any '..' references. |
if (virtual_path.ReferencesParent()) |
@@ -171,36 +198,48 @@ bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
std::string fsid = FilePath(components[0]).MaybeAsASCII(); |
if (fsid.empty()) |
return false; |
- IDToFileSet::const_iterator found_toplevels = toplevel_map_.find(fsid); |
- if (found_toplevels == toplevel_map_.end()) |
+ IDToInstance::const_iterator found_instance = instance_map_.find(fsid); |
+ if (found_instance == instance_map_.end()) |
return false; |
*filesystem_id = fsid; |
if (components.size() == 1) { |
- platform_path->clear(); |
+ path->clear(); |
return true; |
} |
- // components[1] should be a name of the dropped paths. |
- FileSet::const_iterator found = found_toplevels->second.find( |
- FileInfo(FilePath(components[1]).AsUTF8Unsafe(), FilePath())); |
- if (found == found_toplevels->second.end()) |
+ // components[1] should be a name of the registered paths. |
+ FilePath cracked_path; |
+ std::string name = FilePath(components[1]).AsUTF8Unsafe(); |
+ if (!found_instance->second->ResolvePathForName(name, &cracked_path)) |
return false; |
if (root_info) |
- *root_info = *found; |
- FilePath path = found->path; |
+ *root_info = FileInfo(name, cracked_path); |
for (size_t i = 2; i < components.size(); ++i) |
- path = path.Append(components[i]); |
- *platform_path = path; |
+ cracked_path = cracked_path.Append(components[i]); |
+ *path = cracked_path; |
return true; |
} |
-bool IsolatedContext::GetRegisteredFileInfo( |
+bool IsolatedContext::GetDraggedFileInfo( |
const std::string& filesystem_id, std::vector<FileInfo>* files) const { |
DCHECK(files); |
base::AutoLock locker(lock_); |
- IDToFileSet::const_iterator found = toplevel_map_.find(filesystem_id); |
- if (found == toplevel_map_.end()) |
+ IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
+ if (found == instance_map_.end() || |
+ found->second->type() != kFileSystemTypeDragged) |
return false; |
- files->assign(found->second.begin(), found->second.end()); |
+ files->assign(found->second->dragged_files().begin(), |
+ found->second->dragged_files().end()); |
+ return true; |
+} |
+ |
+bool IsolatedContext::GetRegisteredPath( |
+ const std::string& filesystem_id, FilePath* path) const { |
+ DCHECK(path); |
+ base::AutoLock locker(lock_); |
+ IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
+ if (found == instance_map_.end() || found->second->type() == kFileSystemTypeDragged) |
+ return false; |
+ *path = found->second->file_info().path; |
return true; |
} |
@@ -213,12 +252,8 @@ IsolatedContext::IsolatedContext() { |
} |
IsolatedContext::~IsolatedContext() { |
-} |
- |
-void IsolatedContext::RevokeWithoutLocking( |
- const std::string& filesystem_id) { |
- toplevel_map_.erase(filesystem_id); |
- ref_counts_.erase(filesystem_id); |
+ STLDeleteContainerPairSecondPointers(instance_map_.begin(), |
+ instance_map_.end()); |
} |
std::string IsolatedContext::GetNewFileSystemId() const { |
@@ -228,7 +263,7 @@ std::string IsolatedContext::GetNewFileSystemId() const { |
do { |
base::RandBytes(random_data, sizeof(random_data)); |
id = base::HexEncode(random_data, sizeof(random_data)); |
- } while (toplevel_map_.find(id) != toplevel_map_.end()); |
+ } while (instance_map_.find(id) != instance_map_.end()); |
return id; |
} |