Home | History | Annotate | Download | only in filesystem
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  *     * Redistributions of source code must retain the above copyright
     10  * notice, this list of conditions and the following disclaimer.
     11  *     * Redistributions in binary form must reproduce the above
     12  * copyright notice, this list of conditions and the following disclaimer
     13  * in the documentation and/or other materials provided with the
     14  * distribution.
     15  *     * Neither the name of Google Inc. nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef SyncCallbackHelper_h
     33 #define SyncCallbackHelper_h
     34 
     35 #include "bindings/v8/ExceptionState.h"
     36 #include "core/fileapi/FileError.h"
     37 #include "core/html/VoidCallback.h"
     38 #include "modules/filesystem/DirectoryEntry.h"
     39 #include "modules/filesystem/DirectoryReaderSync.h"
     40 #include "modules/filesystem/EntriesCallback.h"
     41 #include "modules/filesystem/EntryCallback.h"
     42 #include "modules/filesystem/EntrySync.h"
     43 #include "modules/filesystem/ErrorCallback.h"
     44 #include "modules/filesystem/FileEntry.h"
     45 #include "modules/filesystem/FileSystemCallback.h"
     46 #include "modules/filesystem/MetadataCallback.h"
     47 #include "wtf/PassRefPtr.h"
     48 #include "wtf/RefCounted.h"
     49 
     50 namespace WebCore {
     51 
     52 template <typename ResultType, typename CallbackArg>
     53 struct HelperResultType {
     54     typedef PassRefPtr<ResultType> ReturnType;
     55     typedef RefPtr<ResultType> StorageType;
     56 
     57     static ReturnType createFromCallbackArg(CallbackArg argument)
     58     {
     59         return ResultType::create(argument);
     60     }
     61 };
     62 
     63 template <>
     64 struct HelperResultType<EntrySyncVector, const EntryVector&> {
     65     typedef EntrySyncVector ReturnType;
     66     typedef EntrySyncVector StorageType;
     67 
     68     static EntrySyncVector createFromCallbackArg(const EntryVector& entries)
     69     {
     70         EntrySyncVector result;
     71         size_t entryCount = entries.size();
     72         result.reserveInitialCapacity(entryCount);
     73         for (size_t i = 0; i < entryCount; ++i)
     74             result.uncheckedAppend(EntrySync::create(entries[i].get()));
     75         return result;
     76     }
     77 };
     78 
     79 // A helper template for FileSystemSync implementation.
     80 template <typename SuccessCallback, typename ObserverType, typename CallbackArg, typename ResultType>
     81 class SyncCallbackHelper {
     82     WTF_MAKE_NONCOPYABLE(SyncCallbackHelper);
     83 public:
     84     typedef SyncCallbackHelper<SuccessCallback, ObserverType, CallbackArg, ResultType> HelperType;
     85     typedef HelperResultType<ResultType, CallbackArg> ResultTypeTrait;
     86     typedef typename ResultTypeTrait::StorageType ResultStorageType;
     87     typedef typename ResultTypeTrait::ReturnType ResultReturnType;
     88 
     89     SyncCallbackHelper(ObserverType* observer = 0)
     90         : m_observer(observer)
     91         , m_successCallback(SuccessCallbackImpl::create(this))
     92         , m_errorCallback(ErrorCallbackImpl::create(this))
     93         , m_errorCode(FileError::OK)
     94         , m_completed(false)
     95     {
     96     }
     97 
     98     ResultReturnType getResult(ExceptionState& es)
     99     {
    100         if (m_observer) {
    101             while (!m_completed) {
    102                 if (!m_observer->waitForOperationToComplete()) {
    103                     m_errorCode = FileError::ABORT_ERR;
    104                     break;
    105                 }
    106             }
    107         }
    108         if (m_errorCode)
    109             FileError::throwDOMException(es, m_errorCode);
    110 
    111         return m_result;
    112     }
    113 
    114     PassRefPtr<SuccessCallback> successCallback() { return m_successCallback; }
    115     PassRefPtr<ErrorCallback> errorCallback() { return m_errorCallback; }
    116 
    117 private:
    118     class SuccessCallbackImpl : public SuccessCallback {
    119     public:
    120         static PassRefPtr<SuccessCallbackImpl> create(HelperType* helper)
    121         {
    122             return adoptRef(new SuccessCallbackImpl(helper));
    123         }
    124 
    125         virtual bool handleEvent()
    126         {
    127             m_helper->setError(FileError::OK);
    128             return true;
    129         }
    130 
    131         virtual bool handleEvent(CallbackArg arg)
    132         {
    133             m_helper->setResult(arg);
    134             return true;
    135         }
    136 
    137     private:
    138         explicit SuccessCallbackImpl(HelperType* helper)
    139             : m_helper(helper)
    140         {
    141         }
    142         HelperType* m_helper;
    143     };
    144 
    145     class ErrorCallbackImpl : public ErrorCallback {
    146     public:
    147         static PassRefPtr<ErrorCallbackImpl> create(HelperType* helper)
    148         {
    149             return adoptRef(new ErrorCallbackImpl(helper));
    150         }
    151 
    152         virtual bool handleEvent(FileError* error)
    153         {
    154             ASSERT(error);
    155             m_helper->setError(error->code());
    156             return true;
    157         }
    158 
    159     private:
    160         explicit ErrorCallbackImpl(HelperType* helper)
    161             : m_helper(helper)
    162         {
    163         }
    164         HelperType* m_helper;
    165     };
    166 
    167     friend class SuccessCallbackImpl;
    168     friend class ErrorCallbackImpl;
    169 
    170     void setError(FileError::ErrorCode code)
    171     {
    172         m_errorCode = code;
    173         m_completed = true;
    174     }
    175 
    176     void setResult(CallbackArg result)
    177     {
    178         m_result = ResultTypeTrait::createFromCallbackArg(result);
    179         m_completed = true;
    180     }
    181 
    182     ObserverType* m_observer;
    183     RefPtr<SuccessCallbackImpl> m_successCallback;
    184     RefPtr<ErrorCallbackImpl> m_errorCallback;
    185     ResultStorageType m_result;
    186     FileError::ErrorCode m_errorCode;
    187     bool m_completed;
    188 };
    189 
    190 struct EmptyType : public RefCounted<EmptyType> {
    191     static PassRefPtr<EmptyType> create(EmptyType*)
    192     {
    193         return 0;
    194     }
    195 };
    196 
    197 struct EmptyObserverType {
    198     bool waitForOperationToComplete()
    199     {
    200         return false;
    201     }
    202 };
    203 
    204 typedef SyncCallbackHelper<EntryCallback, AsyncFileSystem, Entry*, EntrySync> EntrySyncCallbackHelper;
    205 typedef SyncCallbackHelper<EntriesCallback, AsyncFileSystem, const EntryVector&, EntrySyncVector> EntriesSyncCallbackHelper;
    206 typedef SyncCallbackHelper<MetadataCallback, AsyncFileSystem, Metadata*, Metadata> MetadataSyncCallbackHelper;
    207 typedef SyncCallbackHelper<VoidCallback, AsyncFileSystem, EmptyType*, EmptyType> VoidSyncCallbackHelper;
    208 typedef SyncCallbackHelper<FileSystemCallback, EmptyObserverType, DOMFileSystem*, DOMFileSystemSync> FileSystemSyncCallbackHelper;
    209 
    210 } // namespace WebCore
    211 
    212 #endif // SyncCallbackHelper_h
    213