Overview.htm
changeset 127 bf65397910b7
parent 126 be34c357de7f
child 128 56491a744f4d
equal deleted inserted replaced
126:be34c357de7f 127:bf65397910b7
   376 	</section>
   376 	</section>
   377 
   377 
   378 	<section class="section" id="writableByteStream">
   378 	<section class="section" id="writableByteStream">
   379 		<h2>WritableStream Interface</h2>
   379 		<h2>WritableStream Interface</h2>
   380 		<p>
   380 		<p>
   381 			The WritableStream interface defines a protocol for APIs which consume byte streams.
   381 			The WritableStream interface defines a protocol for APIs which consume data stream.
   382 			The protocol includes:
   382 			The protocol includes:
   383 			<ol>
   383 			<ol>
   384 				<li>How to receive the byte stream</li>
   384 				<li>How to receive data stream</li>
   385 				<li>How to notify the writer of completion of writing</li>
   385 				<li>How to notify the writer of completion of writing</li>
   386 				<li>How to notify the writer of how much data can be accepted currently</li>
   386 				<li>How to notify the writer of how much data can be accepted currently</li>
   387 			</ol>
   387 			</ol>
   388 
   388 
   389 			By returning a <a>Promise</a> and delaying fulfillment of it, the WritableStream realizes flow control.
   389 			By returning a <a>Promise</a> and delaying fulfillment of it, the WritableStream realizes flow control.
   390 		</p>
   390 		</p>
   391 
   391 
   392 		<p>
   392 		<p>
   393 			The actual data consumer behind the WritableStream is called a data sink and is identified by <dfn>dataSink</dfn>.
   393 			The actual data consumer behind the WritableStream is called a data sink and is identified by <dfn>dataSink</dfn>.
   394 			A data sink consumes byte streams and notifies the WritableStream of the number of bytes the data sink can newly accept.
   394 			A data sink consumes stream of data and notifies the WritableStream of the cost of data the data sink can newly accept.
   395 			For each data sink, it's defined how to calculate <a>cost</a> of each object which the data sink can consume.
   395 			For each data sink, it must be defined how to calculate <a>cost</a> of each object which the data sink can consume.
   396 		</p>
   396 		</p>
   397 
   397 
   398 		<p>
   398 		<p>
   399 			A WritableStream has a one-to-one mapping with the associated data sink, and has defined semantics for <a href='#interactingWithDataSink'>interacting with the data sink internally</a>.
   399 			A WritableStream has a one-to-one mapping with the associated data sink, and has defined semantics for <a href='#interactingWithDataSink'>interacting with the data sink internally</a>.
   400 		</p>
   400 		</p>
   404 
   404 
   405 			<dl class="idl" title="interface WritableStream">
   405 			<dl class="idl" title="interface WritableStream">
   406 				<dt>attribute DOMString writeEncoding</dt>
   406 				<dt>attribute DOMString writeEncoding</dt>
   407 				<dd>
   407 				<dd>
   408 					<p>
   408 					<p>
   409 						Specifies a <a>DOMString</a> that represents the label of an encoding [[!EncodingDetermination]].
   409 						A <a>DOMString</a> that represents the label of an encoding [[!EncodingDetermination]] to be passed to <a>dataSink</a> together with data passed to <code>write()</code> method.
   410 						If set, it will be used as part of the encoding determination used when processing a <a>DOMString</a> provided in a <code>write()</code> method call.
   410 						It will be used by <a>dataSink</a> for encoding determination.
   411 						It will return the label last set, or the empty DOMString if never set.
   411 						This attribute returns the label last set, or the empty DOMString if never set.
   412 					</p>
   412 					</p>
   413 
   413 
   414 					<section class="note">
   414 					<section class="note">
   415 						This parameter is not designed to be specified as an argument of write() since it's not likely to be changed frequently.
   415 						This parameter is not designed to be specified as an argument of write() since it's not likely to be changed frequently.
   416 					</section>
   416 					</section>
   417 				</dd>
   417 				</dd>
   418 
   418 
   419 				<dt>Promise&amp;lt;unsigned long long&gt; write()</dt>
   419 				<dt>Promise&amp;lt;unsigned long long&gt; write()</dt>
   420 				<dd>
   420 				<dd>
   421 					<p>
   421 					<p>
   422 						This method writes the specified <var>data</var> to the WritableStream.
   422 						This method writes the specified <var>data</var> to <a>dataSink</a>.
   423 					</p>
   423 					</p>
   424 
   424 
   425 					<section class="note">
   425 					<section class="note">
   426 						<p>
   426 						<p>
   427 							write() returns a Promise to make it easy for byte stream producing code to react to backpressure.
   427 							write() returns a Promise to make it easy for byte stream producing code to react to backpressure.
   463 							</li>
   463 							</li>
   464 						</ol>
   464 						</ol>
   465 					</p>
   465 					</p>
   466 
   466 
   467 					<p>
   467 					<p>
   468 						If <var>data</var> argument is an <a>ArrayBufferView</a>, modifications made on the ArrayBufferView's contents between <code>write()</code> method call and fulfill of the returned Promise may affect the data written to <a>dataSink</a>.
   468 						WritableStream interface doesn't guarantee that <var>data</var> argument is cloned.
       
   469 						Modifications made on <var>data</var> argument after <code>write()</code> method call may affect the data written to <a>dataSink</a>.
   469 					</p>
   470 					</p>
   470 
   471 
   471 					<dl class="parameters">
   472 					<dl class="parameters">
   472 						<dt>any data</dt>
   473 						<dt>any data</dt>
   473 						<dd>Data to write.</dd>
   474 						<dd>Data to write.</dd>
   477 				</dd>
   478 				</dd>
   478 
   479 
   479 				<dt>Promise&amp;lt;unsigned long long&gt; awaitSpaceAvailable()</dt>
   480 				<dt>Promise&amp;lt;unsigned long long&gt; awaitSpaceAvailable()</dt>
   480 				<dd>
   481 				<dd>
   481 					<p>
   482 					<p>
   482 						This method waits until the WritableStream becomes able to accept any non-zero amount of data.
   483 						This method returns a <a>Promise</a>.
   483 						The returned <a>Promise</a> will be fulfilled with the number of bytes the WritableStream can accept.
   484 						The returned Promise will be fulfilled with the data <a>cost</a> which <a>dataSink</a> can accept when <a>dataSink</a> becomes able to accept data with any non-zero amount of cost.
   484 					</p>
   485 					</p>
   485 
   486 
   486 					<p>
   487 					<p>
   487 						This method must run the steps below:
   488 						This method must run the steps below:
   488 						<ol>
   489 						<ol>
   489 							<li><a>Abort waiting</a></li>
   490 							<li><a>Abort waiting</a></li>
   490 
       
   491 							<li>Set <a>waitPromise</a> to a new <a>Promise</a></li>
   491 							<li>Set <a>waitPromise</a> to a new <a>Promise</a></li>
   492 							<li>Return <a>waitPromise</a>, and then continue to process the steps in this algorithm</li>
   492 							<li>Return <a>waitPromise</a></li>
   493 							<li>Wait until <a>pendingWriteQueue</a> is empty and <a>spaceAvailable</a> is not 0</li>
       
   494 							<li>
       
   495 								Queue a task to run the steps below:
       
   496 								<ol>
       
   497 									<li>If <a>waitPromise</a> is <code>null</code>, terminate these steps</li>
       
   498 									<li>Let <var>detachedWaitPromise</var> be <a>waitPromise</a></li>
       
   499 									<li>Set <a>waitPromise</a> to <code>null</code></li>
       
   500 									<li>Fulfill <var>detachedWaitPromise</var> with <a>spaceAvailable</a></li>
       
   501 								</ol>
       
   502 							</li>
       
   503 						</ol>
   493 						</ol>
   504 					</p>
   494 					</p>
   505 				</dd>
   495 				</dd>
   506 
   496 
   507 				<dt>Promise&amp;lt;undefined&gt; writeClose()</dt>
   497 				<dt>Promise&amp;lt;undefined&gt; writeClose()</dt>
   508 				<dd>
   498 				<dd>
   509 					<p>
   499 					<p>
   510 						This method tells the WritableStream that no more data will be written to it.
   500 						This method tells the WritableStream that no more data will be written to it.
       
   501 					</p>
       
   502 					<p>
   511 						Once writeClose() has been called on a WritableStream, no further method calls can be made on the WritableStream.
   503 						Once writeClose() has been called on a WritableStream, no further method calls can be made on the WritableStream.
   512 					</p>
   504 					</p>
   513 
   505 
   514 					<p>
   506 					<p>
   515 						This method must run the steps below:
   507 						This method must run the steps below:
   527 				<dd>
   519 				<dd>
   528 					<p>
   520 					<p>
   529 						This method tells the WritableStream that no more data will be written to it with indication of error.
   521 						This method tells the WritableStream that no more data will be written to it with indication of error.
   530 						The details of the error will be given by <var>reason</var> argument.
   522 						The details of the error will be given by <var>reason</var> argument.
   531 						The interpretation of <var>reason</var> is up to <a>dataSink</a>.
   523 						The interpretation of <var>reason</var> is up to <a>dataSink</a>.
   532 						Once writeAbort() has been called on a WritableStream, no further method calls can be made on the WritableStream.
   524 					</p>
       
   525 					<p>
       
   526 						Once this method has been called on a WritableStream, no further method calls can be made on the WritableStream.
   533 					</p>
   527 					</p>
   534 
   528 
   535 					<p>
   529 					<p>
   536 						This method must run the steps below:
   530 						This method must run the steps below:
   537 						<ol>
   531 						<ol>
   538 							<li>Let <var>abortPromise</var> be a new <a>Promise</a></li>
   532 							<li>Let <var>abortPromise</var> be a new <a>Promise</a></li>
   539 							<li>Return <var>abortPromise</var>, and then continue the process the steps in this algorithm</li>
   533 							<li>Return <var>abortPromise</var>, and then continue the process the steps in this algorithm</li>
   540 							<li><a>Write-abort</a> <a>dataSink</a> with <var>reason</var></li>
   534 							<li><a>Write-abort</a> <a>dataSink</a> with <var>reason</var></li>
   541 							<li>Wait until <a>dataSink</a> acknowledges the write-abort</li>
   535 							<li>Wait until <a>dataSink</a> acknowledges the <a>write-abort</a></li>
   542 							<li>Fulfill <var>abortPromise</var> with <code>undefined</code></li>
   536 							<li>Fulfill <var>abortPromise</var> with <code>undefined</code></li>
   543 						</ol>
   537 						</ol>
   544 					</p>
   538 					</p>
   545 				</dd>
   539 				</dd>
   546 			</dl>
   540 			</dl>
   561 					</li>
   555 					</li>
   562 					<li>
   556 					<li>
   563 						Accepts the EOF signal
   557 						Accepts the EOF signal
   564 					</li>
   558 					</li>
   565 					<li>
   559 					<li>
   566 						Accepts the write-abort signal with an object parameter named reason.
   560 						Accepts the <dfn>write-abort</dfn> signal with an object parameter named reason.
   567 					</li>
   561 					</li>
   568 					<li>
   562 					<li>
   569 						Notifies <a>WritableStream</a> of how much data the data sink can newly accept.
   563 						Notifies <a>WritableStream</a> of how much data the data sink can newly accept.
   570 						When and how to generate such notifications is up to data sinks.
   564 						When and how to generate such notifications is up to data sinks.
   571 						Data sinks must be able to accept data more than it notified <a>WritableStream</a> of.
   565 						Data sinks must be able to accept data more than it notified <a>WritableStream</a> of.
   574 						Notifies <a>WritableStream</a> of that the data sink is gone.
   568 						Notifies <a>WritableStream</a> of that the data sink is gone.
   575 						This signal may mean an error.
   569 						This signal may mean an error.
   576 						If it means an error, an object indicating the details of the error is attached.
   570 						If it means an error, an object indicating the details of the error is attached.
   577 					</li>
   571 					</li>
   578 					<li>
   572 					<li>
       
   573 						Notifies <a>WritableStream</a> of acknowledgement of the EOF signal.
       
   574 					</li>
       
   575 					<li>
   579 						Notifies <a>WritableStream</a> of acknowledgement of the write-abort signal with error detail object.
   576 						Notifies <a>WritableStream</a> of acknowledgement of the write-abort signal with error detail object.
   580 					</li>
   577 					</li>
   581 					<li>
   578 					<li>
   582 						How to calculate an integer value <dfn>cost</dfn> of each object which the data sink can consume.
   579 						It's defined how to calculate an integer value <dfn>cost</dfn> of each object which the data sink can consume.
   583 					</li>
   580 					</li>
   584 				</ol>
   581 				</ol>
   585 			</p>
   582 			</p>
   586 		</section>
   583 		</section>
   587 
   584 
   626 				A WritableStream has an associated queue <dfn>pendingWriteQueue</dfn> which holds <a>PendingWriteDescriptor</a>s.
   623 				A WritableStream has an associated queue <dfn>pendingWriteQueue</dfn> which holds <a>PendingWriteDescriptor</a>s.
   627 				This queue is initialized to an empty queue on construction.
   624 				This queue is initialized to an empty queue on construction.
   628 			</p>
   625 			</p>
   629 
   626 
   630 			<p>
   627 			<p>
   631 				To <dfn>process pendingWriteQueue</dfn>, repeat the steps below:
   628 				To <dfn>process pendingWriteQueue</dfn>, run the steps below:
   632 				<ol>
   629 				<ol>
   633 					<li>If <a>pendingWriteQueue</a> is empty, break from this loop</li>
       
   634 					<li>Let <var>pendingWrite</var> be the head element of <a>pendingWriteQueue</a></li>
       
   635 					<li>
   630 					<li>
   636 						<dl class="switch">
   631 						While <a>pendingWriteQueue</a> is not empty, repeat the steps below:
   637 							<dt>If <a>sinkGone</a> is set</dt>
   632 						<ol>
   638 							<dd>Run the steps below:
   633 							<li>Let <var>pendingWrite</var> be the head element of <a>pendingWriteQueue</a></li>
   639 								<ol>
   634 							<li>
   640 									<li>Pop <var>pendingWrite</var> from <a>pendingWriteQueue</a>, and then</li>
   635 								<dl class="switch">
   641 									<li>If <var>pendingWrite.promise</var> is not <code>null</code>, reject it with <a>sinkErrorDetail</a></li>
   636 									<dt>If <a>sinkGone</a> is set</dt>
   642 								</ol>
   637 									<dd>
   643 							</dd>
       
   644 							<dt>Otherwise</dt>
       
   645 							<dd>Run the steps below:
       
   646 								<ol>
       
   647 									<li>Let <var>amountToAcknowledge</var> be min(<var>pendingWrite.amount</var> - <var>pendingWrite.ackedAmount</var>, <a>spaceAvailable</a>)</li>
       
   648 									<li>Set <a>spaceAvailable</a> to <a>spaceAvailable</a> - <var>amountToAcknowledge</var></li>
       
   649 									<li>Set <var>pendingWrite.ackedAmount</var> to <var>pendingWrite.ackedAmount</var> + <var>amountToAcknowledge</var></li>
       
   650 									<li>
       
   651 										If <var>pendingWrite.ackedAmount</var> equals to <var>pendingWrite.amount</var>, run the steps below:
       
   652 										<ol>
   638 										<ol>
   653 											<li>Pop <var>pendingWrite</var> from <a>pendingWriteQueue</a></li>
   639 											<li>Pop <var>pendingWrite</var> from <a>pendingWriteQueue</a>, and then</li>
   654 											<li>If <var>pendingWrite.promise</var> is not <code>null</code>, fulfill it with <var>pendingWrite.amount</var></li>
   640 											<li>If <var>pendingWrite.promise</var> is not <code>null</code>, reject it with <a>sinkErrorDetail</a></li>
   655 										</ol>
   641 										</ol>
   656 									</li>
   642 									</dd>
   657 								</ol>
   643 									<dt>Otherwise</dt>
   658 							</dd>
   644 									<dd>
   659 						</dl>
   645 										<ol>
       
   646 											<li>Let <var>amountToAcknowledge</var> be min(<var>pendingWrite.amount</var> - <var>pendingWrite.ackedAmount</var>, <a>spaceAvailable</a>)</li>
       
   647 											<li>Set <a>spaceAvailable</a> to <a>spaceAvailable</a> - <var>amountToAcknowledge</var></li>
       
   648 											<li>Set <var>pendingWrite.ackedAmount</var> to <var>pendingWrite.ackedAmount</var> + <var>amountToAcknowledge</var></li>
       
   649 											<li>
       
   650 												<dl class="switch">
       
   651 													<dt>If <var>pendingWrite.ackedAmount</var> equals to <var>pendingWrite.amount</var></dt>
       
   652 													<dd>
       
   653 														<ol>
       
   654 															<li>Pop <var>pendingWrite</var> from <a>pendingWriteQueue</a></li>
       
   655 															<li>If <var>pendingWrite.promise</var> is not <code>null</code>, fulfill it with <var>pendingWrite.amount</var></li>
       
   656 														</ol>
       
   657 													</dd>
       
   658 													<dt>Otherwise</dt>
       
   659 													<dd>
       
   660 														Exit from this loop
       
   661 													</dd>
       
   662 												</dl>
       
   663 											</li>
       
   664 										</ol>
       
   665 									</dd>
       
   666 								</dl>
       
   667 							</li>
       
   668 						</ol>
       
   669 					</li>
       
   670 
       
   671 					<li>
       
   672 						If <a>pendingWriteQueue</a> is empty and <a>spaceAvailable</a> is not 0, run the steps below:
       
   673 						<ol>
       
   674 							<li>If <a>waitPromise</a> is <code>null</code>, terminate these steps</li>
       
   675 							<li>Let <var>detachedWaitPromise</var> be <a>waitPromise</a></li>
       
   676 							<li>Set <a>waitPromise</a> to <code>null</code></li>
       
   677 							<li>Fulfill <var>detachedWaitPromise</var> with <a>spaceAvailable</a></li>
       
   678 						</ol>
   660 					</li>
   679 					</li>
   661 				</ol>
   680 				</ol>
   662 			</p>
   681 			</p>
   663 
   682 
   664 			<p>
   683 			<p>