-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1613,91 +1613,6 @@ Specifications should <em>not</em> use this on streams they did not create. | |
1. Return _controller_@[[strategyHWM]] − _queueSize_. | ||
</emu-alg> | ||
|
||
<h3 id="rs-byob-request-class" lt="ReadableStreamBYOBRequest">Class <code>ReadableStreamBYOBRequest</code></h3> | ||
|
||
The <code>ReadableStreamBYOBRequest</code> class represents a pull into request in a | ||
<code>ReadableStreamBYOBController</code>. | ||
|
||
<h4 id="rs-byob-request-class-definition">Class Definition</h4> | ||
|
||
<em>This section is non-normative.</em> | ||
|
||
If one were to write the <code>ReadableStreamBYOBController</code> class in something close to the syntax of | ||
[[!ECMASCRIPT]], it would look like | ||
|
||
<pre><code class="lang-javascript"> | ||
class ReadableStreamBYOBController { | ||
constructor(controller, descriptor) | ||
|
||
get view() | ||
|
||
respond(bytesWritten) | ||
respondWithNewView(view) | ||
|
||
_invalidate() | ||
} | ||
</code></pre> | ||
|
||
<h4 id="rs-byob-request-internal-slots">Internal Slots</h4> | ||
|
||
Instances of <code>ReadableStreamBYOBRequest</code> are created with the internal slots described in the following | ||
table: | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<th>Internal Slot</th> | ||
<th>Description (<em>non-normative</em>)</th> | ||
</tr> | ||
</thead> | ||
<tr> | ||
<td>\[[associatedReadableStreamBYOBController]] | ||
<td>The parent ReadableStreamBYOBController instance | ||
</tr> | ||
<tr> | ||
<td>\[[view]] | ||
<td>A Typed Array representing the destination region to which the controller may write generated data | ||
</tr> | ||
</table> | ||
|
||
<h4 id="rs-byob-request-constructor">new ReadableStreamBYOBRequest(controller, descriptor)</h4> | ||
|
||
<emu-alg> | ||
1. Set *this*@[[associatedReadableStreamBYOBController]] to _controller_. | ||
1. Set *this*@[[view]] to Construct(`Uint8Array`, «_descriptor_.[[buffer]], _descriptor_.[[byteOffset]] + _descriptor_.[[bytesFilled]], _descriptor_.[[byteLength]] - _descriptor_.[[bytesFilled]]»). | ||
</emu-alg> | ||
|
||
<h4 id="rs-byob-request-prototype">Properties of the <code>ReadableStreamBYOBRequest</code> Prototype</h4> | ||
|
||
<h5 id="rs-byob-request-view">get view</h5> | ||
|
||
<emu-alg> | ||
1. Return *this*@[[view]]. | ||
</emu-alg> | ||
|
||
<h5 id="rs-byob-request-respond">respond(bytesWritten)</h5> | ||
|
||
<emu-alg> | ||
1. If IsReadableStreamBYOBRequest(*this*) is *false*, throw a *TypeError* exception. | ||
1. If *this*@[[associatedReadableStreamBYOBController]] is *undefined*, throw a *TypeError* exception. | ||
1. Return ReadableStreamBYOBControllerRespond(*this*@[[associatedReadableStreamBYOBController]], _bytesWritten_). | ||
</emu-alg> | ||
|
||
<h5 id="rs-byob-request-respond-with-new-view">respondWithNewView(view)</h5> | ||
|
||
<emu-alg> | ||
1. If IsReadableStreamBYOBRequest(*this*) is *false*, throw a *TypeError* exception. | ||
1. If *this*@[[associatedReadableStreamBYOBController]] is *undefined*, throw a *TypeError* exception. | ||
1. Return ReadableStreamBYOBControllerRespondWithNewView(*this*@[[associatedReadableStreamBYOBController]], _view_). | ||
</emu-alg> | ||
|
||
<h5 id="rs-byob-request-respond-private-invalidate">_invalidate()</h5> | ||
|
||
<emu-alg> | ||
1. Set *this*@[[associatedReadableStreamBYOBController]] to *undefined*. | ||
1. Set *this*@[[view]] to *undefined*. | ||
</emu-alg> | ||
|
||
<h3 id="rs-byob-controller-class" lt="ReadableStreamBYOBController">Class <code>ReadableStreamBYOBController</code></h3> | ||
|
||
The <code>ReadableStreamBYOBController</code> class has methods that allow control of a <code>ReadableStream</code>'s | ||
|
@@ -1929,6 +1844,91 @@ controllers. | |
1. Return _promise_. | ||
</emu-alg> | ||
|
||
<h3 id="rs-byob-request-class" lt="ReadableStreamBYOBRequest">Class <code>ReadableStreamBYOBRequest</code></h3> | ||
|
||
The <code>ReadableStreamBYOBRequest</code> class represents a pull into request in a | ||
<code>ReadableStreamBYOBController</code>. | ||
|
||
<h4 id="rs-byob-request-class-definition">Class Definition</h4> | ||
|
||
<em>This section is non-normative.</em> | ||
|
||
If one were to write the <code>ReadableStreamBYOBController</code> class in something close to the syntax of | ||
[[!ECMASCRIPT]], it would look like | ||
|
||
<pre><code class="lang-javascript"> | ||
class ReadableStreamBYOBController { | ||
constructor(controller, descriptor) | ||
|
||
get view() | ||
|
||
respond(bytesWritten) | ||
respondWithNewView(view) | ||
|
||
_invalidate() | ||
} | ||
</code></pre> | ||
|
||
<h4 id="rs-byob-request-internal-slots">Internal Slots</h4> | ||
|
||
Instances of <code>ReadableStreamBYOBRequest</code> are created with the internal slots described in the following | ||
table: | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<th>Internal Slot</th> | ||
<th>Description (<em>non-normative</em>)</th> | ||
</tr> | ||
</thead> | ||
<tr> | ||
<td>\[[associatedReadableStreamBYOBController]] | ||
<td>The parent ReadableStreamBYOBController instance | ||
</tr> | ||
<tr> | ||
<td>\[[view]] | ||
<td>A Typed Array representing the destination region to which the controller may write generated data | ||
</tr> | ||
</table> | ||
|
||
<h4 id="rs-byob-request-constructor">new ReadableStreamBYOBRequest(controller, descriptor)</h4> | ||
|
||
<emu-alg> | ||
1. Set *this*@[[associatedReadableStreamBYOBController]] to _controller_. | ||
1. Set *this*@[[view]] to Construct(`Uint8Array`, «_descriptor_.[[buffer]], _descriptor_.[[byteOffset]] + _descriptor_.[[bytesFilled]], _descriptor_.[[byteLength]] - _descriptor_.[[bytesFilled]]»). | ||
</emu-alg> | ||
|
||
<h4 id="rs-byob-request-prototype">Properties of the <code>ReadableStreamBYOBRequest</code> Prototype</h4> | ||
|
||
<h5 id="rs-byob-request-view">get view</h5> | ||
|
||
<emu-alg> | ||
1. Return *this*@[[view]]. | ||
</emu-alg> | ||
|
||
<h5 id="rs-byob-request-respond">respond(bytesWritten)</h5> | ||
|
||
<emu-alg> | ||
1. If IsReadableStreamBYOBRequest(*this*) is *false*, throw a *TypeError* exception. | ||
1. If *this*@[[associatedReadableStreamBYOBController]] is *undefined*, throw a *TypeError* exception. | ||
1. Return ReadableStreamBYOBControllerRespond(*this*@[[associatedReadableStreamBYOBController]], _bytesWritten_). | ||
</emu-alg> | ||
|
||
<h5 id="rs-byob-request-respond-with-new-view">respondWithNewView(view)</h5> | ||
|
||
<emu-alg> | ||
1. If IsReadableStreamBYOBRequest(*this*) is *false*, throw a *TypeError* exception. | ||
1. If *this*@[[associatedReadableStreamBYOBController]] is *undefined*, throw a *TypeError* exception. | ||
1. Return ReadableStreamBYOBControllerRespondWithNewView(*this*@[[associatedReadableStreamBYOBController]], _view_). | ||
</emu-alg> | ||
|
||
<h5 id="rs-byob-request-respond-private-invalidate">_invalidate()</h5> | ||
|
||
<emu-alg> | ||
1. Set *this*@[[associatedReadableStreamBYOBController]] to *undefined*. | ||
1. Set *this*@[[view]] to *undefined*. | ||
</emu-alg> | ||
|
||
<h3 id="rs-byob-controller-abstract-ops">Readable Stream BYOB Controller Abstract Operations</h3> | ||
|
||
<h4 id="is-readable-stream-byob-controller" aoid="IsReadableStreamBYOBController" nothrow>IsReadableStreamBYOBController ( x )</h4> | ||
|
@@ -3133,7 +3133,7 @@ socket. | |
<h3 id="example-rs-pull">A readable stream with an underlying pull source</h3> | ||
|
||
The following function returns <a>readable streams</a> that wrap portions of the | ||
<a href="https://iojs.org/api/fs.html">io.js file system API</a> (which themselves map fairly directly to C's | ||
<a href="https://nodejs.org/api/fs.html">Node.js file system API</a> (which themselves map fairly directly to C's | ||
<code>fopen</code>, <code>fread</code>, and <code>fclose</code> trio). Files are a typical example of <a>pull | ||
sources</a>. Note how in contrast to the examples with push sources, most of the work here happens on-demand in the | ||
<code>pull</code> function, and not at startup time in the <code>start</code> function. | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
@@ -3175,6 +3175,53 @@ sources</a>. Note how in contrast to the examples with push sources, most of the | |
|
||
We can then create and use readable streams for files just as we could before for sockets. | ||
|
||
<h3 id="example-rbs-pull">A readable byte stream with an underlying pull source</h3> | ||
|
||
The following function returns <a>readable byte streams</a> that allow efficient zero-copy reading of files, again | ||
using the <a href="https://nodejs.org/api/fs.html">Node.js file system API</a>. Instead of using a predetermined chunk | ||
size of 1024, it attempts to fill the developer-supplied buffer, allowing full control. | ||
|
||
<pre><code class="lang-javascript"> | ||
const fs = require("pr/fs"); // https://github.com/jden/pr | ||
|
||
function makeReadableByteFileStream(filename) { | ||
let fd; | ||
let position = 0; | ||
|
||
return new ReadableStream({ | ||
byob: true, | ||
|
||
start() { | ||
return fs.open(filename, "r").then(result => { | ||
fd = result; | ||
}); | ||
}, | ||
|
||
pull(controller) { | ||
const v = controller.byobRequest.view; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
return fs.read(fd, v, v.byteOffset, v.byteLength, position).then(bytesRead => { | ||
if (bytesRead === 0) { | ||
return fs.close(fd).then(() => controller.close()); | ||
} else { | ||
position += bytesRead; | ||
controller.byobRequest.respond(bytesRead); | ||
} | ||
}); | ||
}, | ||
|
||
cancel() { | ||
return fs.close(fd); | ||
} | ||
}); | ||
} | ||
</code></pre> | ||
|
||
With this in hand, we can create and use <a>BYOB readers</a> for the returned <code>ReadableStream</code>. But we can | ||
also create <a>default readers</a>, using them in the same simple and generic manner as usual. The adaptation between | ||
the low-level byte tracking of the <a>underlying byte source</a> shown here, and the higher-level chunk-based | ||
consumption of a <a>default reader</a>, is all taken care of automatically by the streams implementation. | ||
This comment has been minimized.
Sorry, something went wrong.
tyoshino
Member
|
||
|
||
<h3 id="example-ws-no-backpressure">A writable stream with no backpressure or success signals</h3> | ||
|
||
The following function returns a <a>writable stream</a> that wraps a web socket [[HTML]]. Web sockets do not provide | ||
|
3 comments
on commit b430f33
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you be able to take over making the examples better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I'll try to today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
BTW, the example below also need to handle
bytesRead
as well as the issue @yutakahirano pointed out at #430 (comment) in the newly added example.buffer
can be filled partially (even if the API blocks until CHUNK_SIZE bytes are filled, we may eventually need to return a partially filled buffer at the end of the file), and there's no way to know that for the user of the stream.