rfb.js: rQwait, cuttext simplification.

- rQwait checks the receive queue to see if there is enough data to
  satisfy the following request. If not it returns true (which is
  almost always translated into an immediate return false by the
  caller).

- rQwait is called quite a bit and this generally allows 4 lines to
  become 1 line where it is called.

- rQwait allows simplification of cuttext processing. No global
  tracking needed anymore.

Overall, about 60 lines less code.
This commit is contained in:
Joel Martin 2010-10-01 11:50:22 -05:00
parent a99959719d
commit 60440cee15
1 changed files with 50 additions and 106 deletions

View File

@ -99,9 +99,6 @@ var that = {}, // Public API interface
fb_height = 0,
fb_name = "",
cuttext = 'none', // ServerCutText wait state
cuttext_length = 0,
scan_imgQ_rate = 100,
last_req_time = 0,
rre_chunk_sz = 100,
@ -204,6 +201,27 @@ function rQshiftBytes(len) {
return rQ.slice(rQi-len, rQi);
}
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
// to be available in the receive queue. Return true if we need to
// wait (and possibly print a debug message), otherwise false.
function rQwait(msg, num, goback) {
if (typeof num !== 'number') { num = FBU.bytes; }
var rQlen = rQ.length - rQi; // Skip rQlen() function call
if (rQlen < num) {
if (goback) {
if (rQi < goback) {
throw("rQwait cannot backup " + goback + " bytes");
}
rQi -= goback;
}
//Util.Debug(" waiting for " + (num-rQlen) +
// " " + msg + " byte(s)");
return true; // true means need more data
}
return false;
}
//
// Setup routines
//
@ -299,8 +317,6 @@ function init_ws() {
init_vars = function() {
/* Reset state */
cuttext = 'none';
cuttext_length = 0;
rQ = [];
rQi = 0;
sQ = "";
@ -670,7 +686,7 @@ function mouseMove(x, y) {
init_msg = function() {
//Util.Debug(">> init_msg [rfb_state '" + rfb_state + "']");
var strlen, reason, reason_len, sversion, cversion,
var strlen, reason, length, sversion, cversion,
i, types, num_types, challenge, response, bpp, depth,
big_endian, true_color, name_length;
@ -724,11 +740,7 @@ init_msg = function() {
case 'Security' :
if (rfb_version >= 3.7) {
num_types = rQ[rQi++];
if (rQlen() < num_types) {
rQi--;
Util.Debug(" waiting for security types");
return;
}
if (rQwait("security type", num_types, 1)) { return false; }
if (num_types === 0) {
strlen = rQshift32();
reason = rQshiftStr(strlen);
@ -752,10 +764,7 @@ init_msg = function() {
send_array([rfb_auth_scheme]);
} else {
if (rQlen() < 4) {
Util.Debug(" waiting for security scheme bytes");
return;
}
if (rQwait("security scheme", 4)) { return false; }
rfb_auth_scheme = rQshift32();
}
updateState('Authentication',
@ -767,10 +776,7 @@ init_msg = function() {
//Util.Debug("Security auth scheme: " + rfb_auth_scheme);
switch (rfb_auth_scheme) {
case 0: // connection failed
if (rQlen() < 4) {
Util.Debug(" waiting for auth reason bytes");
return;
}
if (rQwait("auth reason", 4)) { return false; }
strlen = rQshift32();
reason = rQshiftStr(strlen);
updateState('failed',
@ -784,10 +790,7 @@ init_msg = function() {
updateState('password', "Password Required");
return;
}
if (rQlen() < 16) {
Util.Debug(" waiting for auth challenge bytes");
return;
}
if (rQwait("auth challenge", 16)) { return false; }
challenge = rQshiftBytes(16);
//Util.Debug("Password: " + rfb_password);
//Util.Debug("Challenge: " + challenge +
@ -819,11 +822,9 @@ init_msg = function() {
break;
case 1: // failed
if (rfb_version >= 3.8) {
reason_len = rQshift32();
if (rQlen() < reason_len) {
Util.Debug(" waiting for SecurityResult reason bytes");
rQi -= 8; // Unshift the status and length
return;
length = rQshift32();
if (rQwait("SecurityResult reason", length, 8)) {
return false;
}
reason = rQshiftStr(reason_len);
updateState('failed', reason);
@ -901,13 +902,11 @@ init_msg = function() {
normal_msg = function() {
//Util.Debug(">> normal_msg");
var ret = true, msg_type,
var ret = true, msg_type, length,
c, first_colour, num_colours, red, green, blue;
if (FBU.rects > 0) {
msg_type = 0;
} else if (cuttext !== 'none') {
msg_type = 3;
} else {
msg_type = rQ[rQi++];
}
@ -937,25 +936,12 @@ normal_msg = function() {
break;
case 3: // ServerCutText
Util.Debug("ServerCutText");
Util.Debug("rQ:" + rQ.slice(0,20));
if (cuttext === 'none') {
cuttext = 'header';
}
if (cuttext === 'header') {
if (rQlen() < 7) {
//Util.Debug("waiting for ServerCutText header");
return false;
}
rQshiftBytes(3); // Padding
cuttext_length = rQshift32();
}
cuttext = 'bytes';
if (rQlen() < cuttext_length) {
//Util.Debug("waiting for ServerCutText bytes");
return false;
}
conf.clipboardReceive(that, rQshiftStr(cuttext_length));
cuttext = 'none';
if (rQwait("ServerCutText header", 7, 1)) { return false; }
rQshiftBytes(3); // Padding
length = rQshift32();
if (rQwait("ServerCutText", length, 8)) { return false; }
conf.clipboardReceive(that, rQshiftStr(length));
break;
default:
updateState('failed',
@ -972,13 +958,12 @@ framebufferUpdate = function() {
if (FBU.rects === 0) {
//Util.Debug("New FBU: rQ.slice(0,20): " + rQ.slice(0,20));
if (rQlen() < 3) {
if (rQwait("FBU header", 3)) {
if (rQi === 0) {
rQ.unshift(0); // FBU msg_type
} else {
rQi -= 1;
}
//Util.Debug(" waiting for FBU header bytes");
return false;
}
rQi++;
@ -996,15 +981,9 @@ framebufferUpdate = function() {
if (rfb_state !== "normal") {
return false;
}
if (rQlen() < FBU.bytes) {
//Util.Debug(" waiting for " + (FBU.bytes - rQlen()) + " FBU bytes");
return false;
}
if (rQwait("FBU")) { return false; }
if (FBU.bytes === 0) {
if (rQlen() < 12) {
//Util.Debug(" waiting for rect header bytes");
return false;
}
if (rQwait("rect header", 12)) { return false; }
/* New FramebufferUpdate */
hdr = rQshiftBytes(12);
@ -1092,11 +1071,7 @@ encHandlers.RAW = function display_raw() {
FBU.lines = FBU.height;
}
FBU.bytes = FBU.width * fb_Bpp; // At least a line
if (rQlen() < FBU.bytes) {
//Util.Debug(" waiting for " +
// (FBU.bytes - rQlen()) + " RAW bytes");
return false;
}
if (rQwait("RAW")) { return false; }
cur_y = FBU.y + (FBU.height - FBU.lines);
cur_height = Math.min(FBU.lines,
Math.floor(rQlen()/(FBU.width * fb_Bpp)));
@ -1119,11 +1094,7 @@ encHandlers.COPYRECT = function display_copy_rect() {
var old_x, old_y;
if (rQlen() < 4) {
//Util.Debug(" waiting for " +
// (FBU.bytes - rQlen()) + " COPYRECT bytes");
return false;
}
if (rQwait("COPYRECT", 4)) { return false; }
old_x = rQshift16();
old_y = rQshift16();
canvas.copyImage(old_x, old_y, FBU.x, FBU.y, FBU.width, FBU.height);
@ -1137,11 +1108,7 @@ encHandlers.RRE = function display_rre() {
var color, x, y, width, height, chunk;
if (FBU.subrects === 0) {
if (rQlen() < 4 + fb_Bpp) {
//Util.Debug(" waiting for " +
// (4 + fb_Bpp - rQlen()) + " RRE bytes");
return false;
}
if (rQwait("RRE", 4+fb_Bpp)) { return false; }
FBU.subrects = rQshift32();
color = rQshiftBytes(fb_Bpp); // Background
canvas.fillRect(FBU.x, FBU.y, FBU.width, FBU.height, color);
@ -1184,10 +1151,7 @@ encHandlers.HEXTILE = function display_hextile() {
/* FBU.bytes comes in as 1, rQlen() at least 1 */
while (FBU.tiles > 0) {
FBU.bytes = 1;
if (rQlen() < FBU.bytes) {
//Util.Debug(" waiting for HEXTILE subencoding byte");
return false;
}
if (rQwait("HEXTILE subencoding")) { return false; }
//Util.Debug(" 2 rQ length: " + rQlen() + " rQ[rQi]: " + rQ[rQi] + " rQ.slice(rQi,rQi+20): " + rQ.slice(rQi,rQi+20) + ", FBU.rects: " + FBU.rects + ", FBU.tiles: " + FBU.tiles);
subencoding = rQ[rQi]; // Peek
if (subencoding > 30) { // Raw
@ -1218,11 +1182,7 @@ encHandlers.HEXTILE = function display_hextile() {
}
if (subencoding & 0x08) { // AnySubrects
FBU.bytes += 1; // Since we aren't shifting it off
if (rQlen() < FBU.bytes) {
/* Wait for subrects byte */
//Util.Debug(" waiting for hextile subrects header byte");
return false;
}
if (rQwait("hextile subrects header")) { return false; }
subrects = rQ[rQi + FBU.bytes-1]; // Peek
if (subencoding & 0x10) { // SubrectsColoured
FBU.bytes += subrects * (fb_Bpp + 2);
@ -1243,11 +1203,7 @@ encHandlers.HEXTILE = function display_hextile() {
" last:" + rQ.slice(FBU.bytes-10, FBU.bytes) +
" next:" + rQ.slice(FBU.bytes-1, FBU.bytes+10));
*/
if (rQlen() < FBU.bytes) {
//Util.Debug(" waiting for " +
// (FBU.bytes - rQlen()) + " hextile bytes");
return false;
}
if (rQwait("hextile")) { return false; }
/* We know the encoding and have a whole tile */
FBU.subencoding = rQ[rQi];
@ -1320,10 +1276,7 @@ encHandlers.TIGHT_PNG = function display_tight_png() {
//Util.Debug(" starting rQ.slice(rQi,rQi+20): " + rQ.slice(rQi,rQi+20) + " (" + rQlen() + ")");
FBU.bytes = 1; // compression-control byte
if (rQlen() < FBU.bytes) {
Util.Debug(" waiting for TIGHT compression-control byte");
return false;
}
if (rQwait("TIGHT compression-control")) { return false; }
// Get 'compact length' header and data size
getCLength = function (arr, offset) {
@ -1354,10 +1307,7 @@ encHandlers.TIGHT_PNG = function display_tight_png() {
case "png": FBU.bytes += 3; break; // max clength
}
if (rQlen() < FBU.bytes) {
Util.Debug(" waiting for TIGHT " + cmode + " bytes");
return false;
}
if (rQwait("TIGHT " + cmode)) { return false; }
//Util.Debug(" rQ.slice(0,20): " + rQ.slice(0,20) + " (" + rQlen() + ")");
//Util.Debug(" cmode: " + cmode);
@ -1373,10 +1323,7 @@ encHandlers.TIGHT_PNG = function display_tight_png() {
case "png":
clength = getCLength(rQ, rQi+1);
FBU.bytes = 1 + clength[0] + clength[1]; // ctl + clength size + jpeg-data
if (rQlen() < FBU.bytes) {
Util.Debug(" waiting for TIGHT " + cmode + " bytes");
return false;
}
if (rQwait("TIGHT " + cmode)) { return false; }
// We have everything, render it
//Util.Debug(" png, rQlen(): " + rQlen() + ", clength[0]: " + clength[0] + ", clength[1]: " + clength[1]);
@ -1446,11 +1393,8 @@ encHandlers.Cursor = function set_cursor() {
pixelslength = w * h * fb_Bpp;
masklength = Math.floor((w + 7) / 8) * h;
if (rQlen() < (pixelslength + masklength)) {
//Util.Debug("waiting for cursor encoding bytes");
FBU.bytes = pixelslength + masklength;
return false;
}
FBU.bytes = pixelslength + masklength;
if (rQwait("cursor encoding")) { return false; }
//Util.Debug(" set_cursor, x: " + x + ", y: " + y + ", w: " + w + ", h: " + h);