| <!DOCTYPE html> | 
 | <html lang="en"> | 
 | <head> | 
 |     <meta charset="utf-8"> | 
 |     <title>JSDoc: Source: main/webapp/modules/BlobReader.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: main/webapp/modules/BlobReader.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 reader which automatically handles the given input stream, assembling all | 
 |  * received blobs into a single blob by appending them to each other in order. | 
 |  * Note that this object will overwrite any installed event handlers on the | 
 |  * given Guacamole.InputStream. | 
 |  *  | 
 |  * @constructor | 
 |  * @param {!Guacamole.InputStream} stream | 
 |  *     The stream that data will be read from. | 
 |  * | 
 |  * @param {!string} mimetype | 
 |  *     The mimetype of the blob being built. | 
 |  */ | 
 | Guacamole.BlobReader = function(stream, mimetype) { | 
 |  | 
 |     /** | 
 |      * Reference to this Guacamole.InputStream. | 
 |      * | 
 |      * @private | 
 |      * @type {!Guacamole.BlobReader} | 
 |      */ | 
 |     var guac_reader = this; | 
 |  | 
 |     /** | 
 |      * The length of this Guacamole.InputStream in bytes. | 
 |      * | 
 |      * @private | 
 |      * @type {!number} | 
 |      */ | 
 |     var length = 0; | 
 |  | 
 |     // Get blob builder | 
 |     var blob_builder; | 
 |     if      (window.BlobBuilder)       blob_builder = new BlobBuilder(); | 
 |     else if (window.WebKitBlobBuilder) blob_builder = new WebKitBlobBuilder(); | 
 |     else if (window.MozBlobBuilder)    blob_builder = new MozBlobBuilder(); | 
 |     else | 
 |         blob_builder = new (function() { | 
 |  | 
 |             var blobs = []; | 
 |  | 
 |             /** @ignore */ | 
 |             this.append = function(data) { | 
 |                 blobs.push(new Blob([data], {"type": mimetype})); | 
 |             }; | 
 |  | 
 |             /** @ignore */ | 
 |             this.getBlob = function() { | 
 |                 return new Blob(blobs, {"type": mimetype}); | 
 |             }; | 
 |  | 
 |         })(); | 
 |  | 
 |     // Append received blobs | 
 |     stream.onblob = function(data) { | 
 |  | 
 |         // Convert to ArrayBuffer | 
 |         var binary = window.atob(data); | 
 |         var arrayBuffer = new ArrayBuffer(binary.length); | 
 |         var bufferView = new Uint8Array(arrayBuffer); | 
 |  | 
 |         for (var i=0; i<binary.length; i++) | 
 |             bufferView[i] = binary.charCodeAt(i); | 
 |  | 
 |         blob_builder.append(arrayBuffer); | 
 |         length += arrayBuffer.byteLength; | 
 |  | 
 |         // Call handler, if present | 
 |         if (guac_reader.onprogress) | 
 |             guac_reader.onprogress(arrayBuffer.byteLength); | 
 |  | 
 |         // Send success response | 
 |         stream.sendAck("OK", 0x0000); | 
 |  | 
 |     }; | 
 |  | 
 |     // Simply call onend when end received | 
 |     stream.onend = function() { | 
 |         if (guac_reader.onend) | 
 |             guac_reader.onend(); | 
 |     }; | 
 |  | 
 |     /** | 
 |      * Returns the current length of this Guacamole.InputStream, in bytes. | 
 |      * | 
 |      * @return {!number} | 
 |      *     The current length of this Guacamole.InputStream. | 
 |      */ | 
 |     this.getLength = function() { | 
 |         return length; | 
 |     }; | 
 |  | 
 |     /** | 
 |      * Returns the contents of this Guacamole.BlobReader as a Blob. | 
 |      * | 
 |      * @return {!Blob} | 
 |      *     The contents of this Guacamole.BlobReader. | 
 |      */ | 
 |     this.getBlob = function() { | 
 |         return blob_builder.getBlob(); | 
 |     }; | 
 |  | 
 |     /** | 
 |      * Fired once for every blob of data received. | 
 |      *  | 
 |      * @event | 
 |      * @param {!number} length | 
 |      *     The number of bytes received. | 
 |      */ | 
 |     this.onprogress = null; | 
 |  | 
 |     /** | 
 |      * Fired once this stream is finished and no further data will be written. | 
 |      * @event | 
 |      */ | 
 |     this.onend = null; | 
 |  | 
 | };</code></pre> | 
 |         </article> | 
 |     </section> | 
 |  | 
 |  | 
 |  | 
 |  | 
 | </div> | 
 |  | 
 | <nav> | 
 |     <h2><a href="index.html">Home</a></h2><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">Guacamole.AudioContextFactory</a></li></ul><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">Guacamole.ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">Guacamole.ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">Guacamole.AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">Guacamole.AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">Guacamole.BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">Guacamole.BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">Guacamole.ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Guacamole.Client</a></li><li><a href="Guacamole.DataURIReader.html">Guacamole.DataURIReader</a></li><li><a href="Guacamole.Display.html">Guacamole.Display</a></li><li><a href="Guacamole.Display.Statistics.html">Guacamole.Display.Statistics</a></li><li><a href="Guacamole.Display.VisibleLayer.html">Guacamole.Display.VisibleLayer</a></li><li><a href="Guacamole.Event.html">Guacamole.Event</a></li><li><a href="Guacamole.Event.DOMEvent.html">Guacamole.Event.DOMEvent</a></li><li><a href="Guacamole.Event.Target.html">Guacamole.Event.Target</a></li><li><a href="Guacamole.HTTPTunnel.html">Guacamole.HTTPTunnel</a></li><li><a href="Guacamole.InputSink.html">Guacamole.InputSink</a></li><li><a href="Guacamole.InputStream.html">Guacamole.InputStream</a></li><li><a href="Guacamole.IntegerPool.html">Guacamole.IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">Guacamole.JSONReader</a></li><li><a href="Guacamole.KeyEventInterpreter.html">Guacamole.KeyEventInterpreter</a></li><li><a href="Guacamole.KeyEventInterpreter.KeyDefinition.html">Guacamole.KeyEventInterpreter.KeyDefinition</a></li><li><a href="Guacamole.KeyEventInterpreter.KeyEvent.html">Guacamole.KeyEventInterpreter.KeyEvent</a></li><li><a href="Guacamole.Keyboard.html">Guacamole.Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">Guacamole.Keyboard.ModifierState</a></li><li><a href="Guacamole.Layer.html">Guacamole.Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Guacamole.Layer.Pixel</a></li><li><a href="Guacamole.Mouse.html">Guacamole.Mouse</a></li><li><a href="Guacamole.Mouse.Event.html">Guacamole.Mouse.Event</a></li><li><a href="Guacamole.Mouse.Event.Target.html">Guacamole.Mouse.Event.Target</a></li><li><a href="Guacamole.Mouse.State.html">Guacamole.Mouse.State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Guacamole.Mouse.Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Guacamole.Mouse.Touchscreen</a></li><li><a href="Guacamole.Object.html">Guacamole.Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">Guacamole.OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Guacamole.OnScreenKeyboard.Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Guacamole.OnScreenKeyboard.Layout</a></li><li><a href="Guacamole.OutputStream.html">Guacamole.OutputStream</a></li><li><a href="Guacamole.Parser.html">Guacamole.Parser</a></li><li><a href="Guacamole.Position.html">Guacamole.Position</a></li><li><a href="Guacamole.RawAudioFormat.html">Guacamole.RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">Guacamole.RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioRecorder.html">Guacamole.RawAudioRecorder</a></li><li><a href="Guacamole.SessionRecording.html">Guacamole.SessionRecording</a></li><li><a href="Guacamole.StaticHTTPTunnel.html">Guacamole.StaticHTTPTunnel</a></li><li><a href="Guacamole.Status.html">Guacamole.Status</a></li><li><a href="Guacamole.StringReader.html">Guacamole.StringReader</a></li><li><a href="Guacamole.StringWriter.html">Guacamole.StringWriter</a></li><li><a href="Guacamole.Touch.html">Guacamole.Touch</a></li><li><a href="Guacamole.Touch.Event.html">Guacamole.Touch.Event</a></li><li><a href="Guacamole.Touch.State.html">Guacamole.Touch.State</a></li><li><a href="Guacamole.Tunnel.html">Guacamole.Tunnel</a></li><li><a href="Guacamole.UTF8Parser.html">Guacamole.UTF8Parser</a></li><li><a href="Guacamole.VideoPlayer.html">Guacamole.VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">Guacamole.WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">Guacamole.ArrayBufferReader#ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">Guacamole.ArrayBufferReader#onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">Guacamole.ArrayBufferWriter#onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">Guacamole.AudioRecorder#onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">Guacamole.AudioRecorder#onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">Guacamole.BlobReader#onend</a></li><li><a href="Guacamole.BlobReader.html#event:onprogress">Guacamole.BlobReader#onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">Guacamole.BlobWriter#onack</a></li><li><a href="Guacamole.BlobWriter.html#event:oncomplete">Guacamole.BlobWriter#oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">Guacamole.BlobWriter#onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">Guacamole.BlobWriter#onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">Guacamole.ChainedTunnel#onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">Guacamole.ChainedTunnel#oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">Guacamole.ChainedTunnel#onstatechange</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onuuid">Guacamole.ChainedTunnel#onuuid</a></li><li><a href="Guacamole.Client.html#event:onargv">Guacamole.Client#onargv</a></li><li><a href="Guacamole.Client.html#event:onaudio">Guacamole.Client#onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">Guacamole.Client#onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">Guacamole.Client#onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">Guacamole.Client#onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">Guacamole.Client#onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onjoin">Guacamole.Client#onjoin</a></li><li><a href="Guacamole.Client.html#event:onleave">Guacamole.Client#onleave</a></li><li><a href="Guacamole.Client.html#event:onmsg">Guacamole.Client#onmsg</a></li><li><a href="Guacamole.Client.html#event:onmultitouch">Guacamole.Client#onmultitouch</a></li><li><a href="Guacamole.Client.html#event:onname">Guacamole.Client#onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">Guacamole.Client#onpipe</a></li><li><a href="Guacamole.Client.html#event:onrequired">Guacamole.Client#onrequired</a></li><li><a href="Guacamole.Client.html#event:onstatechange">Guacamole.Client#onstatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">Guacamole.Client#onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">Guacamole.Client#onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">Guacamole.DataURIReader#onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">Guacamole.Display#oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">Guacamole.Display#onresize</a></li><li><a href="Guacamole.Display.html#event:onstatistics">Guacamole.Display#onstatistics</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">Guacamole.HTTPTunnel#onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">Guacamole.HTTPTunnel#oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">Guacamole.HTTPTunnel#onstatechange</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onuuid">Guacamole.HTTPTunnel#onuuid</a></li><li><a href="Guacamole.InputStream.html#event:onblob">Guacamole.InputStream#onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">Guacamole.InputStream#onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">Guacamole.JSONReader#onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">Guacamole.JSONReader#onprogress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">Guacamole.Keyboard#onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">Guacamole.Keyboard#onkeyup</a></li><li><a href="Guacamole.Mouse.html#event:mousedown">Guacamole.Mouse#mousedown</a></li><li><a href="Guacamole.Mouse.html#event:mousemove">Guacamole.Mouse#mousemove</a></li><li><a href="Guacamole.Mouse.html#event:mouseout">Guacamole.Mouse#mouseout</a></li><li><a href="Guacamole.Mouse.html#event:mouseup">Guacamole.Mouse#mouseup</a></li><li><a href="Guacamole.Mouse.Event.Target.html#event:mousedown">Guacamole.Mouse.Event.Target#mousedown</a></li><li><a href="Guacamole.Mouse.Event.Target.html#event:mousemove">Guacamole.Mouse.Event.Target#mousemove</a></li><li><a href="Guacamole.Mouse.Event.Target.html#event:mouseout">Guacamole.Mouse.Event.Target#mouseout</a></li><li><a href="Guacamole.Mouse.Event.Target.html#event:mouseup">Guacamole.Mouse.Event.Target#mouseup</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:mousedown">Guacamole.Mouse.Touchpad#mousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:mousemove">Guacamole.Mouse.Touchpad#mousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:mouseup">Guacamole.Mouse.Touchpad#mouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:mousedown">Guacamole.Mouse.Touchscreen#mousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:mousemove">Guacamole.Mouse.Touchscreen#mousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:mouseup">Guacamole.Mouse.Touchscreen#mouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">Guacamole.Object#onbody</a></li><li><a href="Guacamole.Object.html#event:onundefine">Guacamole.Object#onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">Guacamole.OnScreenKeyboard#onkeydown</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">Guacamole.OnScreenKeyboard#onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">Guacamole.OutputStream#onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">Guacamole.Parser#oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">Guacamole.RawAudioRecorder#onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">Guacamole.RawAudioRecorder#onerror</a></li><li><a href="Guacamole.SessionRecording.html#event:onabort">Guacamole.SessionRecording#onabort</a></li><li><a href="Guacamole.SessionRecording.html#event:onerror">Guacamole.SessionRecording#onerror</a></li><li><a href="Guacamole.SessionRecording.html#event:onkeyevents">Guacamole.SessionRecording#onkeyevents</a></li><li><a href="Guacamole.SessionRecording.html#event:onload">Guacamole.SessionRecording#onload</a></li><li><a href="Guacamole.SessionRecording.html#event:onpause">Guacamole.SessionRecording#onpause</a></li><li><a href="Guacamole.SessionRecording.html#event:onplay">Guacamole.SessionRecording#onplay</a></li><li><a href="Guacamole.SessionRecording.html#event:onprogress">Guacamole.SessionRecording#onprogress</a></li><li><a href="Guacamole.SessionRecording.html#event:onseek">Guacamole.SessionRecording#onseek</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onerror">Guacamole.SessionRecording._PlaybackTunnel#onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:oninstruction">Guacamole.SessionRecording._PlaybackTunnel#oninstruction</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onstatechange">Guacamole.SessionRecording._PlaybackTunnel#onstatechange</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onuuid">Guacamole.SessionRecording._PlaybackTunnel#onuuid</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onerror">Guacamole.StaticHTTPTunnel#onerror</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:oninstruction">Guacamole.StaticHTTPTunnel#oninstruction</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onstatechange">Guacamole.StaticHTTPTunnel#onstatechange</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onuuid">Guacamole.StaticHTTPTunnel#onuuid</a></li><li><a href="Guacamole.StringReader.html#event:onend">Guacamole.StringReader#onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">Guacamole.StringReader#ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">Guacamole.StringWriter#onack</a></li><li><a href="Guacamole.Touch.html#event:touchend">Guacamole.Touch#touchend</a></li><li><a href="Guacamole.Touch.html#event:touchmove">Guacamole.Touch#touchmove</a></li><li><a href="Guacamole.Touch.html#event:touchstart">Guacamole.Touch#touchstart</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">Guacamole.Tunnel#onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">Guacamole.Tunnel#oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">Guacamole.Tunnel#onstatechange</a></li><li><a href="Guacamole.Tunnel.html#event:onuuid">Guacamole.Tunnel#onuuid</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">Guacamole.WebSocketTunnel#onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">Guacamole.WebSocketTunnel#oninstruction</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onstatechange">Guacamole.WebSocketTunnel#onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onuuid">Guacamole.WebSocketTunnel#onuuid</a></li></ul> | 
 | </nav> | 
 |  | 
 | <br class="clear"> | 
 |  | 
 | <footer> | 
 |     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> on Mon Jun 16 2025 15:53:22 GMT-0700 (Pacific Daylight Time) | 
 | </footer> | 
 |  | 
 | <script> prettyPrint(); </script> | 
 | <script src="scripts/linenumber.js"> </script> | 
 | </body> | 
 | </html> |