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