mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-608: Implement UTF-8 encode in StringWriter.
This commit is contained in:
@@ -38,19 +38,142 @@ Guacamole.StringWriter = function(stream) {
|
|||||||
*/
|
*/
|
||||||
var guac_writer = this;
|
var guac_writer = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapped Guacamole.ArrayBufferWriter.
|
||||||
|
* @private
|
||||||
|
* @type Guacamole.ArrayBufferWriter
|
||||||
|
*/
|
||||||
|
var array_writer = new Guacamole.ArrayBufferWriter(stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal buffer for UTF-8 output.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
var buffer = new Uint8Array(8192);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes currently in the buffer.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
var length = 0;
|
||||||
|
|
||||||
// Simply call onack for acknowledgements
|
// Simply call onack for acknowledgements
|
||||||
stream.onack = function(status) {
|
array_writer.onack = function(status) {
|
||||||
if (guac_writer.onack)
|
if (guac_writer.onack)
|
||||||
guac_writer.onack(status);
|
guac_writer.onack(status);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expands the size of the underlying buffer by the given number of bytes,
|
||||||
|
* updating the length appropriately.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Number} bytes The number of bytes to add to the underlying
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
function __expand(bytes) {
|
||||||
|
|
||||||
|
// Resize buffer if more space needed
|
||||||
|
if (length+bytes >= buffer.length) {
|
||||||
|
var new_buffer = new Uint8Array((length+bytes)*2);
|
||||||
|
new_buffer.set(buffer);
|
||||||
|
buffer = new_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += bytes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a single Unicode character to the current buffer, resizing the
|
||||||
|
* buffer if necessary. The character will be encoded as UTF-8.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Number} codepoint The codepoint of the Unicode character to
|
||||||
|
* append.
|
||||||
|
*/
|
||||||
|
function __append_utf8(codepoint) {
|
||||||
|
|
||||||
|
var mask;
|
||||||
|
var bytes;
|
||||||
|
|
||||||
|
// 1 byte
|
||||||
|
if (codepoint <= 0x7F) {
|
||||||
|
mask = 0x00;
|
||||||
|
bytes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 byte
|
||||||
|
else if (codepoint <= 0x7FF) {
|
||||||
|
mask = 0xC0;
|
||||||
|
bytes = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3 byte
|
||||||
|
else if (codepoint <= 0xFFFF) {
|
||||||
|
mask = 0xE0;
|
||||||
|
bytes = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4 byte
|
||||||
|
else if (codepoint <= 0x1FFFFF) {
|
||||||
|
mask = 0xF0;
|
||||||
|
bytes = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If invalid codepoint, append replacement character
|
||||||
|
else {
|
||||||
|
__append_utf8(0xFFFD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset buffer by size
|
||||||
|
__expand(bytes);
|
||||||
|
var offset = length - 1;
|
||||||
|
|
||||||
|
// Add trailing bytes, if any
|
||||||
|
for (var i=1; i<bytes; i++) {
|
||||||
|
buffer[offset--] = 0x80 | (codepoint & 0x3F);
|
||||||
|
codepoint >>= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial byte
|
||||||
|
buffer[offset] = mask | codepoint;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the given string as UTF-8, returning an ArrayBuffer containing
|
||||||
|
* the resulting bytes.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} text The string to encode as UTF-8.
|
||||||
|
* @return {Uint8Array} The encoded UTF-8 data.
|
||||||
|
*/
|
||||||
|
function __encode_utf8(text) {
|
||||||
|
|
||||||
|
// Fill buffer with UTF-8
|
||||||
|
for (var i=0; i<text.length; i++) {
|
||||||
|
var codepoint = text.charCodeAt(i);
|
||||||
|
__append_utf8(codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush buffer
|
||||||
|
if (length > 0) {
|
||||||
|
var out_buffer = buffer.subarray(0, length);
|
||||||
|
length = 0;
|
||||||
|
return out_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the given text.
|
* Sends the given text.
|
||||||
*
|
*
|
||||||
* @param {String} text The text to send.
|
* @param {String} text The text to send.
|
||||||
*/
|
*/
|
||||||
this.sendText = function(text) {
|
this.sendText = function(text) {
|
||||||
stream.sendBlob(window.btoa(text));
|
array_writer.sendData(__encode_utf8(text));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +181,7 @@ Guacamole.StringWriter = function(stream) {
|
|||||||
* stream.
|
* stream.
|
||||||
*/
|
*/
|
||||||
this.sendEnd = function() {
|
this.sendEnd = function() {
|
||||||
stream.sendEnd();
|
array_writer.sendEnd();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user