1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "FileSystemCallbacks.h" 33 34 #if ENABLE(FILE_SYSTEM) 35 36 #include "AsyncFileSystem.h" 37 #include "AsyncFileWriter.h" 38 #include "DOMFilePath.h" 39 #include "DOMFileSystemBase.h" 40 #include "DirectoryEntry.h" 41 #include "DirectoryReader.h" 42 #include "EntriesCallback.h" 43 #include "EntryArray.h" 44 #include "EntryCallback.h" 45 #include "ErrorCallback.h" 46 #include "FileEntry.h" 47 #include "FileError.h" 48 #include "FileMetadata.h" 49 #include "FileSystemCallback.h" 50 #include "FileWriterBase.h" 51 #include "FileWriterBaseCallback.h" 52 #include "Metadata.h" 53 #include "MetadataCallback.h" 54 #include "ScriptExecutionContext.h" 55 #include "VoidCallback.h" 56 57 namespace WebCore { 58 59 FileSystemCallbacksBase::FileSystemCallbacksBase(PassRefPtr<ErrorCallback> errorCallback) 60 : m_errorCallback(errorCallback) 61 { 62 } 63 64 FileSystemCallbacksBase::~FileSystemCallbacksBase() 65 { 66 } 67 68 void FileSystemCallbacksBase::didSucceed() 69 { 70 // Each subclass must implement an appropriate one. 71 ASSERT_NOT_REACHED(); 72 } 73 74 void FileSystemCallbacksBase::didOpenFileSystem(const String&, PassOwnPtr<AsyncFileSystem>) 75 { 76 // Each subclass must implement an appropriate one. 77 ASSERT_NOT_REACHED(); 78 } 79 80 void FileSystemCallbacksBase::didReadMetadata(const FileMetadata&) 81 { 82 // Each subclass must implement an appropriate one. 83 ASSERT_NOT_REACHED(); 84 } 85 86 void FileSystemCallbacksBase::didReadDirectoryEntries(bool) 87 { 88 // Each subclass must implement an appropriate one. 89 ASSERT_NOT_REACHED(); 90 } 91 92 void FileSystemCallbacksBase::didReadDirectoryEntry(const String&, bool) 93 { 94 // Each subclass must implement an appropriate one. 95 ASSERT_NOT_REACHED(); 96 } 97 98 void FileSystemCallbacksBase::didCreateFileWriter(PassOwnPtr<AsyncFileWriter>, long long) 99 { 100 // Each subclass must implement an appropriate one. 101 ASSERT_NOT_REACHED(); 102 } 103 104 void FileSystemCallbacksBase::didFail(int code) 105 { 106 if (m_errorCallback) { 107 m_errorCallback->handleEvent(FileError::create(static_cast<FileError::ErrorCode>(code)).get()); 108 m_errorCallback.clear(); 109 } 110 } 111 112 // EntryCallbacks ------------------------------------------------------------- 113 114 PassOwnPtr<EntryCallbacks> EntryCallbacks::create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DOMFileSystemBase> fileSystem, const String& expectedPath, bool isDirectory) 115 { 116 return adoptPtr(new EntryCallbacks(successCallback, errorCallback, fileSystem, expectedPath, isDirectory)); 117 } 118 119 EntryCallbacks::EntryCallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DOMFileSystemBase> fileSystem, const String& expectedPath, bool isDirectory) 120 : FileSystemCallbacksBase(errorCallback) 121 , m_successCallback(successCallback) 122 , m_fileSystem(fileSystem) 123 , m_expectedPath(expectedPath) 124 , m_isDirectory(isDirectory) 125 { 126 } 127 128 void EntryCallbacks::didSucceed() 129 { 130 if (m_successCallback) { 131 if (m_isDirectory) 132 m_successCallback->handleEvent(DirectoryEntry::create(m_fileSystem, m_expectedPath).get()); 133 else 134 m_successCallback->handleEvent(FileEntry::create(m_fileSystem, m_expectedPath).get()); 135 } 136 m_successCallback.clear(); 137 } 138 139 // EntriesCallbacks ----------------------------------------------------------- 140 141 PassOwnPtr<EntriesCallbacks> EntriesCallbacks::create(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryReaderBase> directoryReader, const String& basePath) 142 { 143 return adoptPtr(new EntriesCallbacks(successCallback, errorCallback, directoryReader, basePath)); 144 } 145 146 EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryReaderBase> directoryReader, const String& basePath) 147 : FileSystemCallbacksBase(errorCallback) 148 , m_successCallback(successCallback) 149 , m_directoryReader(directoryReader) 150 , m_basePath(basePath) 151 , m_entries(EntryArray::create()) 152 { 153 ASSERT(m_directoryReader); 154 } 155 156 void EntriesCallbacks::didReadDirectoryEntry(const String& name, bool isDirectory) 157 { 158 if (isDirectory) 159 m_entries->append(DirectoryEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name))); 160 else 161 m_entries->append(FileEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name))); 162 } 163 164 void EntriesCallbacks::didReadDirectoryEntries(bool hasMore) 165 { 166 m_directoryReader->setHasMoreEntries(hasMore); 167 if (m_successCallback) 168 m_successCallback->handleEvent(m_entries.get()); 169 } 170 171 // FileSystemCallbacks -------------------------------------------------------- 172 173 PassOwnPtr<FileSystemCallbacks> FileSystemCallbacks::create(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* scriptExecutionContext) 174 { 175 return adoptPtr(new FileSystemCallbacks(successCallback, errorCallback, scriptExecutionContext)); 176 } 177 178 FileSystemCallbacks::FileSystemCallbacks(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* context) 179 : FileSystemCallbacksBase(errorCallback) 180 , m_successCallback(successCallback) 181 , m_scriptExecutionContext(context) 182 { 183 } 184 185 void FileSystemCallbacks::didOpenFileSystem(const String& name, PassOwnPtr<AsyncFileSystem> asyncFileSystem) 186 { 187 if (m_successCallback) { 188 ASSERT(asyncFileSystem); 189 m_successCallback->handleEvent(DOMFileSystem::create(m_scriptExecutionContext.get(), name, asyncFileSystem.leakPtr()).get()); 190 m_scriptExecutionContext.clear(); 191 } 192 m_successCallback.clear(); 193 } 194 195 // ResolveURICallbacks -------------------------------------------------------- 196 197 namespace { 198 199 class ErrorCallbackWrapper : public ErrorCallback { 200 public: 201 static PassRefPtr<ErrorCallbackWrapper> create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryEntry> root, const String& filePath) 202 { 203 return adoptRef(new ErrorCallbackWrapper(successCallback, errorCallback, root, filePath)); 204 } 205 206 virtual bool handleEvent(FileError* error) 207 { 208 ASSERT(error); 209 if (error->code() == FileError::TYPE_MISMATCH_ERR) 210 m_root->getFile(m_filePath, 0, m_successCallback, m_errorCallback); 211 else if (m_errorCallback) 212 m_errorCallback->handleEvent(error); 213 return true; 214 } 215 216 private: 217 ErrorCallbackWrapper(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryEntry> root, const String& filePath) 218 : m_successCallback(successCallback) 219 , m_errorCallback(errorCallback) 220 , m_root(root) 221 , m_filePath(filePath) 222 { 223 ASSERT(m_root); 224 } 225 226 RefPtr<EntryCallback> m_successCallback; 227 RefPtr<ErrorCallback> m_errorCallback; 228 RefPtr<DirectoryEntry> m_root; 229 String m_filePath; 230 }; 231 232 } // namespace 233 234 PassOwnPtr<ResolveURICallbacks> ResolveURICallbacks::create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* scriptExecutionContext, const String& filePath) 235 { 236 return adoptPtr(new ResolveURICallbacks(successCallback, errorCallback, scriptExecutionContext, filePath)); 237 } 238 239 ResolveURICallbacks::ResolveURICallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* context, const String& filePath) 240 : FileSystemCallbacksBase(errorCallback) 241 , m_successCallback(successCallback) 242 , m_scriptExecutionContext(context) 243 , m_filePath(filePath) 244 { 245 } 246 247 void ResolveURICallbacks::didOpenFileSystem(const String& name, PassOwnPtr<AsyncFileSystem> asyncFileSystem) 248 { 249 ASSERT(asyncFileSystem); 250 RefPtr<DirectoryEntry> root = DOMFileSystem::create(m_scriptExecutionContext.get(), name, asyncFileSystem.leakPtr())->root(); 251 root->getDirectory(m_filePath, 0, m_successCallback, ErrorCallbackWrapper::create(m_successCallback, m_errorCallback, root, m_filePath)); 252 } 253 254 // MetadataCallbacks ---------------------------------------------------------- 255 256 PassOwnPtr<MetadataCallbacks> MetadataCallbacks::create(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 257 { 258 return adoptPtr(new MetadataCallbacks(successCallback, errorCallback)); 259 } 260 261 MetadataCallbacks::MetadataCallbacks(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 262 : FileSystemCallbacksBase(errorCallback) 263 , m_successCallback(successCallback) 264 { 265 } 266 267 void MetadataCallbacks::didReadMetadata(const FileMetadata& metadata) 268 { 269 if (m_successCallback) 270 m_successCallback->handleEvent(Metadata::create(metadata.modificationTime).get()); 271 m_successCallback.clear(); 272 } 273 274 // FileWriterBaseCallbacks ---------------------------------------------------------- 275 276 PassOwnPtr<FileWriterBaseCallbacks> FileWriterBaseCallbacks::create(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 277 { 278 return adoptPtr(new FileWriterBaseCallbacks(fileWriter, successCallback, errorCallback)); 279 } 280 281 FileWriterBaseCallbacks::FileWriterBaseCallbacks(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 282 : FileSystemCallbacksBase(errorCallback) 283 , m_fileWriter(fileWriter) 284 , m_successCallback(successCallback) 285 { 286 } 287 288 void FileWriterBaseCallbacks::didCreateFileWriter(PassOwnPtr<AsyncFileWriter> asyncFileWriter, long long length) 289 { 290 m_fileWriter->initialize(asyncFileWriter, length); 291 if (m_successCallback) 292 m_successCallback->handleEvent(m_fileWriter.release().get()); 293 m_successCallback.clear(); 294 } 295 296 // VoidCallbacks -------------------------------------------------------------- 297 298 PassOwnPtr<VoidCallbacks> VoidCallbacks::create(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 299 { 300 return adoptPtr(new VoidCallbacks(successCallback, errorCallback)); 301 } 302 303 VoidCallbacks::VoidCallbacks(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 304 : FileSystemCallbacksBase(errorCallback) 305 , m_successCallback(successCallback) 306 { 307 } 308 309 void VoidCallbacks::didSucceed() 310 { 311 if (m_successCallback) 312 m_successCallback->handleEvent(); 313 m_successCallback.clear(); 314 } 315 316 } // namespace 317 318 #endif // ENABLE(FILE_SYSTEM) 319