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

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

Issue 10713007: Make isolated file system works for a device root (e.g. X:\\) (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
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/basictypes.h" 8 #include "base/basictypes.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/rand_util.h" 10 #include "base/rand_util.h"
10 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
11 #include "base/string_util.h" 12 #include "base/string_util.h"
12 13
13 namespace fileapi { 14 namespace fileapi {
14 15
15 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = 16 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context =
16 LAZY_INSTANCE_INITIALIZER; 17 LAZY_INSTANCE_INITIALIZER;
17 18
19 IsolatedContext::FileInfo::FileInfo() {}
20 IsolatedContext::FileInfo::FileInfo(
21 const std::string& name, const FilePath& path)
22 : name(name), path(path) {}
23
18 // static 24 // static
19 IsolatedContext* IsolatedContext::GetInstance() { 25 IsolatedContext* IsolatedContext::GetInstance() {
20 return g_isolated_context.Pointer(); 26 return g_isolated_context.Pointer();
21 } 27 }
22 28
23 std::string IsolatedContext::RegisterIsolatedFileSystem( 29 std::string IsolatedContext::GetNameForPath(const FilePath& path) {
24 const std::set<FilePath>& files) { 30 // If it's not a root path simply return a base name.
31 if (path.DirName() != path)
32 return path.BaseName().AsUTF8Unsafe();
33
34 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
35 FilePath::StringType name;
36 for (size_t i = 0;
37 i < path.value().size() && !FilePath::IsSeparator(path.value()[i]);
38 ++i) {
39 if (path.value()[i] == L':') {
40 name.append(L"_drive");
41 break;
42 }
43 name.append(1, path.value()[i]);
44 }
45 return FilePath(name).AsUTF8Unsafe();
46 #else
47 return "<root>";
48 #endif
49 }
50
51 std::string IsolatedContext::RegisterFileSystem(
52 const std::vector<FileInfo>& files) {
25 base::AutoLock locker(lock_); 53 base::AutoLock locker(lock_);
26 std::string filesystem_id = GetNewFileSystemId(); 54 std::string filesystem_id = GetNewFileSystemId();
27 // Stores basename to fullpath map, as we store the basenames as 55 // Stores name to fullpath map, as we store the name as a key in
28 // the filesystem's toplevel entries. 56 // the filesystem's toplevel entries.
29 PathMap toplevels; 57 FileMap toplevels;
30 for (std::set<FilePath>::const_iterator iter = files.begin(); 58 for (size_t i = 0; i < files.size(); ++i) {
31 iter != files.end(); ++iter) { 59 const FileInfo& info = files[i];
32 // The given path should not contain any '..' and should be absolute. 60 // The given path should not contain any '..' and should be absolute.
33 if (iter->ReferencesParent() || !iter->IsAbsolute()) 61 if (info.path.ReferencesParent() || !info.path.IsAbsolute())
34 continue; 62 continue;
35 63
36 // Register the basename -> fullpath map. (We only expose the basename 64 // Register the basename -> fullpath map. (We only expose the basename
37 // part to the user scripts) 65 // part to the user scripts)
38 FilePath fullpath = iter->NormalizePathSeparators(); 66 FilePath fullpath = info.path.NormalizePathSeparators();
39 FilePath basename = iter->BaseName(); 67 toplevels.insert(std::make_pair(info.name, FileInfo(info.name, fullpath)));
40 // TODO(kinuko): Append a suffix or something if we have multiple pathnames
41 // with the same basename. For now we only register the first one.
42 toplevels.insert(std::make_pair(basename, fullpath));
43 } 68 }
44 69
45 // TODO(kinuko): we may not want to register the file system if there're 70 // TODO(kinuko): we may not want to register the file system if there're
46 // no valid paths in the given file set. 71 // no valid paths in the given file set.
47 72
48 toplevel_map_[filesystem_id] = toplevels; 73 toplevel_map_[filesystem_id] = toplevels;
49 74
50 // Each file system is created with refcount == 0. 75 // Each file system is created with refcount == 0.
51 ref_counts_[filesystem_id] = 0; 76 ref_counts_[filesystem_id] = 0;
52 77
53 return filesystem_id; 78 return filesystem_id;
54 } 79 }
55 80
56 void IsolatedContext::RevokeIsolatedFileSystem( 81 std::string IsolatedContext::RegisterFileSystemForFile(
57 const std::string& filesystem_id) { 82 const std::string& display_name,
83 const FilePath& path) {
84 std::vector<FileInfo> files;
85 files.push_back(FileInfo(display_name, path));
86 return RegisterFileSystem(files);
87 }
88
89 void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
58 base::AutoLock locker(lock_); 90 base::AutoLock locker(lock_);
59 RevokeWithoutLocking(filesystem_id); 91 RevokeWithoutLocking(filesystem_id);
60 } 92 }
61 93
62 void IsolatedContext::AddReference(const std::string& filesystem_id) { 94 void IsolatedContext::AddReference(const std::string& filesystem_id) {
63 base::AutoLock locker(lock_); 95 base::AutoLock locker(lock_);
64 DCHECK(ref_counts_.find(filesystem_id) != ref_counts_.end()); 96 DCHECK(ref_counts_.find(filesystem_id) != ref_counts_.end());
65 ref_counts_[filesystem_id]++; 97 ref_counts_[filesystem_id]++;
66 } 98 }
67 99
68 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { 100 void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
69 base::AutoLock locker(lock_); 101 base::AutoLock locker(lock_);
70 // This could get called for non-existent filesystem if it has been 102 // This could get called for non-existent filesystem if it has been
71 // already deleted by RevokeIsolatedFileSystem. 103 // already deleted by RevokeFileSystem.
72 if (ref_counts_.find(filesystem_id) == ref_counts_.end()) 104 if (ref_counts_.find(filesystem_id) == ref_counts_.end())
73 return; 105 return;
74 DCHECK(ref_counts_[filesystem_id] > 0); 106 DCHECK(ref_counts_[filesystem_id] > 0);
75 if (--ref_counts_[filesystem_id] == 0) 107 if (--ref_counts_[filesystem_id] == 0)
76 RevokeWithoutLocking(filesystem_id); 108 RevokeWithoutLocking(filesystem_id);
77 } 109 }
78 110
79 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, 111 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path,
80 std::string* filesystem_id, 112 std::string* filesystem_id,
81 FilePath* root_path, 113 FileInfo* root_info,
82 FilePath* platform_path) const { 114 FilePath* platform_path) const {
83 DCHECK(filesystem_id); 115 DCHECK(filesystem_id);
84 DCHECK(platform_path); 116 DCHECK(platform_path);
85 117
86 // This should not contain any '..' references. 118 // This should not contain any '..' references.
87 if (virtual_path.ReferencesParent()) 119 if (virtual_path.ReferencesParent())
88 return false; 120 return false;
89 121
90 // The virtual_path should comprise <filesystem_id> and <relative_path> parts. 122 // The virtual_path should comprise <filesystem_id> and <relative_path> parts.
91 std::vector<FilePath::StringType> components; 123 std::vector<FilePath::StringType> components;
92 virtual_path.GetComponents(&components); 124 virtual_path.GetComponents(&components);
93 if (components.size() < 1) 125 if (components.size() < 1)
94 return false; 126 return false;
95 127
96 base::AutoLock locker(lock_); 128 base::AutoLock locker(lock_);
97 std::string fsid = FilePath(components[0]).MaybeAsASCII(); 129 std::string fsid = FilePath(components[0]).MaybeAsASCII();
98 if (fsid.empty()) 130 if (fsid.empty())
99 return false; 131 return false;
100 IDToPathMap::const_iterator found_toplevels = toplevel_map_.find(fsid); 132 IDToFileMap::const_iterator found_toplevels = toplevel_map_.find(fsid);
101 if (found_toplevels == toplevel_map_.end()) 133 if (found_toplevels == toplevel_map_.end())
102 return false; 134 return false;
103 *filesystem_id = fsid; 135 *filesystem_id = fsid;
104 if (components.size() == 1) { 136 if (components.size() == 1) {
105 platform_path->clear(); 137 platform_path->clear();
106 return true; 138 return true;
107 } 139 }
108 // components[1] should be a toplevel path of the dropped paths. 140 // components[1] should be a display name of the dropped paths.
109 PathMap::const_iterator found = found_toplevels->second.find( 141 FileMap::const_iterator found = found_toplevels->second.find(
110 FilePath(components[1])); 142 FilePath(components[1]).AsUTF8Unsafe());
111 if (found == found_toplevels->second.end()) 143 if (found == found_toplevels->second.end())
112 return false; 144 return false;
113 FilePath path = found->second; 145 if (root_info)
114 if (root_path) 146 *root_info = found->second;
115 *root_path = path; 147 FilePath path = found->second.path;
116 for (size_t i = 2; i < components.size(); ++i) { 148 for (size_t i = 2; i < components.size(); ++i)
117 path = path.Append(components[i]); 149 path = path.Append(components[i]);
118 }
119 *platform_path = path; 150 *platform_path = path;
120 return true; 151 return true;
121 } 152 }
122 153
123 bool IsolatedContext::GetTopLevelPaths(const std::string& filesystem_id, 154 bool IsolatedContext::GetRegisteredFileInfo(
124 std::vector<FilePath>* paths) const { 155 const std::string& filesystem_id, std::vector<FileInfo>* files) const {
125 DCHECK(paths); 156 DCHECK(files);
126 base::AutoLock locker(lock_); 157 base::AutoLock locker(lock_);
127 IDToPathMap::const_iterator found = toplevel_map_.find(filesystem_id); 158 IDToFileMap::const_iterator found = toplevel_map_.find(filesystem_id);
128 if (found == toplevel_map_.end()) 159 if (found == toplevel_map_.end())
129 return false; 160 return false;
130 paths->clear(); 161 files->clear();
131 PathMap toplevels = found->second; 162 files->reserve(found->second.size());
132 for (PathMap::const_iterator iter = toplevels.begin(); 163 for (FileMap::const_iterator iter = found->second.begin();
133 iter != toplevels.end(); ++iter) { 164 iter != found->second.end();
134 // Each path map entry holds a map of a toplevel name to its full path. 165 iter++) {
135 paths->push_back(iter->second); 166 files->push_back(iter->second);
136 } 167 }
tzik 2012/06/29 02:56:35 We can use std::vector::assign if we use std::set
kinuko 2012/06/29 08:31:22 Done.
137 return true; 168 return true;
138 } 169 }
139 170
140 bool IsolatedContext::SetWritable(const std::string& filesystem_id, 171 bool IsolatedContext::SetWritable(const std::string& filesystem_id,
141 bool writable) { 172 bool writable) {
142 base::AutoLock locker(lock_); 173 base::AutoLock locker(lock_);
143 if (toplevel_map_.find(filesystem_id) == toplevel_map_.end()) 174 if (toplevel_map_.find(filesystem_id) == toplevel_map_.end())
144 return false; 175 return false;
145 if (writable) 176 if (writable)
146 writable_ids_.insert(filesystem_id); 177 writable_ids_.insert(filesystem_id);
147 else 178 else
148 writable_ids_.erase(filesystem_id); 179 writable_ids_.erase(filesystem_id);
149 return true; 180 return true;
150 } 181 }
151 182
152 bool IsolatedContext::IsWritable(const std::string& filesystem_id) const { 183 bool IsolatedContext::IsWritable(const std::string& filesystem_id) const {
153 base::AutoLock locker(lock_); 184 base::AutoLock locker(lock_);
154 return (writable_ids_.find(filesystem_id) != writable_ids_.end()); 185 return (writable_ids_.find(filesystem_id) != writable_ids_.end());
155 } 186 }
156 187
157 FilePath IsolatedContext::CreateVirtualPath( 188 FilePath IsolatedContext::CreateVirtualRootPath(
158 const std::string& filesystem_id, const FilePath& relative_path) const { 189 const std::string& filesystem_id) const {
159 FilePath full_path; 190 return FilePath().AppendASCII(filesystem_id);
160 full_path = full_path.AppendASCII(filesystem_id);
161 if (relative_path.value() != FILE_PATH_LITERAL("/"))
162 full_path = full_path.Append(relative_path);
163 return full_path;
164 } 191 }
165 192
166 IsolatedContext::IsolatedContext() { 193 IsolatedContext::IsolatedContext() {
167 } 194 }
168 195
169 IsolatedContext::~IsolatedContext() { 196 IsolatedContext::~IsolatedContext() {
170 } 197 }
171 198
172 void IsolatedContext::RevokeWithoutLocking( 199 void IsolatedContext::RevokeWithoutLocking(
173 const std::string& filesystem_id) { 200 const std::string& filesystem_id) {
174 toplevel_map_.erase(filesystem_id); 201 toplevel_map_.erase(filesystem_id);
175 writable_ids_.erase(filesystem_id); 202 writable_ids_.erase(filesystem_id);
176 ref_counts_.erase(filesystem_id); 203 ref_counts_.erase(filesystem_id);
177 } 204 }
178 205
179 std::string IsolatedContext::GetNewFileSystemId() const { 206 std::string IsolatedContext::GetNewFileSystemId() const {
180 // Returns an arbitrary random string which must be unique in the map. 207 // Returns an arbitrary random string which must be unique in the map.
181 uint32 random_data[4]; 208 uint32 random_data[4];
182 std::string id; 209 std::string id;
183 do { 210 do {
184 base::RandBytes(random_data, sizeof(random_data)); 211 base::RandBytes(random_data, sizeof(random_data));
185 id = base::HexEncode(random_data, sizeof(random_data)); 212 id = base::HexEncode(random_data, sizeof(random_data));
186 } while (toplevel_map_.find(id) != toplevel_map_.end()); 213 } while (toplevel_map_.find(id) != toplevel_map_.end());
187 return id; 214 return id;
188 } 215 }
189 216
190 } // namespace fileapi 217 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698