summaryrefslogtreecommitdiffstats
path: root/WebCore/html/FileReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/FileReader.cpp')
-rw-r--r--WebCore/html/FileReader.cpp66
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()