Home | History | Annotate | Download | only in custom
      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 
     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 
     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 
     65 void ParsedProperties::setDefaultLastModified()
     66 {
     67     setLastModified(currentTime());
     68 }
     69 
     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 
    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