예제 #1
0
EncodedJSValue JSC_HOST_CALL constructJSFile(ExecState& exec)
{
    auto* constructor = jsCast<DOMConstructorObject*>(exec.callee());
    ScriptExecutionContext* context = constructor->scriptExecutionContext();
    if (!context)
        return throwVMError(&exec, createReferenceError(&exec, "File constructor associated document is unavailable"));

    JSValue arg = exec.argument(0);
    if (arg.isUndefinedOrNull())
        return throwVMTypeError(&exec, ASCIILiteral("First argument to File constructor must be a valid sequence, was undefined or null"));

    unsigned blobPartsLength = 0;
    JSObject* blobParts = toJSSequence(exec, arg, blobPartsLength);
    if (exec.hadException())
        return JSValue::encode(jsUndefined());
    ASSERT(blobParts);

    arg = exec.argument(1);
    if (arg.isUndefined())
        return throwVMTypeError(&exec, ASCIILiteral("Second argument to File constructor must be a valid string, was undefined"));

    String filename = arg.toWTFString(&exec).replace('/', ':');
    if (exec.hadException())
        return JSValue::encode(jsUndefined());

    String normalizedType;
    Optional<int64_t> lastModified;

    arg = exec.argument(2);
    if (!arg.isUndefinedOrNull()) {
        JSObject* filePropertyBagObject = arg.getObject();
        if (!filePropertyBagObject)
            return throwVMTypeError(&exec, ASCIILiteral("Third argument of the constructor is not of type Object"));

        // Create the dictionary wrapper from the initializer object.
        JSDictionary dictionary(&exec, filePropertyBagObject);

        // Attempt to get the type property.
        String type;
        dictionary.get("type", type);
        if (exec.hadException())
            return JSValue::encode(jsUndefined());

        normalizedType = Blob::normalizedContentType(type);

        // Only try to parse the lastModified date if there was not an invalid type argument.
        if (type.isEmpty() ||  !normalizedType.isEmpty()) {
            dictionary.get("lastModified", lastModified);
            if (exec.hadException())
                return JSValue::encode(jsUndefined());
        }
    }

    if (!lastModified)
        lastModified = currentTimeMS();

    BlobBuilder blobBuilder;

    for (unsigned i = 0; i < blobPartsLength; ++i) {
        JSValue item = blobParts->get(&exec, i);
        if (exec.hadException())
            return JSValue::encode(jsUndefined());

        if (ArrayBuffer* arrayBuffer = toArrayBuffer(item))
            blobBuilder.append(arrayBuffer);
        else if (RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(item))
            blobBuilder.append(WTFMove(arrayBufferView));
        else if (Blob* blob = JSBlob::toWrapped(item))
            blobBuilder.append(blob);
        else {
            String string = item.toWTFString(&exec);
            if (exec.hadException())
                return JSValue::encode(jsUndefined());
            blobBuilder.append(string, ASCIILiteral("transparent"));
        }
    }

    auto file = File::create(blobBuilder.finalize(), filename, normalizedType, lastModified.value());
    return JSValue::encode(CREATE_DOM_WRAPPER(constructor->globalObject(), File, WTFMove(file)));
}
예제 #2
0
v8::Handle<v8::Value> V8Blob::constructorCustom(const v8::Arguments& args)
{
    if (!args.Length()) {
        RefPtr<Blob> blob = Blob::create();
        return toV8(blob.get(), args.Holder(), args.GetIsolate());
    }

    v8::Local<v8::Value> firstArg = args[0];
    if (!firstArg->IsArray())
        return throwTypeError("First argument of the constructor is not of type Array", args.GetIsolate());

    String type;
    String endings = ASCIILiteral("transparent");

    if (args.Length() > 1) {
        if (!args[1]->IsObject())
            return throwTypeError("Second argument of the constructor is not of type Object", args.GetIsolate());

        V8TRYCATCH(Dictionary, dictionary, Dictionary(args[1], args.GetIsolate()));

        V8TRYCATCH(bool, containsEndings, dictionary.get("endings", endings));
        if (containsEndings) {
            if (endings != "transparent" && endings != "native")
                return throwTypeError("The endings property must be either \"transparent\" or \"native\"", args.GetIsolate());
        }

        V8TRYCATCH(bool, containsType, dictionary.get("type", type));
        UNUSED_PARAM(containsType);
        if (!type.containsOnlyASCII())
            return throwError(v8SyntaxError, "type must consist of ASCII characters", args.GetIsolate());
        type.makeLower();
    }

    ASSERT(endings == "transparent" || endings == "native");

    BlobBuilder blobBuilder;

    V8TRYCATCH(v8::Local<v8::Array>, blobParts, v8::Local<v8::Array>::Cast(firstArg));
    uint32_t length = blobParts->Length();

    for (uint32_t i = 0; i < length; ++i) {
        v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(i));
        ASSERT(!item.IsEmpty());
#if ENABLE(BLOB)
        if (V8ArrayBuffer::HasInstance(item, args.GetIsolate(), worldType(args.GetIsolate()))) {
            ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(item));
            ASSERT(arrayBuffer);
            blobBuilder.append(arrayBuffer);
        } else if (V8ArrayBufferView::HasInstance(item, args.GetIsolate(), worldType(args.GetIsolate()))) {
            ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(item));
            ASSERT(arrayBufferView);
            blobBuilder.append(arrayBufferView);
        } else
#endif
        if (V8Blob::HasInstance(item, args.GetIsolate(), worldType(args.GetIsolate()))) {
            Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(item));
            ASSERT(blob);
            blobBuilder.append(blob);
        } else {
            V8TRYCATCH(String, stringValue, toWebCoreString(item));
            blobBuilder.append(stringValue, endings);
        }
    }

    RefPtr<Blob> blob = blobBuilder.getBlob(type);
    return toV8(blob.get(), args.Holder(), args.GetIsolate());
}
예제 #3
0
EncodedJSValue JSC_HOST_CALL JSBlobConstructor::constructJSBlob(ExecState* exec)
{
    JSBlobConstructor* jsConstructor = jsCast<JSBlobConstructor*>(exec->callee());
    ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
    if (!context)
        return throwVMError(exec, createReferenceError(exec, "Blob constructor associated document is unavailable"));

    if (!exec->argumentCount()) {
        RefPtr<Blob> blob = Blob::create();
        return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Blob, blob.get()));
    }

    unsigned blobPartsLength = 0;
    JSObject* blobParts = toJSSequence(exec, exec->argument(0), blobPartsLength);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());
    ASSERT(blobParts);

    String type;
    String endings = ASCIILiteral("transparent");

    if (exec->argumentCount() > 1) {
        JSValue blobPropertyBagValue = exec->argument(1);

        if (!blobPropertyBagValue.isObject())
            return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type Object"));

        // Given the above test, this will always yield an object.
        JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec);

        // Create the dictionary wrapper from the initializer object.
        JSDictionary dictionary(exec, blobPropertyBagObject);

        // Attempt to get the endings property and validate it.
        bool containsEndings = dictionary.get("endings", endings);
        if (exec->hadException())
            return JSValue::encode(jsUndefined());

        if (containsEndings) {
            if (endings != "transparent" && endings != "native")
                return throwVMError(exec, createTypeError(exec, "The endings property must be either \"transparent\" or \"native\""));
        }

        // Attempt to get the type property.
        dictionary.get("type", type);
        if (exec->hadException())
            return JSValue::encode(jsUndefined());
    }

    ASSERT(endings == "transparent" || endings == "native");

    BlobBuilder blobBuilder;

    for (unsigned i = 0; i < blobPartsLength; ++i) {
        JSValue item = blobParts->get(exec, i);
        if (exec->hadException())
            return JSValue::encode(jsUndefined());

#if ENABLE(BLOB)
        if (ArrayBuffer* arrayBuffer = toArrayBuffer(item))
            blobBuilder.append(arrayBuffer);
        else if (RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(item))
            blobBuilder.append(arrayBufferView.release());
        else
#endif
        if (Blob* blob = toBlob(item))
            blobBuilder.append(blob);
        else {
            String string = item.toString(exec)->value(exec);
            if (exec->hadException())
                return JSValue::encode(jsUndefined());
            blobBuilder.append(string, endings);
        }
    }

    RefPtr<Blob> blob = Blob::create(blobBuilder.finalize(), Blob::normalizedContentType(type));

    return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Blob, blob.get()));
}