/* * 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 "FileWriter.h" #include "AsyncFileWriter.h" #include "Blob.h" #include "ExceptionCode.h" #include "FileError.h" #include "FileException.h" #include "ProgressEvent.h" namespace WebCore { FileWriter::FileWriter(ScriptExecutionContext* context) : ActiveDOMObject(context, this) , m_readyState(INIT) , m_startedWriting(false) , m_bytesWritten(0) , m_bytesToWrite(0) , m_truncateLength(-1) { } FileWriter::~FileWriter() { if (m_readyState == WRITING) stop(); } bool FileWriter::hasPendingActivity() const { return m_readyState == WRITING || ActiveDOMObject::hasPendingActivity(); } bool FileWriter::canSuspend() const { // FIXME: It is not currently possible to suspend a FileWriter, so pages with FileWriter can not go into page cache. return false; } void FileWriter::stop() { if (writer() && m_readyState == WRITING) writer()->abort(); m_blobBeingWritten.clear(); m_readyState = DONE; } void FileWriter::write(Blob* data, ExceptionCode& ec) { ASSERT(writer()); if (m_readyState == WRITING) { setError(FileError::INVALID_STATE_ERR, ec); return; } if (!data) { setError(FileError::TYPE_MISMATCH_ERR, ec); return; } m_blobBeingWritten = data; m_readyState = WRITING; m_startedWriting = false; m_bytesWritten = 0; m_bytesToWrite = data->size(); writer()->write(position(), data); } void FileWriter::seek(long long position, ExceptionCode& ec) { ASSERT(writer()); if (m_readyState == WRITING) { setError(FileError::INVALID_STATE_ERR, ec); return; } m_bytesWritten = 0; m_bytesToWrite = 0; seekInternal(position); } void FileWriter::truncate(long long position, ExceptionCode& ec) { ASSERT(writer()); if (m_readyState == WRITING || position < 0) { setError(FileError::INVALID_STATE_ERR, ec); return; } m_readyState = WRITING; m_bytesWritten = 0; m_bytesToWrite = 0; m_truncateLength = position; writer()->truncate(position); } void FileWriter::abort(ExceptionCode& ec) { ASSERT(writer()); if (m_readyState != WRITING) { setError(FileError::INVALID_STATE_ERR, ec); return; } m_error = FileError::create(FileError::ABORT_ERR); writer()->abort(); } void FileWriter::didWrite(long long bytes, bool complete) { ASSERT(bytes + m_bytesWritten > 0); ASSERT(bytes + m_bytesWritten <= m_bytesToWrite); if (!m_startedWriting) { fireEvent(eventNames().writestartEvent); m_startedWriting = true; } m_bytesWritten += bytes; ASSERT((m_bytesWritten == m_bytesToWrite) || !complete); setPosition(position() + bytes); if (position() > length()) setLength(position()); fireEvent(eventNames().progressEvent); if (complete) { m_blobBeingWritten.clear(); fireEvent(eventNames().writeEvent); m_readyState = DONE; fireEvent(eventNames().writeendEvent); } } void FileWriter::didTruncate() { ASSERT(m_truncateLength >= 0); fireEvent(eventNames().writestartEvent); setLength(m_truncateLength); if (position() > length()) setPosition(length()); m_truncateLength = -1; fireEvent(eventNames().writeEvent); m_readyState = DONE; fireEvent(eventNames().writeendEvent); } void FileWriter::didFail(FileError::ErrorCode code) { m_error = FileError::create(code); fireEvent(eventNames().errorEvent); if (FileError::ABORT_ERR == code) fireEvent(eventNames().abortEvent); fireEvent(eventNames().errorEvent); m_blobBeingWritten.clear(); m_readyState = DONE; fireEvent(eventNames().writeendEvent); } void FileWriter::fireEvent(const AtomicString& type) { dispatchEvent(ProgressEvent::create(type, true, m_bytesWritten, m_bytesToWrite)); } void FileWriter::setError(FileError::ErrorCode errorCode, ExceptionCode& ec) { ec = FileException::ErrorCodeToExceptionCode(errorCode); m_error = FileError::create(errorCode); } } // namespace WebCore #endif // ENABLE(FILE_SYSTEM)