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
Blob(PassOwnPtr<BlobData> blobData,long long size)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
Blob(const KURL & srcURL,const String & type,long long size)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
~Blob()60 Blob::~Blob()
61 {
62 ThreadableBlobRegistry::unregisterBlobURL(m_internalURL);
63 }
64
65 #if ENABLE(BLOB)
webkitSlice(long long start,long long end,const String & contentType) const66 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