/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://streams.spec.whatwg.org/#set-up-readable-stream-byob-reader void SetUpReadableStreamBYOBReader(ReadableStreamBYOBReader* reader,
ReadableStream& stream, ErrorResult& rv) { // Step 1. If !IsReadableStreamLocked(stream) is true, throw a TypeError // exception. if (IsReadableStreamLocked(&stream)) {
rv.ThrowTypeError("Trying to read locked stream"); return;
}
// Step 2. If stream.[[controller]] does not implement // ReadableByteStreamController, throw a TypeError exception. if (!stream.Controller()->IsByte()) {
rv.ThrowTypeError("Trying to read with incompatible controller"); return;
}
struct Read_ReadIntoRequest final : public ReadIntoRequest {
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Read_ReadIntoRequest,
ReadIntoRequest)
// We need to wrap this as the chunk could have come from // another compartment.
JS::Rooted<JSObject*> chunk(aCx, &aChunk.toObject()); if (!JS_WrapObject(aCx, &chunk)) {
aRv.StealExceptionFromJSContext(aCx); return;
}
void CloseSteps(JSContext* aCx, JS::Handle<JS::Value> aChunk,
ErrorResult& aRv) override {
MOZ_ASSERT(aChunk.isObject() || aChunk.isUndefined()); // https://streams.spec.whatwg.org/#byob-reader-read Step 6. // // close steps, given chunk: // Resolve promise with «[ "value" → chunk, "done" → true ]».
RootedDictionary<ReadableStreamReadResult> result(aCx); if (aChunk.isObject()) { // We need to wrap this as the chunk could have come from // another compartment.
JS::Rooted<JSObject*> chunk(aCx, &aChunk.toObject()); if (!JS_WrapObject(aCx, &chunk)) {
aRv.StealExceptionFromJSContext(aCx); return;
}
// Step 1. If view.[[ByteLength]] is 0, return a promise rejected with a // TypeError exception. if (JS_GetArrayBufferViewByteLength(view) == 0) { // Binding code should convert this thrown value into a rejected promise.
aRv.ThrowTypeError("Zero Length View"); return nullptr;
}
// Step 2. If view.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0, // return a promise rejected with a TypeError exception. bool isSharedMemory;
JS::Rooted<JSObject*> viewedArrayBuffer(
cx, JS_GetArrayBufferViewBuffer(cx, view, &isSharedMemory)); if (!viewedArrayBuffer) {
aRv.StealExceptionFromJSContext(cx); return nullptr;
}
// Step 3. If ! IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true, return a // promise rejected with a TypeError exception. if (JS::IsDetachedArrayBufferObject(viewedArrayBuffer)) {
aRv.ThrowTypeError("Detached Buffer"); return nullptr;
}
// Step 4. If options["min"] is 0, return a promise rejected with a TypeError // exception. if (aOptions.mMin == 0) {
aRv.ThrowTypeError( "Zero is not a valid value for 'min' member of " "ReadableStreamBYOBReaderReadOptions."); return nullptr;
}
// Step 5. If view has a [[TypedArrayName]] internal slot, if (JS_IsTypedArrayObject(view)) { // Step 5.1. If options["min"] > view.[[ArrayLength]], return a promise // rejected with a RangeError exception. if (aOptions.mMin > JS_GetTypedArrayLength(view)) {
aRv.ThrowRangeError( "Array length exceeded by 'min' member of " "ReadableStreamBYOBReaderReadOptions."); return nullptr;
}
} else { // Step 6. Otherwise (i.e., it is a DataView), // Step 6.1. If options["min"] > view.[[ByteLength]], return a promise // rejected with a RangeError exception. if (aOptions.mMin > JS_GetArrayBufferViewByteLength(view)) {
aRv.ThrowRangeError( "byteLength exceeded by 'min' member of " "ReadableStreamBYOBReaderReadOptions."); return nullptr;
}
}
// Step 7. If this.[[stream]] is undefined, return a promise rejected with a // TypeError exception. if (!GetStream()) {
aRv.ThrowTypeError("Reader has undefined stream"); return nullptr;
}
// Step 8. Let promise be a new promise.
RefPtr<Promise> promise = Promise::CreateInfallible(GetParentObject());
// Step 9. Let readIntoRequest be a new read-into request with the following // items:
RefPtr<ReadIntoRequest> readIntoRequest = new Read_ReadIntoRequest(promise);
// Step 2. Set reader.[[readIntoRequests]] to a new empty list. // Note: The std::move already cleared this anyway.
aReader->ReadIntoRequests().clear();
// Step 3. For each readIntoRequest of readIntoRequests, while (RefPtr<ReadIntoRequest> readIntoRequest =
readIntoRequests.popFirst()) { // Step 3.1. Perform readIntoRequest’s error steps, given e.
readIntoRequest->ErrorSteps(aCx, aError, aRv); if (aRv.Failed()) { return;
}
}
}
// Step 2. Let e be a new TypeError exception.
ErrorResult rv;
rv.ThrowTypeError("Releasing lock");
JS::Rooted<JS::Value> error(aCx);
MOZ_ALWAYS_TRUE(ToJSValue(aCx, std::move(rv), &error));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.