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 "webkit/fileapi/isolated_context.h" | 5 #include "webkit/fileapi/isolated_context.h" |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 if (path.ReferencesParent() || !path.IsAbsolute()) | 83 if (path.ReferencesParent() || !path.IsAbsolute()) |
84 return false; | 84 return false; |
85 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; | 85 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; |
86 } | 86 } |
87 | 87 |
88 //-------------------------------------------------------------------------- | 88 //-------------------------------------------------------------------------- |
89 | 89 |
90 IsolatedContext::Instance::Instance(FileSystemType type, | 90 IsolatedContext::Instance::Instance(FileSystemType type, |
91 const FileInfo& file_info) | 91 const FileInfo& file_info) |
92 : type_(type), | 92 : type_(type), |
| 93 instance_type_(kSinglePathInstance), |
93 file_info_(file_info), | 94 file_info_(file_info), |
94 ref_counts_(0) {} | 95 ref_counts_(0) {} |
95 | 96 |
96 IsolatedContext::Instance::Instance(const std::set<FileInfo>& dragged_files) | 97 IsolatedContext::Instance::Instance(FileSystemType type, |
97 : type_(kFileSystemTypeDragged), | 98 const std::set<FileInfo>& files) |
98 dragged_files_(dragged_files), | 99 : type_(type), |
| 100 instance_type_(kMultiplePathInstance), |
| 101 files_(files), |
99 ref_counts_(0) {} | 102 ref_counts_(0) {} |
100 | 103 |
101 IsolatedContext::Instance::~Instance() {} | 104 IsolatedContext::Instance::~Instance() {} |
102 | 105 |
103 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, | 106 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, |
104 FilePath* path) { | 107 FilePath* path) const { |
105 if (type_ != kFileSystemTypeDragged) { | 108 if (instance_type_ == kSinglePathInstance) { |
106 *path = file_info_.path; | 109 *path = file_info_.path; |
107 return file_info_.name == name; | 110 return file_info_.name == name; |
108 } | 111 } |
109 std::set<FileInfo>::const_iterator found = dragged_files_.find( | 112 std::set<FileInfo>::const_iterator found = files_.find( |
110 FileInfo(name, FilePath())); | 113 FileInfo(name, FilePath())); |
111 if (found == dragged_files_.end()) | 114 if (found == files_.end()) |
112 return false; | 115 return false; |
113 *path = found->path; | 116 *path = found->path; |
114 return true; | 117 return true; |
115 } | 118 } |
116 | 119 |
117 //-------------------------------------------------------------------------- | 120 //-------------------------------------------------------------------------- |
118 | 121 |
119 // static | 122 // static |
120 IsolatedContext* IsolatedContext::GetInstance() { | 123 IsolatedContext* IsolatedContext::GetInstance() { |
121 return g_isolated_context.Pointer(); | 124 return g_isolated_context.Pointer(); |
122 } | 125 } |
123 | 126 |
124 std::string IsolatedContext::RegisterDraggedFileSystem( | 127 std::string IsolatedContext::RegisterDraggedFileSystem( |
125 const FileInfoSet& files) { | 128 const FileInfoSet& files) { |
126 base::AutoLock locker(lock_); | 129 base::AutoLock locker(lock_); |
127 std::string filesystem_id = GetNewFileSystemId(); | 130 std::string filesystem_id = GetNewFileSystemId(); |
128 instance_map_[filesystem_id] = new Instance(files.fileset()); | 131 instance_map_[filesystem_id] = new Instance( |
| 132 kFileSystemTypeDragged, files.fileset()); |
129 return filesystem_id; | 133 return filesystem_id; |
130 } | 134 } |
131 | 135 |
132 std::string IsolatedContext::RegisterFileSystemForPath( | 136 std::string IsolatedContext::RegisterFileSystemForPath( |
133 FileSystemType type, | 137 FileSystemType type, |
134 const FilePath& path, | 138 const FilePath& path, |
135 std::string* register_name) { | 139 std::string* register_name) { |
136 DCHECK(!path.ReferencesParent() && path.IsAbsolute()); | 140 DCHECK(!path.ReferencesParent() && path.IsAbsolute()); |
137 std::string name; | 141 std::string name; |
138 if (register_name && !register_name->empty()) { | 142 if (register_name && !register_name->empty()) { |
139 name = *register_name; | 143 name = *register_name; |
140 } else { | 144 } else { |
141 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); | 145 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); |
142 if (register_name) | 146 if (register_name) |
143 register_name->assign(name); | 147 register_name->assign(name); |
144 } | 148 } |
145 | 149 |
146 base::AutoLock locker(lock_); | 150 base::AutoLock locker(lock_); |
147 std::string filesystem_id = GetNewFileSystemId(); | 151 std::string filesystem_id = GetNewFileSystemId(); |
148 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); | 152 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); |
| 153 path_to_id_map_[path].insert(filesystem_id); |
149 return filesystem_id; | 154 return filesystem_id; |
150 } | 155 } |
151 | 156 |
152 void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { | 157 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path) { |
153 base::AutoLock locker(lock_); | 158 base::AutoLock locker(lock_); |
154 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 159 PathToID::iterator ids_iter = path_to_id_map_.find(path); |
155 if (found == instance_map_.end()) | 160 if (ids_iter == path_to_id_map_.end()) |
156 return; | 161 return; |
157 delete found->second; | 162 std::set<std::string>& ids = ids_iter->second; |
158 instance_map_.erase(found); | 163 for (std::set<std::string>::iterator iter = ids.begin(); |
| 164 iter != ids.end(); ++iter) { |
| 165 IDToInstance::iterator found = instance_map_.find(*iter); |
| 166 if (found != instance_map_.end()) { |
| 167 delete found->second; |
| 168 instance_map_.erase(found); |
| 169 } |
| 170 } |
| 171 path_to_id_map_.erase(ids_iter); |
159 } | 172 } |
160 | 173 |
161 void IsolatedContext::AddReference(const std::string& filesystem_id) { | 174 void IsolatedContext::AddReference(const std::string& filesystem_id) { |
162 base::AutoLock locker(lock_); | 175 base::AutoLock locker(lock_); |
163 DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); | 176 DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); |
164 instance_map_[filesystem_id]->AddRef(); | 177 instance_map_[filesystem_id]->AddRef(); |
165 } | 178 } |
166 | 179 |
167 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { | 180 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { |
168 base::AutoLock locker(lock_); | 181 base::AutoLock locker(lock_); |
169 // This could get called for non-existent filesystem if it has been | 182 // This could get called for non-existent filesystem if it has been |
170 // already deleted by RevokeFileSystem. | 183 // already deleted by RevokeFileSystemByPath. |
171 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 184 IDToInstance::iterator found = instance_map_.find(filesystem_id); |
172 if (found == instance_map_.end()) | 185 if (found == instance_map_.end()) |
173 return; | 186 return; |
174 DCHECK(found->second->ref_counts() > 0); | 187 Instance* instance = found->second; |
175 found->second->RemoveRef(); | 188 DCHECK(instance->ref_counts() > 0); |
176 if (found->second->ref_counts() == 0) { | 189 instance->RemoveRef(); |
177 delete found->second; | 190 if (instance->ref_counts() == 0) { |
| 191 if (instance->IsSinglePathInstance()) { |
| 192 PathToID::iterator ids_iter = path_to_id_map_.find( |
| 193 instance->file_info().path); |
| 194 DCHECK(ids_iter != path_to_id_map_.end()); |
| 195 ids_iter->second.erase(filesystem_id); |
| 196 if (ids_iter->second.empty()) |
| 197 path_to_id_map_.erase(ids_iter); |
| 198 } |
| 199 delete instance; |
178 instance_map_.erase(found); | 200 instance_map_.erase(found); |
179 } | 201 } |
180 } | 202 } |
181 | 203 |
182 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, | 204 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
183 std::string* filesystem_id, | 205 std::string* filesystem_id, |
184 FileSystemType* type, | 206 FileSystemType* type, |
185 FilePath* path) const { | 207 FilePath* path) const { |
186 DCHECK(filesystem_id); | 208 DCHECK(filesystem_id); |
187 DCHECK(path); | 209 DCHECK(path); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 } | 244 } |
223 | 245 |
224 bool IsolatedContext::GetDraggedFileInfo( | 246 bool IsolatedContext::GetDraggedFileInfo( |
225 const std::string& filesystem_id, std::vector<FileInfo>* files) const { | 247 const std::string& filesystem_id, std::vector<FileInfo>* files) const { |
226 DCHECK(files); | 248 DCHECK(files); |
227 base::AutoLock locker(lock_); | 249 base::AutoLock locker(lock_); |
228 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 250 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
229 if (found == instance_map_.end() || | 251 if (found == instance_map_.end() || |
230 found->second->type() != kFileSystemTypeDragged) | 252 found->second->type() != kFileSystemTypeDragged) |
231 return false; | 253 return false; |
232 files->assign(found->second->dragged_files().begin(), | 254 files->assign(found->second->files().begin(), |
233 found->second->dragged_files().end()); | 255 found->second->files().end()); |
234 return true; | 256 return true; |
235 } | 257 } |
236 | 258 |
237 bool IsolatedContext::GetRegisteredPath( | 259 bool IsolatedContext::GetRegisteredPath( |
238 const std::string& filesystem_id, FilePath* path) const { | 260 const std::string& filesystem_id, FilePath* path) const { |
239 DCHECK(path); | 261 DCHECK(path); |
240 base::AutoLock locker(lock_); | 262 base::AutoLock locker(lock_); |
241 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 263 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
242 if (found == instance_map_.end() || | 264 if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) |
243 found->second->type() == kFileSystemTypeDragged) | |
244 return false; | 265 return false; |
245 *path = found->second->file_info().path; | 266 *path = found->second->file_info().path; |
246 return true; | 267 return true; |
247 } | 268 } |
248 | 269 |
249 FilePath IsolatedContext::CreateVirtualRootPath( | 270 FilePath IsolatedContext::CreateVirtualRootPath( |
250 const std::string& filesystem_id) const { | 271 const std::string& filesystem_id) const { |
251 return FilePath().AppendASCII(filesystem_id); | 272 return FilePath().AppendASCII(filesystem_id); |
252 } | 273 } |
253 | 274 |
(...skipping 10 matching lines...) Expand all Loading... |
264 uint32 random_data[4]; | 285 uint32 random_data[4]; |
265 std::string id; | 286 std::string id; |
266 do { | 287 do { |
267 base::RandBytes(random_data, sizeof(random_data)); | 288 base::RandBytes(random_data, sizeof(random_data)); |
268 id = base::HexEncode(random_data, sizeof(random_data)); | 289 id = base::HexEncode(random_data, sizeof(random_data)); |
269 } while (instance_map_.find(id) != instance_map_.end()); | 290 } while (instance_map_.find(id) != instance_map_.end()); |
270 return id; | 291 return id; |
271 } | 292 } |
272 | 293 |
273 } // namespace fileapi | 294 } // namespace fileapi |
OLD | NEW |