Home | History | Annotate | Download | only in custom
      1 /*
      2  * Copyright (C) 2012 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 "core/fileapi/Blob.h"
     33 
     34 #include "V8Blob.h"
     35 #include "V8File.h"
     36 #include "bindings/v8/Dictionary.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/RefPtr.h"
     43 
     44 namespace WebCore {
     45 
     46 v8::Handle<v8::Object> wrap(Blob* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
     47 {
     48     ASSERT(impl);
     49     if (impl->isFile())
     50         return wrap(toFile(impl), creationContext, isolate);
     51     return V8Blob::createWrapper(impl, creationContext, isolate);
     52 }
     53 
     54 void V8Blob::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& args)
     55 {
     56     if (!args.Length()) {
     57         RefPtr<Blob> blob = Blob::create();
     58         args.GetReturnValue().Set(toV8(blob.get(), args.Holder(), args.GetIsolate()));
     59         return;
     60     }
     61 
     62     v8::Local<v8::Value> firstArg = args[0];
     63     if (!firstArg->IsArray()) {
     64         throwTypeError("First argument of the constructor is not of type Array", args.GetIsolate());
     65         return;
     66     }
     67 
     68     String type;
     69     String endings = "transparent";
     70 
     71     if (args.Length() > 1) {
     72         if (!args[1]->IsObject()) {
     73             throwTypeError("Second argument of the constructor is not of type Object", args.GetIsolate());
     74             return;
     75         }
     76 
     77         V8TRYCATCH_VOID(Dictionary, dictionary, Dictionary(args[1], args.GetIsolate()));
     78 
     79         V8TRYCATCH_VOID(bool, containsEndings, dictionary.get("endings", endings));
     80         if (containsEndings) {
     81             if (endings != "transparent" && endings != "native") {
     82                 throwTypeError("The endings property must be either \"transparent\" or \"native\"", args.GetIsolate());
     83                 return;
     84             }
     85         }
     86 
     87         V8TRYCATCH_VOID(bool, containsType, dictionary.get("type", type));
     88         UNUSED_PARAM(containsType);
     89         if (!type.containsOnlyASCII()) {
     90             throwError(v8SyntaxError, "type must consist of ASCII characters", args.GetIsolate());
     91             return;
     92         }
     93         type.makeLower();
     94     }
     95 
     96     ASSERT(endings == "transparent" || endings == "native");
     97 
     98     BlobBuilder blobBuilder;
     99 
    100     V8TRYCATCH_VOID(v8::Local<v8::Array>, blobParts, v8::Local<v8::Array>::Cast(firstArg));
    101     uint32_t length = blobParts->Length();
    102 
    103     for (uint32_t i = 0; i < length; ++i) {
    104         v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(i));
    105         ASSERT(!item.IsEmpty());
    106         if (V8ArrayBuffer::HasInstance(item, args.GetIsolate(), worldType(args.GetIsolate()))) {
    107             ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(item));
    108             ASSERT(arrayBuffer);
    109             blobBuilder.append(arrayBuffer);
    110         } else if (V8ArrayBufferView::HasInstance(item, args.GetIsolate(), worldType(args.GetIsolate()))) {
    111             ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(item));
    112             ASSERT(arrayBufferView);
    113             blobBuilder.append(arrayBufferView);
    114         } else
    115         if (V8Blob::HasInstance(item, args.GetIsolate(), worldType(args.GetIsolate()))) {
    116             Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(item));
    117             ASSERT(blob);
    118             blobBuilder.append(blob);
    119         } else {
    120             V8TRYCATCH_VOID(String, stringValue, toWebCoreString(item));
    121             blobBuilder.append(stringValue, endings);
    122         }
    123     }
    124 
    125     RefPtr<Blob> blob = blobBuilder.getBlob(type);
    126     args.GetReturnValue().Set(toV8(blob.get(), args.Holder(), args.GetIsolate()));
    127 }
    128 
    129 } // namespace WebCore
    130