| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <title>JSDoc: Source: BlobWriter.js</title> |
| |
| <script src="scripts/prettify/prettify.js"> </script> |
| <script src="scripts/prettify/lang-css.js"> </script> |
| <!--[if lt IE 9]> |
| <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |
| <![endif]--> |
| <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |
| <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |
| </head> |
| |
| <body> |
| |
| <div id="main"> |
| |
| <h1 class="page-title">Source: BlobWriter.js</h1> |
| |
| |
| |
| |
| |
| |
| <section> |
| <article> |
| <pre class="prettyprint source linenums"><code>/* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| var Guacamole = Guacamole || {}; |
| |
| /** |
| * A writer which automatically writes to the given output stream with the |
| * contents of provided Blob objects. |
| * |
| * @constructor |
| * @param {Guacamole.OutputStream} stream |
| * The stream that data will be written to. |
| */ |
| Guacamole.BlobWriter = function BlobWriter(stream) { |
| |
| /** |
| * Reference to this Guacamole.BlobWriter. |
| * |
| * @private |
| * @type {Guacamole.BlobWriter} |
| */ |
| var guacWriter = this; |
| |
| /** |
| * Wrapped Guacamole.ArrayBufferWriter which will be used to send any |
| * provided file data. |
| * |
| * @private |
| * @type {Guacamole.ArrayBufferWriter} |
| */ |
| var arrayBufferWriter = new Guacamole.ArrayBufferWriter(stream); |
| |
| // Initially, simply call onack for acknowledgements |
| arrayBufferWriter.onack = function(status) { |
| if (guacWriter.onack) |
| guacWriter.onack(status); |
| }; |
| |
| /** |
| * Browser-independent implementation of Blob.slice() which uses an end |
| * offset to determine the span of the resulting slice, rather than a |
| * length. |
| * |
| * @private |
| * @param {Blob} blob |
| * The Blob to slice. |
| * |
| * @param {Number} start |
| * The starting offset of the slice, in bytes, inclusive. |
| * |
| * @param {Number} end |
| * The ending offset of the slice, in bytes, exclusive. |
| * |
| * @returns {Blob} |
| * A Blob containing the data within the given Blob starting at |
| * <code>start</code> and ending at <code>end - 1</code>. |
| */ |
| var slice = function slice(blob, start, end) { |
| |
| // Use prefixed implementations if necessary |
| var sliceImplementation = ( |
| blob.slice |
| || blob.webkitSlice |
| || blob.mozSlice |
| ).bind(blob); |
| |
| var length = end - start; |
| |
| // The old Blob.slice() was length-based (not end-based). Try the |
| // length version first, if the two calls are not equivalent. |
| if (length !== end) { |
| |
| // If the result of the slice() call matches the expected length, |
| // trust that result. It must be correct. |
| var sliceResult = sliceImplementation(start, length); |
| if (sliceResult.size === length) |
| return sliceResult; |
| |
| } |
| |
| // Otherwise, use the most-recent standard: end-based slice() |
| return sliceImplementation(start, end); |
| |
| }; |
| |
| /** |
| * Sends the contents of the given blob over the underlying stream. |
| * |
| * @param {Blob} blob |
| * The blob to send. |
| */ |
| this.sendBlob = function sendBlob(blob) { |
| |
| var offset = 0; |
| var reader = new FileReader(); |
| |
| /** |
| * Reads the next chunk of the blob provided to |
| * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The chunk itself |
| * is read asynchronously, and will not be available until |
| * reader.onload fires. |
| * |
| * @private |
| */ |
| var readNextChunk = function readNextChunk() { |
| |
| // If no further chunks remain, inform of completion and stop |
| if (offset >= blob.size) { |
| |
| // Fire completion event for completed blob |
| if (guacWriter.oncomplete) |
| guacWriter.oncomplete(blob); |
| |
| // No further chunks to read |
| return; |
| |
| } |
| |
| // Obtain reference to next chunk as a new blob |
| var chunk = slice(blob, offset, offset + arrayBufferWriter.blobLength); |
| offset += arrayBufferWriter.blobLength; |
| |
| // Attempt to read the blob contents represented by the blob into |
| // a new array buffer |
| reader.readAsArrayBuffer(chunk); |
| |
| }; |
| |
| // Send each chunk over the stream, continue reading the next chunk |
| reader.onload = function chunkLoadComplete() { |
| |
| // Send the successfully-read chunk |
| arrayBufferWriter.sendData(reader.result); |
| |
| // Continue sending more chunks after the latest chunk is |
| // acknowledged |
| arrayBufferWriter.onack = function sendMoreChunks(status) { |
| |
| if (guacWriter.onack) |
| guacWriter.onack(status); |
| |
| // Abort transfer if an error occurs |
| if (status.isError()) |
| return; |
| |
| // Inform of blob upload progress via progress events |
| if (guacWriter.onprogress) |
| guacWriter.onprogress(blob, offset - arrayBufferWriter.blobLength); |
| |
| // Queue the next chunk for reading |
| readNextChunk(); |
| |
| }; |
| |
| }; |
| |
| // If an error prevents further reading, inform of error and stop |
| reader.onerror = function chunkLoadFailed() { |
| |
| // Fire error event, including the context of the error |
| if (guacWriter.onerror) |
| guacWriter.onerror(blob, offset, reader.error); |
| |
| }; |
| |
| // Begin reading the first chunk |
| readNextChunk(); |
| |
| }; |
| |
| /** |
| * Signals that no further text will be sent, effectively closing the |
| * stream. |
| */ |
| this.sendEnd = function sendEnd() { |
| arrayBufferWriter.sendEnd(); |
| }; |
| |
| /** |
| * Fired for received data, if acknowledged by the server. |
| * |
| * @event |
| * @param {Guacamole.Status} status |
| * The status of the operation. |
| */ |
| this.onack = null; |
| |
| /** |
| * Fired when an error occurs reading a blob passed to |
| * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The transfer for the |
| * the given blob will cease, but the stream will remain open. |
| * |
| * @event |
| * @param {Blob} blob |
| * The blob that was being read when the error occurred. |
| * |
| * @param {Number} offset |
| * The offset of the failed read attempt within the blob, in bytes. |
| * |
| * @param {DOMError} error |
| * The error that occurred. |
| */ |
| this.onerror = null; |
| |
| /** |
| * Fired for each successfully-read chunk of data as a blob is being sent |
| * via [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. |
| * |
| * @event |
| * @param {Blob} blob |
| * The blob that is being read. |
| * |
| * @param {Number} offset |
| * The offset of the read that just succeeded. |
| */ |
| this.onprogress = null; |
| |
| /** |
| * Fired when a blob passed to |
| * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob} has finished being |
| * sent. |
| * |
| * @event |
| * @param {Blob} blob |
| * The blob that was sent. |
| */ |
| this.oncomplete = null; |
| |
| }; |
| </code></pre> |
| </article> |
| </section> |
| |
| |
| |
| |
| </div> |
| |
| <nav> |
| <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputSink.html">InputSink</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li><li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioRecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.SessionRecording.html">SessionRecording</a></li><li><a href="Guacamole.StaticHTTPTunnel.html">StaticHTTPTunnel</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li><li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onargv">onargv</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onname">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li><li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.SessionRecording.html#event:onpause">onpause</a></li><li><a href="Guacamole.SessionRecording.html#event:onplay">onplay</a></li><li><a href="Guacamole.SessionRecording.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.SessionRecording.html#event:onseek">onseek</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul> |
| </nav> |
| |
| <br class="clear"> |
| |
| <footer> |
| Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST) |
| </footer> |
| |
| <script> prettyPrint(); </script> |
| <script src="scripts/linenumber.js"> </script> |
| </body> |
| </html> |