Home | History | Annotate | Download | only in fileapi
      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