1e14391e94c850b8bd03680c23b38978db68687a8John Reck/* 2e14391e94c850b8bd03680c23b38978db68687a8John Reck * Copyright (C) 2010 Google Inc. All rights reserved. 3e14391e94c850b8bd03680c23b38978db68687a8John Reck * 4e14391e94c850b8bd03680c23b38978db68687a8John Reck * Redistribution and use in source and binary forms, with or without 5e14391e94c850b8bd03680c23b38978db68687a8John Reck * modification, are permitted provided that the following conditions are 6e14391e94c850b8bd03680c23b38978db68687a8John Reck * met: 7e14391e94c850b8bd03680c23b38978db68687a8John Reck * 8e14391e94c850b8bd03680c23b38978db68687a8John Reck * * Redistributions of source code must retain the above copyright 9e14391e94c850b8bd03680c23b38978db68687a8John Reck * notice, this list of conditions and the following disclaimer. 10e14391e94c850b8bd03680c23b38978db68687a8John Reck * * Redistributions in binary form must reproduce the above 11e14391e94c850b8bd03680c23b38978db68687a8John Reck * copyright notice, this list of conditions and the following disclaimer 12e14391e94c850b8bd03680c23b38978db68687a8John Reck * in the documentation and/or other materials provided with the 13e14391e94c850b8bd03680c23b38978db68687a8John Reck * distribution. 14e14391e94c850b8bd03680c23b38978db68687a8John Reck * * Neither the name of Google Inc. nor the names of its 15e14391e94c850b8bd03680c23b38978db68687a8John Reck * contributors may be used to endorse or promote products derived from 16e14391e94c850b8bd03680c23b38978db68687a8John Reck * this software without specific prior written permission. 17e14391e94c850b8bd03680c23b38978db68687a8John Reck * 18e14391e94c850b8bd03680c23b38978db68687a8John Reck * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19e14391e94c850b8bd03680c23b38978db68687a8John Reck * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20e14391e94c850b8bd03680c23b38978db68687a8John Reck * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21e14391e94c850b8bd03680c23b38978db68687a8John Reck * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22e14391e94c850b8bd03680c23b38978db68687a8John Reck * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23e14391e94c850b8bd03680c23b38978db68687a8John Reck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24e14391e94c850b8bd03680c23b38978db68687a8John Reck * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25e14391e94c850b8bd03680c23b38978db68687a8John Reck * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26e14391e94c850b8bd03680c23b38978db68687a8John Reck * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27e14391e94c850b8bd03680c23b38978db68687a8John Reck * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28e14391e94c850b8bd03680c23b38978db68687a8John Reck * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29e14391e94c850b8bd03680c23b38978db68687a8John Reck */ 30e14391e94c850b8bd03680c23b38978db68687a8John Reck 31e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "config.h" 32e14391e94c850b8bd03680c23b38978db68687a8John Reck 33e14391e94c850b8bd03680c23b38978db68687a8John Reck#if ENABLE(BLOB) 34e14391e94c850b8bd03680c23b38978db68687a8John Reck 35e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "FileReaderLoader.h" 36e14391e94c850b8bd03680c23b38978db68687a8John Reck 37e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "ArrayBuffer.h" 38e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "Base64.h" 39e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "Blob.h" 40e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "BlobURL.h" 41e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "FileReaderLoaderClient.h" 42e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "ResourceRequest.h" 43e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "ResourceResponse.h" 44e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "ScriptExecutionContext.h" 45e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "TextResourceDecoder.h" 46e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "ThreadableBlobRegistry.h" 47e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "ThreadableLoader.h" 48e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <wtf/PassRefPtr.h> 49e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <wtf/RefPtr.h> 50e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <wtf/Vector.h> 51e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <wtf/text/StringBuilder.h> 52e14391e94c850b8bd03680c23b38978db68687a8John Reck 53f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochusing namespace std; 54f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 55e14391e94c850b8bd03680c23b38978db68687a8John Recknamespace WebCore { 56e14391e94c850b8bd03680c23b38978db68687a8John Reck 57e14391e94c850b8bd03680c23b38978db68687a8John ReckFileReaderLoader::FileReaderLoader(ReadType readType, FileReaderLoaderClient* client) 58e14391e94c850b8bd03680c23b38978db68687a8John Reck : m_readType(readType) 59e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_client(client) 60e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_isRawDataConverted(false) 61e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_stringResult("") 62e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_bytesLoaded(0) 63e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_totalBytes(0) 64e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_errorCode(0) 65e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 66e14391e94c850b8bd03680c23b38978db68687a8John Reck} 67e14391e94c850b8bd03680c23b38978db68687a8John Reck 68e14391e94c850b8bd03680c23b38978db68687a8John ReckFileReaderLoader::~FileReaderLoader() 69e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 70e14391e94c850b8bd03680c23b38978db68687a8John Reck terminate(); 71e14391e94c850b8bd03680c23b38978db68687a8John Reck ThreadableBlobRegistry::unregisterBlobURL(m_urlForReading); 72e14391e94c850b8bd03680c23b38978db68687a8John Reck} 73e14391e94c850b8bd03680c23b38978db68687a8John Reck 74e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::start(ScriptExecutionContext* scriptExecutionContext, Blob* blob) 75e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 76e14391e94c850b8bd03680c23b38978db68687a8John Reck // The blob is read by routing through the request handling layer given a temporary public url. 77e14391e94c850b8bd03680c23b38978db68687a8John Reck m_urlForReading = BlobURL::createPublicURL(scriptExecutionContext->securityOrigin()); 782bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_urlForReading.isEmpty()) { 792bde8e466a4451c7319e3a072d118917957d6554Steve Block failed(FileError::SECURITY_ERR); 802bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 812bde8e466a4451c7319e3a072d118917957d6554Steve Block } 82e14391e94c850b8bd03680c23b38978db68687a8John Reck ThreadableBlobRegistry::registerBlobURL(m_urlForReading, blob->url()); 83e14391e94c850b8bd03680c23b38978db68687a8John Reck 84e14391e94c850b8bd03680c23b38978db68687a8John Reck // Construct and load the request. 85e14391e94c850b8bd03680c23b38978db68687a8John Reck ResourceRequest request(m_urlForReading); 86e14391e94c850b8bd03680c23b38978db68687a8John Reck request.setHTTPMethod("GET"); 87e14391e94c850b8bd03680c23b38978db68687a8John Reck 88e14391e94c850b8bd03680c23b38978db68687a8John Reck ThreadableLoaderOptions options; 89e14391e94c850b8bd03680c23b38978db68687a8John Reck options.sendLoadCallbacks = true; 90e14391e94c850b8bd03680c23b38978db68687a8John Reck options.sniffContent = false; 91e14391e94c850b8bd03680c23b38978db68687a8John Reck options.forcePreflight = false; 92e14391e94c850b8bd03680c23b38978db68687a8John Reck options.allowCredentials = true; 93e14391e94c850b8bd03680c23b38978db68687a8John Reck options.crossOriginRequestPolicy = DenyCrossOriginRequests; 94e14391e94c850b8bd03680c23b38978db68687a8John Reck 95e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_client) 96e14391e94c850b8bd03680c23b38978db68687a8John Reck m_loader = ThreadableLoader::create(scriptExecutionContext, this, request, options); 97e14391e94c850b8bd03680c23b38978db68687a8John Reck else 98e14391e94c850b8bd03680c23b38978db68687a8John Reck ThreadableLoader::loadResourceSynchronously(scriptExecutionContext, request, *this, options); 99e14391e94c850b8bd03680c23b38978db68687a8John Reck} 100e14391e94c850b8bd03680c23b38978db68687a8John Reck 101e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::cancel() 102e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 103e14391e94c850b8bd03680c23b38978db68687a8John Reck m_errorCode = FileError::ABORT_ERR; 104e14391e94c850b8bd03680c23b38978db68687a8John Reck terminate(); 105e14391e94c850b8bd03680c23b38978db68687a8John Reck} 106e14391e94c850b8bd03680c23b38978db68687a8John Reck 107e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::terminate() 108e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 109e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_loader) { 110e14391e94c850b8bd03680c23b38978db68687a8John Reck m_loader->cancel(); 111e14391e94c850b8bd03680c23b38978db68687a8John Reck cleanup(); 112e14391e94c850b8bd03680c23b38978db68687a8John Reck } 113e14391e94c850b8bd03680c23b38978db68687a8John Reck} 114e14391e94c850b8bd03680c23b38978db68687a8John Reck 115e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::cleanup() 116e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 117e14391e94c850b8bd03680c23b38978db68687a8John Reck m_loader = 0; 118e14391e94c850b8bd03680c23b38978db68687a8John Reck 119e14391e94c850b8bd03680c23b38978db68687a8John Reck // If we get any error, we do not need to keep a buffer around. 120e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_errorCode) { 121e14391e94c850b8bd03680c23b38978db68687a8John Reck m_rawData = 0; 122e14391e94c850b8bd03680c23b38978db68687a8John Reck m_stringResult = ""; 123e14391e94c850b8bd03680c23b38978db68687a8John Reck } 124e14391e94c850b8bd03680c23b38978db68687a8John Reck} 125e14391e94c850b8bd03680c23b38978db68687a8John Reck 126e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::didReceiveResponse(const ResourceResponse& response) 127e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 128e14391e94c850b8bd03680c23b38978db68687a8John Reck if (response.httpStatusCode() != 200) { 129e14391e94c850b8bd03680c23b38978db68687a8John Reck failed(httpStatusCodeToErrorCode(response.httpStatusCode())); 130e14391e94c850b8bd03680c23b38978db68687a8John Reck return; 131e14391e94c850b8bd03680c23b38978db68687a8John Reck } 132e14391e94c850b8bd03680c23b38978db68687a8John Reck 133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch unsigned long long length = response.expectedContentLength(); 134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 135f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Check that we can cast to unsigned since we have to do 136f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // so to call ArrayBuffer's create function. 137e14391e94c850b8bd03680c23b38978db68687a8John Reck // FIXME: Support reading more than the current size limit of ArrayBuffer. 138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (length > numeric_limits<unsigned>::max()) { 139e14391e94c850b8bd03680c23b38978db68687a8John Reck failed(FileError::NOT_READABLE_ERR); 140e14391e94c850b8bd03680c23b38978db68687a8John Reck return; 141e14391e94c850b8bd03680c23b38978db68687a8John Reck } 142e14391e94c850b8bd03680c23b38978db68687a8John Reck 143e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(!m_rawData); 144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_rawData = ArrayBuffer::create(static_cast<unsigned>(length), 1); 145f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 146f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_rawData) { 147f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch failed(FileError::NOT_READABLE_ERR); 148f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 149f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 150f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 151f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_totalBytes = static_cast<unsigned>(length); 152e14391e94c850b8bd03680c23b38978db68687a8John Reck 153e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_client) 154e14391e94c850b8bd03680c23b38978db68687a8John Reck m_client->didStartLoading(); 155e14391e94c850b8bd03680c23b38978db68687a8John Reck} 156e14391e94c850b8bd03680c23b38978db68687a8John Reck 1572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid FileReaderLoader::didReceiveData(const char* data, int dataLength) 158e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 159f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(data); 1602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(dataLength > 0); 161e14391e94c850b8bd03680c23b38978db68687a8John Reck 162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Bail out if we already encountered an error. 163e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_errorCode) 164e14391e94c850b8bd03680c23b38978db68687a8John Reck return; 165e14391e94c850b8bd03680c23b38978db68687a8John Reck 1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int length = dataLength; 167f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch unsigned remainingBufferSpace = m_totalBytes - m_bytesLoaded; 168f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (length > static_cast<long long>(remainingBufferSpace)) 169f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch length = static_cast<int>(remainingBufferSpace); 170f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 171f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (length <= 0) 172f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 173f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch memcpy(static_cast<char*>(m_rawData->data()) + m_bytesLoaded, data, length); 175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_bytesLoaded += length; 176e14391e94c850b8bd03680c23b38978db68687a8John Reck 177e14391e94c850b8bd03680c23b38978db68687a8John Reck m_isRawDataConverted = false; 178e14391e94c850b8bd03680c23b38978db68687a8John Reck 179e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_client) 180e14391e94c850b8bd03680c23b38978db68687a8John Reck m_client->didReceiveData(); 181e14391e94c850b8bd03680c23b38978db68687a8John Reck} 182e14391e94c850b8bd03680c23b38978db68687a8John Reck 18381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid FileReaderLoader::didFinishLoading(unsigned long, double) 184e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 185e14391e94c850b8bd03680c23b38978db68687a8John Reck cleanup(); 186e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_client) 187e14391e94c850b8bd03680c23b38978db68687a8John Reck m_client->didFinishLoading(); 188e14391e94c850b8bd03680c23b38978db68687a8John Reck} 189e14391e94c850b8bd03680c23b38978db68687a8John Reck 190e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::didFail(const ResourceError&) 191e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 192e14391e94c850b8bd03680c23b38978db68687a8John Reck // If we're aborting, do not proceed with normal error handling since it is covered in aborting code. 193e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_errorCode == FileError::ABORT_ERR) 194e14391e94c850b8bd03680c23b38978db68687a8John Reck return; 195e14391e94c850b8bd03680c23b38978db68687a8John Reck 196e14391e94c850b8bd03680c23b38978db68687a8John Reck failed(FileError::NOT_READABLE_ERR); 197e14391e94c850b8bd03680c23b38978db68687a8John Reck} 198e14391e94c850b8bd03680c23b38978db68687a8John Reck 199e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::failed(int errorCode) 200e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 201e14391e94c850b8bd03680c23b38978db68687a8John Reck m_errorCode = errorCode; 202e14391e94c850b8bd03680c23b38978db68687a8John Reck cleanup(); 203e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_client) 204e14391e94c850b8bd03680c23b38978db68687a8John Reck m_client->didFail(m_errorCode); 205e14391e94c850b8bd03680c23b38978db68687a8John Reck} 206e14391e94c850b8bd03680c23b38978db68687a8John Reck 207e14391e94c850b8bd03680c23b38978db68687a8John ReckFileError::ErrorCode FileReaderLoader::httpStatusCodeToErrorCode(int httpStatusCode) 208e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 209e14391e94c850b8bd03680c23b38978db68687a8John Reck switch (httpStatusCode) { 210e14391e94c850b8bd03680c23b38978db68687a8John Reck case 403: 211e14391e94c850b8bd03680c23b38978db68687a8John Reck return FileError::SECURITY_ERR; 212e14391e94c850b8bd03680c23b38978db68687a8John Reck case 404: 213e14391e94c850b8bd03680c23b38978db68687a8John Reck return FileError::NOT_FOUND_ERR; 214e14391e94c850b8bd03680c23b38978db68687a8John Reck default: 215e14391e94c850b8bd03680c23b38978db68687a8John Reck return FileError::NOT_READABLE_ERR; 216e14391e94c850b8bd03680c23b38978db68687a8John Reck } 217e14391e94c850b8bd03680c23b38978db68687a8John Reck} 218e14391e94c850b8bd03680c23b38978db68687a8John Reck 219e14391e94c850b8bd03680c23b38978db68687a8John ReckPassRefPtr<ArrayBuffer> FileReaderLoader::arrayBufferResult() const 220e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 221e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(m_readType == ReadAsArrayBuffer); 222e14391e94c850b8bd03680c23b38978db68687a8John Reck 223e14391e94c850b8bd03680c23b38978db68687a8John Reck // If the loading is not started or an error occurs, return an empty result. 224e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_rawData || m_errorCode) 225e14391e94c850b8bd03680c23b38978db68687a8John Reck return 0; 226e14391e94c850b8bd03680c23b38978db68687a8John Reck 227e14391e94c850b8bd03680c23b38978db68687a8John Reck // If completed, we can simply return our buffer. 228e14391e94c850b8bd03680c23b38978db68687a8John Reck if (isCompleted()) 229e14391e94c850b8bd03680c23b38978db68687a8John Reck return m_rawData; 230e14391e94c850b8bd03680c23b38978db68687a8John Reck 231e14391e94c850b8bd03680c23b38978db68687a8John Reck // Otherwise, return a copy. 232e14391e94c850b8bd03680c23b38978db68687a8John Reck return ArrayBuffer::create(m_rawData.get()); 233e14391e94c850b8bd03680c23b38978db68687a8John Reck} 234e14391e94c850b8bd03680c23b38978db68687a8John Reck 235e14391e94c850b8bd03680c23b38978db68687a8John ReckString FileReaderLoader::stringResult() 236e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 237e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(m_readType != ReadAsArrayBuffer); 238e14391e94c850b8bd03680c23b38978db68687a8John Reck 239e14391e94c850b8bd03680c23b38978db68687a8John Reck // If the loading is not started or an error occurs, return an empty result. 240e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_rawData || m_errorCode) 241e14391e94c850b8bd03680c23b38978db68687a8John Reck return m_stringResult; 242e14391e94c850b8bd03680c23b38978db68687a8John Reck 243e14391e94c850b8bd03680c23b38978db68687a8John Reck // If already converted from the raw data, return the result now. 244e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_isRawDataConverted) 245e14391e94c850b8bd03680c23b38978db68687a8John Reck return m_stringResult; 246e14391e94c850b8bd03680c23b38978db68687a8John Reck 247e14391e94c850b8bd03680c23b38978db68687a8John Reck switch (m_readType) { 248e14391e94c850b8bd03680c23b38978db68687a8John Reck case ReadAsArrayBuffer: 249e14391e94c850b8bd03680c23b38978db68687a8John Reck // No conversion is needed. 250e14391e94c850b8bd03680c23b38978db68687a8John Reck break; 251e14391e94c850b8bd03680c23b38978db68687a8John Reck case ReadAsBinaryString: 252e14391e94c850b8bd03680c23b38978db68687a8John Reck m_stringResult = String(static_cast<const char*>(m_rawData->data()), m_bytesLoaded); 253e14391e94c850b8bd03680c23b38978db68687a8John Reck break; 254e14391e94c850b8bd03680c23b38978db68687a8John Reck case ReadAsText: 255e14391e94c850b8bd03680c23b38978db68687a8John Reck convertToText(); 256e14391e94c850b8bd03680c23b38978db68687a8John Reck break; 257e14391e94c850b8bd03680c23b38978db68687a8John Reck case ReadAsDataURL: 258e14391e94c850b8bd03680c23b38978db68687a8John Reck // Partial data is not supported when reading as data URL. 259e14391e94c850b8bd03680c23b38978db68687a8John Reck if (isCompleted()) 260e14391e94c850b8bd03680c23b38978db68687a8John Reck convertToDataURL(); 261e14391e94c850b8bd03680c23b38978db68687a8John Reck break; 262e14391e94c850b8bd03680c23b38978db68687a8John Reck default: 263e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT_NOT_REACHED(); 264e14391e94c850b8bd03680c23b38978db68687a8John Reck } 265e14391e94c850b8bd03680c23b38978db68687a8John Reck 266e14391e94c850b8bd03680c23b38978db68687a8John Reck return m_stringResult; 267e14391e94c850b8bd03680c23b38978db68687a8John Reck} 268e14391e94c850b8bd03680c23b38978db68687a8John Reck 269e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::convertToText() 270e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 271e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_bytesLoaded) 272e14391e94c850b8bd03680c23b38978db68687a8John Reck return; 273e14391e94c850b8bd03680c23b38978db68687a8John Reck 274e14391e94c850b8bd03680c23b38978db68687a8John Reck // Decode the data. 275e14391e94c850b8bd03680c23b38978db68687a8John Reck // The File API spec says that we should use the supplied encoding if it is valid. However, we choose to ignore this 276e14391e94c850b8bd03680c23b38978db68687a8John Reck // requirement in order to be consistent with how WebKit decodes the web content: always has the BOM override the 277e14391e94c850b8bd03680c23b38978db68687a8John Reck // provided encoding. 278e14391e94c850b8bd03680c23b38978db68687a8John Reck // FIXME: consider supporting incremental decoding to improve the perf. 279e14391e94c850b8bd03680c23b38978db68687a8John Reck StringBuilder builder; 280e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_decoder) 281e14391e94c850b8bd03680c23b38978db68687a8John Reck m_decoder = TextResourceDecoder::create("text/plain", m_encoding.isValid() ? m_encoding : UTF8Encoding()); 282e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append(m_decoder->decode(static_cast<const char*>(m_rawData->data()), m_bytesLoaded)); 283e14391e94c850b8bd03680c23b38978db68687a8John Reck 284e14391e94c850b8bd03680c23b38978db68687a8John Reck if (isCompleted()) 285e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append(m_decoder->flush()); 286e14391e94c850b8bd03680c23b38978db68687a8John Reck 287e14391e94c850b8bd03680c23b38978db68687a8John Reck m_stringResult = builder.toString(); 288e14391e94c850b8bd03680c23b38978db68687a8John Reck} 289e14391e94c850b8bd03680c23b38978db68687a8John Reck 290e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::convertToDataURL() 291e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 292e14391e94c850b8bd03680c23b38978db68687a8John Reck StringBuilder builder; 293e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append("data:"); 294e14391e94c850b8bd03680c23b38978db68687a8John Reck 295e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_bytesLoaded) { 296e14391e94c850b8bd03680c23b38978db68687a8John Reck m_stringResult = builder.toString(); 297e14391e94c850b8bd03680c23b38978db68687a8John Reck return; 298e14391e94c850b8bd03680c23b38978db68687a8John Reck } 299e14391e94c850b8bd03680c23b38978db68687a8John Reck 300e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_dataType.isEmpty()) { 301e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append(m_dataType); 302e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append(";base64,"); 303e14391e94c850b8bd03680c23b38978db68687a8John Reck } else 304e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append("base64,"); 305e14391e94c850b8bd03680c23b38978db68687a8John Reck 306e14391e94c850b8bd03680c23b38978db68687a8John Reck Vector<char> out; 307e14391e94c850b8bd03680c23b38978db68687a8John Reck base64Encode(static_cast<const char*>(m_rawData->data()), m_bytesLoaded, out); 308e14391e94c850b8bd03680c23b38978db68687a8John Reck out.append('\0'); 309e14391e94c850b8bd03680c23b38978db68687a8John Reck builder.append(out.data()); 310e14391e94c850b8bd03680c23b38978db68687a8John Reck 311e14391e94c850b8bd03680c23b38978db68687a8John Reck m_stringResult = builder.toString(); 312e14391e94c850b8bd03680c23b38978db68687a8John Reck} 313e14391e94c850b8bd03680c23b38978db68687a8John Reck 314e14391e94c850b8bd03680c23b38978db68687a8John Reckbool FileReaderLoader::isCompleted() const 315e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 316e14391e94c850b8bd03680c23b38978db68687a8John Reck return m_bytesLoaded == m_totalBytes; 317e14391e94c850b8bd03680c23b38978db68687a8John Reck} 318e14391e94c850b8bd03680c23b38978db68687a8John Reck 319e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid FileReaderLoader::setEncoding(const String& encoding) 320e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 321e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!encoding.isEmpty()) 322e14391e94c850b8bd03680c23b38978db68687a8John Reck m_encoding = TextEncoding(encoding); 323e14391e94c850b8bd03680c23b38978db68687a8John Reck} 324e14391e94c850b8bd03680c23b38978db68687a8John Reck 325e14391e94c850b8bd03680c23b38978db68687a8John Reck} // namespace WebCore 326e14391e94c850b8bd03680c23b38978db68687a8John Reck 327e14391e94c850b8bd03680c23b38978db68687a8John Reck#endif // ENABLE(BLOB) 328