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 #ifndef SyncCallbackHelper_h 32 #define SyncCallbackHelper_h 33 34 #if ENABLE(FILE_SYSTEM) 35 36 #include "DirectoryEntry.h" 37 #include "EntriesCallback.h" 38 #include "EntryArraySync.h" 39 #include "EntryCallback.h" 40 #include "ErrorCallback.h" 41 #include "ExceptionCode.h" 42 #include "FileEntry.h" 43 #include "FileError.h" 44 #include "FileException.h" 45 #include "FileSystemCallback.h" 46 #include "MetadataCallback.h" 47 #include "VoidCallback.h" 48 #include <wtf/PassRefPtr.h> 49 #include <wtf/RefCounted.h> 50 51 namespace WebCore { 52 53 class AsyncFileSystem; 54 class DirectoryEntrySync; 55 class EntryArraySync; 56 class EntrySync; 57 class FileEntrySync; 58 59 // A helper template for FileSystemSync implementation. 60 template <typename SuccessCallback, typename ObserverType, typename CallbackArg, typename ResultType> 61 class SyncCallbackHelper { 62 WTF_MAKE_NONCOPYABLE(SyncCallbackHelper); 63 public: 64 typedef SyncCallbackHelper<SuccessCallback, ObserverType, CallbackArg, ResultType> HelperType; 65 SyncCallbackHelper(ObserverType* observer = 0) 66 : m_observer(observer) 67 , m_successCallback(SuccessCallbackImpl::create(this)) 68 , m_errorCallback(ErrorCallbackImpl::create(this)) 69 , m_exceptionCode(0) 70 , m_completed(false) 71 { 72 } 73 74 PassRefPtr<ResultType> getResult(ExceptionCode& ec) 75 { 76 if (m_observer) { 77 while (!m_completed) { 78 if (!m_observer->waitForOperationToComplete()) { 79 m_exceptionCode = FileException::ABORT_ERR; 80 break; 81 } 82 } 83 } 84 ec = m_exceptionCode; 85 return m_result.release(); 86 } 87 88 PassRefPtr<SuccessCallback> successCallback() { return m_successCallback; } 89 PassRefPtr<ErrorCallback> errorCallback() { return m_errorCallback; } 90 91 private: 92 class SuccessCallbackImpl : public SuccessCallback { 93 public: 94 static PassRefPtr<SuccessCallbackImpl> create(HelperType* helper) 95 { 96 return adoptRef(new SuccessCallbackImpl(helper)); 97 } 98 99 virtual void handleEvent() 100 { 101 m_helper->setError(0); 102 } 103 104 virtual bool handleEvent(CallbackArg* arg) 105 { 106 m_helper->setResult(ResultType::create(arg)); 107 return true; 108 } 109 110 private: 111 SuccessCallbackImpl(HelperType* helper) 112 : m_helper(helper) 113 { 114 } 115 HelperType* m_helper; 116 }; 117 118 class ErrorCallbackImpl : public ErrorCallback { 119 public: 120 static PassRefPtr<ErrorCallbackImpl> create(HelperType* helper) 121 { 122 return adoptRef(new ErrorCallbackImpl(helper)); 123 } 124 125 virtual bool handleEvent(FileError* error) 126 { 127 ASSERT(error); 128 m_helper->setError(error->code()); 129 return true; 130 } 131 132 private: 133 ErrorCallbackImpl(HelperType* helper) 134 : m_helper(helper) 135 { 136 } 137 HelperType* m_helper; 138 }; 139 140 friend class SuccessCallbackImpl; 141 friend class ErrorCallbackImpl; 142 143 void setError(int code) 144 { 145 m_exceptionCode = FileException::ErrorCodeToExceptionCode(code); 146 m_completed = true; 147 } 148 149 void setResult(PassRefPtr<ResultType> result) 150 { 151 m_result = result; 152 m_completed = true; 153 } 154 155 ObserverType* m_observer; 156 RefPtr<SuccessCallbackImpl> m_successCallback; 157 RefPtr<ErrorCallbackImpl> m_errorCallback; 158 RefPtr<ResultType> m_result; 159 ExceptionCode m_exceptionCode; 160 bool m_completed; 161 }; 162 163 struct EmptyType : public RefCounted<EmptyType> { 164 static PassRefPtr<EmptyType> create(EmptyType*) 165 { 166 return 0; 167 } 168 }; 169 170 struct EmptyObserverType { 171 bool waitForOperationToComplete() 172 { 173 return false; 174 } 175 }; 176 177 typedef SyncCallbackHelper<EntryCallback, AsyncFileSystem, Entry, EntrySync> EntrySyncCallbackHelper; 178 typedef SyncCallbackHelper<EntriesCallback, AsyncFileSystem, EntryArray, EntryArraySync> EntriesSyncCallbackHelper; 179 typedef SyncCallbackHelper<MetadataCallback, AsyncFileSystem, Metadata, Metadata> MetadataSyncCallbackHelper; 180 typedef SyncCallbackHelper<VoidCallback, AsyncFileSystem, EmptyType, EmptyType> VoidSyncCallbackHelper; 181 typedef SyncCallbackHelper<FileSystemCallback, EmptyObserverType, DOMFileSystem, DOMFileSystemSync> FileSystemSyncCallbackHelper; 182 183 } // namespace WebCore 184 185 #endif // ENABLE(FILE_SYSTEM) 186 187 #endif // SyncCallbackHelper_h 188