diff options
Diffstat (limited to 'WebCore/html/FileReader.cpp')
-rw-r--r-- | WebCore/html/FileReader.cpp | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/WebCore/html/FileReader.cpp b/WebCore/html/FileReader.cpp index 69e01ce..3442342 100644 --- a/WebCore/html/FileReader.cpp +++ b/WebCore/html/FileReader.cpp @@ -41,6 +41,7 @@ #include "Logging.h" #include "ProgressEvent.h" #include "ScriptExecutionContext.h" +#include "TextResourceDecoder.h" #include <wtf/CurrentTime.h> namespace WebCore { @@ -50,14 +51,13 @@ const double progressNotificationIntervalMS = 50; FileReader::FileReader(ScriptExecutionContext* context) : ActiveDOMObject(context, this) - , m_state(Empty) + , m_state(None) , m_readType(ReadFileAsBinaryString) , m_result("") , m_isRawDataConverted(false) , m_bytesLoaded(0) , m_totalBytes(0) , m_lastProgressNotificationTimeMS(0) - , m_alreadyStarted(false) { m_buffer.resize(bufferSize); } @@ -69,7 +69,7 @@ FileReader::~FileReader() bool FileReader::hasPendingActivity() const { - return m_state == Loading || ActiveDOMObject::hasPendingActivity(); + return (m_state != None && m_state != Completed) || ActiveDOMObject::hasPendingActivity(); } bool FileReader::canSuspend() const @@ -110,11 +110,12 @@ void FileReader::readAsDataURL(File* file) void FileReader::readInternal(Blob* fileBlob, ReadType type) { // readAs*** methods() can be called multiple times. Only the last call before the actual reading happens is processed. - if (m_alreadyStarted) + if (m_state != None && m_state != Starting) return; m_fileBlob = fileBlob; m_readType = type; + m_state = Starting; // When FileStreamProxy is created, FileReader::didStart() will get notified on the File thread and we will start // opening and reading the file since then. @@ -142,18 +143,18 @@ void FileReader::terminate() m_streamProxy->stop(); m_streamProxy = 0; } - m_state = Done; + m_state = Completed; } void FileReader::didStart() { - m_alreadyStarted = true; + m_state = Opening; m_streamProxy->openForRead(m_fileBlob.get()); } void FileReader::didGetSize(long long size) { - m_state = Loading; + m_state = Reading; fireEvent(eventNames().loadstartEvent); m_totalBytes = size; @@ -165,7 +166,7 @@ void FileReader::didRead(const char* data, int bytesRead) ASSERT(data && bytesRead); // Bail out if we have aborted the reading. - if (m_state == Done) + if (m_state == Completed) return; switch (m_readType) { @@ -198,7 +199,7 @@ void FileReader::didRead(const char* data, int bytesRead) void FileReader::didFinish() { - m_state = Done; + m_state = Completed; m_streamProxy->close(); @@ -208,7 +209,7 @@ void FileReader::didFinish() void FileReader::didFail(ExceptionCode ec) { - m_state = Done; + m_state = Completed; m_error = FileError::create(ec); m_streamProxy->close(); @@ -223,6 +224,22 @@ void FileReader::fireEvent(const AtomicString& type) dispatchEvent(ProgressEvent::create(type, true, static_cast<unsigned>(m_bytesLoaded), static_cast<unsigned>(m_totalBytes))); } +FileReader::ReadyState FileReader::readyState() const +{ + switch (m_state) { + case None: + case Starting: + return Empty; + case Opening: + case Reading: + return Loading; + case Completed: + return Done; + } + ASSERT_NOT_REACHED(); + return Empty; +} + const ScriptString& FileReader::result() { // If reading as binary string, we can return the result immediately. @@ -237,7 +254,7 @@ const ScriptString& FileReader::result() if (m_readType == ReadFileAsText) convertToText(); // For data URL, we only do the coversion until we receive all the raw data. - else if (m_readType == ReadFileAsDataURL && m_state == Done) + else if (m_readType == ReadFileAsDataURL && m_state == Completed) convertToDataURL(); return m_result; @@ -250,26 +267,17 @@ void FileReader::convertToText() return; } - // Try to determine the encoding if it is not provided. - // FIXME: move the following logic to a more generic place. - int offset = 0; - if (!m_encoding.isValid()) { - if (m_rawData.size() >= 2 && m_rawData[0] == '\xFE' && m_rawData[1] == '\xFF') { - offset = 2; - m_encoding = UTF16BigEndianEncoding(); - } else if (m_rawData.size() >= 2 && m_rawData[0] == '\xFF' && m_rawData[1] == '\xFE') { - offset = 2; - m_encoding = UTF16LittleEndianEncoding(); - } else if (m_rawData.size() >= 2 && m_rawData[0] == '\xEF' && m_rawData[1] == '\xBB' && m_rawData[2] == '\xBF') { - offset = 3; - m_encoding = UTF8Encoding(); - } else - m_encoding = UTF8Encoding(); - } - // Decode the data. + // The File API spec says that we should use the supplied encoding if it is valid. However, we choose to ignore this + // requirement in order to be consistent with how WebKit decodes the web content: always has the BOM override the + // provided encoding. // FIXME: consider supporting incremental decoding to improve the perf. - m_result = m_encoding.decode(&m_rawData.at(0) + offset, m_rawData.size() - offset); + if (!m_decoder) + m_decoder = TextResourceDecoder::create("text/plain", m_encoding.isValid() ? m_encoding : UTF8Encoding()); + m_result = m_decoder->decode(&m_rawData.at(0), m_rawData.size()); + + if (m_state == Completed && !m_error) + m_result += m_decoder->flush(); } void FileReader::convertToDataURL() |