Overview.htm
author Takeshi Yoshino <tyoshino@google.com>
Wed, 29 Jan 2014 21:51:07 +0900
changeset 144 4aad0585848b
parent 143 d58caffffd98
child 145 1e237f753a38
permissions -rw-r--r--
More clean up
<!DOCTYPE html>

<html>

<head>
	<title>Streams API</title>
	<meta content="text/html;charset=utf-8" http-equiv="Content-Type">

	<!-- <script class=remove src="http://dev.w3.org/2009/dap/ReSpec.js/js/respec.js"></script> -->
	<script class="remove" src="https://www.w3.org/Tools/respec/respec-w3c-common"></script>
	<!-- <script class="remove" src="respec-w3c-common.js"></script> -->

	<script class="remove">
var respecConfig = {
	// specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
	specStatus:           "ED",

	// the specification's short name, as in http://www.w3.org/TR/short-name/
	shortName:            "streams-api",

	// if your specification has a subtitle that goes below the main
	// formal title, define it here
	// subtitle   :  "an excellent document",

	// if you wish the publication date to be other than today, set this
	// publishDate:  "yyyy-mm-dd",

	// if the specification's copyright date is a range of years, specify
	// the start date here:
	// copyrightStart: "2005"

	// if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
	// and its maturity status
	// previousPublishDate:  "yyyy-mm-dd",
	// previousMaturity:  "WD",

	// if there a publicly available Editor's Draft, this is the link
	edDraftURI:           "http://dvcs.w3.org/hg/streams-api/raw-file/tip/Overview.htm",

	// if this is a LCWD, uncomment and set the end of its review period
	// lcEnd: "2009-08-05",

	// if you want to have extra CSS, append them to this list
	// it is recommended that the respec.css stylesheet be kept
	//extraCSS:             ["http://dev.w3.org/2009/dap/ReSpec.js/css/respec.css",
	//	"http://www.w3.org/StyleSheets/TR/W3C-ED.css",
	//	],

	// editors, add as many as you like
	// only "name" is required

	localBiblio: {
		"EncodingDetermination": {
			title: "Encoding",
			href: "http://encoding.spec.whatwg.org/",
			authors: ["Anne van Kesteren", "Joshua Bell"],
			publisher: "WHATWG"
		}
	},

	editors:  [
		{ name: "Feras Moussa", url: "mailto:feras.moussa@hotmail.com",
			company: "Invited Expert",  },
		{ name: "Takeshi Yoshino", url: "mailto:tyoshino@google.com",
			company: "Google, Inc.",  },
	],

	// authors, add as many as you like.
	// This is optional, uncomment if you have authors as well as editors.
	// only "name" is required. Same format as editors.

	//authors:  [
	//    { name: "Your Name", url: "http://example.org/",
	//      company: "Your Company", companyURL: "http://example.com/" },
	//],

	// name of the WG
	wg:           "W3C Web Applications (WebApps)",

	// URI of the public WG page
	wgURI:        "http://www.w3.org/2008/webapps/",

	// name (with the @w3c.org) of the public mailing to which comments are due
	wgPublicList: "public-webapps",

	// URI of the patent status for this WG, for Rec-track documents
	// !!!! IMPORTANT !!!!
	// This is important for Rec-track documents, do not copy a patent URI from a random
	// document unless you know what you're doing. If in doubt ask your friendly neighbourhood
	// Team Contact.
	wgPatentURI:  "",
};
</script>

	<!-- Styles to mimic File API spec -->
	<!-- <style type="text/css"> -->
	<!-- 	table.error { border-collapse:collapse; border-style:hidden hidden none hidden } -->
	<!-- 	table.error thead { border-bottom:solid } -->
	<!-- 	table.error tbody th:first-child { border-left:solid } -->
	<!-- 	table.error td, table th { border-left:solid; border-right:solid; border-bottom:solid thin; vertical-align:top; padding:0.2em } -->
	<!-- </style> -->

</head>
<body>

	<section id="sotd">
		<p>
			This document is not complete.
			It is subject to major changes and, while early experimentations are encouraged, it is therefore not intended for implementation.
		</p>

		<p>
			To check recent changes and rationale for them, please visit <a href="https://dvcs.w3.org/hg/streams-api/">Mercurial history</a>.
			Check open bugs at Bugzilla using <a href="https://www.w3.org/Bugs/Public/buglist.cgi?component=Streams%20API">this link</a>.
			If you wish to submit a bug, please use <a href="https://www.w3.org/Bugs/Public/enter_bug.cgi?product=WebAppsWG&component=Streams%20API">this link</a>.
			All comments and bug reports are welcome.
		</p>
	</section>

	<section id="abstract">
		<p>
			This specification provides an API for representing a stream of data in web applications, as well as programmatically reading and writing it.
			This includes:
		</p>
		<ul>
			<li>
				An interface named <a>WritableStream</a> which defines a general protocol for data consuming APIs (<a href="#consumers">consumers</a>) to communicate with data producing code (<a href="#producers">producers</a>).
			</li>
			<li>
				An interface named <a>ReadableStream</a> which defines a general protocol for data producing APIs to communicate with data consuming code.
			</li>
			<li>
				An interface named <a>ByteStream</a> which inherits both WritableStream and ReadableStream and represents a sequence of data.
			</li>
			<li>
				A struct type named <a>StreamReadResult</a> which represents the result of consuming operations such as <code>read()</code> and <code>pipe()</code>.
				It holds:
				<ul>
					<li>Chunk of content read from a <a>ReadableStream</a></li>
					<li>The total cost of the chunk</li>
					<li>EOF signal</li>
					<li>Error info</li>
				</ul>
			</li>
			<li>
				An enum <a>StreamReadType</a> which represents data types as which data can be read from a <a>ReadableStream</a>.
			</li>
			<li>
				A list of notable data <a href="#producers">producers</a> and <a href="#consumers">consumers</a> for which we can apply either or both of <a>ReadableStream</a> and <a>WritableStream</a> model.
			</li>
			<li>
				Extensions to <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-xmlhttprequest-interface">XMLHttpRequest</a> [[!XMLHTTPREQUEST2]] to add support for uploading data via <a>WritableStream</a> and downloading a response as a <a>ReadableStream</a>.
			</li>
			<li>
				Extensions to <a href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-createObjectURL">URL.createObjectURL</a> and <a href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-revokeObjectURL">URL.revokeObjectURL</a> to add support for <a>ReadableStream</a>.
			</li>
		</ul>

		<p>
			This API is designed to be used in conjunction with other APIs and elements on the web platform, notably:
			<ul>
				<li><a href="http://dev.w3.org/2006/webapi/FileAPI">FileAPI</a> [[!FILE-API]]</li>
				<li>
					<a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2">XMLHttpRequest</a>.
					E.g. with an overloaded <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-send-method"><code>send()</code></a> method and <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-responsetype-attribute"><code>response</code></a> object for <a>ReadableStream</a> objects) [[!XMLHTTPREQUEST2]].
				</li>
				<li><a href="http://dev.w3.org/html5/postmsg/#dom-window-postmessage"><code>postMessage</code></a></li>
				<li>Web Workers [[!WEBWORKERS]]</li>
			</ul>
		</p>
	</section>

	<section id="introduction" class="section informative">
		<h2>Introduction</h2>

		<p>
			Web applications should have the ability to acquire, manipulate, and pass data in a wide variety of forms, including as a sequence of data made available over time.
			This specification defines the basic representation for streams of data, and programmatic ways to read and write streams of data and errors raised on those operations.
		</p>

		<p>
			The <a>WritableStream</a> interface defines a general protocol for <a href="#consumers">data consuming APIs</a> to communicate with data producing code.
			In these cases, the data consuming API, such as a decoder, provides a <a>WritableStream</a> for other applications to write to, enabling the decoder to begin decoding data as it becomes available.
			The data is written to the internal data sink inside the data consuming API using:
			<ul>
				<li>
					The <code>write()</code> method which writes the given data to the data sink
				</li>
				<li>
					The <code>awaitSpaceAvailable()</code> method which allows a data producing code to write data to the data consuming API only when its data sink is available to consume more data.
					This is useful for cases where an app may want to avoid filling the internal buffer.
				</li>
			</ul>
			Actual transfer of data to the data sink may happen either synchronously or asynchronously.
			<a>WritableStream</a> hides the details of actual communication with the data sink while allowing for an efficient transfer of data.
		</p>

		<p>
			The <a>ReadableStream</a> interface defines a general protocol for <a href="#producers">data producing APIs</a> to communicate with data consuming code.
			This interface represents the potential for an infinite amount of data which are obtained over time and read once.
			Data consuming code reads data from the internal data source inside the data producing API using:
			<ul>
				<li>
					The <code>read()</code> and <code>readUpTo()</code> methods which reads data from the data source
				</li>
				<li>
					The <code>pullAmount</code> attribute which paces data retrieval from the data source
				</li>
				<li>
					The <code>pipe()</code> method which transfers data in bulk from the data source into the data sink of another API which implements <a>WritableStream</a>
				</li>
			</ul>
			Actual transfer of data from the data source may happen either synchronously or asynchronously.
			The <a>ReadableStream</a> hides the details of actual communication with the data source while allowing for an efficient transfer of data.
		</p>

		<p>
			With the combination of the following features, this interface suite responds to various simple and complex needs of data stream handling.
			<ul>
				<li>Delayed notification of completion by using <a>Promise</a>s. See below for more details.</li>
				<li>Explicit back pressure management by propagating room for consumption back to producers</li>
				<li><a>WritableStream</a> always accepts incoming data synchronously to bridge with legacy APIs that don't understand backpressure</li>
			</ul>
		</p>

		<p>
			The <a>ByteStream</a> is a simple implementation of both the <a>WritableStream</a> and <a>ReadableStream</a> interface.
			A ByteStream has a single queue of bytes which works as a data sink for the WritableStream interface and as a data source for the ReadableStream interface.
		</p>

		<p>
			Read and write operations on these interfaces are implemented using <a>Promise</a>.
			When an operation completes, the Promise returned by a method will be fulfilled, and then the fulfill callback set to the Promise will handle the result.
			Error conditions that may arise during an operation will be handled by the reject callback set to the Promise.
		</p>

		<p>
			The base stream classes are defined as JavaScript primitives.
			Extensions to it for use in browsers are defined separately.
		</p>

		<p>
			Examples below will be illustrative.
		</p>

		<p>
			The example below demonstrates how to read a chunk of data from a <a>ReadableStream</a> using <code>read()</code>.
			The <a>ReadableStream</a> may of come from a <a href="#producers">producer</a> such as <code>XMLHttpRequest</code>.
		</p>

		<pre class="example">
// Tell stream that we're ready to consume 1024 bytes.
stream.pullAmount = 1024;
stream.readEncoding = "UTF-8";
stream.readBinaryAs = "arraybuffer";
stream.read().then(
  function (result) {
    // Process data
  },
  function (error) {
    // Handle error
  });</pre>

		<p>
			The example below demonstrates how to read bytes from a <a>ReadableStream</a> until an EOF is encountered.
		</p>

		<pre class="example">// Read data from the ReadableStream repeatedly
function readUntilEof() {
  stream.read().then(
    function (result) {
      processData(result.data);

      if (!result.eof) {
        readUntilEof();
      }
    },
    function (error) {
      // Handle error
    });
}

readUntilEof();</pre>

		<p>
			The example below demonstrates how to obtain a <a>ReadableStream</a> from <a>XMLHttpRequest</a> to begin playing a large video in <code>readystate</code> LOADING.
			The example takes the <a>ReadableStream</a> from a <a href="#producers">producer</a>, <a>XMLHttpRequest</a>, and gives it to a <a href="#consumers">consumer</a>, the video tag.
			If the consumer implements the <a>WritableStream</a> interface, we could use <code>pipe()</code> to transfer data to it instead of URL.
		</p>

		<pre class="example">function handler() {
  if(this.readyState == this.LOADING) {
    var theStream = this.response;
    var streamURL = URL.createObjectURL(theStream);
    document.getElementById("myVideoTag").src = streamURL;
  }
}

var client = new XMLHttpRequest();
client.onreadystatechange = handler;
client.setRequestHeader('customHeader', 'value');
client.setRequestHeader('customHeader2', 'value2');
client.open("GET", "myvideo.h264");
client.responseType = "stream";
client.send();</pre>

		<p>
			The example below demonstrates how to use <code>write()</code> to load a <a>ReadableStream</a> into the audio tag, whose data could be processed and built dynamically at read time.
			ByteStream in the example is a class which implements both <a>WritableStream</a> and <a>ReadableStream</a>.
			It accepts bytes generated by the code via <a>WritableStream</a> methods, and the written data will be consumed by the audio element via the object URL which is a part of <a>ReadableStream</a>'s functionality.
		</p>

		<pre class="example">var stream = new ByteStream("audio/mp3");

function writeData() {
  // Do work to create more data to place into the stream
  var data = generateMusic();

  // If we have no more data to process and place in the stream, we close
  if (moreData == null){
    stream.writeClose();
  } else{
    // Wait until write() completes.
    stream.write(data).then(
      function () {
        writeData();
      },
      function (error) {
        // Handle error
      }
    );
  }
}

var streamURL = URL.createObjectURL(stream);
document.getElementById('audioTag').src = streamURL;

writeData();</pre>

		<p>
			A producer can also do work only when pulled by using <code>awaitSpaceAvailable()</code>.
			This method informs the data producing code of that the data consuming API is ready to consume data.
			This is useful when high-performance is necessary.
		</p>

		<pre class="example">function poll() {
  stream.awaitSpaceAvailable().then(
    function (pulledAmount) {
      stream.write(generateRandomBytes(pulledAmount));
      poll();
    }
  );
}

poll();</pre>

		<p>
			The example below demonstrates how the timing to pull new data is determined.
			When data of cost X is loaded and passed to the Promise, the <a>ReadableStream</a> marks X bytes of pullAmount as used.
			The next <code>read()</code> call automatically clears the mask to request the data source to produce X more data.
			If precise flow control is needed, you update pullAmount before the next <code>read()</code>.
			In the example, the producer API is requested to produce 16 bytes, and then in the fulfill callback, pullAmount is set to the remaining number of bytes not to let the API produce more data.
		</p>

		<pre class="example">stream.pullAmount = 16;
function read() {
  stream.read().then(
    function (result) {
      process(result);
      stream.pullAmount -= result.size;
      if (stream.pullAmount == 0) {
        // Done
      } else if (stream.eof) {
        // Done
      } else {
        read();
      }
    }
  );
}</pre>
	</section>

	<section class="section" id="writableByteStream">
		<h2>WritableStream Interface</h2>
		<p>
			The WritableStream interface defines a protocol for APIs which consume a data stream.
			The protocol includes:
			<ol>
				<li>How to receive data stream</li>
				<li>How to notify the writer (data producing code) of completion of writing</li>
				<li>How to notify the writer of how much data can be accepted currently</li>
			</ol>

			By returning a <a>Promise</a> and delaying fulfillment of it, the WritableStream realizes flow control.
		</p>

		<p>
			The actual data consumer behind the WritableStream is called a data sink and is identified by <dfn>dataSink</dfn>.
			A data sink consumes stream of data and notifies the WritableStream of the cost of data the data sink can newly accept.
			For each data sink, it must be defined how to calculate <a>cost</a> of each object which the data sink can consume.
		</p>

		<p>
			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>.
		</p>

		<section class="section">
			<h3>WritableStream interface</h3>

			<dl class="idl" title="interface WritableStream">
				<dt>attribute DOMString writeEncoding</dt>
				<dd>
					<p>
						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.
						It will be used by <a>dataSink</a> for encoding determination.
						This attribute returns the label last set, or the empty DOMString if never set.
					</p>

					<section class="note">
						This parameter is not designed to be specified as an argument of write() since it's not likely to be changed frequently.
					</section>
				</dd>

				<dt>Promise&amp;lt;unsigned long long&gt; write()</dt>
				<dd>
					<p>
						This method writes the specified <var>data</var> to <a>dataSink</a>.
					</p>

					<section class="note">
						<p>
							write() returns a Promise to make it easy for byte stream producing code to react to backpressure.
						</p>
					</section>

					<p>
						This method must run the steps below:
						<ol>
							<li>Let <var>latchedEncoding</var> be the current value of <a href="#widl-WritableStream-writeEncoding">writeEncoding</a></li>

							<li><a>Abort wait</a></li>

							<li>
								If <var>costOverride</var> argument is specified, let <var>amountToWrite</var> be <var>costOverride</var> argument.
								Otherwise, let <var>amountToWrite</var> be the <a>cost</a> of <var>data</var>
							</li>

							<li>Let <var>writePromise</var> be a newly-created <a>Promise</a></li>

							<li>Let <var>pendingWrite</var> be a newly-created <a>PendingWriteDescriptor</a></li>
							<li>Set <var>pendingWrite.promise</var> to <var>writePromise</var></li>
							<li>Set <var>pendingWrite.amount</var> to <var>amountToWrite</var></li>
							<li>Push <var>pendingWrite</var> to <a>pendingWriteQueue</a></li>

							<li><a>Process pendingWriteQueue</a></li>

							<li>
								Run the steps below possibly asynchronously:

								<dl class="switch">
									<dt>If <var>data</var> is a <a>DOMString</a></dt>
									<dd>
										Write <var>data</var> to <a>dataSink</a> together with <var>latchedEncoding</var> as <var>encoding</var> parameter.
										Interpretation of <var>latchedEncoding</var> is up to <a>dataSink</a>.
									</dd>
									<dt>Otherwise</dt>
									<dd>
										Write <var>data</var> to <a>dataSink</a>.
									</dd>
								</dl>
							</li>

							<li>Return <var>writePromise</var></li>
						</ol>
					</p>

					<p>
						WritableStream interface doesn't guarantee that <var>data</var> argument is cloned.
						Modifications made on <var>data</var> argument after <code>write()</code> method call may affect the data written to <a>dataSink</a>.
					</p>

					<dl class="parameters">
						<dt>any data</dt>
						<dd>Data to write.</dd>
						<dt>optional [Clamp] unsigned long long costOverride</dt>
						<dd>Overrides <a>cost</a> of data.</dd>
					</dl>
				</dd>

				<dt>Promise&amp;lt;unsigned long long&gt; awaitSpaceAvailable()</dt>
				<dd>
					<p>
						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.
					</p>

					<p>
						This method must run the steps below:
						<ol>
							<li><a>Abort awaitSpace</a></li>
							<li>Set <a>awaitSpacePromise</a> to a newly-created <a>Promise</a></li>
							<li>Return <a>awaitSpacePromise</a></li>
						</ol>
					</p>
				</dd>

				<dt>Promise&amp;lt;undefined&gt; writeClose()</dt>
				<dd>
					<p>
						This method tells the WritableStream that no more data will be written to it.
					</p>
					<p>
						Once writeClose() has been called on a WritableStream, no further method calls can be made on the WritableStream.
					</p>

					<p>
						This method must run the steps below:
						<ol>
							<li>Let <var>closePromise</var> be a newly-created <a>Promise</a></li>
							<li>Return <var>closePromise</var>, and then continue the process the steps in this algorithm</li>
							<li>Write the EOF to <a>dataSink</a></li>
							<li>Wait until <a>dataSink</a> acknowledges the EOF</li>
							<li>Fulfill <var>closePromise</var> with <code>undefined</code></li>
						</ol>
					</p>
				</dd>

				<dt>Promise&amp;lt;undefined&gt; writeAbort(optional any reason)</dt>
				<dd>
					<p>
						This method tells the WritableStream that no more data will be written to it with indication of error.
						The details of the error will be given by <var>reason</var> argument.
						The interpretation of <var>reason</var> is up to <a>dataSink</a>.
					</p>
					<p>
						Once this method has been called on a WritableStream, no further method calls can be made on the WritableStream.
					</p>

					<p>
						This method must run the steps below:
						<ol>
							<li>Let <var>abortPromise</var> be a newly-created <a>Promise</a></li>
							<li>
								Run the steps below possibly asynchronously:
								<ol>
									<li><a>Write-abort</a> <a>dataSink</a> with <var>reason</var></li>
									<li>Wait until <a>dataSink</a> acknowledges the <a>write-abort</a></li>
									<li>Fulfill <var>abortPromise</var> with <code>undefined</code></li>
								</ol>
							</li>
							<li>Return <var>abortPromise</var></li>
						</ol>
					</p>
				</dd>
			</dl>
		</section>

		<section class="section">
			<h2>Data sink model</h2>

			<p>
				The data sink is the underlying mechanism which a <a>WritableStream</a> interacts with and stores its data in.
			</p>

			<p>
				A data sink to which the <a>WritableStream</a> interface writes bytes can be anything which:
				<ol>
					<li>
						Accepts data possibly together with a <a>DOMString</a> parameter named <var>encoding</var> indicating in what encoding the data must be interpreted.
					</li>
					<li>
						Accepts the EOF signal
					</li>
					<li>
						Accepts the <dfn>write-abort</dfn> signal with an object parameter named reason.
					</li>
					<li>
						Notifies <a>WritableStream</a> of how much data the data sink can newly accept.
						When and how to generate such notifications is up to data sinks.
						Data sinks must be able to accept data more than it notified <a>WritableStream</a> of.
					</li>
					<li>
						Notifies <a>WritableStream</a> of that the data sink is gone.
						This signal may mean an error.
						If it means an error, an object indicating the details of the error is attached.
					</li>
					<li>
						Notifies <a>WritableStream</a> of acknowledgement of the EOF signal.
					</li>
					<li>
						Notifies <a>WritableStream</a> of acknowledgement of the write-abort signal with error detail object.
					</li>
					<li>
						It's defined how to calculate an integer value <dfn>cost</dfn> of each object which the data sink can consume.
					</li>
				</ol>
			</p>
		</section>

		<section class="section" id='interactingWithDataSink'>
			<h2>Interacting with the data sink</h2>

			<p>
				This section defines the internal mechanisms for how the WritableStream interacts with <a>dataSink</a>.
				This section specifies both the internal properties as well as the algorithms.
			</p>

			<p>
				A WritableStream has an associated integer variable <dfn>spaceAvailable</dfn> which holds the number of bytes that <a>dataSink</a> requested but not yet written to it.
				This variable is initialized to 0 on construction.
			</p>

			<p>
				A WritableStream has an associated <a>Promise</a> <dfn>awaitSpacePromise</dfn> which is used by the <code>awaitSpaceAvailable()</code> method.
				This variable is initialized to <code>null</code> on construction.
			</p>

			<p>
				To <dfn>abort awaitSpace</dfn>, run the steps below:

				<ol>
					<li>If <a>awaitSpacePromise</a> is <code>null</code>, terminate these steps</li>
					<li>Let <var>detachedWaitPromise</var> be <a>awaitSpacePromise</a></li>
					<li>Set <a>awaitSpacePromise</a> to <code>null</code></li>
					<li>Reject <var>detachedWaitPromise</var> with an "<code><a>AbortError</a></code>"</li>
				</ol>
			</p>

			<p>
				A struct type <dfn>PendingWriteDescriptor</dfn> has the following members:
				<ul>
					<li>A <a>Promise</a> <var>promise</var></li>
					<li>An integer <var>amount</var></li>
					<li>An integer <var>ackedAmount</var></li>
				</ul>
			</p>

			<p>
				A WritableStream has an associated queue <dfn>pendingWriteQueue</dfn> which holds <a>PendingWriteDescriptor</a>s.
				This queue is initialized to an empty queue on construction.
			</p>

			<p>
				To <dfn>process pendingWriteQueue</dfn>, run the steps below:
				<ol>
					<li>
						While <a>pendingWriteQueue</a> is not empty, repeat the steps below:
						<ol>
							<li>Let <var>pendingWrite</var> be the head element of <a>pendingWriteQueue</a></li>
							<li>
								<dl class="switch">
									<dt>If <a>sinkGone</a> is set</dt>
									<dd>
										<ol>
											<li>Pop <var>pendingWrite</var> from <a>pendingWriteQueue</a>, and then</li>
											<li>If <var>pendingWrite.promise</var> is not <code>null</code>, reject it with <a>sinkErrorDetail</a></li>
										</ol>
									</dd>
									<dt>Otherwise</dt>
									<dd>
										<ol>
											<li>Let <var>amountToAcknowledge</var> be min(<var>pendingWrite.amount</var> - <var>pendingWrite.ackedAmount</var>, <a>spaceAvailable</a>)</li>
											<li>Set <a>spaceAvailable</a> to <a>spaceAvailable</a> - <var>amountToAcknowledge</var></li>
											<li>Set <var>pendingWrite.ackedAmount</var> to <var>pendingWrite.ackedAmount</var> + <var>amountToAcknowledge</var></li>
											<li>
												<dl class="switch">
													<dt>If <var>pendingWrite.ackedAmount</var> equals to <var>pendingWrite.amount</var></dt>
													<dd>
														<ol>
															<li>Pop <var>pendingWrite</var> from <a>pendingWriteQueue</a></li>
															<li>If <var>pendingWrite.promise</var> is not <code>null</code>, fulfill it with <var>pendingWrite.amount</var></li>
														</ol>
													</dd>
													<dt>Otherwise</dt>
													<dd>
														Exit from this loop
													</dd>
												</dl>
											</li>
										</ol>
									</dd>
								</dl>
							</li>
						</ol>
					</li>

					<li>
						If <a>pendingWriteQueue</a> is empty and <a>spaceAvailable</a> is not 0 and <a>awaitSpacePromise</a> is not <code>null</code>, run the steps below:

						<ol>
							<li>Let <var>detachedPromise</var> be <a>awaitSpacePromise</a></li>
							<li>Set <a>awaitSpacePromise</a> to <code>null</code></li>
							<li>Fulfill <var>detachedPromise</var> with <a>spaceAvailable</a></li>
						</ol>
					</li>
				</ol>
			</p>

			<p>
				When <a>dataSink</a> requests <var>amountNewlyRequested</var> more data, queue a task which runs the steps below:
				<ol>
					<li>Set <a>spaceAvailable</a> to <a>spaceAvailable</a> + <var>amountNewlyRequested</var></li>
					<li><a>Process pendingWriteQueue</a></li>
				</ol>
			</p>

			<p>
				A WritableStream has an associated flag <dfn>sinkGone</dfn> which is set when the data sink is gone.
			</p>

			<p>
				A WritableStream has an associated object <dfn>sinkErrorDetail</dfn> which is initialized to null, and when the data sink is gone, set to the error detail object.
			</p>

			<p>
				When <a>dataSink</a> notifies the WritableStream of that the data sink is gone, queue a task which runs the steps below:
				<ol>
					<li>Set <a>sinkGone</a></li>
					<li>Set <a>sinkErrorDetail</a> to the error detail object</li>
					<li><a>Process pendingWriteQueue</a></li>
				</ol>
			</p>
		</section>
	</section>

	<section class="section" id="readableByteStream">
		<h2>ReadableStream Interface</h2>
		<p>
			The ReadableStream interface defines a protocol for APIs which produce a data stream.
			This protocol includes:
			<ol>
				<li>How to receive read requests from the reader (data consuming code) and pass output data to the reader</li>
				<li>How to transfer data in bulk to another <a>WritableStream</a> (by using the <code>pipe()</code> method)</li>
				<li>How to mirror data to multiple destinations (by using the <code>fork()</code>)</li>
			</ol>

			By returning a <a>Promise</a> and delaying fulfillment of it, the ReadableStream realizes asynchronous data consumption.
		</p>

		<p>
			Interfaces introduced in this section provide simple and convenient ways to consume data.
			They connect arbitrary data stream producer and data consuming code using Promises and method invocations.
		</p>

		<p>
			A ReadableStream has a one-to-one mapping with an associated <a href="#readableByteStreamDataSource">data source</a>, and has defined semantics for <a href='#interactingWithDataSource'>interacting with the data source internally</a>.
			A data source, however, can have a one-to-many relationship with ReadableStreams, in cases where <code>fork()</code> is used.
		</p>

		<section class="section" id="readableByteStreamInterface">
			<h3>ReadableStream interface</h3>

			<dl class="idl" title="interface ReadableStream">
				<dt>attribute StreamReadType readBinaryAs</dt>
				<dd>
					<p>
						Specifies what data type will be returned by a <code>read()</code> and <code>readUpTo()</code> method call.
						This attribute can be set to any of the supported types in <a>StreamReadType</a>.
					<p>
					</p>
						The default value for this attribute is "<code>as-is</code>".
					</p>
					<p>
						Values other than "<code>as-is</code>" works only when the data to be read from the ReadableStream represents binary data.
					</p>
				</dd>

				<dt>attribute DOMString readEncoding</dt>
				<dd>
					<p>
						Specifies a <a>DOMString</a> that represents the label of an encoding [[!EncodingDetermination]].
						If set, it will be used as part of the encoding determination used when processing a <code>read()</code> and <code>readUpTo()</code> method call.
					</p>
					<p>
						This attribute works only when the data to be read from the ReadableStream represents binary data.
					</p>

					<section class="note">
						This parameter is not designed to be specified as an argument of the reading methods since it's not likely to be changed frequently.
					</section>
				</dd>

				<dt>attribute unsigned long long pullAmount</dt>
				<dd>
					<p>
						This attribute provides the ReadableStream with a hint of how much data the reader can consume currently.
					</p>
					<p>
						Each implementation of the ReadableStream must initialize the value of pullAmount on construction.
					</p>

					<p>
						When this attribute is set, the user agent must <a>retrieve data</a>.
					</p>

					<section class="note">
						This flow control functionality is provided as a separated attribute rather than as an argument of the read() method based on the assumption that this value is not changed frequently.
					</section>
					<section class="note">
						It's possible that the cost of data received by <code>read()</code> is more than the pullAmount value.
					</section>
				</dd>

				<dt>Promise&amp;lt;StreamReadResult&gt; readUpTo()</dt>
				<dd>
					<p>
						This method reads binary data from the ReadableStream.
						The returned <a>Promise</a> is fulfilled when any of the following conditions is met:
						<ul>
							<li>The total size of produced bytes becomes equal to <var></var></li>
							<li>The EOF is reached</li>
						</ul>
						The <a>cost</a> of data returned by this method can be less than <var>size</var> when data cannot be fully converted into the type specified by <a href="#widl-ReadableStream-readBinaryAs">readBinaryAs</a> or the EOF is reached.
					</p>

					<p>
						This method must run the steps below:
						<ol>
							<li>If <a href="#widl-ReadableStream-readBinaryAs">readBinaryAs</a> is "<code>as-is</code>", return a <a>Promise</a> rejected with a "<code><a>SyntaxError</a></code>"</li>

							<li>If <a>pendingRead</a> is not <code>null</code>, return a <a>Promise</a> rejected with an "<code><a>InvalidStateError</a></code>"</li>

							<li>Let <var>readPromise</var> be a newly-created <a>Promise</a></li>

							<li>Set <a>pendingRead</a> to a newly-created <a>PendingReadDescriptor</a></li>

							<li>Set <a>pendingRead</a>.<var>binaryAs</var> to the current value of <a href="#widl-ReadableStream-readBinaryAs">readBinaryAs</a></li>
							<li>Set <a>pendingRead</a>.<var>encoding</var> to the current value of <a href="#widl-ReadableStream-readEncoding">readEncoding</a></li>
							<li>Set <a>pendingRead</a>.<var>size</var> to <var>size</var></li>
							<li>Set <a>pendingRead</a>.<var>promise</var> to <var>readPromise</var></li>
							<li>Set <a>pendingRead</a>.<var>destination</var> to <code>null</code></li>

							<li>Set <a>readUpToPullAmount</a> to <var>size</var></li>
							<li>Set <a>amountBeingReturned</a> to 0</li>

							<li><a>Retrieve data</a> possibly asynchronously</li>

							<li>Return <var>readPromise</var></li>
						</ol>
					</p>

					<dl class="parameters">
						<dt>[Clamp] unsigned long long size</dt>
						<dd>Upper limit of total cost of data to be read</dd>
					</dl>

					<section class="note">
						This method is useful if
						<ol>
							<li>You don't want to get notified of new data unless bytes of the specified number become available.</li>
							<li>You don't want to get your data fragmented into multiple parts, thus avoiding the need to buffer and combine chunks yourself.</li>
						</ol>
					</section>
				</dd>

				<dt>Promise&amp;lt;StreamReadResult&gt; read()</dt>
				<dd>
					<p>
						This method reads data from the ReadableStream.
						The speed of reading can be roughly adjusted by using <a href="#widl-StreamReadResult-pullAmount">pullAmount</a>.
						<a href="#widl-StreamReadResult-pullAmount">pullAmount</a> doesn't necessarily limit the size of data being read by this method.
					</p>

					<p>
						This method must run the steps below:

						<ol>
							<li>If <a>pendingRead</a> is not <code>null</code>, return a Promise reject with an "<code><a>InvalidStateError</a></code>"</li>

							<li>Let <var>readPromise</var> be a newly-created <a>Promise</a></li>

							<li>Set <a>pendingRead</a> to a newly-created <a>PendingReadDescriptor</a></li>

							<li>Set <a>pendingRead</a>.<var>binaryAs</var> to the current value of <a href="#widl-ReadableStream-readBinaryAs">readBinaryAs</a></li>
							<li>Set <a>pendingRead</a>.<var>encoding</var> to the current value of <a href="#widl-ReadableStream-readEncoding">readEncoding</a></li>
							<li>Set <a>pendingRead</a>.<var>size</var> to <code>undefined</code></li>
							<li>Set <a>pendingRead</a>.<var>promise</var> to <var>readPromise</var></li>
							<li>Set <a>pendingRead</a>.<var>destination</var> to <code>null</code></li>

							<li>Set <a>amountBeingReturned</a> to 0</li>

							<li><a>Retrieve data</a> possibly asynchronously</li>

							<li>Return <var>readPromise</var></li>
						</ol>
					</p>

					<p>
						<img src="images/fulfilling.png" alt="How new data is automatically fetched">
					</p>

					<section class="note">
						This method is useful if
						<ol>
							<li>You don't care in what size and as how many fragments the data will be received</li>
							<li>You want to limit the number of bytes read for flow control</li>
						</ol>
					</section>
				</dd>

				<dt>Promise&amp;lt;StreamReadResult&gt; pipe()</dt>
				<dd>
					<p>
						This method bulk transfers bytes from the ReadableStream to another <a>WritableStream</a>.
					</p>

					<section class="note">
						Fulfillment of the returned Promise doesn't necessarily mean that the data transferred to <var>destination</var> has been successfully read from it.
					</section>

					<section class="note">
						TODO: Rewrite this to update <a>amountBeingReturned</a> as numBytesAcknowledged of <a>PendingWriteDescriptor</a>s are updated
					</section>

					<p>
						This method must run the steps below:

						<ol>
							<li>If <a>pendingRead</a> is not <code>null</code>, return a <a>Promise</a> rejected with an "<code><a>InvalidStateError</a></code>"</li>

							<li>Set <var>pipePromise</var> be a newly-created <a>Promise</a></li>

							<li>Set <a>pendingRead</a> to a newly-created <a>PendingReadDescriptor</a></li>

							<li>Set <a>pendingRead</a>.<var>binaryAs</var> to <code>undefined</code></li>
							<li>Set <a>pendingRead</a>.<var>encoding</var> to <code>undefined</code></li>
							<li>Set <a>pendingRead</a>.<var>size</var> to <var>size</var> argument</li>
							<li>Set <a>pendingRead</a>.<var>promise</var> to <var>pipePromise</var></li>
							<li>Set <a>pendingRead</a>.<var>destination</var> to <var>destination</var> argument</li>

							<li>Set <a>totalAmountTransferred</a> to 0</li>

							<li><a>Wait for destination</a> possibly asynchronously</li>

							<li>Return <var>pipePromise</var></li>
						</ol>
					</p>

					<dl class="parameters">
						<dt>WritableStream destination</dt>
						<dd>Destination <a>WritableStream</a>.</dd>
						<dt>optional [Clamp] unsigned long long size</dt>
						<dd>Number of bytes to transfer.</dd>
					</dl>
				</dd>

				<dt>ReadableStream fork()</dt>
				<dd>
					<p>
						This method creates a new ReadableStream which refers to the same <a>dataSource</a> as the current ReadableStream.
						Data sources are range reference counted so that a range in a data source is freed only when all the ReadableStreams sharing the data source finish consuming it.
					</p>

					<p>
						This method must run the steps below:
						<ol>
							<li>Let <var>branch</var> be a new ReadableStream which refers to <a>dataSource</a> and has the same <a>amountRequested</a> value, <a>readDataBuffer</a> contents and <a>eofReached</a> value as the current ReadableStream.</li>
							<li>If <a>amountRequested</a> is not 0, up to <a>amountRequested</a> bytes arriving in the future must be forwarded to <var>branch</var>.</li>
							<li>Return <var>branch</var>.</li>
						</ol>
					</p>
				</dd>

				<dt>Promise&amp;lt;undefined&gt; readAbort(optional any reason)</dt>
				<dd>
					<p>
						This method tells the ReadableStream that no more data will be read from it optionally with indication of error.
						The details of the error will be given by <var>reason</var> argument.
						The interpretation of <var>reason</var> is up to <a>dataSource</a>.
					</p>
					<p>
						Once this method has been called on a ReadableStream, no further method calls can be made on the ReadableStream.
					</p>

					<p>
						This method must run the steps below:
						<ol>
							<li>Let <var>abortPromise</var> be a newly-created <a>Promise</a></li>
							<li>
								Run the steps below possibly asynchronously:
								<ol>
									<li><a>Read-abort</a> <a>dataSource</a> with <var>reason</var></li>
									<li>Wait until <a>dataSource</a> acknowledges the <a>read-abort</a></li>
									<li>Fulfill <var>abortPromise</var> with <code>undefined</code></li>
								</ol>
							</li>
							<li>Return <var>abortPromise</var></li>
						</ol>
					</p>
				</dd>
			</dl>
		</section>

		<section class="section" id='readableByteStreamDataSource'>
			<h3>Data source model</h3>

			<p>
				A data source produces data stream to be consumed via the <a>ReadableStream</a> interface instances.
				A <a>ReadableStream</a> retrieves data from an associated data source.
				The data source model is not directly surfaced in the API, and is described here to provide details on how internal operations such as <a href="#widl-ReadableStream-fork-ReadableStream">fork()</a> can be handled.
			</p>

			<p>
				A <dfn>data source</dfn> can be anything that:
				<ul>
					<li>
						Produces data.
						Newly produced data will be delivered to the associated <a>ReadableStream</a>.
					</li>
					<li>
						Notifies <a>ReadableStream</a> of the <dfn>read EOF</dfn> signal.
						This signal may include indication of an error.
						When it indicates an error, an object which represents the details of the error is attached.
					</li>
					<li>
						Accepts requests for production of data from a <a>ReadableStream</a>.
						A data production request consists of an integer indicating the total cost of data to produce in addition to already requested ones.
						Interpretation of the request is up to each data source.
						Data sources may respond to retrieval requests with data larger than requested.
						Requests and delivery of data don't need to 1-to-1 correspond.
						Data sources may produce data and send to <a>ReadableStream</a> unsolicitedly without receiving any retrieval request.
					</li>
					<li>
						Accepts and acknowledges <dfn>read-abort</dfn> signal which means the associated <a>ReadableStream</a> has completed consuming data from this data source optionally with indication of any error.
					</li>
				</ul>
			</p>

			<p>
				To allow multiple consumers, we use a wrapper <dfn>data source wrapper</dfn> for range reference counting on produced bytes.
				A <a>data source wrapper</a> has the following functionalities:
				<ul>
					<li>has a <var>queue</var> to which newly produced bytes are pushed</li>
					<li>has a sorted map <dfn>cursorMap</dfn> whose key is reader ID and value is integer called cursor</li>
					<li>can issue reader IDs which are unique to the <a>data source wrapper</a> instance when requested</li>
					<li>pops bytes from <var>queue</var> when the smallest cursor in <a>cursorMap</a> by the difference of the new smallest cursor and the old smallest cursor</li>
					<li>when there's not sufficient bytes in <var>queue</var> to respond to coming retrieval request, retrieves bytes from the wrapped data source</li>
				</ul>
			</p>

			<p>
				When <a href="#widl-ReadableStream-fork-ReadableStream">fork()</a> is called, a new reader is registered to the original <a>ReadableStream</a>'s data source and the new <a>ReadableStream</a> uses read() method to fetch data from it.
			</p>
		</section>

		<section class="section" id="interactingWithDataSource">
			<h2>Interacting with the data source</h2>

			<section class="note">
				This interface is designed to work even if operations on <a>dataSource</a> are asynchronous.
				If <a>dataSource</a> is synchronously accessible, some of the algorithms can be simplified.
			</section>

			<p>
				A <a>ReadableStream</a> has an associated <a>data source</a> referred by <dfn>dataSource</dfn> from which the ReadableStream retrieves data.
				The data source model is explained in <a href="#h2_data_source">this section</a>.
				A data source can be shared by multiple ReadableStream instances when <code>fork()</code> is used.
				A ReadableStream is registered with a data source on construction and given a reader ID.
				The <a>dataSource</a> of a ReadableStream refers to its data source, and <dfn>readerId</dfn> of a ReadableStream refers to its reader ID.
			</p>

			<p>
				A ReadableStream has the following internal mechanisms:
			</p>

			<p>
				An associated flag <dfn>readPending</dfn> which prevents multiple read operations from being run.
				This flag is set to false on construction.
			</p>

			<p>
				An associated integer variable <dfn>readUpToPullAmount</dfn> which temporarily overrides <a href="#widl-ReadableStream-pullAmount">pullAmount</a> if necessary for a <code>readUpTo()</code> method call.
				This variable is initialized to 0 on construction.
			</p>
			<p>
				An associated integer variable <dfn>pipePullAmount</dfn> which temporarily overrides <a href="#widl-ReadableStream-pullAmount">pullAmount</a> if necessary for a <code>pipe()</code> method call.
				This variable is initialized to 0 on construction.
			</p>

			<p>
				An associated integer variable <dfn>amountRequested</dfn> which holds the cost of data being retrieved from the <a>dataSource</a>.
				This variable is initialized to 0 on construction.
			</p>
			<p>
				An associated integer variable <dfn>amountBeingReturned</dfn> which holds the cost of data consumed on the last read operation.
				This variable is initialized to 0 on construction.

				<section class="note">
					amountBeingReturned delays replenishment of pullAmount until the next read()/pipe() operation is made.
				</section>
			</p>

			<p>
				An associated queue <dfn>readDataBuffer</dfn> which holds data retrieved from <a>dataSource</a>.
				This queue is initialized to an empty queue on construction.
			</p>

			<p>
				<img src="images/readdatabuffer.png" alt="Read data buffer related variables">
			</p>

			<p>
				An associated binary data queue <dfn>splicedBinaryBuffer</dfn> which holds binary data spliced from <a>readDataBuffer</a>.
				THis queue is initialized to an empty queue on construction.
			</p>

			<p>
				A struct type <dfn>PendingReadDescriptor</dfn> has the following members:
				<ul>
					<li>A <a>Promise</a> <var>promise</var></li>
					<li>An integer <var>amount</var></li>
					<li>A <a>DOMString</a> <var>binaryAs</var></li>
					<li>A <a>DOMString</a> <var>encoding</var></li>
					<li>A <a>WritableStream</a> <var>destination</var></li>
				</ul>
			</p>

			<p>
				A WritableStream has an associated <a>PendingReadDescriptor</a> <dfn>pendingRead</dfn>.
				This variable is initialized to <code>null</code> on construction.
			</p>

			<p>
				An associated flag <dfn>eofReached</dfn> which indicates that the <a>read EOF</a> was received from the <a>dataSource</a>.
			</p>

			<p>
				An associated object <dfn>sourceErrorDetail</dfn> which is initialized to <code>null</code>. Once the <a>read EOF</a> including indication of an error is received from the <a>dataSource</a>, this variable is set to the error detail object.
			</p>

			<p>
				An associated integer variable <dfn>totalAmountTransferred</dfn> which holds the total cost of data transferred for the current <code>pipe()</code> method call.
				This variable is initialized to 0 on construction.
			</p>

			<p>
				To <dfn>retrieve data</dfn>, run the steps below:
				<ol>
					<li>Let <var>readableAmount</var> be sum of the total <a>cost</a> in <a>readDataBuffer</a> and the total number of bytes in <a>splicedBinaryBuffer</a></li>
					<li>Let <var>amountToNewlyRetrieve</var> be max(max(<a href="#widl-ReadableStream-pullAmount">pullAmount</a>, <a>readUpToPullAmount</a>, <a>pipePullAmount</a>) - (<a>amountRequested</a> + <var>readableAmount</var> + <a>amountBeingReturned</a>), 0)</li>
					<li>Set <a>amountRequested</a> to <a>amountRequested</a> + <var>amountToNewlyRetrieve</var></li>
					<li>Send a request to the <a>dataSource</a> to produce data with <var>amountToNewlyRetrieve</var> <a>cost</a> to the ReadableStream</li>
				</ol>
			</p>

			<p>
				To <dfn>splice binary data</dfn>, repeat the steps below while <a>readDataBuffer</a> is not empty:

				<ol>
					<li>If <a>pendingRead</a>.<var>size</var> is 0, return from this algorithm</li>

					<li>Let <var>head</var> be the first element in <a>readDataBuffer</a></li>
					<li>
						<dl class="switch">
							<dt>If <var>head</var> is not an object representing binary data</dt>
							<dd>
								<ol>
									<li>Let <var>readPromise</var> be <a>pendingRead</a>.<var>promise</var></li>
									<li>Set <a>pendingRead</a> to <code>null</code></li>
									<li>Reject <var>readPromise</var> with an "<code><a>InvalidStateError</a></code>"</li>
									<li>Return from this algorithm with failure</li>
								</ol>
							</dd>
							<dt>If <a>pendingRead</a>.<var>size</var> is <code>undefined</code></dt>
							<dd>
								<ol>
									<li>Pop <var>head</var> from <a>readDataBuffer</a></li>
									<li>Push <var>head</var> to <a>splicedBinaryBuffer</a></li>
								</ol>

								<section class="note">
									Implementations may choose to pop only part of bytes readable if it helps reducing memory copy.
								</section>
							</dd>
							<dt>If the number of bytes in <var>head</var> is not greater than <a>pendingRead</a>.<var>size</var></dt>
							<dd>
								<ol>
									<li>Pop <var>head</var> from <a>readDataBuffer</a></li>
									<li>Push <var>head</var> to <a>splicedBinaryBuffer</a></li>
									<li>Set <a>pendingRead</a>.<var>size</var> to <a>pendingRead</a>.<var>size</var> - (the number of bytes in <var>head</var>)</li>
								</ol>
							</dd>
							<dt>Otherwise</dt>
							<dd>
								<ol>
									<li>Split <var>head</var> into two elements <var>first</var> and <var>last</var> where the number of bytes in <var>first</var> is <a>pendingRead</a>.<var>size</var></li>
									<li>Replace <var>head</var> in <a>readDataBuffer</a> with <var>last</var></li>
									<li>Push <var>first</var> to <var>splicedBinaryBuffer</var></li>
									<li>Set <a>pendingRead</a>.<var>size</var> to 0</li>
								</ol>
							</dd>
						</dl>
					</li>
				</ol>
			</p>

			<p>
				To <dfn>output data</dfn>, run the steps below:

				<ol>
					<li>Let <var>result</var> be a newly-created <a>StreamReadResult</a></li>

					<li>
						<dl class="switch">
							<dt>If <a>pendingRead</a>.<var>binaryAs</var> is "<code>as-is</code>"</dt>
							<dd>
								<ol>
									<li>Pop one element from <a>readDataBuffer</a>, and set <var>result</var>.<a href="#widl-StreamReadResult-data">data</a> to the element</li>
									<li>Let <var>amountConsumed</var> be <a>cost</a> of the element</li>
								</ol>
							</dd>

							<dt>Otherwise</dt>
							<dd>
								<ol>
									<li><a>Splice binary data</a></li>
									<li>If the last step failed, terminate these steps</li>

									<li>If <a>pendingRead</a>.<var>size</var> is not <code>undefined</code> and <a>eofReached</a> is not set and the number of bytes in <a>splicedBinaryBuffer</a> is less than <a>pendingRead</a>.<var>size</var>, terminate these steps</li>

									<li>
										Switch on <a>pendingRead</a>.<var>binaryAs</var>:

										<dl class="switch">
											<dt>"<code>arraybuffer</code>"</dt>
											<dd>
												<ol>
													<li>Set <var>result</var>.<a href="#widl-StreamReadResult-data">data</a> to an object of the type specified by <a>pendingRead</a>.<var>binaryAs</var> that represents binary data stored in <a>splicedBinaryBuffer</a></li>
													<li>Let <var>amountConsumed</var> be the number of bytes in <a>splicedBinaryBuffer</a></li>
												</ol>
											</dd>
											<dt>"<code>text</code>"</dt>
											<dd>
												<ol>
													<li>Set <var>result</var>.<a href="#widl-StreamReadResult-data">data</a> to a DOMString that is the result of decoding as many bytes in <a>splicedBinaryBuffer</a> as possible using <a>pendingRead</a>.<var>encoding</var></li>
													<li>
														Let <var>unusedBytes</var> be the bytes in <a>splicedBinaryBuffer</a> which were not used in the last step, and
													  let <var>amountConsumed</var> be the number of bytes in <a>splicedBinaryBuffer</a> used in the last step
													</li>
													<li>
														If <a>eofReached</a> is set and <var>unusedBytes</var> is not empty, run the steps below:
														<ol>
															<li>Let <var>readPromise</var> be <a>pendingRead</a>.<var>promise</var></li>
															<li>Set <a>pendingRead</a> to <code>null</code></li>
															<li>Reject <var>readPromise</var> with an "<code><a>EncodingError</a></code>"</li>
														</ol>
													</li>
													<li>Prepend <var>unusedBytes</var> to <a>readDataBuffer</a></li>
												</ol>
											</dd>
											<dt>"<code>none</code>"</dt>
											<dd>
												<ol>
													<li>Set <var>result</var>.<a href="#widl-StreamReadResult-data">data</a> to <code>undefined</code></li>
													<li>Let <var>amountConsumed</var> be the number of bytes in <a>splicedBinaryBuffer</a></li>
												</ol>
											</dd>
										</dl>
									</li>
									<li>Clear <a>splicedBinaryBuffer</a></li>
								</ol>
							</dd>
						</dl>
					</li>

					<li>Set <var>result</var>.<a href="#widl-StreamReadResult-size">size</a> to <var>amountConsumed</var></li>
					<li>Set <var>result</var>.<a href="#widl-StreamReadResult-eof">eof</a> to <code>true</code> if <a>readDataBuffer</a> is empty and <a>eofReached</a> is set</li>
					<li>Set <var>result</var>.<a href="#widl-StreamReadResult-error">error</a> to <a>sourceErrorDetail</a></li>

					<li>Set <a>amountBeingReturned</a> to <var>amountConsumed</var></li>

					<li>Set <a>readUpToPullAmount</a> to 0</li>

					<li>Let <var>readPromise</var> to <a>pendingRead</a>.<var>promise</var></li>
					<li>Set <a>pendingRead</a> to <code>null</code></li>
					<li>Fulfill <var>readPromise</var> with <var>result</var></li>
				</ol>
			</p>

			<p>
				To <dfn>wait for destination</dfn>, run the steps below:

				<ol>
					<li>
						Let <var>onFulfilled</var> be a callback which runs the steps below:

						<ol>
							<li>Let <var>space</var> be the first argument</li>
							<li>
								<dl class="switch">
									<dt>If <a>pendingRead</a>.<var>size</var> is specified</dt>
									<dd>
										Set <a>pipePullAmount</a> to min(<a>pendingRead</a>.<var>size</var>, <var>space</var>)

										<section class="note">
											If <a href="#widl-ReadableStream-pullAmount">pullAmount</a> is set to 0, pipe() transfers data in pull style.
											I.e. only data of the same cost as one writable to <var>destination</var> are retrieved from the data source.
										</section>
										<section class="note">
											Setting <a href="#widl-ReadableStream-pullAmount">pullAmount</a> to a small value doesn't have an effect of throttling the pace of pipe().
										</section>
									</dd>
									<dt>Otherwise</dt>
									<dd>Set <a>pipePullAmount</a> to <var>space</var></dd>
								</dl>
							</li>
							<li>Set <a>amountBeingReturned</a> to 0</li>
							<li><a>Retrieve data</a></li>
						</ol>
					</li>

					<li>
						Let <var>onRejected</var> be a callback which runs the steps below:

						<ol>
							<li>Set <a>pipePullAmount</a> to 0</li>

							<li>Let <var>pipePromise</var> be <a>pendingRead</a>.<var>promise</var></li>
							<li>Set <a>pendingRead</a> to <code>null</code></li>

							<li>Reject <var>pipePromise</var> with the first argument</li>
						</ol>
					</li>

					<li>
						Run the algorithm of <code>awaitSpaceAvailable()</code> method on <var>destination</var>, and let <var>promise</var> be the returned <a>Promise</a>
					</li>
					<li>
						Transform <var>promise</var> of <var>destination</var> with <var>onFulfilled</var> and <var>onRejected</var>
					</li>
				</ol>
			</p>

			<p>
				To <dfn>transfer data</dfn>, run the steps below:

				<ol>
					<li>
						Let <var>onFulfilled</var> be a callback which runs the steps below:

						<ol>
							<li>Let <var>writtenAmounts</var> be the first argument</li>
							<li>Set <a>totalAmountTransferred</a> to <a>totalAmountTransferred</a> + (the sum of elements in <var>writtenAmounts</var>)</var>
							<li>
								<dl class="switch">
									<dt>If <a>eofReached</a> is set or <a>pendingRead</a>.<var>size</var> is 0</dt>
									<dd>
										<ol>
											<li>Set <a>pipePullAmount</a> to 0</li>

											<li>Let <var>pipePromise</var> be <a>pendingRead</a>.<var>promise</var></li>
											<li>Set <a>pendingRead</a> to <code>null</code></li>

											<li>Let <var>result</var> be a newly-created <a>StreamReadResult</a></li>

											<li>Set <var>result</var>.<a href="#widl-StreamReadResult-data">data</a> to <code>undefined</code></li>
											<li>Set <var>result</var>.<a href="#widl-StreamReadResult-eof">eof</a> to <code>true</code> if <a>eofReached</a></li>
											<li>Set <var>result</var>.<a href="#widl-StreamReadResult-amountConsumed">amountConsumed</a> to <a>totalAmountTransferred</a></li>
											<li>Set <a>totalAmountTransferred</a> to 0</li>
											<li>
												Fulfill <var>pipePromise</var> with <var>result</var>
												<section class="note">
													At this point, <a>amountBeingReturned</a> is not yet reset
												</section>
											</li>
										</ol>
										<section class="note">
											Need to revisit. Finish when write to the destination completes?
										</section>
									</dd>
									<dt>Otherwise</dt>
									<dd>
										<a>Wait for destination</a>
									</dd>
								</dl>
							</li>
						</ol>
					</li>

					<li>
						Let <var>onRejected</var> be a callback which runs the steps below:

						<ol>
							<li>Set <a>pipePullAmount</a> to 0</li>

							<li>Let <var>pipePromise</var> be <a>pendingRead</a>.<var>promise</var></li>
							<li>Set <a>pendingRead</a> to <code>null</code></li>

							<li>Reject <var>pipePromise</var> with the first argument</li>
						</ol>
					</li>

					<li>
						<dl class="switch">
							<dt>If <a>pendingRead</a>.<var>size</var> is <code>undefined</code></dt>
							<dd>
								<ol>
									<li>Let <var>writePromises</var> be an array of <a>Promise</a>s.
									<li>
										Repeat the steps below while <a>readDataBuffer</a> is not empty:
										<ol>
											<li>Pop one element from <a>readDataBuffer</a>, and let <var>head</var> be the element</li>
											<li>Set <a>amountBeingReturned</a> to <a>amountBeingReturned</a> + (<a>cost</a> of <var>head</var>)</li>
											<li>Run the algorithm of write() method with <var>head</var> on <a>pendingRead</a>.<var>destination</var></li>
											<li>Push the <a>Promise</a> returned by the last step to <var>writePromises</var></li>
										</ol>
									</li>

									<li>Let <var>allPromise</var> be waiting for all of <var>writePromises</var></li>
									<li>Transform <var>allPromise</var> with <var>onFulfilled</var> and <code>undefined</code></li>
								</ol>
							</dd>
							<dt>Otherwise</dt>
							<dd>
								<ol>
									<li><a>Splice binary data</a></li>
									<li>If the last step failed, terminate these steps</li>

									<li>
										Repeat the steps below while <a>splicedBinaryBuffer</a> is not empty:

										<ol>
											<li>Pop one element from <a>splicedBinaryBuffer</a>, and let <var>head</var> be the element</li>
											<li>Run the algorithm of write() method with <var>head</var> to <a>pendingRead</a>.<var>destination</var></li>
										</ol>
									</li>
								</ol>
							</dd>
						</dl>
					</li>
				</ol>
			</p>

			<p>
				When data is received from <a>dataSource</a>, run the steps below (if not in the event loop, queue a task which runs the steps below):
				<ol>
					<li>Let <var>receivedData</var> be the received data</li>
					<li>Let <var>receivedAmount</var> be the size of <var>receivedData</var></li>
					<li>Set <a>amountRequested</a> to <a>amountRequested</a> - <var>receivedAmount</var></li>
					<li>Push <var>receivedData</var> to <a>readDataBuffer</a></li>

					<li>If <a>pendingRead</a> is <code>null</code>, terminate these steps</li>
					<li>
						<dl class="switch">
							<dt>If <a>pendingRead</a>.<var>destination</var> is <code>null</code></dt>
							<dd><a>Output data</a></dd>
							<dt>Otherwise</dt>
							<dd><a>Transfer data</a></dd>
						</dl>
					</li>
				</ol>
			</p>

			<p>
				<img src="images/increasing_pullamount.png" alt="When pullAmount is increased, new data will be fetched">
			</p>

			<p>
				When the <a>read EOF</a> is received from <a>dataSource</a>, run the steps below:

				<ol>
					<li>
						<dl class="switch">
							<dt>If in the event loop</dt>
							<dd>Run the rest of these steps</dd>
							<dt>Otherwise</dt>
							<dd>Queue a task which runs the rest of these steps</dd>
						</dl>
					</li>
					<li>Set <a>eofReached</a> and <a>sourceErrorDetail</a></li>
				</ol>
			</p>
	  </section>
	</section>

	<section class="section">
		<h2>StreamReadResult Interface</h2>

		<p>
			This interface represents the result of methods on <a>ReadableStream</a>.
		</p>

		<dl class="idl" title="interface StreamReadResult">
			<dt>readonly attribute boolean eof</dt>
			<dd>Set if the operation resulted in the <a>read EOF</a></dd>
			<dt>readonly attribute any data</dt>
			<dd>The contents read (and converted into an object of the specified type if needed)</dd>
			<dt>readonly attribute unsigned long long amountConsumed</dt>
			<dd>The cost of the data read</dd>
			<dt>readonly attribute any error</dt>
			<dd>Once any error occurred, set to the error detail object on all StreamReadResults returned after the error</dd>
		</dl>
	</section>

	<section class="section">
		<h2>StreamReadType enum</h2>

		<p>
			Data can be read as various data types from <a>ReadableStream</a>.
			This enum defines <a>DOMString</a> values to specify the data types.
		</p>

		<dl class="idl" title="enum StreamReadType">
			<dt>as-is</dt>
			<dd>Default. <code>read()</code> and <code>readUpTo()</code> return produced data as-is</dd>
			<dt>arraybuffer</dt>
			<dd><code>read()</code> and <code>readUpTo()</code> attempt to convert produced data into an <a>ArrayBuffer</a>, and then return it</dd>
			<dt>text</dt>
			<dd><code>read()</code> and <code>readUpTo()</code> attempt to convert produced data into a <a>DOMString</a>, and then return it</dd>
			<dt>none</dt>
			<dd>
				<code>read()</code> and <code>readUpTo()</code> return nothing.
				Useful for seeking data by skipping some amount of data.
				User agents may implement some optimization for "<code>none</code>" type read for example omitting internal data transfer.
			</dd>
		</dl>
	</section>

	<section class="section" id="streams">
		<h2>ByteStream</h2>

		<p>
			This section introduces a simple implementation of the <a>WritableStream</a> and <a>ReadableStream</a> named <code>ByteStream</code>, as well as accompanying interfaces required as part of the <a>ByteStream</a> implementation.
			This includes a constructor to build a <a>ByteStream</a> object and the type attribute.
		</p>

		<section class="section" id="stream-interface">
			<h2>ByteStream Interface</h2>

			<p>
				This interface represents a sequence of bytes which can be read only once over time and to which we can push data.
			</p>

			<p>
				A ByteStream has an associated <dfn>bufferedDataQueue</dfn>.
				The buffer can be stored in memory or backed by slower devices such as a disk.
			</p>

			<p>
				The ByteStream inherits the <a>WritableStream</a> interface.
				Its <a>dataSink</a> is <a>bufferedDataQueue</a> wrapped with a <a>data source wrapper</a>.
			</p>

			<p>
				The ByteStream inherits the <a>ReadableStream</a> interface.
				Its <a>dataSource</a> is also <a>bufferedDataQueue</a>.
			</p>

			<p>
				<a>bufferedDataQueue</a> just forwards retrieval requests coming from the <a>data source wrapper</a> to the <a>WritableStream</a> as a notification of the number of newly acceptable bytes with the same amount.
			</p>

			<dl class="idl" title="interface ByteStream : ReadableStream, WritableStream">
				<dt>Constructor()</dt>
				<dd>
					Constructs a <a>ByteStream</a> and sets the <a href="#widl-ByteStream-type">type</a> to the specified value.

					<dl class="parameters">
						<dt>in unsigned long long pullAmount</dt>
						<dd>
							Specifies the initial value of <a href="#widl-ReadableStream-pullAmount">pullAmount</a>.
						</dd>
						<dt>in optional DOMString type</dt>
						<dd>
							Specifies the MIME type [[!RFC2046]] of the <a>ByteStream</a>.
						</dd>
					</dl>
				</dd>
			</dl>
		</section>

		<section class="section" id="error-uris_for_streams">
			<h3>URIs for Stream</h3>
			<p>
				To reference a <a>ByteStream</a>, <a href="http://dev.w3.org/2006/webapi/FileAPI/#url">the same URI used</a> for <code>Blobs</code> and <code>Files</code> in
				<a href="http://dev.w3.org/2006/webapi/FileAPI/#url">6.7. A URI for Blob and File reference</a> of
				the File API specification should be used. [[!FILE-API]]
				The definitions of <strong>Origin</strong>, <strong>Lifetime</strong>, <strong>Referencing</strong>, and <strong>Dereferencing</strong> of a <code>Blob</code> should be applied to a <a>ByteStream</a>.
			</p>

			<section class="section" id="creating-revoking-streamuri">
				<h4>Creating and Revoking a Stream URI</h4>
				<p>
					A <dfn id="stream-uri">Stream URI</dfn> is a <code>Blob URI</code> that is referencing a <a>ReadableStream</a>.
					These URIs are created and revoked using methods exposed on the URL object,
					as defined in <a href="http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking">6.7.5. Creating and Revoking a Blob URI</a>
					of the File API specification. [[!FILE-API]]
				</p>
				<p>
					<a href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-createObjectURL">URL.createObjectURL</a>
					and <a href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-revokeObjectURL">URL.revokeObjectURL</a>
					should both be extended as follows:
				</p>
				<dl class="idl" title="interface URL">
					<dt>static DOMString? createObjectURL()</dt>
					<dd>
						<dl class="parameters">
							<dt>ReadableStream stream</dt>
							<dd>The <a>ReadableStream</a> for which a Blob URI will be created</dd>
							<dt>DOMString type</dt>
							<dd>
								<p>
									The media type of this stream.
									The media type is returned as an ASCII-encoded string in lower case representing the media type, expressed as an RFC2046 MIME type [[!RFC2046]].
									A string is a valid media type if it matches the media-type token defined in section 3.7 "Media Types" of RFC 2616 [[!HTTP11]].
								</p>
							</dd>
						</dl>

						<p>
							The extension onto <code>createObjectURL</code> should have the following steps added.
						</p>

						<p>
							Returns a unique Blob URL each time it is called on a <a>ReadableStream</a>.
							This method must act as follows:

							<dl class="switch">
								<dt>If <var>stream</var> is non-null and in scope of the global object's URL property from which this static method is called</dt>
								<dd>
									Run the steps below:
									<ol>
										<li>If <a>readPending</a> of <var>stream</var> is set, return null</li>
										<li>Set <a>readPending</a> of <var>stream</var></li>
										<li>Return a unique <code>Blob URI</code> that can be used to dereference <var>stream</var></li>
										<li>Add an entry to the Blob URL Store for this Blob URL</li>
									</ol>
								</dd>
								<dt>Otherwise</dt>
								<dd>Return null</dd>
							</dl>
						</p>
					</dd>

					<dt>static DOMString? createFor()</dt>
					<dd>
						<dl class="parameters">
							<dt>ReadableStream stream</dt>
							<dd></dd>
							<dt>DOMString type</dt>
							<dd></dd>
						</dl>

						<p>
							The extension onto <code>createFor</code> should have the following steps added.
						</p>
						<p>
							Returns a unique Blob URL each time it is called on a <a>ReadableStream</a>.
							Blob URLs created with this method are said to be auto-revoking since user-agents are responsible for the revocation of Blob URLs created with this method, subject to the lifetime stipulation for Blob URLs.
							This method must act as follows:

							<dl class="switch">
								<dt>If <var>stream</var> is non-null and in scope of the global object's URL property from which this static method is called</dt>
								<dd>
									Run the steps below:
									<ol>
										<li>If <a>readPending</a> of <var>stream</var> is set, return null</li>
										<li>Set <a>readPending</a> of <var>stream</var></li>
										<li>Return a unique <code>Blob URI</code> that can be used to dereference <var>stream</var></li>
										<li>Add an entry to the Blob URL Store for this Blob URL</li>
										<li>Add an entry to the Revocation List for this Blob URL</li>
									</ol>
								</dd>
								<dt>Otherwise</dt>
								<dd>Return null</dd>
							</dl>
						</p>
					</dd>

					<dt>static void revokeObjectURL(in DOMString url)</dt>
					<dd>
						<p>
							The extension onto <code>revokeObjectURL</code> should have the following steps added.
						</p>
						<dl class="switch">
							<dt>If <var>url</var> is a Blob URI which refers to a <a>ReadableStream</a> and it's in the same origin of the global object’s <code>URL</code> property on which this static method was calld</dt>
							<dd>Return a 404 response code when the URL is dereferenced</dd>
							<dt>Otherwise</dt>
							<dd>
								Do nothing.
								A message on their error console may be displayed.
							</dd>
						</dl>
					</dd>
				</dl>
			</section>
		</section>
	</section>

	<section class="section" id="producers-consumers">
		<h2>Stream Consumers and Producers</h2>
		<p>
			Byte streams can be both produced and consumed by various APIs. APIs which create streams are identified as producers, and ones which read and act on a byte stream are known as consumers.
			This section identifies some of the APIs where Streams may be produced and consumed.
			<section class="note">The list of producers and consumers below is not an exhaustive list. It is placed here as informative for the time being.</section>
		</p>
		<section class="section" id="consumers">
			<h2>Stream Consumers</h2>
			<p>This section outlines APIs which can consume a byte stream</p>
			<ul>
				<li>XMLHttpRequest</li>
				<li>Web Audio</li>
				<li>Media Source Extensions</li>
				<li>Web Cryptography API</li>
				<li>TextEncoder</li>
				<li>TextDecoder</li>
				<li>WebSockets</li>
				<li>RTCPeerConnection</li>
				<li>FileWriter</li>
			</ul>
		</section>

		<section class="section" id="producers">
			<h2>Stream Producers</h2>
			<p>This section outlines APIs which can produce a byte stream</p>
			<ul>
				<li>XMLHttpRequest</li>
				<li>FileReader</li>
				<li>Media Capture</li>
				<li>MediaStream Recording API</li>
				<li>Indexed Database</li>
				<li>Web Cryptography API</li>
				<li>TextEncoder</li>
				<li>TextDecoder</li>
				<li>WebSockets</li>
				<li>EventSource</li>
				<li>RTCPeerConnection</li>
			</ul>
		</section>
	</section>

	<section class="section" id="security">
		<h2>Security Considerations</h2>
		<p>
			A <a>ReadableStream</a> should have the same security considerations as a <code>Blob</code>.
			This is outlined in <a href="http://dev.w3.org/2006/webapi/FileAPI/#security-discussion">6.8. Security Considerations</a>
			of the File API specification. [[!FILE-API]]
			Because a <a>ReadableStream</a> uses a <code>Blob URI</code>, cross origin requests on a <a>ReadableStream</a> will not be supported.
		</p>
	</section>

	<section class="section" id="XMLHttpRequest">
		<h2>Extension of XMLHttpRequest</h2>
		<p>
			This specification proposes an extension to <code>XMLHttpRequest</code> [[!XMLHTTPREQUEST2]] to add support for <a>ByteStream</a>.
			This section is temporary and is meant to provide a recommendation for how <a>ByteStream</a> should be incorporated into <code>XMLHttpRequest</code>.
			This will extend <code>XMLHttpRequest</code> to allow for receiving and uploading of a <a>ByteStream</a>.
			One such scenario is providing access to data during <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-readystate"><code>readyState</code></a> 3 (LOADING).
			The sections below document in detail what extensions must be done to <code>XMLHttpRequest</code> to support <a>ByteStream</a>.
		</p>

		<section class="section" title="addition-of-stream-response-entity">
			<h3>Addition of stream response entity body</h3>
			<p>
				<a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#response-entity-body-0">The section named "Response Entity Body"</a>
				in XMLHttpRequest specification [[!XMLHTTPREQUEST2]] should have the following additions:
			</p>
			<p>
				The <dfn id="stream-response-entity">stream response entity body</dfn> is either a <a>ByteStream</a> representing the <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#response-entity-body">response entity body</a> or null.
				If the <a href="#stream-response-entity">stream response entity body</a> is null, let it be the return value of the following algorithm:
			</p>
			<ol>
				<li>
					If the <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#response-entity-body">response entity body</a> is null,
					return an empty <a>ByteStream</a> object.
				</li>
				<li>
					Return a <a>ByteStream</a> object representing the <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#response-entity-body">response entity body</a>.
				</li>
			</ol>
		</section>

		<section class="section" title="addition-of-stream">
			<h3>Addition of "<code>stream</code>" responseType</h3>
			<p>
				A new value for the <code>responseType</code> attribute "<code>stream</code>" should be introduced.
			</p>
			<p>
				In the IDL list in <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#interface-xmlhttprequest">the section named "Interface XMLHttpRequest"</a> in XMLHttpRequest specification [[!XMLHTTPREQUEST2]], the definition of <code>XMLHttpRequestResponseType</code> enum should now read:
				<pre>
enum XMLHttpRequestResponseType {
  "",
  "arraybuffer",
  "blob",
  "stream",
  "document",
  "json",
  "text"
}</pre>
			</p>
		</section>

		<section class="section" title="modification-on-response-algorithm">
			<h3>Modification on the <code>response</code> attribute</h3>
			<p>
				The algorithm of the <code>response</code> attribute should be modified to handle the new <code>responseType</code> value "<code>stream</code>".
				A Stream is binary data obtained sequentially over time.
				Given this, a <a>ByteStream</a> should be accessible in <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-readystate"><code>readyState</code></a> 3 (LOADING).
			</p>
			<p>
				<a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-response-attribute">The section named "The response attribute"</a> in XMLHttpRequest specification [[!XMLHTTPREQUEST2]] should now read:
			</p>
			<p>
				The <code>response</code> attribute must return the result of running these steps:
			</p>
			<dl class="switch">
				<dt>If <a href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#dom-xmlhttprequest-responsetype"><code>responseType</code></a> is the empty string or "<code>text</code>"</dt>
				<dd>
					The same as the original XMLHttpRequest specification.
				</dd>
				<dt>If <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-responsetype"><code>responseType</code></a> is "<code>stream</code>"</dt>
				<dd>
					<ol>
						<li>
							If the state is not <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-loading">LOADING</a> or
							<a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-done">DONE</a>, return null.
						</li>
						<li>
							If the <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#error-flag">error flag</a> is set, return null.
						</li>
						<li>
							Return the <a href="#stream-response-entity">stream response entity body</a>.
						</li>
					</ol>
				</dd>
				<dt>Otherwise</dt>
				<dd>
					The same as the original XMLHttpRequest specification.
				</dd>
			</dl>
		</section>

		<section class="section" id="modification-on-send-algorithm">
			<h3>send()</h3>
			<p>
				The switch in otherwise case of step 4 of
				<a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#the-send()-method">The section named "The <code>send()</code> method"</a>
				in XMLHttpRequest specification [[!XMLHTTPREQUEST2]] should have the following additions:
			</p>
			<dl class="switch">
				<dt><a>ReadableStream</a></dt>
				<dd>
					<p>
						If the object's <a href="#widl-ByteStream-type">type</a> attribute is not the empty string let <var>mime type</var> be its value.
					</p>
					<p>
						Set <a>readPending</a> of the <a>ReadableStream</a>.
					</p>
					<p>
						Let the <a href="https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#request-entity-body">request entity body</a> be the raw data represented by <var>data</var>.
					</p>
				</dd>
			</dl>
		</section>
	</section>

	<section class="section" id="terminology">
		<h2>Terminology</h2>

		<p>
			<dfn>ArrayBuffer</dfn> and <dfn>ArrayBufferView</dfn> are defined in <a href="http://www.khronos.org/registry/typedarray/specs/latest/">Typed Array specification</a>.
		</p>

		<p>
			<dfn>Blob</dfn> is defined in <a href="http://dev.w3.org/2006/webapi/FileAPI/">File API specification</a>.
		</p>

		<p>
			<dfn>Promise</dfn> is defined in <a href="https://github.com/domenic/promises-unwrapping/blob/master/README.md">Promise Objects specification</a>.
			Shorthand phrases to refer operations on Promises are borrowed from <a href="https://github.com/w3ctag/promises-guide">Writing Promise-Using Specifications</a>.
		</p>

		<p>
			<dfn>DOMString</dfn> is defined in <a href="http://www.w3.org/TR/DOM-Level-3-Core/core.html">DOM Level 3 Core specification</a>.
		</p>

		<p>
			<dfn>XMLHttpRequest</dfn> is defined in [[!XMLHTTPREQUEST2]].
		</p>

		<p>
			<dfn>AbortError</dfn> is defined in <a href="https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#aborterror">DOM4 specification</a>.
			<dfn>InvalidStateError</dfn> is defined in <a href="https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#invalidstateerror">DOM4 specification</a>.
			<dfn>SyntaxError</dfn> is defined in <a href="https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#syntaxerror">DOM4 specification</a>.
			<dfn>EncodingError</dfn> is defined in <a href="https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#encodingerror">DOM4 specification</a>.
		</p>
	</section>

	<section class="section" id="requirements">
		<h2>Requirements and Use Cases</h2>
		<p>
			The <a>ByteStream</a> type allows for completion of several end-to-end experiences. This section covers what the requirements are for this API, and
			illustrates some use cases.
		</p>
		<ul>
			<li>
				Begin loading a video through <code>XMLHttpRequest</code> in <code>readyState</code> LOADING
				<p>
					Videos can typically be large files that may take a long time to download, and require authentication or certain headers to access.
					For certain video formats, an application can begin playing the video once the first chunks of data are available, and would not need to wait for the entire video to download.
				</p>
			</li>
			<li>
				Begin processing the data of a <a>ByteStream</a> as it is being read via <code>XMLHttpRequest</code>
				<p>
					If a file format is understood, then an application can make sense of the data as it being made available. For example, a given
					file may be very large and the application wants to begin processing the data immediately, rather than having to wait for full download of the file.
				</p>
			</li>
			<li>
				Upload of dynamic runtime data using <a>ByteStream</a> and <code>XMLHttpRequest</code>
				<p>
					There are situations where an application may have data to upload once the application is processing. This could involve processing
					of data an application wants to upload as it is being created. One such case is the upload of GPS coordinates within an application. The
					coordiantes may constantly change, and the application wants to upload the data as it being collected.
				</p>
			</li>
			<li>
				Media streaming scenarios using <a>ByteStream</a> and <code>XMLHttpRequest</code>
				<p>
					Media streaming scenarios require the ability to quickly receive data over the network and connect it to a media element.
					An application can successfully accomplish this by receiving a Stream in <code>readyState</code> LOADING and assign it to a media element.
					This helps avoid the application from having to buffer the data prior to assigning it to a media element.
				</p>
			</li>
		</ul>
	</section>

	<section class=appendix>
		<h2>Acknowledgements</h2>
		<p>
			Thanks to Eliot Graff for editorial assistance.
			Special thanks to the W3C.
			The editor would like to thank
			Adrian Bateman,
			Anne van Kesteren,
			Austin William Wright,
			Aymeric Vitte,
			Domenic Denicola,
			Elliott Sprehn,
			Francois-Xavier Kowalski,
			Harris Syed,
			Isaac Schlueter,
			Jonas Sicking,
			Kenneth Russell,
			Kinuko Yasuda,
			Lindsay Verola,
			Michael Davidson,
			Rob Manson,
			Taiju Tsuiki,
			Yusuke Suzuki,
			Yutaka Hirano,
			for their contributions to this specification.
		</p>
	</section>

</body>
</html>