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

Side by Side Diff: webkit/fileapi/isolated_context.cc

Issue 10817006: Add more FS types and introduce type field into IsolatedContext (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/fileapi/isolated_context.h ('k') | webkit/fileapi/isolated_context_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/stl_util.h"
11 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
12 #include "base/string_util.h" 13 #include "base/string_util.h"
13 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
14 15
15 namespace fileapi { 16 namespace fileapi {
16 17
17 namespace { 18 namespace {
18 19
19 FilePath::StringType GetRegisterNameForPath(const FilePath& path) { 20 FilePath::StringType GetRegisterNameForPath(const FilePath& path) {
20 // If it's not a root path simply return a base name. 21 // If it's not a root path simply return a base name.
(...skipping 23 matching lines...) Expand all
44 LAZY_INSTANCE_INITIALIZER; 45 LAZY_INSTANCE_INITIALIZER;
45 46
46 IsolatedContext::FileInfo::FileInfo() {} 47 IsolatedContext::FileInfo::FileInfo() {}
47 IsolatedContext::FileInfo::FileInfo( 48 IsolatedContext::FileInfo::FileInfo(
48 const std::string& name, const FilePath& path) 49 const std::string& name, const FilePath& path)
49 : name(name), path(path) {} 50 : name(name), path(path) {}
50 51
51 IsolatedContext::FileInfoSet::FileInfoSet() {} 52 IsolatedContext::FileInfoSet::FileInfoSet() {}
52 IsolatedContext::FileInfoSet::~FileInfoSet() {} 53 IsolatedContext::FileInfoSet::~FileInfoSet() {}
53 54
54 std::string IsolatedContext::FileInfoSet::AddPath( 55 bool IsolatedContext::FileInfoSet::AddPath(
55 const FilePath& path) { 56 const FilePath& path, std::string* registered_name) {
57 // The given path should not contain any '..' and should be absolute.
58 if (path.ReferencesParent() || !path.IsAbsolute())
59 return false;
56 FilePath::StringType name = GetRegisterNameForPath(path); 60 FilePath::StringType name = GetRegisterNameForPath(path);
57 std::string utf8name = FilePath(name).AsUTF8Unsafe(); 61 std::string utf8name = FilePath(name).AsUTF8Unsafe();
58 bool inserted = fileset_.insert(FileInfo(utf8name, path)).second; 62 FilePath normalized_path = path.NormalizePathSeparators();
63 bool inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second;
59 if (!inserted) { 64 if (!inserted) {
60 int suffix = 1; 65 int suffix = 1;
61 std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe(); 66 std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe();
62 std::string ext = FilePath(FilePath(name).Extension()).AsUTF8Unsafe(); 67 std::string ext = FilePath(FilePath(name).Extension()).AsUTF8Unsafe();
63 while (!inserted) { 68 while (!inserted) {
64 utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++); 69 utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++);
65 if (!ext.empty()) 70 if (!ext.empty())
66 utf8name.append(ext); 71 utf8name.append(ext);
67 inserted = fileset_.insert(FileInfo(utf8name, path)).second; 72 inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second;
68 } 73 }
69 } 74 }
70 return utf8name; 75 if (registered_name)
76 *registered_name = utf8name;
77 return true;
71 } 78 }
72 79
73 bool IsolatedContext::FileInfoSet::AddPathWithName( 80 bool IsolatedContext::FileInfoSet::AddPathWithName(
74 const FilePath& path, const std::string& name) { 81 const FilePath& path, const std::string& name) {
75 return fileset_.insert(FileInfo(name, path)).second; 82 // The given path should not contain any '..' and should be absolute.
83 if (path.ReferencesParent() || !path.IsAbsolute())
84 return false;
85 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second;
76 } 86 }
77 87
88 //--------------------------------------------------------------------------
89
90 IsolatedContext::Instance::Instance(FileSystemType type,
91 const FileInfo& file_info)
92 : type_(type),
93 file_info_(file_info),
94 ref_counts_(0) {}
95
96 IsolatedContext::Instance::Instance(const std::set<FileInfo>& dragged_files)
97 : type_(kFileSystemTypeDragged),
98 dragged_files_(dragged_files),
99 ref_counts_(0) {}
100
101 IsolatedContext::Instance::~Instance() {}
102
103 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name,
104 FilePath* path) {
105 if (type_ != kFileSystemTypeDragged) {
106 *path = file_info_.path;
107 return file_info_.name == name;
108 }
109 std::set<FileInfo>::const_iterator found = dragged_files_.find(
110 FileInfo(name, FilePath()));
111 if (found == dragged_files_.end())
112 return false;
113 *path = found->path;
114 return true;
115 }
116
117 //--------------------------------------------------------------------------
118
78 // static 119 // static
79 IsolatedContext* IsolatedContext::GetInstance() { 120 IsolatedContext* IsolatedContext::GetInstance() {
80 return g_isolated_context.Pointer(); 121 return g_isolated_context.Pointer();
81 } 122 }
82 123
83 std::string IsolatedContext::RegisterFileSystem(const FileInfoSet& files) { 124 std::string IsolatedContext::RegisterDraggedFileSystem(
125 const FileInfoSet& files) {
84 base::AutoLock locker(lock_); 126 base::AutoLock locker(lock_);
85 std::string filesystem_id = GetNewFileSystemId(); 127 std::string filesystem_id = GetNewFileSystemId();
86 // Stores name to fullpath map, as we store the name as a key in 128 instance_map_[filesystem_id] = new Instance(files.fileset());
87 // the filesystem's toplevel entries.
88 FileSet toplevels;
89 for (std::set<FileInfo>::const_iterator iter = files.fileset().begin();
90 iter != files.fileset().end();
91 ++iter) {
92 const FileInfo& info = *iter;
93 // The given path should not contain any '..' and should be absolute.
94 if (info.path.ReferencesParent() || !info.path.IsAbsolute())
95 continue;
96
97 // Register the basename -> fullpath map. (We only expose the basename
98 // part to the user scripts)
99 FilePath fullpath = info.path.NormalizePathSeparators();
100 const bool inserted = toplevels.insert(
101 FileInfo(info.name, fullpath)).second;
102 DCHECK(inserted);
103 }
104
105 // TODO(kinuko): we may not want to register the file system if there're
106 // no valid paths in the given file set.
107
108 toplevel_map_[filesystem_id] = toplevels;
109
110 // Each file system is created with refcount == 0.
111 ref_counts_[filesystem_id] = 0;
112
113 return filesystem_id; 129 return filesystem_id;
114 } 130 }
115 131
116 std::string IsolatedContext::RegisterFileSystemForFile( 132 std::string IsolatedContext::RegisterFileSystemForPath(
133 FileSystemType type,
117 const FilePath& path, 134 const FilePath& path,
118 std::string* register_name) { 135 std::string* register_name) {
119 FileInfoSet files; 136 DCHECK(!path.ReferencesParent() && path.IsAbsolute());
137 std::string name;
120 if (register_name && !register_name->empty()) { 138 if (register_name && !register_name->empty()) {
121 const bool added = files.AddPathWithName(path, *register_name); 139 name = *register_name;
122 DCHECK(added);
123 } else { 140 } else {
124 std::string name = files.AddPath(path); 141 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe();
125 if (register_name) 142 if (register_name)
126 register_name->assign(name); 143 register_name->assign(name);
127 } 144 }
128 return RegisterFileSystem(files); 145
146 base::AutoLock locker(lock_);
147 std::string filesystem_id = GetNewFileSystemId();
148 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path));
149 return filesystem_id;
129 } 150 }
130 151
131 void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { 152 void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
132 base::AutoLock locker(lock_); 153 base::AutoLock locker(lock_);
133 RevokeWithoutLocking(filesystem_id); 154 IDToInstance::iterator found = instance_map_.find(filesystem_id);
155 if (found == instance_map_.end())
156 return;
157 delete found->second;
158 instance_map_.erase(found);
134 } 159 }
135 160
136 void IsolatedContext::AddReference(const std::string& filesystem_id) { 161 void IsolatedContext::AddReference(const std::string& filesystem_id) {
137 base::AutoLock locker(lock_); 162 base::AutoLock locker(lock_);
138 DCHECK(ref_counts_.find(filesystem_id) != ref_counts_.end()); 163 DCHECK(instance_map_.find(filesystem_id) != instance_map_.end());
139 ref_counts_[filesystem_id]++; 164 instance_map_[filesystem_id]->AddRef();
140 } 165 }
141 166
142 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { 167 void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
143 base::AutoLock locker(lock_); 168 base::AutoLock locker(lock_);
144 // This could get called for non-existent filesystem if it has been 169 // This could get called for non-existent filesystem if it has been
145 // already deleted by RevokeFileSystem. 170 // already deleted by RevokeFileSystem.
146 if (ref_counts_.find(filesystem_id) == ref_counts_.end()) 171 IDToInstance::iterator found = instance_map_.find(filesystem_id);
172 if (found == instance_map_.end())
147 return; 173 return;
148 DCHECK(ref_counts_[filesystem_id] > 0); 174 DCHECK(found->second->ref_counts() > 0);
149 if (--ref_counts_[filesystem_id] == 0) 175 found->second->RemoveRef();
150 RevokeWithoutLocking(filesystem_id); 176 if (found->second->ref_counts() == 0) {
177 delete found->second;
178 instance_map_.erase(found);
179 }
151 } 180 }
152 181
153 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, 182 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path,
154 std::string* filesystem_id, 183 std::string* filesystem_id,
155 FileInfo* root_info, 184 FileInfo* root_info,
156 FilePath* platform_path) const { 185 FilePath* path) const {
157 DCHECK(filesystem_id); 186 DCHECK(filesystem_id);
158 DCHECK(platform_path); 187 DCHECK(path);
159 188
160 // This should not contain any '..' references. 189 // This should not contain any '..' references.
161 if (virtual_path.ReferencesParent()) 190 if (virtual_path.ReferencesParent())
162 return false; 191 return false;
163 192
164 // The virtual_path should comprise <filesystem_id> and <relative_path> parts. 193 // The virtual_path should comprise <filesystem_id> and <relative_path> parts.
165 std::vector<FilePath::StringType> components; 194 std::vector<FilePath::StringType> components;
166 virtual_path.GetComponents(&components); 195 virtual_path.GetComponents(&components);
167 if (components.size() < 1) 196 if (components.size() < 1)
168 return false; 197 return false;
169 198
170 base::AutoLock locker(lock_); 199 base::AutoLock locker(lock_);
171 std::string fsid = FilePath(components[0]).MaybeAsASCII(); 200 std::string fsid = FilePath(components[0]).MaybeAsASCII();
172 if (fsid.empty()) 201 if (fsid.empty())
173 return false; 202 return false;
174 IDToFileSet::const_iterator found_toplevels = toplevel_map_.find(fsid); 203 IDToInstance::const_iterator found_instance = instance_map_.find(fsid);
175 if (found_toplevels == toplevel_map_.end()) 204 if (found_instance == instance_map_.end())
176 return false; 205 return false;
177 *filesystem_id = fsid; 206 *filesystem_id = fsid;
178 if (components.size() == 1) { 207 if (components.size() == 1) {
179 platform_path->clear(); 208 path->clear();
180 return true; 209 return true;
181 } 210 }
182 // components[1] should be a name of the dropped paths. 211 // components[1] should be a name of the registered paths.
183 FileSet::const_iterator found = found_toplevels->second.find( 212 FilePath cracked_path;
184 FileInfo(FilePath(components[1]).AsUTF8Unsafe(), FilePath())); 213 std::string name = FilePath(components[1]).AsUTF8Unsafe();
185 if (found == found_toplevels->second.end()) 214 if (!found_instance->second->ResolvePathForName(name, &cracked_path))
186 return false; 215 return false;
187 if (root_info) 216 if (root_info)
188 *root_info = *found; 217 *root_info = FileInfo(name, cracked_path);
189 FilePath path = found->path;
190 for (size_t i = 2; i < components.size(); ++i) 218 for (size_t i = 2; i < components.size(); ++i)
191 path = path.Append(components[i]); 219 cracked_path = cracked_path.Append(components[i]);
192 *platform_path = path; 220 *path = cracked_path;
193 return true; 221 return true;
194 } 222 }
195 223
196 bool IsolatedContext::GetRegisteredFileInfo( 224 bool IsolatedContext::GetDraggedFileInfo(
197 const std::string& filesystem_id, std::vector<FileInfo>* files) const { 225 const std::string& filesystem_id, std::vector<FileInfo>* files) const {
198 DCHECK(files); 226 DCHECK(files);
199 base::AutoLock locker(lock_); 227 base::AutoLock locker(lock_);
200 IDToFileSet::const_iterator found = toplevel_map_.find(filesystem_id); 228 IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
201 if (found == toplevel_map_.end()) 229 if (found == instance_map_.end() ||
230 found->second->type() != kFileSystemTypeDragged)
202 return false; 231 return false;
203 files->assign(found->second.begin(), found->second.end()); 232 files->assign(found->second->dragged_files().begin(),
233 found->second->dragged_files().end());
204 return true; 234 return true;
205 } 235 }
206 236
237 bool IsolatedContext::GetRegisteredPath(
238 const std::string& filesystem_id, FilePath* path) const {
239 DCHECK(path);
240 base::AutoLock locker(lock_);
241 IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
242 if (found == instance_map_.end() || found->second->type() == kFileSystemTypeDr agged)
243 return false;
244 *path = found->second->file_info().path;
245 return true;
246 }
247
207 FilePath IsolatedContext::CreateVirtualRootPath( 248 FilePath IsolatedContext::CreateVirtualRootPath(
208 const std::string& filesystem_id) const { 249 const std::string& filesystem_id) const {
209 return FilePath().AppendASCII(filesystem_id); 250 return FilePath().AppendASCII(filesystem_id);
210 } 251 }
211 252
212 IsolatedContext::IsolatedContext() { 253 IsolatedContext::IsolatedContext() {
213 } 254 }
214 255
215 IsolatedContext::~IsolatedContext() { 256 IsolatedContext::~IsolatedContext() {
216 } 257 STLDeleteContainerPairSecondPointers(instance_map_.begin(),
217 258 instance_map_.end());
218 void IsolatedContext::RevokeWithoutLocking(
219 const std::string& filesystem_id) {
220 toplevel_map_.erase(filesystem_id);
221 ref_counts_.erase(filesystem_id);
222 } 259 }
223 260
224 std::string IsolatedContext::GetNewFileSystemId() const { 261 std::string IsolatedContext::GetNewFileSystemId() const {
225 // Returns an arbitrary random string which must be unique in the map. 262 // Returns an arbitrary random string which must be unique in the map.
226 uint32 random_data[4]; 263 uint32 random_data[4];
227 std::string id; 264 std::string id;
228 do { 265 do {
229 base::RandBytes(random_data, sizeof(random_data)); 266 base::RandBytes(random_data, sizeof(random_data));
230 id = base::HexEncode(random_data, sizeof(random_data)); 267 id = base::HexEncode(random_data, sizeof(random_data));
231 } while (toplevel_map_.find(id) != toplevel_map_.end()); 268 } while (instance_map_.find(id) != instance_map_.end());
232 return id; 269 return id;
233 } 270 }
234 271
235 } // namespace fileapi 272 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/isolated_context.h ('k') | webkit/fileapi/isolated_context_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698