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 57namespace WebCore { 58 59FileSystemCallbacksBase::FileSystemCallbacksBase(PassRefPtr<ErrorCallback> errorCallback) 60 : m_errorCallback(errorCallback) 61{ 62} 63 64FileSystemCallbacksBase::~FileSystemCallbacksBase() 65{ 66} 67 68void FileSystemCallbacksBase::didSucceed() 69{ 70 // Each subclass must implement an appropriate one. 71 ASSERT_NOT_REACHED(); 72} 73 74void FileSystemCallbacksBase::didOpenFileSystem(const String&, PassOwnPtr<AsyncFileSystem>) 75{ 76 // Each subclass must implement an appropriate one. 77 ASSERT_NOT_REACHED(); 78} 79 80void FileSystemCallbacksBase::didReadMetadata(const FileMetadata&) 81{ 82 // Each subclass must implement an appropriate one. 83 ASSERT_NOT_REACHED(); 84} 85 86void FileSystemCallbacksBase::didReadDirectoryEntries(bool) 87{ 88 // Each subclass must implement an appropriate one. 89 ASSERT_NOT_REACHED(); 90} 91 92void FileSystemCallbacksBase::didReadDirectoryEntry(const String&, bool) 93{ 94 // Each subclass must implement an appropriate one. 95 ASSERT_NOT_REACHED(); 96} 97 98void FileSystemCallbacksBase::didCreateFileWriter(PassOwnPtr<AsyncFileWriter>, long long) 99{ 100 // Each subclass must implement an appropriate one. 101 ASSERT_NOT_REACHED(); 102} 103 104void 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 114PassOwnPtr<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 119EntryCallbacks::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 128void 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 141PassOwnPtr<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 146EntriesCallbacks::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 156void 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 164void 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 173PassOwnPtr<FileSystemCallbacks> FileSystemCallbacks::create(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* scriptExecutionContext) 174{ 175 return adoptPtr(new FileSystemCallbacks(successCallback, errorCallback, scriptExecutionContext)); 176} 177 178FileSystemCallbacks::FileSystemCallbacks(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* context) 179 : FileSystemCallbacksBase(errorCallback) 180 , m_successCallback(successCallback) 181 , m_scriptExecutionContext(context) 182{ 183} 184 185void 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 197namespace { 198 199class ErrorCallbackWrapper : public ErrorCallback { 200public: 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 216private: 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 234PassOwnPtr<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 239ResolveURICallbacks::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 247void 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 256PassOwnPtr<MetadataCallbacks> MetadataCallbacks::create(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 257{ 258 return adoptPtr(new MetadataCallbacks(successCallback, errorCallback)); 259} 260 261MetadataCallbacks::MetadataCallbacks(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 262 : FileSystemCallbacksBase(errorCallback) 263 , m_successCallback(successCallback) 264{ 265} 266 267void 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 276PassOwnPtr<FileWriterBaseCallbacks> FileWriterBaseCallbacks::create(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 277{ 278 return adoptPtr(new FileWriterBaseCallbacks(fileWriter, successCallback, errorCallback)); 279} 280 281FileWriterBaseCallbacks::FileWriterBaseCallbacks(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 282 : FileSystemCallbacksBase(errorCallback) 283 , m_fileWriter(fileWriter) 284 , m_successCallback(successCallback) 285{ 286} 287 288void 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 298PassOwnPtr<VoidCallbacks> VoidCallbacks::create(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 299{ 300 return adoptPtr(new VoidCallbacks(successCallback, errorCallback)); 301} 302 303VoidCallbacks::VoidCallbacks(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 304 : FileSystemCallbacksBase(errorCallback) 305 , m_successCallback(successCallback) 306{ 307} 308 309void 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