1 /*
2 * Copyright (C) 2013 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 "bindings/core/v8/custom/V8BlobCustomHelpers.h"
33
34 #include "bindings/core/v8/Dictionary.h"
35 #include "bindings/core/v8/ExceptionState.h"
36 #include "bindings/core/v8/V8Binding.h"
37 #include "bindings/core/v8/V8Blob.h"
38 #include "bindings/core/v8/custom/V8ArrayBufferCustom.h"
39 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h"
40 #include "wtf/DateMath.h"
41
42 namespace blink {
43
44 namespace V8BlobCustomHelpers {
45
ParsedProperties(bool hasFileProperties)46 ParsedProperties::ParsedProperties(bool hasFileProperties)
47 : m_normalizeLineEndingsToNative(false)
48 , m_hasFileProperties(hasFileProperties)
49 #if ENABLE(ASSERT)
50 , m_hasLastModified(false)
51 #endif // ENABLE(ASSERT)
52 {
53 }
54
setLastModified(double lastModified)55 void ParsedProperties::setLastModified(double lastModified)
56 {
57 ASSERT(m_hasFileProperties);
58 ASSERT(!m_hasLastModified);
59 m_lastModified = lastModified;
60 #if ENABLE(ASSERT)
61 m_hasLastModified = true;
62 #endif // ENABLE(ASSERT)
63 }
64
setDefaultLastModified()65 void ParsedProperties::setDefaultLastModified()
66 {
67 setLastModified(currentTime());
68 }
69
parseBlobPropertyBag(v8::Local<v8::Value> propertyBag,const char * blobClassName,ExceptionState & exceptionState,v8::Isolate * isolate)70 bool ParsedProperties::parseBlobPropertyBag(v8::Local<v8::Value> propertyBag, const char* blobClassName, ExceptionState& exceptionState, v8::Isolate* isolate)
71 {
72 TONATIVE_DEFAULT(Dictionary, dictionary, Dictionary(propertyBag, isolate), false);
73
74 String endings;
75 TONATIVE_DEFAULT(bool, containsEndings, DictionaryHelper::get(dictionary, "endings", endings), false);
76 if (containsEndings) {
77 if (endings != "transparent" && endings != "native") {
78 exceptionState.throwTypeError("The 'endings' property must be either 'transparent' or 'native'.");
79 return false;
80 }
81 if (endings == "native")
82 m_normalizeLineEndingsToNative = true;
83 }
84
85 TONATIVE_DEFAULT(bool, containsType, DictionaryHelper::get(dictionary, "type", m_contentType), false);
86 if (containsType) {
87 if (!m_contentType.containsOnlyASCII()) {
88 exceptionState.throwDOMException(SyntaxError, "The 'type' property must consist of ASCII characters.");
89 return false;
90 }
91 m_contentType = m_contentType.lower();
92 }
93
94 if (!m_hasFileProperties)
95 return true;
96
97 v8::Local<v8::Value> lastModified;
98 TONATIVE_DEFAULT(bool, containsLastModified, DictionaryHelper::get(dictionary, "lastModified", lastModified), false);
99 if (containsLastModified) {
100 TONATIVE_DEFAULT(long long, lastModifiedInt, toInt64(lastModified), false);
101 setLastModified(static_cast<double>(lastModifiedInt) / msPerSecond);
102 } else {
103 setDefaultLastModified();
104 }
105
106 return true;
107 }
108
processBlobParts(v8::Local<v8::Object> blobParts,bool normalizeLineEndingsToNative,BlobData & blobData,v8::Isolate * isolate)109 bool processBlobParts(v8::Local<v8::Object> blobParts, bool normalizeLineEndingsToNative, BlobData& blobData, v8::Isolate* isolate)
110 {
111 // FIXME: handle sequences based on ES6 @@iterator, see http://crbug.com/393866
112 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(blobParts);
113 uint32_t length = v8::Local<v8::Array>::Cast(blobParts)->Length();
114 for (uint32_t i = 0; i < length; ++i) {
115 v8::Local<v8::Value> item = array->Get(i);
116 if (item.IsEmpty())
117 return false;
118
119 if (V8ArrayBuffer::hasInstance(item, isolate)) {
120 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(v8::Handle<v8::Object>::Cast(item));
121 ASSERT(arrayBuffer);
122 blobData.appendArrayBuffer(arrayBuffer);
123 } else if (V8ArrayBufferView::hasInstance(item, isolate)) {
124 ArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(v8::Handle<v8::Object>::Cast(item));
125 ASSERT(arrayBufferView);
126 blobData.appendArrayBufferView(arrayBufferView);
127 } else if (V8Blob::hasInstance(item, isolate)) {
128 Blob* blob = V8Blob::toImpl(v8::Handle<v8::Object>::Cast(item));
129 ASSERT(blob);
130 blob->appendTo(blobData);
131 } else {
132 TOSTRING_DEFAULT(V8StringResource<>, stringValue, item, false);
133 blobData.appendText(stringValue, normalizeLineEndingsToNative);
134 }
135 }
136 return true;
137 }
138
139 } // namespace V8BlobCustomHelpers
140
141 } // namespace blink
142