OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.h" | 5 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/browser/media_galleries/fileapi/filtering_file_enumerator.h" | |
13 #include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_p
rovider.h" | 12 #include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_p
rovider.h" |
14 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_album_table_reade
r.h" | 13 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_album_table_reade
r.h" |
15 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" | 14 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" |
16 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" | 15 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" |
17 #include "webkit/browser/fileapi/file_system_operation_context.h" | 16 #include "webkit/browser/fileapi/file_system_operation_context.h" |
18 #include "webkit/browser/fileapi/file_system_url.h" | 17 #include "webkit/browser/fileapi/file_system_url.h" |
19 #include "webkit/common/fileapi/file_system_util.h" | 18 #include "webkit/common/fileapi/file_system_util.h" |
20 | 19 |
21 using base::FilePath; | 20 using base::FilePath; |
22 using fileapi::FileSystemOperationContext; | 21 using fileapi::FileSystemOperationContext; |
23 using fileapi::FileSystemURL; | 22 using fileapi::FileSystemURL; |
24 | 23 |
25 namespace picasa { | 24 namespace picasa { |
26 | 25 |
27 namespace { | 26 namespace { |
28 | 27 |
29 class DirectorySkippingFileEnumerator | 28 fileapi::DirectoryEntry MakeDirectoryEntry( |
30 : public fileapi::FileSystemFileUtil::AbstractFileEnumerator { | 29 const base::FilePath& path, |
31 public: | 30 int64 size, |
32 DirectorySkippingFileEnumerator( | 31 const base::Time& last_modified_time, |
33 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> | 32 bool is_directory) { |
34 base_enumerator) | 33 fileapi::DirectoryEntry entry; |
35 : base_enumerator_(base_enumerator.Pass()) { | 34 entry.name = path.BaseName().value(); |
36 } | 35 entry.is_directory = is_directory; |
37 virtual ~DirectorySkippingFileEnumerator() {} | 36 entry.size = size; |
38 | 37 entry.last_modified_time = last_modified_time; |
39 virtual base::FilePath Next() OVERRIDE { | 38 return entry; |
40 while (true) { | 39 } |
41 base::FilePath next = base_enumerator_->Next(); | |
42 if (next.empty() || !base_enumerator_->IsDirectory()) | |
43 return next; | |
44 } | |
45 } | |
46 | |
47 virtual int64 Size() OVERRIDE { | |
48 return base_enumerator_->Size(); | |
49 } | |
50 | |
51 virtual base::Time LastModifiedTime() OVERRIDE { | |
52 return base_enumerator_->LastModifiedTime(); | |
53 } | |
54 | |
55 virtual bool IsDirectory() OVERRIDE { | |
56 DCHECK(!base_enumerator_->IsDirectory()); | |
57 return base_enumerator_->IsDirectory(); | |
58 } | |
59 | |
60 private: | |
61 // The file enumerator to be wrapped. | |
62 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> | |
63 base_enumerator_; | |
64 }; | |
65 | |
66 struct VirtualFile { | |
67 VirtualFile(const base::FilePath& path, int64 size, | |
68 const base::Time& last_modified_time, bool is_directory) | |
69 : path(path), | |
70 size(size), | |
71 last_modified_time(last_modified_time), | |
72 is_directory(is_directory) {} | |
73 | |
74 base::FilePath path; | |
75 int64 size; | |
76 base::Time last_modified_time; | |
77 bool is_directory; | |
78 }; | |
79 | |
80 class VirtualFileEnumerator | |
81 : public fileapi::FileSystemFileUtil::AbstractFileEnumerator { | |
82 public: | |
83 explicit VirtualFileEnumerator(const std::vector<VirtualFile>& files) | |
84 : files_(files), next_called_(false), index_(0) {} | |
85 | |
86 virtual base::FilePath Next() OVERRIDE { | |
87 if (next_called_ && index_ < files_.size()) | |
88 ++index_; | |
89 | |
90 next_called_ = true; | |
91 | |
92 if (index_ >= files_.size()) | |
93 return FilePath(); | |
94 return files_[index_].path; | |
95 } | |
96 | |
97 virtual int64 Size() OVERRIDE { | |
98 if (index_ >= files_.size()) | |
99 return 0; | |
100 return files_[index_].size; | |
101 } | |
102 | |
103 virtual base::Time LastModifiedTime() OVERRIDE { | |
104 if (index_ >= files_.size()) | |
105 return base::Time(); | |
106 return files_[index_].last_modified_time; | |
107 } | |
108 | |
109 virtual bool IsDirectory() OVERRIDE { | |
110 if (index_ >= files_.size()) | |
111 return false; | |
112 return files_[index_].is_directory; | |
113 } | |
114 | |
115 private: | |
116 std::vector<VirtualFile> files_; | |
117 bool next_called_; | |
118 size_t index_; | |
119 }; | |
120 | 40 |
121 // |error| is only set when the method fails and the return is NULL. | 41 // |error| is only set when the method fails and the return is NULL. |
122 base::PlatformFileError FindAlbumInfo(const std::string& key, | 42 base::PlatformFileError FindAlbumInfo(const std::string& key, |
123 const AlbumMap* map, | 43 const AlbumMap* map, |
124 AlbumInfo* album_info) { | 44 AlbumInfo* album_info) { |
125 if (!map) | 45 if (!map) |
126 return base::PLATFORM_FILE_ERROR_FAILED; | 46 return base::PLATFORM_FILE_ERROR_FAILED; |
127 | 47 |
128 AlbumMap::const_iterator it = map->find(key); | 48 AlbumMap::const_iterator it = map->find(key); |
129 | 49 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 | 86 |
167 } // namespace | 87 } // namespace |
168 | 88 |
169 const char kPicasaDirAlbums[] = "albums"; | 89 const char kPicasaDirAlbums[] = "albums"; |
170 const char kPicasaDirFolders[] = "folders"; | 90 const char kPicasaDirFolders[] = "folders"; |
171 | 91 |
172 PicasaFileUtil::PicasaFileUtil() {} | 92 PicasaFileUtil::PicasaFileUtil() {} |
173 | 93 |
174 PicasaFileUtil::~PicasaFileUtil() {} | 94 PicasaFileUtil::~PicasaFileUtil() {} |
175 | 95 |
176 base::PlatformFileError PicasaFileUtil::GetFileInfo( | 96 base::PlatformFileError PicasaFileUtil::GetFileInfoSync( |
177 FileSystemOperationContext* context, const FileSystemURL& url, | 97 FileSystemOperationContext* context, const FileSystemURL& url, |
178 base::PlatformFileInfo* file_info, base::FilePath* platform_path) { | 98 base::PlatformFileInfo* file_info, base::FilePath* platform_path) { |
179 DCHECK(context); | 99 DCHECK(context); |
180 DCHECK(file_info); | 100 DCHECK(file_info); |
181 DCHECK(platform_path); | 101 DCHECK(platform_path); |
182 | 102 |
183 *platform_path = base::FilePath(); | 103 *platform_path = base::FilePath(); |
184 | 104 |
185 std::vector<std::string> path_components = GetComponents(url); | 105 std::vector<std::string> path_components = GetComponents(url); |
186 | 106 |
(...skipping 16 matching lines...) Expand all Loading... |
203 base::PlatformFileError error = | 123 base::PlatformFileError error = |
204 FindAlbumInfo(path_components[1], album_map.get(), NULL); | 124 FindAlbumInfo(path_components[1], album_map.get(), NULL); |
205 if (error != base::PLATFORM_FILE_OK) | 125 if (error != base::PLATFORM_FILE_OK) |
206 return error; | 126 return error; |
207 | 127 |
208 file_info->is_directory = true; | 128 file_info->is_directory = true; |
209 return base::PLATFORM_FILE_OK; | 129 return base::PLATFORM_FILE_OK; |
210 } | 130 } |
211 | 131 |
212 if (path_components[0] == kPicasaDirFolders) { | 132 if (path_components[0] == kPicasaDirFolders) { |
213 return NativeMediaFileUtil::GetFileInfo(context, url, file_info, | 133 return NativeMediaFileUtil::GetFileInfoSync(context, url, file_info, |
214 platform_path); | 134 platform_path); |
215 } | 135 } |
216 break; | 136 break; |
217 case 3: | 137 case 3: |
218 // NativeMediaFileUtil::GetInfo calls into virtual function | 138 // NativeMediaFileUtil::GetInfo calls into virtual function |
219 // PicasaFileUtil::GetLocalFilePath, and that will handle both | 139 // PicasaFileUtil::GetLocalFilePath, and that will handle both |
220 // album contents and folder contents. | 140 // album contents and folder contents. |
221 base::PlatformFileError result = NativeMediaFileUtil::GetFileInfo( | 141 base::PlatformFileError result = NativeMediaFileUtil::GetFileInfoSync( |
222 context, url, file_info, platform_path); | 142 context, url, file_info, platform_path); |
223 | 143 |
224 DCHECK(path_components[0] == kPicasaDirAlbums || | 144 DCHECK(path_components[0] == kPicasaDirAlbums || |
225 path_components[0] == kPicasaDirFolders || | 145 path_components[0] == kPicasaDirFolders || |
226 result == base::PLATFORM_FILE_ERROR_NOT_FOUND); | 146 result == base::PLATFORM_FILE_ERROR_NOT_FOUND); |
227 | 147 |
228 return result; | 148 return result; |
229 } | 149 } |
230 | 150 |
231 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 151 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
232 } | 152 } |
233 | 153 |
234 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> | 154 base::PlatformFileError PicasaFileUtil::ReadDirectorySync( |
235 PicasaFileUtil::CreateFileEnumerator(FileSystemOperationContext* context, | 155 fileapi::FileSystemOperationContext* context, |
236 const FileSystemURL& url) { | 156 const fileapi::FileSystemURL& url, |
| 157 EntryList* file_list) { |
237 DCHECK(context); | 158 DCHECK(context); |
| 159 DCHECK(file_list); |
| 160 DCHECK(file_list->empty()); |
| 161 |
| 162 base::PlatformFileInfo file_info; |
| 163 base::FilePath platform_directory_path; |
| 164 base::PlatformFileError error = GetFileInfoSync( |
| 165 context, url, &file_info, &platform_directory_path); |
| 166 |
| 167 if (error != base::PLATFORM_FILE_OK) |
| 168 return error; |
| 169 |
| 170 if (!file_info.is_directory) |
| 171 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 172 |
238 std::vector<std::string> path_components = GetComponents(url); | 173 std::vector<std::string> path_components = GetComponents(url); |
239 | 174 |
240 std::vector<VirtualFile> files; | |
241 FilePath folders_path = base::FilePath().AppendASCII(kPicasaDirFolders); | 175 FilePath folders_path = base::FilePath().AppendASCII(kPicasaDirFolders); |
242 | 176 |
243 switch (path_components.size()) { | 177 switch (path_components.size()) { |
244 case 0: { | 178 case 0: { |
245 // Root directory. | 179 // Root directory. |
246 FilePath albums_path = base::FilePath().AppendASCII(kPicasaDirAlbums); | 180 FilePath albums_path = base::FilePath().AppendASCII(kPicasaDirAlbums); |
247 files.push_back(VirtualFile(albums_path, 0, base::Time(), true)); | 181 file_list->push_back( |
248 files.push_back(VirtualFile(folders_path, 0, base::Time(), true)); | 182 MakeDirectoryEntry(albums_path, 0, base::Time(), true)); |
| 183 file_list->push_back( |
| 184 MakeDirectoryEntry(folders_path, 0, base::Time(), true)); |
249 break; | 185 break; |
250 } | 186 } |
251 case 1: | 187 case 1: |
252 if (path_components[0] == kPicasaDirAlbums) { | 188 if (path_components[0] == kPicasaDirAlbums) { |
253 scoped_ptr<AlbumMap> albums = DataProvider()->GetAlbums(); | 189 scoped_ptr<AlbumMap> albums = DataProvider()->GetAlbums(); |
254 if (!albums) | 190 if (!albums) |
255 return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); | 191 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
256 | 192 |
257 // TODO(tommycli): Use AlbumMap enumerator to avoid copies. | |
258 for (AlbumMap::const_iterator it = albums->begin(); | 193 for (AlbumMap::const_iterator it = albums->begin(); |
259 it != albums->end(); ++it) { | 194 it != albums->end(); ++it) { |
260 files.push_back(VirtualFile( | 195 file_list->push_back(MakeDirectoryEntry( |
261 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), | 196 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), |
262 0, | 197 0, |
263 it->second.timestamp, | 198 it->second.timestamp, |
264 true)); | 199 true)); |
265 } | 200 } |
266 } else if (path_components[0] == kPicasaDirFolders) { | 201 } else if (path_components[0] == kPicasaDirFolders) { |
267 scoped_ptr<AlbumMap> folders = DataProvider()->GetFolders(); | 202 scoped_ptr<AlbumMap> folders = DataProvider()->GetFolders(); |
268 if (!folders) | 203 if (!folders) |
269 return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); | 204 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
270 | 205 |
271 // TODO(tommycli): Use AlbumMap enumerator to avoid copies. | |
272 for (AlbumMap::const_iterator it = folders->begin(); | 206 for (AlbumMap::const_iterator it = folders->begin(); |
273 it != folders->end(); ++it) { | 207 it != folders->end(); ++it) { |
274 files.push_back(VirtualFile( | 208 file_list->push_back(MakeDirectoryEntry( |
275 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), | 209 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), |
276 0, | 210 0, |
277 it->second.timestamp, | 211 it->second.timestamp, |
278 true)); | 212 true)); |
279 } | 213 } |
280 } | 214 } |
281 break; | 215 break; |
282 case 2: | 216 case 2: |
283 if (path_components[0] == kPicasaDirAlbums) { | 217 if (path_components[0] == kPicasaDirAlbums) { |
284 // TODO(tommycli): Implement album contents. | 218 // TODO(tommycli): Implement album contents. |
285 } | 219 } |
286 | 220 |
287 if (path_components[0] == kPicasaDirFolders) | 221 if (path_components[0] == kPicasaDirFolders) { |
288 return scoped_ptr<AbstractFileEnumerator>( | 222 EntryList super_list; |
289 new DirectorySkippingFileEnumerator( | 223 base::PlatformFileError error = |
290 NativeMediaFileUtil::CreateFileEnumerator(context, url))); | 224 NativeMediaFileUtil::ReadDirectorySync(context, url, &super_list); |
| 225 if (error != base::PLATFORM_FILE_OK) |
| 226 return error; |
| 227 |
| 228 for (EntryList::const_iterator it = super_list.begin(); |
| 229 it != super_list.end(); ++it) { |
| 230 if (!it->is_directory) |
| 231 file_list->push_back(*it); |
| 232 } |
| 233 } |
| 234 |
291 break; | 235 break; |
292 } | 236 } |
293 | 237 |
294 return scoped_ptr<AbstractFileEnumerator>(new VirtualFileEnumerator(files)); | 238 return base::PLATFORM_FILE_OK; |
295 } | 239 } |
296 | 240 |
297 base::PlatformFileError PicasaFileUtil::GetLocalFilePath( | 241 base::PlatformFileError PicasaFileUtil::GetLocalFilePath( |
298 FileSystemOperationContext* context, const FileSystemURL& url, | 242 FileSystemOperationContext* context, const FileSystemURL& url, |
299 base::FilePath* local_file_path) { | 243 base::FilePath* local_file_path) { |
300 DCHECK(local_file_path); | 244 DCHECK(local_file_path); |
301 DCHECK(url.is_valid()); | 245 DCHECK(url.is_valid()); |
302 std::vector<std::string> path_components = GetComponents(url); | 246 std::vector<std::string> path_components = GetComponents(url); |
303 | 247 |
304 switch (path_components.size()) { | 248 switch (path_components.size()) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 // intercepted by GetFileInfo()/CreateFileEnumerator(). Invalid cases | 292 // intercepted by GetFileInfo()/CreateFileEnumerator(). Invalid cases |
349 // return a NOT_FOUND error. | 293 // return a NOT_FOUND error. |
350 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 294 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
351 } | 295 } |
352 | 296 |
353 PicasaDataProvider* PicasaFileUtil::DataProvider() { | 297 PicasaDataProvider* PicasaFileUtil::DataProvider() { |
354 return chrome::ImportedMediaGalleryRegistry::picasa_data_provider(); | 298 return chrome::ImportedMediaGalleryRegistry::picasa_data_provider(); |
355 } | 299 } |
356 | 300 |
357 } // namespace picasa | 301 } // namespace picasa |
OLD | NEW |