15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc.  All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/FileReaderLoader.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/FetchInitiatorTypeNames.h"
361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/Blob.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/FileReaderLoaderClient.h"
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/html/parser/TextResourceDecoder.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/ThreadableLoader.h"
41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/streams/Stream.h"
42bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/blob/BlobRegistry.h"
43bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/blob/BlobURL.h"
44bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceRequest.h"
45bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceResponse.h"
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "public/platform/WebURLRequest.h"
47bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "wtf/PassOwnPtr.h"
48e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/PassRefPtr.h"
49e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/RefPtr.h"
50e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/Vector.h"
51e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/Base64.h"
52e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/StringBuilder.h"
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FileReaderLoader::FileReaderLoader(ReadType readType, FileReaderLoaderClient* client)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_readType(readType)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_client(client)
5906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    , m_urlForReadingIsStream(false)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_isRawDataConverted(false)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_stringResult("")
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    , m_finishedLoading(false)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_bytesLoaded(0)
64bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    , m_totalBytes(-1)
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_hasRange(false)
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_rangeStart(0)
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_rangeEnd(0)
68591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    , m_errorCode(FileError::OK)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FileReaderLoader::~FileReaderLoader()
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    terminate();
7506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!m_urlForReading.isEmpty()) {
7606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (m_urlForReadingIsStream)
7706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            BlobRegistry::unregisterStreamURL(m_urlForReading);
7806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        else
791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            BlobRegistry::revokePublicBlobURL(m_urlForReading);
8006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
83a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochvoid FileReaderLoader::startInternal(ExecutionContext& executionContext, const Stream* stream, PassRefPtr<BlobDataHandle> blobData)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The blob is read by routing through the request handling layer given a temporary public url.
86a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    m_urlForReading = BlobURL::createPublicURL(executionContext.securityOrigin());
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_urlForReading.isEmpty()) {
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        failed(FileError::SECURITY_ERR);
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (blobData) {
931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ASSERT(!stream);
94a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        BlobRegistry::registerPublicBlobURL(executionContext.securityOrigin(), m_urlForReading, blobData);
951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else {
961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ASSERT(stream);
97a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        BlobRegistry::registerStreamURL(executionContext.securityOrigin(), m_urlForReading, stream->url());
981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Construct and load the request.
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceRequest request(m_urlForReading);
102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
103197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // FIXME: Should this really be 'internal'? Do we know anything about the actual request that generated this fetch?
104e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    request.setRequestContext(WebURLRequest::RequestContextInternal);
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    request.setHTTPMethod("GET");
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_hasRange)
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        request.setHTTPHeaderField("Range", AtomicString(String::format("bytes=%d-%d", m_rangeStart, m_rangeEnd)));
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ThreadableLoaderOptions options;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    options.preflightPolicy = ConsiderPreflight;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    options.crossOriginRequestPolicy = DenyCrossOriginRequests;
113e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    // FIXME: Is there a directive to which this load should be subject?
114e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    options.contentSecurityPolicyEnforcement = DoNotEnforceContentSecurityPolicy;
1151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // Use special initiator to hide the request from the inspector.
1161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    options.initiator = FetchInitiatorTypeNames::internal;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
118f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ResourceLoaderOptions resourceLoaderOptions;
119f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
120f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_client)
122f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_loader = ThreadableLoader::create(executionContext, this, request, options, resourceLoaderOptions);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
124f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, options, resourceLoaderOptions);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void FileReaderLoader::start(ExecutionContext* executionContext, PassRefPtr<BlobDataHandle> blobData)
128e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
129a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    ASSERT(executionContext);
13006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_urlForReadingIsStream = false;
131a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    startInternal(*executionContext, 0, blobData);
132e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
133e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
1341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void FileReaderLoader::start(ExecutionContext* executionContext, const Stream& stream, unsigned readSize)
135e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
136a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    ASSERT(executionContext);
13706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (readSize > 0) {
13806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_hasRange = true;
13906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_rangeStart = 0;
14006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_rangeEnd = readSize - 1; // End is inclusive so (0,0) is a 1-byte read.
14106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
14206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
14306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_urlForReadingIsStream = true;
144a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    startInternal(*executionContext, &stream, nullptr);
145e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
146e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::cancel()
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_errorCode = FileError::ABORT_ERR;
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    terminate();
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::terminate()
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_loader) {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_loader->cancel();
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cleanup();
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::cleanup()
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_loader = nullptr;
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If we get any error, we do not need to keep a buffer around.
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_errorCode) {
167bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_rawData.clear();
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_stringResult = "";
16906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_isRawDataConverted = true;
17051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_decoder.clear();
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::didReceiveResponse(unsigned long, const ResourceResponse& response)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (response.httpStatusCode() != 200) {
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        failed(httpStatusCodeToErrorCode(response.httpStatusCode()));
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
181bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // A negative value means that the content length wasn't specified.
182bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    m_totalBytes = response.expectedContentLength();
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
184bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    long long initialBufferLength = -1;
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
186bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (m_totalBytes >= 0) {
187bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        initialBufferLength = m_totalBytes;
188bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    } else if (m_hasRange) {
189bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Set m_totalBytes and allocate a buffer based on the specified range.
190bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_totalBytes = 1LL + m_rangeEnd - m_rangeStart;
191bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        initialBufferLength = m_totalBytes;
192bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    } else {
193bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Nothing is known about the size of the resource. Normalize
194bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // m_totalBytes to -1 and initialize the buffer for receiving with the
195bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // default size.
196bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_totalBytes = -1;
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_rawData);
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (m_readType != ReadByClient) {
202bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Check that we can cast to unsigned since we have to do
203bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // so to call ArrayBuffer's create function.
204bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // FIXME: Support reading more than the current size limit of ArrayBuffer.
2055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (initialBufferLength > std::numeric_limits<unsigned>::max()) {
206bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            failed(FileError::NOT_READABLE_ERR);
207bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            return;
208bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        }
209bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
21007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (initialBufferLength < 0)
211bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            m_rawData = adoptPtr(new ArrayBufferBuilder());
21207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        else
213bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            m_rawData = adoptPtr(new ArrayBufferBuilder(static_cast<unsigned>(initialBufferLength)));
2141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
21507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (!m_rawData || !m_rawData->isValid()) {
2161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            failed(FileError::NOT_READABLE_ERR);
2171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return;
2181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
21907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
22007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (initialBufferLength >= 0) {
22107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            // Total size is known. Set m_rawData to ignore overflowed data.
22207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            m_rawData->setVariableCapacity(false);
22307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        }
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_client)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_client->didStartLoading();
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::didReceiveData(const char* data, int dataLength)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(data);
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(dataLength > 0);
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Bail out if we already encountered an error.
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_errorCode)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (m_readType == ReadByClient) {
24006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_bytesLoaded += dataLength;
24106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
24206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (m_client)
24306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            m_client->didReceiveDataForClient(data, dataLength);
24406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return;
24506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
24606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
247bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    unsigned bytesAppended = m_rawData->append(data, static_cast<unsigned>(dataLength));
248bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (!bytesAppended) {
249bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_rawData.clear();
250bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_bytesLoaded = 0;
251bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        failed(FileError::NOT_READABLE_ERR);
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
253bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
254bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    m_bytesLoaded += bytesAppended;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_isRawDataConverted = false;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_client)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_client->didReceiveData();
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::didFinishLoading(unsigned long, double)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
263bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (m_readType != ReadByClient && m_rawData) {
264bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_rawData->shrinkToFit();
26506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_isRawDataConverted = false;
266bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
26706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
268bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (m_totalBytes == -1) {
269bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Update m_totalBytes only when in dynamic buffer grow mode.
270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_totalBytes = m_bytesLoaded;
271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
2721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_finishedLoading = true;
2741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cleanup();
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_client)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_client->didFinishLoading();
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::didFail(const ResourceError&)
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If we're aborting, do not proceed with normal error handling since it is covered in aborting code.
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_errorCode == FileError::ABORT_ERR)
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    failed(FileError::NOT_READABLE_ERR);
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
289591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid FileReaderLoader::failed(FileError::ErrorCode errorCode)
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_errorCode = errorCode;
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cleanup();
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_client)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_client->didFail(m_errorCode);
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FileError::ErrorCode FileReaderLoader::httpStatusCodeToErrorCode(int httpStatusCode)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (httpStatusCode) {
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case 403:
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FileError::SECURITY_ERR;
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case 404:
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FileError::NOT_FOUND_ERR;
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FileError::NOT_READABLE_ERR;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<ArrayBuffer> FileReaderLoader::arrayBufferResult() const
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_readType == ReadAsArrayBuffer);
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the loading is not started or an error occurs, return an empty result.
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_rawData || m_errorCode)
315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
317bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return m_rawData->toArrayBuffer();
318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String FileReaderLoader::stringResult()
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
32206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_readType != ReadAsArrayBuffer && m_readType != ReadAsBlob && m_readType != ReadByClient);
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the loading is not started or an error occurs, return an empty result.
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_rawData || m_errorCode)
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_stringResult;
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If already converted from the raw data, return the result now.
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_isRawDataConverted)
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_stringResult;
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_readType) {
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ReadAsArrayBuffer:
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // No conversion is needed.
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ReadAsBinaryString:
337bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_stringResult = m_rawData->toString();
33806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_isRawDataConverted = true;
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ReadAsText:
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        convertToText();
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ReadAsDataURL:
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Partial data is not supported when reading as data URL.
3451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (m_finishedLoading)
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            convertToDataURL();
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_NOT_REACHED();
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
35102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_stringResult;
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::convertToText()
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
35706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_isRawDataConverted = true;
35806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
35906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!m_bytesLoaded) {
36006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_stringResult = "";
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
36206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Decode the data.
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The File API spec says that we should use the supplied encoding if it is valid. However, we choose to ignore this
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // requirement in order to be consistent with how WebKit decodes the web content: always has the BOM override the
36702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // provided encoding.
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: consider supporting incremental decoding to improve the perf.
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder builder;
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_decoder)
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_decoder = TextResourceDecoder::create("text/plain", m_encoding.isValid() ? m_encoding : UTF8Encoding());
372bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    builder.append(m_decoder->decode(static_cast<const char*>(m_rawData->data()), m_rawData->byteLength()));
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (m_finishedLoading)
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        builder.append(m_decoder->flush());
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_stringResult = builder.toString();
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::convertToDataURL()
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
38206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_isRawDataConverted = true;
38306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder builder;
3859e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    builder.appendLiteral("data:");
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_bytesLoaded) {
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_stringResult = builder.toString();
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.append(m_dataType);
3939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    builder.appendLiteral(";base64,");
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<char> out;
396bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    base64Encode(static_cast<const char*>(m_rawData->data()), m_rawData->byteLength(), out);
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    out.append('\0');
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.append(out.data());
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_stringResult = builder.toString();
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FileReaderLoader::setEncoding(const String& encoding)
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!encoding.isEmpty())
40681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        m_encoding = WTF::TextEncoding(encoding);
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
409c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
410