/* * Copyright (c) 2023, Matthew Olsson * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include namespace Web::Streams { JS_DEFINE_ALLOCATOR(WritableStreamDefaultWriter); WebIDL::ExceptionOr> WritableStreamDefaultWriter::construct_impl(JS::Realm& realm, JS::NonnullGCPtr stream) { auto writer = realm.heap().allocate(realm, realm); // 1. Perform ? SetUpWritableStreamDefaultWriter(this, stream). TRY(set_up_writable_stream_default_writer(*writer, stream)); return writer; } // https://streams.spec.whatwg.org/#default-writer-closed JS::GCPtr WritableStreamDefaultWriter::closed() { // 1. Return this.[[closedPromise]]. return m_closed_promise->promise(); } // https://streams.spec.whatwg.org/#default-writer-desired-size WebIDL::ExceptionOr> WritableStreamDefaultWriter::desired_size() const { // 1. If this.[[stream]] is undefined, throw a TypeError exception. if (!m_stream) return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot get desired size of writer that has no locked stream"sv }; // 2. Return ! WritableStreamDefaultWriterGetDesiredSize(this). return writable_stream_default_writer_get_desired_size(*this); } // https://streams.spec.whatwg.org/#default-writer-ready JS::GCPtr WritableStreamDefaultWriter::ready() { // 1. Return this.[[readyPromise]]. return m_ready_promise->promise(); } // https://streams.spec.whatwg.org/#default-writer-abort JS::GCPtr WritableStreamDefaultWriter::abort(JS::Value reason) { auto& realm = this->realm(); // 1. If this.[[stream]] is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { auto exception = JS::TypeError::create(realm, "Cannot abort a writer that has no locked stream"sv); return WebIDL::create_rejected_promise(realm, exception)->promise(); } // 2. Return ! WritableStreamDefaultWriterAbort(this, reason). return writable_stream_default_writer_abort(*this, reason)->promise(); } // https://streams.spec.whatwg.org/#default-writer-close JS::GCPtr WritableStreamDefaultWriter::close() { auto& realm = this->realm(); // 1. Let stream be this.[[stream]]. // 2. If stream is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { auto exception = JS::TypeError::create(realm, "Cannot close a writer that has no locked stream"sv); return WebIDL::create_rejected_promise(realm, exception)->promise(); } // 3. If ! WritableStreamCloseQueuedOrInFlight(stream) is true, return a promise rejected with a TypeError exception. if (writable_stream_close_queued_or_in_flight(*m_stream)) { auto exception = JS::TypeError::create(realm, "Cannot close a stream that is already closed or errored"sv); return WebIDL::create_rejected_promise(realm, exception)->promise(); } // 4. Return ! WritableStreamDefaultWriterClose(this). return writable_stream_default_writer_close(*this)->promise(); } // https://streams.spec.whatwg.org/#default-writer-release-lock void WritableStreamDefaultWriter::release_lock() { // 1. Let stream be this.[[stream]]. // 2. If stream is undefined, return. if (!m_stream) return; // 3. Assert: stream.[[writer]] is not undefined. VERIFY(m_stream->writer()); // 4. Perform ! WritableStreamDefaultWriterRelease(this). writable_stream_default_writer_release(*this); } // https://streams.spec.whatwg.org/#default-writer-write JS::GCPtr WritableStreamDefaultWriter::write(JS::Value chunk) { auto& realm = this->realm(); // 1. If this.[[stream]] is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { auto exception = JS::TypeError::create(realm, "Cannot write to a writer that has no locked stream"sv); return WebIDL::create_rejected_promise(realm, exception)->promise(); } // 2. Return ! WritableStreamDefaultWriterWrite(this, chunk). return writable_stream_default_writer_write(*this, chunk)->promise(); } WritableStreamDefaultWriter::WritableStreamDefaultWriter(JS::Realm& realm) : Bindings::PlatformObject(realm) { } void WritableStreamDefaultWriter::initialize(JS::Realm& realm) { Base::initialize(realm); WEB_SET_PROTOTYPE_FOR_INTERFACE(WritableStreamDefaultWriter); } void WritableStreamDefaultWriter::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_closed_promise); visitor.visit(m_ready_promise); visitor.visit(m_stream); } }