diff options
author | Shimeng (Simon) Wang <swang@google.com> | 2010-12-07 17:22:45 -0800 |
---|---|---|
committer | Shimeng (Simon) Wang <swang@google.com> | 2010-12-22 14:15:40 -0800 |
commit | 4576aa36e9a9671459299c7963ac95aa94beaea9 (patch) | |
tree | 3863574e050f168c0126ecb47c83319fab0972d8 /WebCore/fileapi | |
parent | 55323ac613cc31553107b68603cb627264d22bb0 (diff) | |
download | external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.zip external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.tar.gz external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.tar.bz2 |
Merge WebKit at r73109: Initial merge by git.
Change-Id: I61f1a66d9642e3d8405d3ac6ccab2a53421c75d8
Diffstat (limited to 'WebCore/fileapi')
-rw-r--r-- | WebCore/fileapi/AsyncFileWriter.h | 4 | ||||
-rw-r--r-- | WebCore/fileapi/DOMFileSystem.cpp | 27 | ||||
-rw-r--r-- | WebCore/fileapi/DOMFileSystemSync.cpp | 101 | ||||
-rw-r--r-- | WebCore/fileapi/DOMFileSystemSync.h | 2 | ||||
-rw-r--r-- | WebCore/fileapi/FileEntrySync.cpp | 6 | ||||
-rw-r--r-- | WebCore/fileapi/FileEntrySync.h | 2 | ||||
-rw-r--r-- | WebCore/fileapi/FileEntrySync.idl | 1 | ||||
-rw-r--r-- | WebCore/fileapi/FileError.h | 1 | ||||
-rw-r--r-- | WebCore/fileapi/FileReader.cpp | 13 | ||||
-rw-r--r-- | WebCore/fileapi/FileReaderLoader.cpp | 35 | ||||
-rw-r--r-- | WebCore/fileapi/FileSystemCallbacks.cpp | 14 | ||||
-rw-r--r-- | WebCore/fileapi/FileSystemCallbacks.h | 14 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriter.cpp | 50 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriter.h | 32 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriterBase.cpp | 76 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriterBase.h | 94 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriterBaseCallback.h | 52 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriterSync.cpp | 97 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriterSync.h | 38 | ||||
-rw-r--r-- | WebCore/fileapi/FileWriterSync.idl | 1 |
20 files changed, 532 insertions, 128 deletions
diff --git a/WebCore/fileapi/AsyncFileWriter.h b/WebCore/fileapi/AsyncFileWriter.h index fef1643..d6a28d5 100644 --- a/WebCore/fileapi/AsyncFileWriter.h +++ b/WebCore/fileapi/AsyncFileWriter.h @@ -47,6 +47,10 @@ public: virtual void write(long long position, Blob* data) = 0; virtual void truncate(long long length) = 0; virtual void abort() = 0; + virtual bool waitForOperationToComplete() // Needed for FileWriterSync only. + { + return false; + } }; } // namespace diff --git a/WebCore/fileapi/DOMFileSystem.cpp b/WebCore/fileapi/DOMFileSystem.cpp index f38acaa..f4ebe7c 100644 --- a/WebCore/fileapi/DOMFileSystem.cpp +++ b/WebCore/fileapi/DOMFileSystem.cpp @@ -41,6 +41,7 @@ #include "FileEntry.h" #include "FileSystemCallbacks.h" #include "FileWriter.h" +#include "FileWriterBaseCallback.h" #include "FileWriterCallback.h" #include "MetadataCallback.h" #include "ScriptExecutionContext.h" @@ -75,6 +76,29 @@ void DOMFileSystem::contextDestroyed() ActiveDOMObject::contextDestroyed(); } +namespace { + +class ConvertToFileWriterCallback : public FileWriterBaseCallback { +public: + static PassRefPtr<ConvertToFileWriterCallback> create(PassRefPtr<FileWriterCallback> callback) + { + return adoptRef(new ConvertToFileWriterCallback(callback)); + } + + bool handleEvent(FileWriterBase* fileWriterBase) + { + return m_callback->handleEvent(static_cast<FileWriter*>(fileWriterBase)); + } +private: + ConvertToFileWriterCallback(PassRefPtr<FileWriterCallback> callback) + : m_callback(callback) + { + } + RefPtr<FileWriterCallback> m_callback; +}; + +} + void DOMFileSystem::createWriter(const FileEntry* fileEntry, PassRefPtr<FileWriterCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) { ASSERT(fileEntry); @@ -82,7 +106,8 @@ void DOMFileSystem::createWriter(const FileEntry* fileEntry, PassRefPtr<FileWrit String platformPath = m_asyncFileSystem->virtualToPlatformPath(fileEntry->fullPath()); RefPtr<FileWriter> fileWriter = FileWriter::create(scriptExecutionContext()); - OwnPtr<FileWriterCallbacks> callbacks = FileWriterCallbacks::create(fileWriter, successCallback, errorCallback); + RefPtr<FileWriterBaseCallback> conversionCallback = ConvertToFileWriterCallback::create(successCallback); + OwnPtr<FileWriterBaseCallbacks> callbacks = FileWriterBaseCallbacks::create(fileWriter, conversionCallback, errorCallback); m_asyncFileSystem->createWriter(fileWriter.get(), platformPath, callbacks.release()); } diff --git a/WebCore/fileapi/DOMFileSystemSync.cpp b/WebCore/fileapi/DOMFileSystemSync.cpp index 3de64a7..dcbc9c7 100644 --- a/WebCore/fileapi/DOMFileSystemSync.cpp +++ b/WebCore/fileapi/DOMFileSystemSync.cpp @@ -35,11 +35,19 @@ #include "DOMFilePath.h" #include "DirectoryEntrySync.h" +#include "ErrorCallback.h" #include "File.h" #include "FileEntrySync.h" +#include "FileError.h" +#include "FileException.h" +#include "FileSystemCallbacks.h" +#include "FileWriterBaseCallback.h" +#include "FileWriterSync.h" namespace WebCore { +class FileWriterBase; + PassRefPtr<DOMFileSystemSync> DOMFileSystemSync::create(DOMFileSystemBase* fileSystem) { return adoptRef(new DOMFileSystemSync(fileSystem->m_name, fileSystem->m_asyncFileSystem.release())); @@ -66,6 +74,99 @@ PassRefPtr<File> DOMFileSystemSync::createFile(const FileEntrySync* fileEntry, E return File::create(platformPath); } +namespace { + +class ReceiveFileWriterCallback : public FileWriterBaseCallback { +public: + static PassRefPtr<ReceiveFileWriterCallback> create() + { + return adoptRef(new ReceiveFileWriterCallback()); + } + + bool handleEvent(FileWriterBase* fileWriterBase) + { +#ifndef NDEBUG + m_fileWriterBase = fileWriterBase; +#else + ASSERT_UNUSED(fileWriterBase, fileWriterBase); +#endif + return true; + } + +#ifndef NDEBUG + FileWriterBase* fileWriterBase() + { + return m_fileWriterBase; + } +#endif + +private: + ReceiveFileWriterCallback() +#ifndef NDEBUG + : m_fileWriterBase(0) +#endif + { + } + +#ifndef NDEBUG + FileWriterBase* m_fileWriterBase; +#endif +}; + +class LocalErrorCallback : public ErrorCallback { +public: + static PassRefPtr<LocalErrorCallback> create() + { + return adoptRef(new LocalErrorCallback()); + } + + bool handleEvent(FileError* error) + { + m_error = error; + return true; + } + + FileError* error() + { + return m_error.get(); + } + +private: + LocalErrorCallback() + { + } + RefPtr<FileError> m_error; +}; + +} + +PassRefPtr<FileWriterSync> DOMFileSystemSync::createWriter(const FileEntrySync* fileEntry, ExceptionCode& ec) +{ + ASSERT(fileEntry); + ec = 0; + + String platformPath = m_asyncFileSystem->virtualToPlatformPath(fileEntry->fullPath()); + + RefPtr<FileWriterSync> fileWriter = FileWriterSync::create(); + RefPtr<ReceiveFileWriterCallback> successCallback = ReceiveFileWriterCallback::create(); + RefPtr<LocalErrorCallback> errorCallback = LocalErrorCallback::create(); + + OwnPtr<FileWriterBaseCallbacks> callbacks = FileWriterBaseCallbacks::create(fileWriter, successCallback, errorCallback); + m_asyncFileSystem->createWriter(fileWriter.get(), platformPath, callbacks.release()); + if (!m_asyncFileSystem->waitForOperationToComplete()) { + ec = FileException::ABORT_ERR; + return 0; + } + if (errorCallback->error()) { + ASSERT(!successCallback->fileWriterBase()); + ec = FileException::ErrorCodeToExceptionCode(errorCallback->error()->code()); + return 0; + } + ASSERT(successCallback->fileWriterBase()); + ASSERT(static_cast<FileWriterSync*>(successCallback->fileWriterBase()) == fileWriter.get()); + return fileWriter; +} + } #endif // ENABLE(FILE_SYSTEM) diff --git a/WebCore/fileapi/DOMFileSystemSync.h b/WebCore/fileapi/DOMFileSystemSync.h index 1856747..ce07c85 100644 --- a/WebCore/fileapi/DOMFileSystemSync.h +++ b/WebCore/fileapi/DOMFileSystemSync.h @@ -40,6 +40,7 @@ namespace WebCore { class DirectoryEntrySync; class File; class FileEntrySync; +class FileWriterSync; typedef int ExceptionCode; @@ -57,6 +58,7 @@ public: PassRefPtr<DirectoryEntrySync> root(); PassRefPtr<File> createFile(const FileEntrySync*, ExceptionCode&); + PassRefPtr<FileWriterSync> createWriter(const FileEntrySync*, ExceptionCode&); private: DOMFileSystemSync(const String& name, PassOwnPtr<AsyncFileSystem>); diff --git a/WebCore/fileapi/FileEntrySync.cpp b/WebCore/fileapi/FileEntrySync.cpp index 36ec735..d899de7 100644 --- a/WebCore/fileapi/FileEntrySync.cpp +++ b/WebCore/fileapi/FileEntrySync.cpp @@ -34,6 +34,7 @@ #if ENABLE(FILE_SYSTEM) #include "File.h" +#include "FileWriterSync.h" namespace WebCore { @@ -47,6 +48,11 @@ PassRefPtr<File> FileEntrySync::file(ExceptionCode& ec) return filesystem()->createFile(this, ec); } +PassRefPtr<FileWriterSync> FileEntrySync::createWriter(ExceptionCode& ec) +{ + return filesystem()->createWriter(this, ec); +} + } #endif // ENABLE(FILE_SYSTEM) diff --git a/WebCore/fileapi/FileEntrySync.h b/WebCore/fileapi/FileEntrySync.h index be12e21..615a604 100644 --- a/WebCore/fileapi/FileEntrySync.h +++ b/WebCore/fileapi/FileEntrySync.h @@ -41,6 +41,7 @@ namespace WebCore { class File; +class FileWriterSync; class FileEntrySync : public EntrySync { public: @@ -52,6 +53,7 @@ public: virtual bool isFile() const { return true; } PassRefPtr<File> file(ExceptionCode&); + PassRefPtr<FileWriterSync> createWriter(ExceptionCode&); private: friend class EntrySync; diff --git a/WebCore/fileapi/FileEntrySync.idl b/WebCore/fileapi/FileEntrySync.idl index e2d2871..c569839 100644 --- a/WebCore/fileapi/FileEntrySync.idl +++ b/WebCore/fileapi/FileEntrySync.idl @@ -36,5 +36,6 @@ module storage { NoStaticTables ] FileEntrySync : EntrySync { File file() raises (FileException); + FileWriterSync createWriter() raises (FileException); }; } diff --git a/WebCore/fileapi/FileError.h b/WebCore/fileapi/FileError.h index 27ad397..0597633 100644 --- a/WebCore/fileapi/FileError.h +++ b/WebCore/fileapi/FileError.h @@ -41,6 +41,7 @@ namespace WebCore { class FileError : public RefCounted<FileError> { public: enum ErrorCode { + OK = 0, NOT_FOUND_ERR = 1, SECURITY_ERR = 2, ABORT_ERR = 3, diff --git a/WebCore/fileapi/FileReader.cpp b/WebCore/fileapi/FileReader.cpp index a54a337..9ee3b01 100644 --- a/WebCore/fileapi/FileReader.cpp +++ b/WebCore/fileapi/FileReader.cpp @@ -35,20 +35,16 @@ #include "FileReader.h" #include "ArrayBuffer.h" -#include "Blob.h" #include "CrossThreadTask.h" #include "File.h" #include "Logging.h" #include "ProgressEvent.h" #include "ScriptExecutionContext.h" #include <wtf/CurrentTime.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> namespace WebCore { -const double progressNotificationIntervalMS = 50; +static const double progressNotificationIntervalMS = 50; FileReader::FileReader(ScriptExecutionContext* context) : ActiveDOMObject(context, this) @@ -195,7 +191,7 @@ void FileReader::didStartLoading() void FileReader::didReceiveData() { // Fire the progress event at least every 50ms. - double now = WTF::currentTimeMS(); + double now = currentTimeMS(); if (!m_lastProgressNotificationTimeMS) m_lastProgressNotificationTimeMS = now; else if (now - m_lastProgressNotificationTimeMS > progressNotificationIntervalMS) { @@ -227,10 +223,7 @@ void FileReader::didFail(int errorCode) void FileReader::fireEvent(const AtomicString& type) { - // FIXME: the current ProgressEvent uses "unsigned long" for total and loaded attributes. Need to talk with the spec writer to resolve the issue. - unsigned bytesLoaded = m_loader ? m_loader->bytesLoaded() : 0; - unsigned totalBytes = m_loader ? m_loader->totalBytes() : 0; - dispatchEvent(ProgressEvent::create(type, true, bytesLoaded, totalBytes)); + dispatchEvent(ProgressEvent::create(type, true, m_loader ? m_loader->bytesLoaded() : 0, m_loader ? m_loader->totalBytes() : 0)); } FileReader::ReadyState FileReader::readyState() const diff --git a/WebCore/fileapi/FileReaderLoader.cpp b/WebCore/fileapi/FileReaderLoader.cpp index dcd5860..24904e2 100644 --- a/WebCore/fileapi/FileReaderLoader.cpp +++ b/WebCore/fileapi/FileReaderLoader.cpp @@ -50,6 +50,8 @@ #include <wtf/Vector.h> #include <wtf/text/StringBuilder.h> +using namespace std; + namespace WebCore { FileReaderLoader::FileReaderLoader(ReadType readType, FileReaderLoaderClient* client) @@ -124,15 +126,25 @@ void FileReaderLoader::didReceiveResponse(const ResourceResponse& response) return; } + unsigned long long length = response.expectedContentLength(); + + // Check that we can cast to unsigned since we have to do + // so to call ArrayBuffer's create function. // FIXME: Support reading more than the current size limit of ArrayBuffer. - if (static_cast<unsigned long long>(response.expectedContentLength()) > std::numeric_limits<unsigned>::max()) { + if (length > numeric_limits<unsigned>::max()) { failed(FileError::NOT_READABLE_ERR); return; } - m_totalBytes = static_cast<unsigned>(response.expectedContentLength()); ASSERT(!m_rawData); - m_rawData = ArrayBuffer::create(static_cast<unsigned>(m_totalBytes), 1); + m_rawData = ArrayBuffer::create(static_cast<unsigned>(length), 1); + + if (!m_rawData) { + failed(FileError::NOT_READABLE_ERR); + return; + } + + m_totalBytes = static_cast<unsigned>(length); if (m_client) m_client->didStartLoading(); @@ -140,14 +152,23 @@ void FileReaderLoader::didReceiveResponse(const ResourceResponse& response) void FileReaderLoader::didReceiveData(const char* data, int lengthReceived) { - ASSERT(data && lengthReceived > 0); + ASSERT(data); + ASSERT(lengthReceived > 0); - // Bail out if we encounter an error. + // Bail out if we already encountered an error. if (m_errorCode) return; - memcpy(static_cast<char*>(m_rawData->data()) + static_cast<unsigned>(m_bytesLoaded), data, static_cast<unsigned>(lengthReceived)); - m_bytesLoaded += static_cast<unsigned>(lengthReceived); + int length = lengthReceived; + unsigned remainingBufferSpace = m_totalBytes - m_bytesLoaded; + if (length > static_cast<long long>(remainingBufferSpace)) + length = static_cast<int>(remainingBufferSpace); + + if (length <= 0) + return; + + memcpy(static_cast<char*>(m_rawData->data()) + m_bytesLoaded, data, length); + m_bytesLoaded += length; m_isRawDataConverted = false; diff --git a/WebCore/fileapi/FileSystemCallbacks.cpp b/WebCore/fileapi/FileSystemCallbacks.cpp index 6644589..966337b 100644 --- a/WebCore/fileapi/FileSystemCallbacks.cpp +++ b/WebCore/fileapi/FileSystemCallbacks.cpp @@ -47,8 +47,8 @@ #include "FileError.h" #include "FileMetadata.h" #include "FileSystemCallback.h" -#include "FileWriter.h" -#include "FileWriterCallback.h" +#include "FileWriterBase.h" +#include "FileWriterBaseCallback.h" #include "Metadata.h" #include "MetadataCallback.h" #include "ScriptExecutionContext.h" @@ -212,21 +212,21 @@ void MetadataCallbacks::didReadMetadata(const FileMetadata& metadata) m_successCallback.clear(); } -// FileWriterCallbacks ---------------------------------------------------------- +// FileWriterBaseCallbacks ---------------------------------------------------------- -PassOwnPtr<FileWriterCallbacks> FileWriterCallbacks::create(PassRefPtr<FileWriter> fileWriter, PassRefPtr<FileWriterCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) +PassOwnPtr<FileWriterBaseCallbacks> FileWriterBaseCallbacks::create(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) { - return adoptPtr(new FileWriterCallbacks(fileWriter, successCallback, errorCallback)); + return adoptPtr(new FileWriterBaseCallbacks(fileWriter, successCallback, errorCallback)); } -FileWriterCallbacks::FileWriterCallbacks(PassRefPtr<FileWriter> fileWriter, PassRefPtr<FileWriterCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) +FileWriterBaseCallbacks::FileWriterBaseCallbacks(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) : FileSystemCallbacksBase(errorCallback) , m_fileWriter(fileWriter) , m_successCallback(successCallback) { } -void FileWriterCallbacks::didCreateFileWriter(PassOwnPtr<AsyncFileWriter> asyncFileWriter, long long length) +void FileWriterBaseCallbacks::didCreateFileWriter(PassOwnPtr<AsyncFileWriter> asyncFileWriter, long long length) { m_fileWriter->initialize(asyncFileWriter, length); if (m_successCallback) diff --git a/WebCore/fileapi/FileSystemCallbacks.h b/WebCore/fileapi/FileSystemCallbacks.h index 100fd0c..83000c2 100644 --- a/WebCore/fileapi/FileSystemCallbacks.h +++ b/WebCore/fileapi/FileSystemCallbacks.h @@ -49,8 +49,8 @@ class EntryArray; class EntryCallback; struct FileMetadata; class FileSystemCallback; -class FileWriter; -class FileWriterCallback; +class FileWriterBase; +class FileWriterBaseCallback; class MetadataCallback; class ScriptExecutionContext; class VoidCallback; @@ -133,15 +133,15 @@ private: RefPtr<MetadataCallback> m_successCallback; }; -class FileWriterCallbacks : public FileSystemCallbacksBase { +class FileWriterBaseCallbacks : public FileSystemCallbacksBase { public: - static PassOwnPtr<FileWriterCallbacks> create(PassRefPtr<FileWriter>, PassRefPtr<FileWriterCallback>, PassRefPtr<ErrorCallback>); + static PassOwnPtr<FileWriterBaseCallbacks> create(PassRefPtr<FileWriterBase>, PassRefPtr<FileWriterBaseCallback>, PassRefPtr<ErrorCallback>); virtual void didCreateFileWriter(PassOwnPtr<AsyncFileWriter>, long long length); private: - FileWriterCallbacks(PassRefPtr<FileWriter>, PassRefPtr<FileWriterCallback>, PassRefPtr<ErrorCallback>); - RefPtr<FileWriter> m_fileWriter; - RefPtr<FileWriterCallback> m_successCallback; + FileWriterBaseCallbacks(PassRefPtr<FileWriterBase>, PassRefPtr<FileWriterBaseCallback>, PassRefPtr<ErrorCallback>); + RefPtr<FileWriterBase> m_fileWriter; + RefPtr<FileWriterBaseCallback> m_successCallback; }; class VoidCallbacks : public FileSystemCallbacksBase { diff --git a/WebCore/fileapi/FileWriter.cpp b/WebCore/fileapi/FileWriter.cpp index 7775709..45ba42b 100644 --- a/WebCore/fileapi/FileWriter.cpp +++ b/WebCore/fileapi/FileWriter.cpp @@ -46,7 +46,6 @@ namespace WebCore { FileWriter::FileWriter(ScriptExecutionContext* context) : ActiveDOMObject(context, this) , m_readyState(INIT) - , m_position(0) , m_startedWriting(false) , m_bytesWritten(0) , m_bytesToWrite(0) @@ -54,14 +53,6 @@ FileWriter::FileWriter(ScriptExecutionContext* context) { } -void FileWriter::initialize(PassOwnPtr<AsyncFileWriter> writer, long long length) -{ - ASSERT(!m_writer); - ASSERT(length >= 0); - m_writer = writer; - m_length = length; -} - FileWriter::~FileWriter() { if (m_readyState == WRITING) @@ -81,15 +72,15 @@ bool FileWriter::canSuspend() const void FileWriter::stop() { - if (m_writer && m_readyState == WRITING) - m_writer->abort(); + if (writer() && m_readyState == WRITING) + writer()->abort(); m_blobBeingWritten.clear(); m_readyState = DONE; } void FileWriter::write(Blob* data, ExceptionCode& ec) { - ASSERT(m_writer); + ASSERT(writer()); if (m_readyState == WRITING) { setError(FileError::INVALID_STATE_ERR, ec); return; @@ -104,12 +95,12 @@ void FileWriter::write(Blob* data, ExceptionCode& ec) m_startedWriting = false; m_bytesWritten = 0; m_bytesToWrite = data->size(); - m_writer->write(m_position, data); + writer()->write(position(), data); } void FileWriter::seek(long long position, ExceptionCode& ec) { - ASSERT(m_writer); + ASSERT(writer()); if (m_readyState == WRITING) { setError(FileError::INVALID_STATE_ERR, ec); return; @@ -117,18 +108,12 @@ void FileWriter::seek(long long position, ExceptionCode& ec) m_bytesWritten = 0; m_bytesToWrite = 0; - if (position > m_length) - position = m_length; - else if (position < 0) - position = m_length + position; - if (position < 0) - position = 0; - m_position = position; + seekInternal(position); } void FileWriter::truncate(long long position, ExceptionCode& ec) { - ASSERT(m_writer); + ASSERT(writer()); if (m_readyState == WRITING || position < 0) { setError(FileError::INVALID_STATE_ERR, ec); return; @@ -137,19 +122,19 @@ void FileWriter::truncate(long long position, ExceptionCode& ec) m_bytesWritten = 0; m_bytesToWrite = 0; m_truncateLength = position; - m_writer->truncate(position); + writer()->truncate(position); } void FileWriter::abort(ExceptionCode& ec) { - ASSERT(m_writer); + ASSERT(writer()); if (m_readyState != WRITING) { setError(FileError::INVALID_STATE_ERR, ec); return; } m_error = FileError::create(FileError::ABORT_ERR); - m_writer->abort(); + writer()->abort(); } void FileWriter::didWrite(long long bytes, bool complete) @@ -162,9 +147,9 @@ void FileWriter::didWrite(long long bytes, bool complete) } m_bytesWritten += bytes; ASSERT((m_bytesWritten == m_bytesToWrite) || !complete); - m_position += bytes; - if (m_position > m_length) - m_length = m_position; + setPosition(position() + bytes); + if (position() > length()) + setLength(position()); fireEvent(eventNames().progressEvent); if (complete) { m_blobBeingWritten.clear(); @@ -178,9 +163,9 @@ void FileWriter::didTruncate() { ASSERT(m_truncateLength >= 0); fireEvent(eventNames().writestartEvent); - m_length = m_truncateLength; - if (m_position > m_length) - m_position = m_length; + setLength(m_truncateLength); + if (position() > length()) + setPosition(length()); m_truncateLength = -1; fireEvent(eventNames().writeEvent); m_readyState = DONE; @@ -201,8 +186,7 @@ void FileWriter::didFail(FileError::ErrorCode code) void FileWriter::fireEvent(const AtomicString& type) { - // FIXME: the current ProgressEvent uses "unsigned long" for total and loaded attributes. Need to talk with the spec writer to resolve the issue. - dispatchEvent(ProgressEvent::create(type, true, static_cast<unsigned>(m_bytesWritten), static_cast<unsigned>(m_bytesToWrite))); + dispatchEvent(ProgressEvent::create(type, true, m_bytesWritten, m_bytesToWrite)); } void FileWriter::setError(FileError::ErrorCode errorCode, ExceptionCode& ec) diff --git a/WebCore/fileapi/FileWriter.h b/WebCore/fileapi/FileWriter.h index 0e884ea..89289a9 100644 --- a/WebCore/fileapi/FileWriter.h +++ b/WebCore/fileapi/FileWriter.h @@ -34,45 +34,34 @@ #if ENABLE(FILE_SYSTEM) #include "ActiveDOMObject.h" -#include "AsyncFileWriterClient.h" #include "EventTarget.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> +#include "FileWriterBase.h" #include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> #include <wtf/RefPtr.h> namespace WebCore { -class AsyncFileWriter; -class Blob; -class FileError; class ScriptExecutionContext; -class FileWriter : public RefCounted<FileWriter>, public ActiveDOMObject, public EventTarget, public AsyncFileWriterClient { +class FileWriter : public FileWriterBase, public ActiveDOMObject, public EventTarget, public AsyncFileWriterClient { public: static PassRefPtr<FileWriter> create(ScriptExecutionContext* context) { return adoptRef(new FileWriter(context)); } - void initialize(PassOwnPtr<AsyncFileWriter> writer, long long length); - enum ReadyState { INIT = 0, WRITING = 1, DONE = 2 }; - void write(Blob* data, ExceptionCode& ec); - void seek(long long position, ExceptionCode& ec); - void truncate(long long length, ExceptionCode& ec); - void abort(ExceptionCode& ec); - + void write(Blob*, ExceptionCode&); + void seek(long long position, ExceptionCode&); + void truncate(long long length, ExceptionCode&); + void abort(ExceptionCode&); ReadyState readyState() const { return m_readyState; } FileError* error() const { return m_error.get(); } - long long position() const { return m_position; } - long long length() const { return m_length; } // AsyncFileWriterClient void didWrite(long long bytes, bool complete); @@ -88,8 +77,8 @@ public: virtual FileWriter* toFileWriter() { return this; } virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); } - using RefCounted<FileWriter>::ref; - using RefCounted<FileWriter>::deref; + using RefCounted<FileWriterBase>::ref; + using RefCounted<FileWriterBase>::deref; DEFINE_ATTRIBUTE_EVENT_LISTENER(writestart); DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); @@ -103,8 +92,6 @@ private: virtual ~FileWriter(); - friend class WTF::RefCounted<FileWriter>; - // EventTarget virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } @@ -117,10 +104,7 @@ private: RefPtr<FileError> m_error; EventTargetData m_eventTargetData; - OwnPtr<AsyncFileWriter> m_writer; ReadyState m_readyState; - long long m_position; - long long m_length; bool m_startedWriting; long long m_bytesWritten; long long m_bytesToWrite; diff --git a/WebCore/fileapi/FileWriterBase.cpp b/WebCore/fileapi/FileWriterBase.cpp new file mode 100644 index 0000000..dc55bb8 --- /dev/null +++ b/WebCore/fileapi/FileWriterBase.cpp @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#include "config.h" + +#if ENABLE(FILE_SYSTEM) + +#include "FileWriterBase.h" + +#include "AsyncFileWriter.h" +#include "Blob.h" +#include "ExceptionCode.h" +#include "FileError.h" +#include "FileException.h" +#include "ProgressEvent.h" + +namespace WebCore { + +FileWriterBase::~FileWriterBase() +{ +} + +void FileWriterBase::initialize(PassOwnPtr<AsyncFileWriter> writer, long long length) +{ + ASSERT(!m_writer); + ASSERT(length >= 0); + m_writer = writer; + m_length = length; +} + +FileWriterBase::FileWriterBase() + : m_position(0) +{ +} + +void FileWriterBase::seekInternal(long long position) +{ + if (position > m_length) + position = m_length; + else if (position < 0) + position = m_length + position; + if (position < 0) + position = 0; + m_position = position; +} + +} // namespace WebCore + +#endif // ENABLE(FILE_SYSTEM) diff --git a/WebCore/fileapi/FileWriterBase.h b/WebCore/fileapi/FileWriterBase.h new file mode 100644 index 0000000..2eecfff --- /dev/null +++ b/WebCore/fileapi/FileWriterBase.h @@ -0,0 +1,94 @@ +/* + * 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 FileWriterBase_h +#define FileWriterBase_h + +#if ENABLE(FILE_SYSTEM) + +#include "AsyncFileWriterClient.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class AsyncFileWriter; +class Blob; + +typedef int ExceptionCode; + +class FileWriterBase : public RefCounted<FileWriterBase> { +public: + virtual ~FileWriterBase(); + void initialize(PassOwnPtr<AsyncFileWriter>, long long length); + + long long position() const + { + return m_position; + } + long long length() const + { + return m_length; + } + +protected: + FileWriterBase(); + + AsyncFileWriter* writer() + { + return m_writer.get(); + } + + void setPosition(long long position) + { + m_position = position; + } + + void setLength(long long length) + { + m_length = length; + } + + void seekInternal(long long position); + +private: + friend class WTF::RefCounted<FileWriterBase>; + + OwnPtr<AsyncFileWriter> m_writer; + long long m_position; + long long m_length; +}; + +} // namespace WebCore + +#endif // ENABLE(FILE_SYSTEM) + +#endif // FileWriterBase_h diff --git a/WebCore/fileapi/FileWriterBaseCallback.h b/WebCore/fileapi/FileWriterBaseCallback.h new file mode 100644 index 0000000..51e8ab7 --- /dev/null +++ b/WebCore/fileapi/FileWriterBaseCallback.h @@ -0,0 +1,52 @@ +/* + * 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 FileWriterBaseCallback_h +#define FileWriterBaseCallback_h + +#if ENABLE(FILE_SYSTEM) + +#include <wtf/RefCounted.h> + +namespace WebCore { + +class FileWriterBase; + +class FileWriterBaseCallback : public RefCounted<FileWriterBaseCallback> { +public: + virtual ~FileWriterBaseCallback() { } + virtual bool handleEvent(FileWriterBase*) = 0; +}; + +} // namespace + +#endif // ENABLE(FILE_SYSTEM) + +#endif // FileWriterBaseCallback_h diff --git a/WebCore/fileapi/FileWriterSync.cpp b/WebCore/fileapi/FileWriterSync.cpp index 5fa5137..28a68f8 100644 --- a/WebCore/fileapi/FileWriterSync.cpp +++ b/WebCore/fileapi/FileWriterSync.cpp @@ -34,46 +34,109 @@ #include "FileWriterSync.h" +#include "AsyncFileWriter.h" +#include "Blob.h" +#include "FileException.h" + namespace WebCore { -void FileWriterSync::write(Blob*, ExceptionCode&) +void FileWriterSync::write(Blob* data, ExceptionCode& ec) { - ASSERT_NOT_REACHED(); // FIXME: Not implemented yet. + ASSERT(writer()); + ASSERT(m_complete); + ec = 0; + if (!data) { + ec = FileException::TYPE_MISMATCH_ERR; + return; + } + + prepareForWrite(); + writer()->write(position(), data); + writer()->waitForOperationToComplete(); + ASSERT(m_complete); + ec = FileException::ErrorCodeToExceptionCode(m_error); + if (ec) + return; + setPosition(position() + data->size()); + if (position() > length()) + setLength(position()); } -void FileWriterSync::seek(long long, ExceptionCode&) +void FileWriterSync::seek(long long position, ExceptionCode& ec) { - ASSERT_NOT_REACHED(); // FIXME: Not implemented yet. + ASSERT(writer()); + ASSERT(m_complete); + ec = 0; + seekInternal(position); } -void FileWriterSync::truncate(long long, ExceptionCode&) +void FileWriterSync::truncate(long long offset, ExceptionCode& ec) { - ASSERT_NOT_REACHED(); // FIXME: Not implemented yet. + ASSERT(writer()); + ASSERT(m_complete); + ec = 0; + if (offset < 0) { + ec = FileException::INVALID_STATE_ERR; + return; + } + prepareForWrite(); + writer()->truncate(offset); + writer()->waitForOperationToComplete(); + ASSERT(m_complete); + ec = FileException::ErrorCodeToExceptionCode(m_error); + if (ec) + return; + if (offset < position()) + setPosition(offset); + setLength(offset); } -bool FileWriterSync::canSuspend() const +void FileWriterSync::didWrite(long long bytes, bool complete) { - // FIXME: It is not currently possible to suspend a FileWriterSync, so pages with FileWriter can not go into page cache. - return false; + ASSERT(m_error == FileError::OK); + ASSERT(!m_complete); +#ifndef NDEBUG + m_complete = complete; +#else + ASSERT_UNUSED(complete, complete); +#endif } -bool FileWriterSync::hasPendingActivity() const +void FileWriterSync::didTruncate() { - return ActiveDOMObject::hasPendingActivity(); + ASSERT(m_error == FileError::OK); + ASSERT(!m_complete); +#ifndef NDEBUG + m_complete = true; +#endif } -void FileWriterSync::stop() +void FileWriterSync::didFail(FileError::ErrorCode error) { + ASSERT(m_error == FileError::OK); + m_error = error; + ASSERT(!m_complete); +#ifndef NDEBUG + m_complete = true; +#endif } - -FileWriterSync::FileWriterSync(ScriptExecutionContext* context) - : ActiveDOMObject(context, this) - , m_position(0) - , m_length(0) +FileWriterSync::FileWriterSync() + : m_error(FileError::OK) +#ifndef NDEBUG + , m_complete(true) +#endif { } +void FileWriterSync::prepareForWrite() +{ + ASSERT(m_complete); + m_error = FileError::OK; +#ifndef NDEBUG + m_complete = false; +#endif +} FileWriterSync::~FileWriterSync() { diff --git a/WebCore/fileapi/FileWriterSync.h b/WebCore/fileapi/FileWriterSync.h index 0051870..3917f2e 100644 --- a/WebCore/fileapi/FileWriterSync.h +++ b/WebCore/fileapi/FileWriterSync.h @@ -34,8 +34,9 @@ #if ENABLE(FILE_SYSTEM) #include "ActiveDOMObject.h" +#include "FileError.h" +#include "FileWriterBase.h" #include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> namespace WebCore { @@ -43,37 +44,32 @@ class Blob; typedef int ExceptionCode; -// FIXME: This is an empty shell waiting for implementation. -class FileWriterSync : public RefCounted<FileWriterSync>, public ActiveDOMObject { +class FileWriterSync : public FileWriterBase, public AsyncFileWriterClient { public: - static PassRefPtr<FileWriterSync> create(ScriptExecutionContext* context) + static PassRefPtr<FileWriterSync> create() { - return adoptRef(new FileWriterSync(context)); + return adoptRef(new FileWriterSync()); } virtual ~FileWriterSync(); - void write(Blob* data, ExceptionCode&); + // FileWriterBase + void write(Blob*, ExceptionCode&); void seek(long long position, ExceptionCode&); void truncate(long long length, ExceptionCode&); - long long position() const { return m_position; } - long long length() const { return m_length; } - - // ActiveDOMObject - virtual bool canSuspend() const; - virtual bool hasPendingActivity() const; - virtual void stop(); - - using RefCounted<FileWriterSync>::ref; - using RefCounted<FileWriterSync>::deref; + // AsyncFileWriterClient, via FileWriterBase + void didWrite(long long bytes, bool complete); + void didTruncate(); + void didFail(FileError::ErrorCode); private: - FileWriterSync(ScriptExecutionContext*); - - friend class RefCounted<FileWriterSync>; + FileWriterSync(); + void prepareForWrite(); - long long m_position; - long long m_length; + FileError::ErrorCode m_error; +#ifndef NDEBUG + bool m_complete; +#endif }; } // namespace WebCore diff --git a/WebCore/fileapi/FileWriterSync.idl b/WebCore/fileapi/FileWriterSync.idl index 214c509..c561bb4 100644 --- a/WebCore/fileapi/FileWriterSync.idl +++ b/WebCore/fileapi/FileWriterSync.idl @@ -31,7 +31,6 @@ module html { interface [ Conditional=FILE_SYSTEM, - CallWith=ScriptExecutionContext ] FileWriterSync { // synchronous write/modify methods void write(in Blob data) raises (FileException); |