Migrate blob to input stream (ish) API.

This commit is contained in:
Michael Jumper
2013-09-24 13:14:26 -07:00
parent 8848b87c21
commit 68e2e2b028
2 changed files with 68 additions and 64 deletions

View File

@@ -84,7 +84,7 @@ Guacamole.Parser = function() {
* this Guacamole.Parser, executing all completed instructions at * this Guacamole.Parser, executing all completed instructions at
* the beginning of this buffer, if any. * the beginning of this buffer, if any.
* *
* @param {String} packet The instruction data to append. * @param {String} packet The instruction data to receive.
*/ */
this.receive = function(packet) { this.receive = function(packet) {
@@ -180,23 +180,22 @@ Guacamole.Parser = function() {
/** /**
* A blob abstraction used by the Guacamole client to facilitate transfer of * An input stream abstraction used by the Guacamole client to facilitate
* files or other binary data. * transfer of files or other binary data.
* *
* @constructor * @constructor
* @param {String} mimetype The mimetype of the data this blob will contain. * @param {String} mimetype The mimetype of the data this stream will receive.
* @param {String} name An arbitrary name for this blob.
*/ */
Guacamole.Blob = function(mimetype, name) { Guacamole.InputStream = function(mimetype) {
/** /**
* Reference to this Guacamole.Blob. * Reference to this Guacamole.InputStream.
* @private * @private
*/ */
var guac_blob = this; var guac_stream = this;
/** /**
* The length of this Guacamole.Blob in bytes. * The length of this Guacamole.InputStream in bytes.
* @private * @private
*/ */
var length = 0; var length = 0;
@@ -206,12 +205,6 @@ Guacamole.Blob = function(mimetype, name) {
*/ */
this.mimetype = mimetype; this.mimetype = mimetype;
/**
* The name of this blob. In general, this should be an appropriate
* filename.
*/
this.name = name;
// Get blob builder // Get blob builder
var blob_builder; var blob_builder;
if (window.BlobBuilder) blob_builder = new BlobBuilder(); if (window.BlobBuilder) blob_builder = new BlobBuilder();
@@ -235,46 +228,48 @@ Guacamole.Blob = function(mimetype, name) {
})(); })();
/** /**
* Appends the given ArrayBuffer to this Guacamole.Blob. * Receives the given ArrayBuffer, storing its data within this
* Guacamole.InputStream.
* *
* @param {ArrayBuffer} buffer An ArrayBuffer containing the data to be * @param {ArrayBuffer} buffer An ArrayBuffer containing the data to be
* appended. * received.
*/ */
this.append = function(buffer) { this.receive = function(buffer) {
blob_builder.append(buffer); blob_builder.append(buffer);
length += buffer.byteLength; length += buffer.byteLength;
// Call handler, if present // Call handler, if present
if (guac_blob.ondata) if (guac_stream.onreceive)
guac_blob.ondata(buffer.byteLength); guac_stream.onreceive(buffer.byteLength);
}; };
/** /**
* Closes this Guacamole.Blob such that no further data will be written. * Closes this Guacamole.InputStream such that no further data will be
* written.
*/ */
this.close = function() { this.close = function() {
// Call handler, if present // Call handler, if present
if (guac_blob.oncomplete) if (guac_stream.onclose)
guac_blob.oncomplete(); guac_stream.onclose();
// NOTE: Currently not enforced. // NOTE: Currently not enforced.
}; };
/** /**
* Returns the current length of this Guacamole.Blob, in bytes. * Returns the current length of this Guacamole.InputStream, in bytes.
* @return {Number} The current length of this Guacamole.Blob. * @return {Number} The current length of this Guacamole.InputStream.
*/ */
this.getLength = function() { this.getLength = function() {
return length; return length;
}; };
/** /**
* Returns the contents of this Guacamole.Blob as a Blob. * Returns the contents of this Guacamole.InputStream as a Blob.
* @return {Blob} The contents of this Guacamole.Blob. * @return {Blob} The contents of this Guacamole.InputStream.
*/ */
this.getBlob = function() { this.getBlob = function() {
return blob_builder.getBlob(); return blob_builder.getBlob();
@@ -286,13 +281,13 @@ Guacamole.Blob = function(mimetype, name) {
* @event * @event
* @param {Number} length The number of bytes received. * @param {Number} length The number of bytes received.
*/ */
this.ondata = null; this.onreceive = null;
/** /**
* Fired once this blob is finished and no further data will be written. * Fired once this stream is finished and no further data will be written.
* @event * @event
*/ */
this.oncomplete = null; this.onclose = null;
}; };
@@ -496,8 +491,8 @@ Guacamole.Client = function(tunnel) {
// No initial audio channels // No initial audio channels
var audio_channels = []; var audio_channels = [];
// No initial blobs // No initial streams
var blobs = []; var streams = [];
// Pool of available streams // Pool of available streams
var stream_indices = new Guacamole.IntegerPool(); var stream_indices = new Guacamole.IntegerPool();
@@ -745,15 +740,16 @@ Guacamole.Client = function(tunnel) {
this.onresize = null; this.onresize = null;
/** /**
* Fired when a blob is created. The blob provided to this event handler * Fired when a file stream is created. The stream provided to this event
* will contain its own event handlers for received data and the close * handler will contain its own event handlers for received data and the
* event. * close event.
* *
* @event * @event
* @param {Guacamole.Blob} blob A container for blob data that will receive * @param {String} filename The name of the file received.
* data from the server. * @param {Guacamole.InputStream} stream A stream that will receive
* data from the server.
*/ */
this.onblob = null; this.onfile = null;
// Layers // Layers
function getBufferLayer(index) { function getBufferLayer(index) {
@@ -871,21 +867,28 @@ Guacamole.Client = function(tunnel) {
"audio": function(parameters) { "audio": function(parameters) {
var channel = getAudioChannel(parseInt(parameters[0])); var stream_index = parseInt(parameters[0]);
var mimetype = parameters[1];
var duration = parseFloat(parameters[2]);
var data = parameters[3];
channel.play(mimetype, duration, data); // Create stream
var stream = streams[stream_index] =
new Guacamole.InputStream(mimetype);
var channel = getAudioChannel(parseInt(parameters[1]));
var mimetype = parameters[2];
var duration = parseFloat(parameters[3]);
stream.onclose = function() {
channel.play(mimetype, duration, stream.getBlob());
};
}, },
"blob": function(parameters) { "blob": function(parameters) {
// Get blob // Get stream
var blob_index = parseInt(parameters[0]); var stream_index = parseInt(parameters[0]);
var data = parameters[1]; var data = parameters[1];
var blob = blobs[blob_index]; var stream = streams[stream_index];
// Convert to ArrayBuffer // Convert to ArrayBuffer
var binary = window.atob(data); var binary = window.atob(data);
@@ -896,7 +899,7 @@ Guacamole.Client = function(tunnel) {
bufferView[i] = binary.charCodeAt(i); bufferView[i] = binary.charCodeAt(i);
// Write data // Write data
blob.append(arrayBuffer); stream.receive(arrayBuffer);
}, },
@@ -1078,27 +1081,28 @@ Guacamole.Client = function(tunnel) {
"end": function(parameters) { "end": function(parameters) {
// Get blob // Get stream
var blob_index = parseInt(parameters[0]); var stream_index = parseInt(parameters[0]);
var blob = blobs[blob_index]; var stream = streams[stream_index];
// Close blob // Close stream
blob.close(); stream.close();
}, },
"file": function(parameters) { "file": function(parameters) {
var blob_index = parseInt(parameters[0]); var stream_index = parseInt(parameters[0]);
var mimetype = parameters[1]; var mimetype = parameters[1];
var filename = parameters[2]; var filename = parameters[2];
// Create blob // Create stream
var blob = blobs[blob_index] = new Guacamole.Blob(mimetype, filename); var stream = streams[stream_index] =
new Guacamole.InputStream(mimetype);
// Call handler now that blob is created // Call handler now that file stream is created
if (guac_client.onblob) if (guac_client.onfile)
guac_client.onblob(blob); guac_client.onfile(filename, stream);
}, },

View File

@@ -790,23 +790,23 @@ GuacUI.Client.attach = function(guac) {
} }
guac.onblob = function(blob) { guac.onfile = function(filename, stream) {
var download = new GuacUI.Download(blob.name); var download = new GuacUI.Download(filename);
download.updateProgress(getSizeString(0)); download.updateProgress(getSizeString(0));
GuacUI.Client.notification_area.appendChild(download.getElement()); GuacUI.Client.notification_area.appendChild(download.getElement());
// Update progress as data is received // Update progress as data is received
blob.ondata = function() { stream.onreceive = function() {
download.updateProgress(getSizeString(blob.getLength())); download.updateProgress(getSizeString(stream.getLength()));
}; };
// When complete, prompt for download // When complete, prompt for download
blob.oncomplete = function() { stream.onclose = function() {
download.ondownload = function() { download.ondownload = function() {
saveAs(blob.getBlob(), blob.name); saveAs(stream.getBlob(), filename);
}; };
download.complete(); download.complete();