You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/12/30 20:22:13 UTC
[30/52] [abbrv] [partial] guacamole-website git commit: Add
documentation for 1.0.0.
http://git-wip-us.apache.org/repos/asf/guacamole-website/blob/044692cf/doc/1.0.0/guacamole-common-js/Parser.js.html
----------------------------------------------------------------------
diff --git a/doc/1.0.0/guacamole-common-js/Parser.js.html b/doc/1.0.0/guacamole-common-js/Parser.js.html
new file mode 100644
index 0000000..ba72df6
--- /dev/null
+++ b/doc/1.0.0/guacamole-common-js/Parser.js.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: Parser.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: Parser.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 || {};
+
+/**
+ * Simple Guacamole protocol parser that invokes an oninstruction event when
+ * full instructions are available from data received via receive().
+ *
+ * @constructor
+ */
+Guacamole.Parser = function() {
+
+ /**
+ * Reference to this parser.
+ * @private
+ */
+ var parser = this;
+
+ /**
+ * Current buffer of received data. This buffer grows until a full
+ * element is available. After a full element is available, that element
+ * is flushed into the element buffer.
+ *
+ * @private
+ */
+ var buffer = "";
+
+ /**
+ * Buffer of all received, complete elements. After an entire instruction
+ * is read, this buffer is flushed, and a new instruction begins.
+ *
+ * @private
+ */
+ var element_buffer = [];
+
+ // The location of the last element's terminator
+ var element_end = -1;
+
+ // Where to start the next length search or the next element
+ var start_index = 0;
+
+ /**
+ * Appends the given instruction data packet to the internal buffer of
+ * this Guacamole.Parser, executing all completed instructions at
+ * the beginning of this buffer, if any.
+ *
+ * @param {String} packet The instruction data to receive.
+ */
+ this.receive = function(packet) {
+
+ // Truncate buffer as necessary
+ if (start_index > 4096 && element_end >= start_index) {
+
+ buffer = buffer.substring(start_index);
+
+ // Reset parse relative to truncation
+ element_end -= start_index;
+ start_index = 0;
+
+ }
+
+ // Append data to buffer
+ buffer += packet;
+
+ // While search is within currently received data
+ while (element_end < buffer.length) {
+
+ // If we are waiting for element data
+ if (element_end >= start_index) {
+
+ // We now have enough data for the element. Parse.
+ var element = buffer.substring(start_index, element_end);
+ var terminator = buffer.substring(element_end, element_end+1);
+
+ // Add element to array
+ element_buffer.push(element);
+
+ // If last element, handle instruction
+ if (terminator == ";") {
+
+ // Get opcode
+ var opcode = element_buffer.shift();
+
+ // Call instruction handler.
+ if (parser.oninstruction != null)
+ parser.oninstruction(opcode, element_buffer);
+
+ // Clear elements
+ element_buffer.length = 0;
+
+ }
+ else if (terminator != ',')
+ throw new Error("Illegal terminator.");
+
+ // Start searching for length at character after
+ // element terminator
+ start_index = element_end + 1;
+
+ }
+
+ // Search for end of length
+ var length_end = buffer.indexOf(".", start_index);
+ if (length_end != -1) {
+
+ // Parse length
+ var length = parseInt(buffer.substring(element_end+1, length_end));
+ if (isNaN(length))
+ throw new Error("Non-numeric character in element length.");
+
+ // Calculate start of element
+ start_index = length_end + 1;
+
+ // Calculate location of element terminator
+ element_end = start_index + length;
+
+ }
+
+ // If no period yet, continue search when more data
+ // is received
+ else {
+ start_index = buffer.length;
+ break;
+ }
+
+ } // end parse loop
+
+ };
+
+ /**
+ * Fired once for every complete Guacamole instruction received, in order.
+ *
+ * @event
+ * @param {String} opcode The Guacamole instruction opcode.
+ * @param {Array} parameters The parameters provided for the instruction,
+ * if any.
+ */
+ this.oninstruction = 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><l
i><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 hre
f="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: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">onfilesys
tem</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 h
ref="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:o
ninstruction">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 Fri Dec 21 2018 13:47:10 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/guacamole-website/blob/044692cf/doc/1.0.0/guacamole-common-js/RawAudioFormat.js.html
----------------------------------------------------------------------
diff --git a/doc/1.0.0/guacamole-common-js/RawAudioFormat.js.html b/doc/1.0.0/guacamole-common-js/RawAudioFormat.js.html
new file mode 100644
index 0000000..a353fe1
--- /dev/null
+++ b/doc/1.0.0/guacamole-common-js/RawAudioFormat.js.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: RawAudioFormat.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: RawAudioFormat.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 description of the format of raw PCM audio, such as that used by
+ * Guacamole.RawAudioPlayer and Guacamole.RawAudioRecorder. This object
+ * describes the number of bytes per sample, the number of channels, and the
+ * overall sample rate.
+ *
+ * @constructor
+ * @param {Guacamole.RawAudioFormat|Object} template
+ * The object whose properties should be copied into the corresponding
+ * properties of the new Guacamole.RawAudioFormat.
+ */
+Guacamole.RawAudioFormat = function RawAudioFormat(template) {
+
+ /**
+ * The number of bytes in each sample of audio data. This value is
+ * independent of the number of channels.
+ *
+ * @type {Number}
+ */
+ this.bytesPerSample = template.bytesPerSample;
+
+ /**
+ * The number of audio channels (ie: 1 for mono, 2 for stereo).
+ *
+ * @type {Number}
+ */
+ this.channels = template.channels;
+
+ /**
+ * The number of samples per second, per channel.
+ *
+ * @type {Number}
+ */
+ this.rate = template.rate;
+
+};
+
+/**
+ * Parses the given mimetype, returning a new Guacamole.RawAudioFormat
+ * which describes the type of raw audio data represented by that mimetype. If
+ * the mimetype is not a supported raw audio data mimetype, null is returned.
+ *
+ * @param {String} mimetype
+ * The audio mimetype to parse.
+ *
+ * @returns {Guacamole.RawAudioFormat}
+ * A new Guacamole.RawAudioFormat which describes the type of raw
+ * audio data represented by the given mimetype, or null if the given
+ * mimetype is not supported.
+ */
+Guacamole.RawAudioFormat.parse = function parseFormat(mimetype) {
+
+ var bytesPerSample;
+
+ // Rate is absolutely required - if null is still present later, the
+ // mimetype must not be supported
+ var rate = null;
+
+ // Default for both "audio/L8" and "audio/L16" is one channel
+ var channels = 1;
+
+ // "audio/L8" has one byte per sample
+ if (mimetype.substring(0, 9) === 'audio/L8;') {
+ mimetype = mimetype.substring(9);
+ bytesPerSample = 1;
+ }
+
+ // "audio/L16" has two bytes per sample
+ else if (mimetype.substring(0, 10) === 'audio/L16;') {
+ mimetype = mimetype.substring(10);
+ bytesPerSample = 2;
+ }
+
+ // All other types are unsupported
+ else
+ return null;
+
+ // Parse all parameters
+ var parameters = mimetype.split(',');
+ for (var i = 0; i < parameters.length; i++) {
+
+ var parameter = parameters[i];
+
+ // All parameters must have an equals sign separating name from value
+ var equals = parameter.indexOf('=');
+ if (equals === -1)
+ return null;
+
+ // Parse name and value from parameter string
+ var name = parameter.substring(0, equals);
+ var value = parameter.substring(equals+1);
+
+ // Handle each supported parameter
+ switch (name) {
+
+ // Number of audio channels
+ case 'channels':
+ channels = parseInt(value);
+ break;
+
+ // Sample rate
+ case 'rate':
+ rate = parseInt(value);
+ break;
+
+ // All other parameters are unsupported
+ default:
+ return null;
+
+ }
+
+ };
+
+ // The rate parameter is required
+ if (rate === null)
+ return null;
+
+ // Return parsed format details
+ return new Guacamole.RawAudioFormat({
+ bytesPerSample : bytesPerSample,
+ channels : channels,
+ rate : rate
+ });
+
+};
+</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><l
i><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 hre
f="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: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">onfilesys
tem</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 h
ref="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:o
ninstruction">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 Fri Dec 21 2018 13:47:10 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/guacamole-website/blob/044692cf/doc/1.0.0/guacamole-common-js/SessionRecording.js.html
----------------------------------------------------------------------
diff --git a/doc/1.0.0/guacamole-common-js/SessionRecording.js.html b/doc/1.0.0/guacamole-common-js/SessionRecording.js.html
new file mode 100644
index 0000000..21d741a
--- /dev/null
+++ b/doc/1.0.0/guacamole-common-js/SessionRecording.js.html
@@ -0,0 +1,870 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: SessionRecording.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: SessionRecording.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 recording of a Guacamole session. Given a {@link Guacamole.Tunnel}, the
+ * Guacamole.SessionRecording automatically handles incoming Guacamole
+ * instructions, storing them for playback. Playback of the recording may be
+ * controlled through function calls to the Guacamole.SessionRecording, even
+ * while the recording has not yet finished being created or downloaded.
+ *
+ * @constructor
+ * @param {Guacamole.Tunnel} tunnel
+ * The Guacamole.Tunnel from which the instructions of the recording should
+ * be read.
+ */
+Guacamole.SessionRecording = function SessionRecording(tunnel) {
+
+ /**
+ * Reference to this Guacamole.SessionRecording.
+ *
+ * @private
+ * @type {Guacamole.SessionRecording}
+ */
+ var recording = this;
+
+ /**
+ * The minimum number of characters which must have been read between
+ * keyframes.
+ *
+ * @private
+ * @constant
+ * @type {Number}
+ */
+ var KEYFRAME_CHAR_INTERVAL = 16384;
+
+ /**
+ * The minimum number of milliseconds which must elapse between keyframes.
+ *
+ * @private
+ * @constant
+ * @type {Number}
+ */
+ var KEYFRAME_TIME_INTERVAL = 5000;
+
+ /**
+ * The maximum amount of time to spend in any particular seek operation
+ * before returning control to the main thread, in milliseconds. Seek
+ * operations exceeding this amount of time will proceed asynchronously.
+ *
+ * @private
+ * @constant
+ * @type {Number}
+ */
+ var MAXIMUM_SEEK_TIME = 5;
+
+ /**
+ * All frames parsed from the provided tunnel.
+ *
+ * @private
+ * @type {Guacamole.SessionRecording._Frame[]}
+ */
+ var frames = [];
+
+ /**
+ * All instructions which have been read since the last frame was added to
+ * the frames array.
+ *
+ * @private
+ * @type {Guacamole.SessionRecording._Frame.Instruction[]}
+ */
+ var instructions = [];
+
+ /**
+ * The approximate number of characters which have been read from the
+ * provided tunnel since the last frame was flagged for use as a keyframe.
+ *
+ * @private
+ * @type {Number}
+ */
+ var charactersSinceLastKeyframe = 0;
+
+ /**
+ * The timestamp of the last frame which was flagged for use as a keyframe.
+ * If no timestamp has yet been flagged, this will be 0.
+ *
+ * @private
+ * @type {Number}
+ */
+ var lastKeyframeTimestamp = 0;
+
+ /**
+ * Tunnel which feeds arbitrary instructions to the client used by this
+ * Guacamole.SessionRecording for playback of the session recording.
+ *
+ * @private
+ * @type {Guacamole.SessionRecording._PlaybackTunnel}
+ */
+ var playbackTunnel = new Guacamole.SessionRecording._PlaybackTunnel();
+
+ /**
+ * Guacamole.Client instance used for visible playback of the session
+ * recording.
+ *
+ * @private
+ * @type {Guacamole.Client}
+ */
+ var playbackClient = new Guacamole.Client(playbackTunnel);
+
+ /**
+ * The current frame rendered within the playback client. If no frame is
+ * yet rendered, this will be -1.
+ *
+ * @private
+ * @type {Number}
+ */
+ var currentFrame = -1;
+
+ /**
+ * The timestamp of the frame when playback began, in milliseconds. If
+ * playback is not in progress, this will be null.
+ *
+ * @private
+ * @type {Number}
+ */
+ var startVideoTimestamp = null;
+
+ /**
+ * The real-world timestamp when playback began, in milliseconds. If
+ * playback is not in progress, this will be null.
+ *
+ * @private
+ * @type {Number}
+ */
+ var startRealTimestamp = null;
+
+ /**
+ * The ID of the timeout which will continue the in-progress seek
+ * operation. If no seek operation is in progress, the ID stored here (if
+ * any) will not be valid.
+ *
+ * @private
+ * @type {Number}
+ */
+ var seekTimeout = null;
+
+ // Start playback client connected
+ playbackClient.connect();
+
+ // Hide cursor unless mouse position is received
+ playbackClient.getDisplay().showCursor(false);
+
+ // Read instructions from provided tunnel, extracting each frame
+ tunnel.oninstruction = function handleInstruction(opcode, args) {
+
+ // Store opcode and arguments for received instruction
+ var instruction = new Guacamole.SessionRecording._Frame.Instruction(opcode, args.slice());
+ instructions.push(instruction);
+ charactersSinceLastKeyframe += instruction.getSize();
+
+ // Once a sync is received, store all instructions since the last
+ // frame as a new frame
+ if (opcode === 'sync') {
+
+ // Parse frame timestamp from sync instruction
+ var timestamp = parseInt(args[0]);
+
+ // Add a new frame containing the instructions read since last frame
+ var frame = new Guacamole.SessionRecording._Frame(timestamp, instructions);
+ frames.push(frame);
+
+ // This frame should eventually become a keyframe if enough data
+ // has been processed and enough recording time has elapsed, or if
+ // this is the absolute first frame
+ if (frames.length === 1 || (charactersSinceLastKeyframe >= KEYFRAME_CHAR_INTERVAL
+ && timestamp - lastKeyframeTimestamp >= KEYFRAME_TIME_INTERVAL)) {
+ frame.keyframe = true;
+ lastKeyframeTimestamp = timestamp;
+ charactersSinceLastKeyframe = 0;
+ }
+
+ // Clear set of instructions in preparation for next frame
+ instructions = [];
+
+ // Notify that additional content is available
+ if (recording.onprogress)
+ recording.onprogress(recording.getDuration());
+
+ }
+
+ };
+
+ /**
+ * Converts the given absolute timestamp to a timestamp which is relative
+ * to the first frame in the recording.
+ *
+ * @private
+ * @param {Number} timestamp
+ * The timestamp to convert to a relative timestamp.
+ *
+ * @returns {Number}
+ * The difference in milliseconds between the given timestamp and the
+ * first frame of the recording, or zero if no frames yet exist.
+ */
+ var toRelativeTimestamp = function toRelativeTimestamp(timestamp) {
+
+ // If no frames yet exist, all timestamps are zero
+ if (frames.length === 0)
+ return 0;
+
+ // Calculate timestamp relative to first frame
+ return timestamp - frames[0].timestamp;
+
+ };
+
+ /**
+ * Searches through the given region of frames for the frame having a
+ * relative timestamp closest to the timestamp given.
+ *
+ * @private
+ * @param {Number} minIndex
+ * The index of the first frame in the region (the frame having the
+ * smallest timestamp).
+ *
+ * @param {Number} maxIndex
+ * The index of the last frame in the region (the frame having the
+ * largest timestamp).
+ *
+ * @param {Number} timestamp
+ * The relative timestamp to search for, where zero denotes the first
+ * frame in the recording.
+ *
+ * @returns {Number}
+ * The index of the frame having a relative timestamp closest to the
+ * given value.
+ */
+ var findFrame = function findFrame(minIndex, maxIndex, timestamp) {
+
+ // Do not search if the region contains only one element
+ if (minIndex === maxIndex)
+ return minIndex;
+
+ // Split search region into two halves
+ var midIndex = Math.floor((minIndex + maxIndex) / 2);
+ var midTimestamp = toRelativeTimestamp(frames[midIndex].timestamp);
+
+ // If timestamp is within lesser half, search again within that half
+ if (timestamp < midTimestamp && midIndex > minIndex)
+ return findFrame(minIndex, midIndex - 1, timestamp);
+
+ // If timestamp is within greater half, search again within that half
+ if (timestamp > midTimestamp && midIndex < maxIndex)
+ return findFrame(midIndex + 1, maxIndex, timestamp);
+
+ // Otherwise, we lucked out and found a frame with exactly the
+ // desired timestamp
+ return midIndex;
+
+ };
+
+ /**
+ * Replays the instructions associated with the given frame, sending those
+ * instructions to the playback client.
+ *
+ * @private
+ * @param {Number} index
+ * The index of the frame within the frames array which should be
+ * replayed.
+ */
+ var replayFrame = function replayFrame(index) {
+
+ var frame = frames[index];
+
+ // Replay all instructions within the retrieved frame
+ for (var i = 0; i < frame.instructions.length; i++) {
+ var instruction = frame.instructions[i];
+ playbackTunnel.receiveInstruction(instruction.opcode, instruction.args);
+ }
+
+ // Store client state if frame is flagged as a keyframe
+ if (frame.keyframe && !frame.clientState) {
+ playbackClient.exportState(function storeClientState(state) {
+ frame.clientState = state;
+ });
+ }
+
+ };
+
+ /**
+ * Moves the playback position to the given frame, resetting the state of
+ * the playback client and replaying frames as necessary. The seek
+ * operation will proceed asynchronously. If a seek operation is already in
+ * progress, that seek is first aborted. The progress of the seek operation
+ * can be observed through the onseek handler and the provided callback.
+ *
+ * @private
+ * @param {Number} index
+ * The index of the frame which should become the new playback
+ * position.
+ *
+ * @param {function} callback
+ * The callback to invoke once the seek operation has completed.
+ *
+ * @param {Number} [delay=0]
+ * The number of milliseconds that the seek operation should be
+ * scheduled to take.
+ */
+ var seekToFrame = function seekToFrame(index, callback, delay) {
+
+ // Abort any in-progress seek
+ abortSeek();
+
+ // Replay frames asynchronously
+ seekTimeout = window.setTimeout(function continueSeek() {
+
+ var startIndex;
+
+ // Back up until startIndex represents current state
+ for (startIndex = index; startIndex >= 0; startIndex--) {
+
+ var frame = frames[startIndex];
+
+ // If we've reached the current frame, startIndex represents
+ // current state by definition
+ if (startIndex === currentFrame)
+ break;
+
+ // If frame has associated absolute state, make that frame the
+ // current state
+ if (frame.clientState) {
+ playbackClient.importState(frame.clientState);
+ break;
+ }
+
+ }
+
+ // Advance to frame index after current state
+ startIndex++;
+
+ var startTime = new Date().getTime();
+
+ // Replay any applicable incremental frames
+ for (; startIndex <= index; startIndex++) {
+
+ // Stop seeking if the operation is taking too long
+ var currentTime = new Date().getTime();
+ if (currentTime - startTime >= MAXIMUM_SEEK_TIME)
+ break;
+
+ replayFrame(startIndex);
+ }
+
+ // Current frame is now at requested index
+ currentFrame = startIndex - 1;
+
+ // Notify of changes in position
+ if (recording.onseek)
+ recording.onseek(recording.getPosition());
+
+ // If the seek operation has not yet completed, schedule continuation
+ if (currentFrame !== index)
+ seekToFrame(index, callback,
+ Math.max(delay - (new Date().getTime() - startTime), 0));
+
+ // Notify that the requested seek has completed
+ else
+ callback();
+
+ }, delay || 0);
+
+ };
+
+ /**
+ * Aborts the seek operation currently in progress, if any. If no seek
+ * operation is in progress, this function has no effect.
+ *
+ * @private
+ */
+ var abortSeek = function abortSeek() {
+ window.clearTimeout(seekTimeout);
+ };
+
+ /**
+ * Advances playback to the next frame in the frames array and schedules
+ * playback of the frame following that frame based on their associated
+ * timestamps. If no frames exist after the next frame, playback is paused.
+ *
+ * @private
+ */
+ var continuePlayback = function continuePlayback() {
+
+ // If frames remain after advancing, schedule next frame
+ if (currentFrame + 1 < frames.length) {
+
+ // Pull the upcoming frame
+ var next = frames[currentFrame + 1];
+
+ // Calculate the real timestamp corresponding to when the next
+ // frame begins
+ var nextRealTimestamp = next.timestamp - startVideoTimestamp + startRealTimestamp;
+
+ // Calculate the relative delay between the current time and
+ // the next frame start
+ var delay = Math.max(nextRealTimestamp - new Date().getTime(), 0);
+
+ // Advance to next frame after enough time has elapsed
+ seekToFrame(currentFrame + 1, function frameDelayElapsed() {
+ continuePlayback();
+ }, delay);
+
+ }
+
+ // Otherwise stop playback
+ else
+ recording.pause();
+
+ };
+
+ /**
+ * Fired when new frames have become available while the recording is
+ * being downloaded.
+ *
+ * @event
+ * @param {Number} duration
+ * The new duration of the recording, in milliseconds.
+ */
+ this.onprogress = null;
+
+ /**
+ * Fired whenever playback of the recording has started.
+ *
+ * @event
+ */
+ this.onplay = null;
+
+ /**
+ * Fired whenever playback of the recording has been paused. This may
+ * happen when playback is explicitly paused with a call to pause(), or
+ * when playback is implicitly paused due to reaching the end of the
+ * recording.
+ *
+ * @event
+ */
+ this.onpause = null;
+
+ /**
+ * Fired whenever the playback position within the recording changes.
+ *
+ * @event
+ * @param {Number} position
+ * The new position within the recording, in milliseconds.
+ */
+ this.onseek = null;
+
+ /**
+ * Connects the underlying tunnel, beginning download of the Guacamole
+ * session. Playback of the Guacamole session cannot occur until at least
+ * one frame worth of instructions has been downloaded.
+ *
+ * @param {String} data
+ * The data to send to the tunnel when connecting.
+ */
+ this.connect = function connect(data) {
+ tunnel.connect(data);
+ };
+
+ /**
+ * Disconnects the underlying tunnel, stopping further download of the
+ * Guacamole session.
+ */
+ this.disconnect = function disconnect() {
+ tunnel.disconnect();
+ };
+
+ /**
+ * Returns the underlying display of the Guacamole.Client used by this
+ * Guacamole.SessionRecording for playback. The display contains an Element
+ * which can be added to the DOM, causing the display (and thus playback of
+ * the recording) to become visible.
+ *
+ * @return {Guacamole.Display}
+ * The underlying display of the Guacamole.Client used by this
+ * Guacamole.SessionRecording for playback.
+ */
+ this.getDisplay = function getDisplay() {
+ return playbackClient.getDisplay();
+ };
+
+ /**
+ * Returns whether playback is currently in progress.
+ *
+ * @returns {Boolean}
+ * true if playback is currently in progress, false otherwise.
+ */
+ this.isPlaying = function isPlaying() {
+ return !!startVideoTimestamp;
+ };
+
+ /**
+ * Returns the current playback position within the recording, in
+ * milliseconds, where zero is the start of the recording.
+ *
+ * @returns {Number}
+ * The current playback position within the recording, in milliseconds.
+ */
+ this.getPosition = function getPosition() {
+
+ // Position is simply zero if playback has not started at all
+ if (currentFrame === -1)
+ return 0;
+
+ // Return current position as a millisecond timestamp relative to the
+ // start of the recording
+ return toRelativeTimestamp(frames[currentFrame].timestamp);
+
+ };
+
+ /**
+ * Returns the duration of this recording, in milliseconds. If the
+ * recording is still being downloaded, this value will gradually increase.
+ *
+ * @returns {Number}
+ * The duration of this recording, in milliseconds.
+ */
+ this.getDuration = function getDuration() {
+
+ // If no frames yet exist, duration is zero
+ if (frames.length === 0)
+ return 0;
+
+ // Recording duration is simply the timestamp of the last frame
+ return toRelativeTimestamp(frames[frames.length - 1].timestamp);
+
+ };
+
+ /**
+ * Begins continuous playback of the recording downloaded thus far.
+ * Playback of the recording will continue until pause() is invoked or
+ * until no further frames exist. Playback is initially paused when a
+ * Guacamole.SessionRecording is created, and must be explicitly started
+ * through a call to this function. If playback is already in progress,
+ * this function has no effect. If a seek operation is in progress,
+ * playback resumes at the current position, and the seek is aborted as if
+ * completed.
+ */
+ this.play = function play() {
+
+ // If playback is not already in progress and frames remain,
+ // begin playback
+ if (!recording.isPlaying() && currentFrame + 1 < frames.length) {
+
+ // Notify that playback is starting
+ if (recording.onplay)
+ recording.onplay();
+
+ // Store timestamp of playback start for relative scheduling of
+ // future frames
+ var next = frames[currentFrame + 1];
+ startVideoTimestamp = next.timestamp;
+ startRealTimestamp = new Date().getTime();
+
+ // Begin playback of video
+ continuePlayback();
+
+ }
+
+ };
+
+ /**
+ * Seeks to the given position within the recording. If the recording is
+ * currently being played back, playback will continue after the seek is
+ * performed. If the recording is currently paused, playback will be
+ * paused after the seek is performed. If a seek operation is already in
+ * progress, that seek is first aborted. The seek operation will proceed
+ * asynchronously.
+ *
+ * @param {Number} position
+ * The position within the recording to seek to, in milliseconds.
+ *
+ * @param {function} [callback]
+ * The callback to invoke once the seek operation has completed.
+ */
+ this.seek = function seek(position, callback) {
+
+ // Do not seek if no frames exist
+ if (frames.length === 0)
+ return;
+
+ // Pause playback, preserving playback state
+ var originallyPlaying = recording.isPlaying();
+ recording.pause();
+
+ // Perform seek
+ seekToFrame(findFrame(0, frames.length - 1, position), function restorePlaybackState() {
+
+ // Restore playback state
+ if (originallyPlaying)
+ recording.play();
+
+ // Notify that seek has completed
+ if (callback)
+ callback();
+
+ });
+
+ };
+
+ /**
+ * Pauses playback of the recording, if playback is currently in progress.
+ * If playback is not in progress, this function has no effect. If a seek
+ * operation is in progress, the seek is aborted. Playback is initially
+ * paused when a Guacamole.SessionRecording is created, and must be
+ * explicitly started through a call to play().
+ */
+ this.pause = function pause() {
+
+ // Abort any in-progress seek / playback
+ abortSeek();
+
+ // Stop playback only if playback is in progress
+ if (recording.isPlaying()) {
+
+ // Notify that playback is stopping
+ if (recording.onpause)
+ recording.onpause();
+
+ // Playback is stopped
+ startVideoTimestamp = null;
+ startRealTimestamp = null;
+
+ }
+
+ };
+
+};
+
+/**
+ * A single frame of Guacamole session data. Each frame is made up of the set
+ * of instructions used to generate that frame, and the timestamp as dictated
+ * by the "sync" instruction terminating the frame. Optionally, a frame may
+ * also be associated with a snapshot of Guacamole client state, such that the
+ * frame can be rendered without replaying all previous frames.
+ *
+ * @private
+ * @constructor
+ * @param {Number} timestamp
+ * The timestamp of this frame, as dictated by the "sync" instruction which
+ * terminates the frame.
+ *
+ * @param {Guacamole.SessionRecording._Frame.Instruction[]} instructions
+ * All instructions which are necessary to generate this frame relative to
+ * the previous frame in the Guacamole session.
+ */
+Guacamole.SessionRecording._Frame = function _Frame(timestamp, instructions) {
+
+ /**
+ * Whether this frame should be used as a keyframe if possible. This value
+ * is purely advisory. The stored clientState must eventually be manually
+ * set for the frame to be used as a keyframe. By default, frames are not
+ * keyframes.
+ *
+ * @type {Boolean}
+ * @default false
+ */
+ this.keyframe = false;
+
+ /**
+ * The timestamp of this frame, as dictated by the "sync" instruction which
+ * terminates the frame.
+ *
+ * @type {Number}
+ */
+ this.timestamp = timestamp;
+
+ /**
+ * All instructions which are necessary to generate this frame relative to
+ * the previous frame in the Guacamole session.
+ *
+ * @type {Guacamole.SessionRecording._Frame.Instruction[]}
+ */
+ this.instructions = instructions;
+
+ /**
+ * A snapshot of client state after this frame was rendered, as returned by
+ * a call to exportState(). If no such snapshot has been taken, this will
+ * be null.
+ *
+ * @type {Object}
+ * @default null
+ */
+ this.clientState = null;
+
+};
+
+/**
+ * A Guacamole protocol instruction. Each Guacamole protocol instruction is
+ * made up of an opcode and set of arguments.
+ *
+ * @private
+ * @constructor
+ * @param {String} opcode
+ * The opcode of this Guacamole instruction.
+ *
+ * @param {String[]} args
+ * All arguments associated with this Guacamole instruction.
+ */
+Guacamole.SessionRecording._Frame.Instruction = function Instruction(opcode, args) {
+
+ /**
+ * Reference to this Guacamole.SessionRecording._Frame.Instruction.
+ *
+ * @private
+ * @type {Guacamole.SessionRecording._Frame.Instruction}
+ */
+ var instruction = this;
+
+ /**
+ * The opcode of this Guacamole instruction.
+ *
+ * @type {String}
+ */
+ this.opcode = opcode;
+
+ /**
+ * All arguments associated with this Guacamole instruction.
+ *
+ * @type {String[]}
+ */
+ this.args = args;
+
+ /**
+ * Returns the approximate number of characters which make up this
+ * instruction. This value is only approximate as it excludes the length
+ * prefixes and various delimiters used by the Guacamole protocol; only
+ * the content of the opcode and each argument is taken into account.
+ *
+ * @returns {Number}
+ * The approximate size of this instruction, in characters.
+ */
+ this.getSize = function getSize() {
+
+ // Init with length of opcode
+ var size = instruction.opcode.length;
+
+ // Add length of all arguments
+ for (var i = 0; i < instruction.args.length; i++)
+ size += instruction.args[i].length;
+
+ return size;
+
+ };
+
+};
+
+/**
+ * A read-only Guacamole.Tunnel implementation which streams instructions
+ * received through explicit calls to its receiveInstruction() function.
+ *
+ * @private
+ * @constructor
+ * @augments {Guacamole.Tunnel}
+ */
+Guacamole.SessionRecording._PlaybackTunnel = function _PlaybackTunnel() {
+
+ /**
+ * Reference to this Guacamole.SessionRecording._PlaybackTunnel.
+ *
+ * @private
+ * @type {Guacamole.SessionRecording._PlaybackTunnel}
+ */
+ var tunnel = this;
+
+ this.connect = function connect(data) {
+ // Do nothing
+ };
+
+ this.sendMessage = function sendMessage(elements) {
+ // Do nothing
+ };
+
+ this.disconnect = function disconnect() {
+ // Do nothing
+ };
+
+ /**
+ * Invokes this tunnel's oninstruction handler, notifying users of this
+ * tunnel (such as a Guacamole.Client instance) that an instruction has
+ * been received. If the oninstruction handler has not been set, this
+ * function has no effect.
+ *
+ * @param {String} opcode
+ * The opcode of the Guacamole instruction.
+ *
+ * @param {String[]} args
+ * All arguments associated with this Guacamole instruction.
+ */
+ this.receiveInstruction = function receiveInstruction(opcode, args) {
+ if (tunnel.oninstruction)
+ tunnel.oninstruction(opcode, args);
+ };
+
+};
+</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><l
i><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 hre
f="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: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">onfilesys
tem</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 h
ref="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:o
ninstruction">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 Fri Dec 21 2018 13:47:10 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/guacamole-website/blob/044692cf/doc/1.0.0/guacamole-common-js/Status.js.html
----------------------------------------------------------------------
diff --git a/doc/1.0.0/guacamole-common-js/Status.js.html b/doc/1.0.0/guacamole-common-js/Status.js.html
new file mode 100644
index 0000000..318b528
--- /dev/null
+++ b/doc/1.0.0/guacamole-common-js/Status.js.html
@@ -0,0 +1,369 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: Status.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: Status.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 Guacamole status. Each Guacamole status consists of a status code, defined
+ * by the protocol, and an optional human-readable message, usually only
+ * included for debugging convenience.
+ *
+ * @constructor
+ * @param {Number} code
+ * The Guacamole status code, as defined by Guacamole.Status.Code.
+ *
+ * @param {String} [message]
+ * An optional human-readable message.
+ */
+Guacamole.Status = function(code, message) {
+
+ /**
+ * Reference to this Guacamole.Status.
+ * @private
+ */
+ var guac_status = this;
+
+ /**
+ * The Guacamole status code.
+ * @see Guacamole.Status.Code
+ * @type {Number}
+ */
+ this.code = code;
+
+ /**
+ * An arbitrary human-readable message associated with this status, if any.
+ * The human-readable message is not required, and is generally provided
+ * for debugging purposes only. For user feedback, it is better to translate
+ * the Guacamole status code into a message.
+ *
+ * @type {String}
+ */
+ this.message = message;
+
+ /**
+ * Returns whether this status represents an error.
+ * @returns {Boolean} true if this status represents an error, false
+ * otherwise.
+ */
+ this.isError = function() {
+ return guac_status.code < 0 || guac_status.code > 0x00FF;
+ };
+
+};
+
+/**
+ * Enumeration of all Guacamole status codes.
+ */
+Guacamole.Status.Code = {
+
+ /**
+ * The operation succeeded.
+ *
+ * @type {Number}
+ */
+ "SUCCESS": 0x0000,
+
+ /**
+ * The requested operation is unsupported.
+ *
+ * @type {Number}
+ */
+ "UNSUPPORTED": 0x0100,
+
+ /**
+ * The operation could not be performed due to an internal failure.
+ *
+ * @type {Number}
+ */
+ "SERVER_ERROR": 0x0200,
+
+ /**
+ * The operation could not be performed as the server is busy.
+ *
+ * @type {Number}
+ */
+ "SERVER_BUSY": 0x0201,
+
+ /**
+ * The operation could not be performed because the upstream server is not
+ * responding.
+ *
+ * @type {Number}
+ */
+ "UPSTREAM_TIMEOUT": 0x0202,
+
+ /**
+ * The operation was unsuccessful due to an error or otherwise unexpected
+ * condition of the upstream server.
+ *
+ * @type {Number}
+ */
+ "UPSTREAM_ERROR": 0x0203,
+
+ /**
+ * The operation could not be performed as the requested resource does not
+ * exist.
+ *
+ * @type {Number}
+ */
+ "RESOURCE_NOT_FOUND": 0x0204,
+
+ /**
+ * The operation could not be performed as the requested resource is
+ * already in use.
+ *
+ * @type {Number}
+ */
+ "RESOURCE_CONFLICT": 0x0205,
+
+ /**
+ * The operation could not be performed as the requested resource is now
+ * closed.
+ *
+ * @type {Number}
+ */
+ "RESOURCE_CLOSED": 0x0206,
+
+ /**
+ * The operation could not be performed because the upstream server does
+ * not appear to exist.
+ *
+ * @type {Number}
+ */
+ "UPSTREAM_NOT_FOUND": 0x0207,
+
+ /**
+ * The operation could not be performed because the upstream server is not
+ * available to service the request.
+ *
+ * @type {Number}
+ */
+ "UPSTREAM_UNAVAILABLE": 0x0208,
+
+ /**
+ * The session within the upstream server has ended because it conflicted
+ * with another session.
+ *
+ * @type {Number}
+ */
+ "SESSION_CONFLICT": 0x0209,
+
+ /**
+ * The session within the upstream server has ended because it appeared to
+ * be inactive.
+ *
+ * @type {Number}
+ */
+ "SESSION_TIMEOUT": 0x020A,
+
+ /**
+ * The session within the upstream server has been forcibly terminated.
+ *
+ * @type {Number}
+ */
+ "SESSION_CLOSED": 0x020B,
+
+ /**
+ * The operation could not be performed because bad parameters were given.
+ *
+ * @type {Number}
+ */
+ "CLIENT_BAD_REQUEST": 0x0300,
+
+ /**
+ * Permission was denied to perform the operation, as the user is not yet
+ * authorized (not yet logged in, for example).
+ *
+ * @type {Number}
+ */
+ "CLIENT_UNAUTHORIZED": 0x0301,
+
+ /**
+ * Permission was denied to perform the operation, and this permission will
+ * not be granted even if the user is authorized.
+ *
+ * @type {Number}
+ */
+ "CLIENT_FORBIDDEN": 0x0303,
+
+ /**
+ * The client took too long to respond.
+ *
+ * @type {Number}
+ */
+ "CLIENT_TIMEOUT": 0x0308,
+
+ /**
+ * The client sent too much data.
+ *
+ * @type {Number}
+ */
+ "CLIENT_OVERRUN": 0x030D,
+
+ /**
+ * The client sent data of an unsupported or unexpected type.
+ *
+ * @type {Number}
+ */
+ "CLIENT_BAD_TYPE": 0x030F,
+
+ /**
+ * The operation failed because the current client is already using too
+ * many resources.
+ *
+ * @type {Number}
+ */
+ "CLIENT_TOO_MANY": 0x031D
+
+};
+
+/**
+ * Returns the Guacamole protocol status code which most closely
+ * represents the given HTTP status code.
+ *
+ * @param {Number} status
+ * The HTTP status code to translate into a Guacamole protocol status
+ * code.
+ *
+ * @returns {Number}
+ * The Guacamole protocol status code which most closely represents the
+ * given HTTP status code.
+ */
+Guacamole.Status.Code.fromHTTPCode = function fromHTTPCode(status) {
+
+ // Translate status codes with known equivalents
+ switch (status) {
+
+ // HTTP 400 - Bad request
+ case 400:
+ return Guacamole.Status.Code.CLIENT_BAD_REQUEST;
+
+ // HTTP 403 - Forbidden
+ case 403:
+ return Guacamole.Status.Code.CLIENT_FORBIDDEN;
+
+ // HTTP 404 - Resource not found
+ case 404:
+ return Guacamole.Status.Code.RESOURCE_NOT_FOUND;
+
+ // HTTP 429 - Too many requests
+ case 429:
+ return Guacamole.Status.Code.CLIENT_TOO_MANY;
+
+ // HTTP 503 - Server unavailable
+ case 503:
+ return Guacamole.Status.Code.SERVER_BUSY;
+
+ }
+
+ // Default all other codes to generic internal error
+ return Guacamole.Status.Code.SERVER_ERROR;
+
+};
+
+/**
+ * Returns the Guacamole protocol status code which most closely
+ * represents the given WebSocket status code.
+ *
+ * @param {Number} code
+ * The WebSocket status code to translate into a Guacamole protocol
+ * status code.
+ *
+ * @returns {Number}
+ * The Guacamole protocol status code which most closely represents the
+ * given WebSocket status code.
+ */
+Guacamole.Status.Code.fromWebSocketCode = function fromWebSocketCode(code) {
+
+ // Translate status codes with known equivalents
+ switch (code) {
+
+ // Successful disconnect (no error)
+ case 1000: // Normal Closure
+ return Guacamole.Status.Code.SUCCESS;
+
+ // Codes which indicate the server is not reachable
+ case 1006: // Abnormal Closure (also signalled by JavaScript when the connection cannot be opened in the first place)
+ case 1015: // TLS Handshake
+ return Guacamole.Status.Code.UPSTREAM_NOT_FOUND;
+
+ // Codes which indicate the server is reachable but busy/unavailable
+ case 1001: // Going Away
+ case 1012: // Service Restart
+ case 1013: // Try Again Later
+ case 1014: // Bad Gateway
+ return Guacamole.Status.Code.UPSTREAM_UNAVAILABLE;
+
+ }
+
+ // Default all other codes to generic internal error
+ return Guacamole.Status.Code.SERVER_ERROR;
+
+};
+</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><l
i><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 hre
f="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: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">onfilesys
tem</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 h
ref="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:o
ninstruction">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 Fri Dec 21 2018 13:47:10 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+</body>
+</html>