15ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen/*
25ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * Copyright (C) 2010 Google Inc.  All rights reserved.
35ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *
45ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * Redistribution and use in source and binary forms, with or without
55ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * modification, are permitted provided that the following conditions are
65ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * met:
75ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *
85ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *     * Redistributions of source code must retain the above copyright
95ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * notice, this list of conditions and the following disclaimer.
105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *     * Redistributions in binary form must reproduce the above
115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * copyright notice, this list of conditions and the following disclaimer
125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * in the documentation and/or other materials provided with the
135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * distribution.
145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *     * Neither the name of Google Inc. nor the names of its
155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * contributors may be used to endorse or promote products derived from
165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * this software without specific prior written permission.
175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *
185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen */
305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "config.h"
325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
3368513a70bcd92384395513322f1b801e7bf9c729Steve Block#if ENABLE(FILE_SYSTEM)
345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "FileWriter.h"
365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "AsyncFileWriter.h"
385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "Blob.h"
395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "ExceptionCode.h"
405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "FileError.h"
41e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "FileException.h"
425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "ProgressEvent.h"
435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsennamespace WebCore {
455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenFileWriter::FileWriter(ScriptExecutionContext* context)
475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    : ActiveDOMObject(context, this)
485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    , m_readyState(INIT)
49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_startedWriting(false)
505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    , m_bytesWritten(0)
515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    , m_bytesToWrite(0)
52bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_truncateLength(-1)
535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenFileWriter::~FileWriter()
575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_readyState == WRITING)
595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        stop();
605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenbool FileWriter::hasPendingActivity() const
635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return m_readyState == WRITING || ActiveDOMObject::hasPendingActivity();
655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenbool FileWriter::canSuspend() const
685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // FIXME: It is not currently possible to suspend a FileWriter, so pages with FileWriter can not go into page cache.
705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return false;
715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::stop()
745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (writer() && m_readyState == WRITING)
764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        writer()->abort();
77a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_blobBeingWritten.clear();
785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_readyState = DONE;
795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::write(Blob* data, ExceptionCode& ec)
825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(writer());
845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_readyState == WRITING) {
85e14391e94c850b8bd03680c23b38978db68687a8John Reck        setError(FileError::INVALID_STATE_ERR, ec);
865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return;
875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
88a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!data) {
89e14391e94c850b8bd03680c23b38978db68687a8John Reck        setError(FileError::TYPE_MISMATCH_ERR, ec);
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_blobBeingWritten = data;
945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_readyState = WRITING;
95a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_startedWriting = false;
965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesWritten = 0;
975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesToWrite = data->size();
984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    writer()->write(position(), data);
995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1005ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::seek(long long position, ExceptionCode& ec)
1025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(writer());
1045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_readyState == WRITING) {
105e14391e94c850b8bd03680c23b38978db68687a8John Reck        setError(FileError::INVALID_STATE_ERR, ec);
1065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return;
1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
1085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesWritten = 0;
1105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesToWrite = 0;
1114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    seekInternal(position);
1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::truncate(long long position, ExceptionCode& ec)
1155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(writer());
117bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (m_readyState == WRITING || position < 0) {
118e14391e94c850b8bd03680c23b38978db68687a8John Reck        setError(FileError::INVALID_STATE_ERR, ec);
1195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return;
1205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
1215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_readyState = WRITING;
1225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesWritten = 0;
1235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesToWrite = 0;
124bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_truncateLength = position;
1254576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    writer()->truncate(position);
1265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::abort(ExceptionCode& ec)
1295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(writer());
1315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_readyState != WRITING) {
132e14391e94c850b8bd03680c23b38978db68687a8John Reck        setError(FileError::INVALID_STATE_ERR, ec);
1335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return;
1345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
135e14391e94c850b8bd03680c23b38978db68687a8John Reck
136e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_error = FileError::create(FileError::ABORT_ERR);
1374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    writer()->abort();
1385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::didWrite(long long bytes, bool complete)
1415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    ASSERT(bytes + m_bytesWritten > 0);
1435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    ASSERT(bytes + m_bytesWritten <= m_bytesToWrite);
144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_startedWriting) {
145bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        fireEvent(eventNames().writestartEvent);
146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_startedWriting = true;
147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_bytesWritten += bytes;
149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT((m_bytesWritten == m_bytesToWrite) || !complete);
1504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    setPosition(position() + bytes);
1514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (position() > length())
1524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        setLength(position());
153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    fireEvent(eventNames().progressEvent);
154bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (complete) {
155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_blobBeingWritten.clear();
156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        fireEvent(eventNames().writeEvent);
157bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_readyState = DONE;
1585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        fireEvent(eventNames().writeendEvent);
159bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
1605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
162bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid FileWriter::didTruncate()
1635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
164bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(m_truncateLength >= 0);
165bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    fireEvent(eventNames().writestartEvent);
1664576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    setLength(m_truncateLength);
1674576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (position() > length())
1684576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        setPosition(length());
169bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_truncateLength = -1;
1705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    fireEvent(eventNames().writeEvent);
171bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_readyState = DONE;
1725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    fireEvent(eventNames().writeendEvent);
1735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
175e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileWriter::didFail(FileError::ErrorCode code)
1765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
177e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_error = FileError::create(code);
1785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    fireEvent(eventNames().errorEvent);
179e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (FileError::ABORT_ERR == code)
180bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        fireEvent(eventNames().abortEvent);
181bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    fireEvent(eventNames().errorEvent);
182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_blobBeingWritten.clear();
183bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_readyState = DONE;
1845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    fireEvent(eventNames().writeendEvent);
1855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FileWriter::fireEvent(const AtomicString& type)
1885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
189f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    dispatchEvent(ProgressEvent::create(type, true, m_bytesWritten, m_bytesToWrite));
1905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
192e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileWriter::setError(FileError::ErrorCode errorCode, ExceptionCode& ec)
193e14391e94c850b8bd03680c23b38978db68687a8John Reck{
194e14391e94c850b8bd03680c23b38978db68687a8John Reck    ec = FileException::ErrorCodeToExceptionCode(errorCode);
195e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_error = FileError::create(errorCode);
196e14391e94c850b8bd03680c23b38978db68687a8John Reck}
197e14391e94c850b8bd03680c23b38978db68687a8John Reck
1985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} // namespace WebCore
199e14391e94c850b8bd03680c23b38978db68687a8John Reck
20068513a70bcd92384395513322f1b801e7bf9c729Steve Block#endif // ENABLE(FILE_SYSTEM)
201