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