/*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SyncCallbackHelper_h
#define SyncCallbackHelper_h
#if ENABLE(FILE_SYSTEM)
#include "DirectoryEntry.h"
#include "EntriesCallback.h"
#include "EntryArraySync.h"
#include "EntryCallback.h"
#include "ErrorCallback.h"
#include "ExceptionCode.h"
#include "FileEntry.h"
#include "FileError.h"
#include "FileException.h"
#include "FileSystemCallback.h"
#include "MetadataCallback.h"
#include "VoidCallback.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class AsyncFileSystem;
class DirectoryEntrySync;
class EntryArraySync;
class EntrySync;
class FileEntrySync;
// A helper template for FileSystemSync implementation.
template <typename SuccessCallback, typename ObserverType, typename CallbackArg, typename ResultType>
class SyncCallbackHelper {
WTF_MAKE_NONCOPYABLE(SyncCallbackHelper);
public:
typedef SyncCallbackHelper<SuccessCallback, ObserverType, CallbackArg, ResultType> HelperType;
SyncCallbackHelper(ObserverType* observer = 0)
: m_observer(observer)
, m_successCallback(SuccessCallbackImpl::create(this))
, m_errorCallback(ErrorCallbackImpl::create(this))
, m_exceptionCode(0)
, m_completed(false)
{
}
PassRefPtr<ResultType> getResult(ExceptionCode& ec)
{
if (m_observer) {
while (!m_completed) {
if (!m_observer->waitForOperationToComplete()) {
m_exceptionCode = FileException::ABORT_ERR;
break;
}
}
}
ec = m_exceptionCode;
return m_result.release();
}
PassRefPtr<SuccessCallback> successCallback() { return m_successCallback; }
PassRefPtr<ErrorCallback> errorCallback() { return m_errorCallback; }
private:
class SuccessCallbackImpl : public SuccessCallback {
public:
static PassRefPtr<SuccessCallbackImpl> create(HelperType* helper)
{
return adoptRef(new SuccessCallbackImpl(helper));
}
virtual void handleEvent()
{
m_helper->setError(0);
}
virtual bool handleEvent(CallbackArg* arg)
{
m_helper->setResult(ResultType::create(arg));
return true;
}
private:
SuccessCallbackImpl(HelperType* helper)
: m_helper(helper)
{
}
HelperType* m_helper;
};
class ErrorCallbackImpl : public ErrorCallback {
public:
static PassRefPtr<ErrorCallbackImpl> create(HelperType* helper)
{
return adoptRef(new ErrorCallbackImpl(helper));
}
virtual bool handleEvent(FileError* error)
{
ASSERT(error);
m_helper->setError(error->code());
return true;
}
private:
ErrorCallbackImpl(HelperType* helper)
: m_helper(helper)
{
}
HelperType* m_helper;
};
friend class SuccessCallbackImpl;
friend class ErrorCallbackImpl;
void setError(int code)
{
m_exceptionCode = FileException::ErrorCodeToExceptionCode(code);
m_completed = true;
}
void setResult(PassRefPtr<ResultType> result)
{
m_result = result;
m_completed = true;
}
ObserverType* m_observer;
RefPtr<SuccessCallbackImpl> m_successCallback;
RefPtr<ErrorCallbackImpl> m_errorCallback;
RefPtr<ResultType> m_result;
ExceptionCode m_exceptionCode;
bool m_completed;
};
struct EmptyType : public RefCounted<EmptyType> {
static PassRefPtr<EmptyType> create(EmptyType*)
{
return 0;
}
};
struct EmptyObserverType {
bool waitForOperationToComplete()
{
return false;
}
};
typedef SyncCallbackHelper<EntryCallback, AsyncFileSystem, Entry, EntrySync> EntrySyncCallbackHelper;
typedef SyncCallbackHelper<EntriesCallback, AsyncFileSystem, EntryArray, EntryArraySync> EntriesSyncCallbackHelper;
typedef SyncCallbackHelper<MetadataCallback, AsyncFileSystem, Metadata, Metadata> MetadataSyncCallbackHelper;
typedef SyncCallbackHelper<VoidCallback, AsyncFileSystem, EmptyType, EmptyType> VoidSyncCallbackHelper;
typedef SyncCallbackHelper<FileSystemCallback, EmptyObserverType, DOMFileSystem, DOMFileSystemSync> FileSystemSyncCallbackHelper;
} // namespace WebCore
#endif // ENABLE(FILE_SYSTEM)
#endif // SyncCallbackHelper_h