1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "Blob.h" 33 34 #include "BlobURL.h" 35 #include "File.h" 36 #include "ThreadableBlobRegistry.h" 37 38 namespace WebCore { 39 40 Blob::Blob(PassOwnPtr<BlobData> blobData, long long size) 41 : m_type(blobData->contentType()) 42 , m_size(size) 43 { 44 ASSERT(blobData); 45 46 // Create a new internal URL and register it with the provided blob data. 47 m_internalURL = BlobURL::createInternalURL(); 48 ThreadableBlobRegistry::registerBlobURL(m_internalURL, blobData); 49 } 50 51 Blob::Blob(const KURL& srcURL, const String& type, long long size) 52 : m_type(type) 53 , m_size(size) 54 { 55 // Create a new internal URL and register it with the same blob data as the source URL. 56 m_internalURL = BlobURL::createInternalURL(); 57 ThreadableBlobRegistry::registerBlobURL(m_internalURL, srcURL); 58 } 59 60 Blob::~Blob() 61 { 62 ThreadableBlobRegistry::unregisterBlobURL(m_internalURL); 63 } 64 65 #if ENABLE(BLOB) 66 PassRefPtr<Blob> Blob::webkitSlice(long long start, long long end, const String& contentType) const 67 { 68 // When we slice a file for the first time, we obtain a snapshot of the file by capturing its current size and modification time. 69 // The modification time will be used to verify if the file has been changed or not, when the underlying data are accessed. 70 long long size; 71 double modificationTime; 72 if (isFile()) 73 // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous. 74 static_cast<const File*>(this)->captureSnapshot(size, modificationTime); 75 else { 76 ASSERT(m_size != -1); 77 size = m_size; 78 } 79 80 // Convert the negative value that is used to select from the end. 81 if (start < 0) 82 start = start + size; 83 if (end < 0) 84 end = end + size; 85 86 // Clamp the range if it exceeds the size limit. 87 if (start < 0) 88 start = 0; 89 if (end < 0) 90 end = 0; 91 if (start >= size) { 92 start = 0; 93 end = 0; 94 } else if (end < start) 95 end = start; 96 else if (end > size) 97 end = size; 98 99 long long length = end - start; 100 OwnPtr<BlobData> blobData = BlobData::create(); 101 blobData->setContentType(contentType); 102 if (isFile()) 103 blobData->appendFile(static_cast<const File*>(this)->path(), start, length, modificationTime); 104 else 105 blobData->appendBlob(m_internalURL, start, length); 106 107 return Blob::create(blobData.release(), length); 108 } 109 #endif 110 111 } // namespace WebCore 112