V new_blob(int size) { V t = make_new_value(T_BLOB, true, sizeof(Blob)); toBlob(t)->size = size; toBlob(t)->data = calloc(size, 1); //TODO: check return value return t; }
int getbyte_blob(V blob, blobsize_t index) { if (index < 0 || index >= toBlob(blob)->size) { return -1; // :( } return toBlob(blob)->data[index]; }
int setbyte_blob(V blob, blobsize_t index, unsigned char value) { if (index < 0 || index >= toBlob(blob)->size) { return -1; // :( } toBlob(blob)->data[index] = value; return 0; }
int blit_blob(V dest, V src, blobsize_t offset) { if (offset < 0 || toBlob(dest)->size < offset + toBlob(src)->size) { return -1; } memcpy(toBlob(dest)->data + offset, toBlob(src)->data, toBlob(src)->size); return 0; }
JSValue JSXMLHttpRequest::send(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; if (args.isEmpty()) impl()->send(ec); else { JSValue val = args.at(0); if (val.isUndefinedOrNull()) impl()->send(ec); else if (val.inherits(&JSDocument::s_info)) impl()->send(toDocument(val), ec); else if (val.inherits(&JSBlob::s_info)) impl()->send(toBlob(val), ec); else impl()->send(val.toString(exec), ec); } int signedLineNumber; intptr_t sourceID; UString sourceURL; JSValue function; exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function); impl()->setLastSendLineNumber(signedLineNumber >= 0 ? signedLineNumber : 0); impl()->setLastSendURL(sourceURL); setDOMException(exec, ec); return jsUndefined(); }
JSValue JSXMLHttpRequest::send(ExecState* exec) { ExceptionCode ec = 0; if (!exec->argumentCount()) impl()->send(ec); else { JSValue val = exec->argument(0); if (val.isUndefinedOrNull()) impl()->send(ec); else if (val.inherits(&JSDocument::s_info)) impl()->send(toDocument(val), ec); else if (val.inherits(&JSBlob::s_info)) impl()->send(toBlob(val), ec); else if (val.inherits(&JSDOMFormData::s_info)) impl()->send(toDOMFormData(val), ec); else impl()->send(ustringToString(val.toString(exec)), ec); } int signedLineNumber; intptr_t sourceID; UString sourceURL; JSValue function; exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function); impl()->setLastSendLineNumber(signedLineNumber >= 0 ? signedLineNumber : 0); impl()->setLastSendURL(ustringToString(sourceURL)); setDOMException(exec, ec); return jsUndefined(); }
JSValue JSWebSocket::send(ExecState* exec) { if (!exec->argumentCount()) return throwError(exec, createSyntaxError(exec, "Not enough arguments")); JSValue message = exec->argument(0); ExceptionCode ec = 0; bool result; if (message.inherits(&JSArrayBuffer::s_info)) result = impl()->send(toArrayBuffer(message), ec); else if (message.inherits(&JSBlob::s_info)) result = impl()->send(toBlob(message), ec); else { String stringMessage = ustringToString(message.toString(exec)->value(exec)); if (exec->hadException()) return jsUndefined(); result = impl()->send(stringMessage, ec); } if (ec) { setDOMException(exec, ec); return jsUndefined(); } return jsBoolean(result); }
JSValue JSXMLHttpRequest::send(ExecState* exec) { InspectorInstrumentation::willSendXMLHttpRequest(impl().scriptExecutionContext(), impl().url()); ExceptionCode ec = 0; JSValue val = exec->argument(0); if (val.isUndefinedOrNull()) impl().send(ec); else if (val.inherits(JSDocument::info())) impl().send(toDocument(val), ec); else if (val.inherits(JSBlob::info())) impl().send(toBlob(val), ec); else if (val.inherits(JSDOMFormData::info())) impl().send(toDOMFormData(val), ec); else if (val.inherits(JSArrayBuffer::info())) impl().send(toArrayBuffer(val), ec); else if (val.inherits(JSArrayBufferView::info())) { RefPtr<ArrayBufferView> view = toArrayBufferView(val); impl().send(view.get(), ec); } else impl().send(val.toString(exec)->value(exec), ec); SendFunctor functor; exec->iterate(functor); impl().setLastSendLineNumber(functor.line()); impl().setLastSendURL(functor.url()); setDOMException(exec, ec); return jsUndefined(); }
TITANIUM_FUNCTION(Buffer, toBlob) { const auto blob = toBlob(); if (blob) { return blob->get_object(); } else { return get_context().CreateNull(); } }
V clone_blob(V blob) { V t = make_new_value(T_BLOB, true, sizeof(Blob)); toBlob(t)->size = toBlob(blob)->size; toBlob(t)->data = malloc(toBlob(blob)->size); //TODO: check return value memcpy(toBlob(t)->data, toBlob(blob)->data, toBlob(blob)->size); return t; }
void resize_blob(V blob, blobsize_t size) { Blob *b = toBlob(blob); b->data = realloc(b->data, size); if (size > b->size) { memset(b->data + b->size, 0, size - b->size); } b->size = size; }
EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsDataURL(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSFileReader::s_info)) return throwVMTypeError(exec); JSFileReader* castedThis = static_cast<JSFileReader*>(asObject(thisValue)); FileReader* imp = static_cast<FileReader*>(castedThis->impl()); Blob* blob(toBlob(exec->argument(0))); if (exec->hadException()) return JSValue::encode(jsUndefined()); imp->readAsDataURL(blob); return JSValue::encode(jsUndefined()); }
JSValue JSDOMFormData::append(ExecState* exec) { if (exec->argumentCount() >= 2) { String name = ustringToString(exec->argument(0).toString(exec)); JSValue value = exec->argument(1); if (value.inherits(&JSBlob::s_info)) { String filename; if (exec->argumentCount() >= 3 && !exec->argument(2).isUndefinedOrNull()) filename = ustringToString(exec->argument(2).toString(exec)); impl()->append(name, toBlob(value), filename); } else impl()->append(name, ustringToString(value.toString(exec))); } return jsUndefined(); }
EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsText(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSFileReader::s_info)) return throwVMTypeError(exec); JSFileReader* castedThis = static_cast<JSFileReader*>(asObject(thisValue)); FileReader* imp = static_cast<FileReader*>(castedThis->impl()); Blob* blob(toBlob(exec->argument(0))); if (exec->hadException()) return JSValue::encode(jsUndefined()); int argsCount = exec->argumentCount(); if (argsCount <= 1) { imp->readAsText(blob); return JSValue::encode(jsUndefined()); } const String& encoding(ustringToString(exec->argument(1).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); imp->readAsText(blob, encoding); return JSValue::encode(jsUndefined()); }
JSValue JSXMLHttpRequest::send(ExecState* exec) { InspectorInstrumentation::willSendXMLHttpRequest(impl()->scriptExecutionContext(), impl()->url()); ExceptionCode ec = 0; if (!exec->argumentCount()) impl()->send(ec); else { JSValue val = exec->argument(0); if (val.isUndefinedOrNull()) impl()->send(ec); else if (val.inherits(&JSDocument::s_info)) impl()->send(toDocument(val), ec); else if (val.inherits(&JSBlob::s_info)) impl()->send(toBlob(val), ec); else if (val.inherits(&JSDOMFormData::s_info)) impl()->send(toDOMFormData(val), ec); else if (val.inherits(&JSArrayBuffer::s_info)) impl()->send(toArrayBuffer(val), ec); else if (val.inherits(&JSArrayBufferView::s_info)) impl()->send(toArrayBufferView(val), ec); else impl()->send(val.toString(exec)->value(exec), ec); } int signedLineNumber; intptr_t sourceID; String sourceURL; JSValue function; exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function); impl()->setLastSendLineNumber(signedLineNumber >= 0 ? signedLineNumber : 0); impl()->setLastSendURL(sourceURL); setDOMException(exec, ec); return jsUndefined(); }
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(exec, jsConstructor->globalObject(), Blob, blob.get())); } JSValue firstArg = exec->argument(0); if (!isJSArray(firstArg)) return throwVMError(exec, createTypeError(exec, "First argument of the constructor is not of type Array")); String type; String endings = "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"); // FIXME: this would be better if the WebKitBlobBuilder were a stack object to avoid the allocation. RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create(); JSArray* array = asArray(firstArg); unsigned length = array->length(); for (unsigned i = 0; i < length; ++i) { JSValue item = array->getIndex(i); #if ENABLE(BLOB) if (item.inherits(&JSArrayBuffer::s_info)) blobBuilder->append(toArrayBuffer(item)); else #endif if (item.inherits(&JSBlob::s_info)) blobBuilder->append(toBlob(item)); else { String string = ustringToString(item.toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); blobBuilder->append(string, endings, ASSERT_NO_EXCEPTION); } } RefPtr<Blob> blob = blobBuilder->getBlob(type); return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get())); }
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())); }