Commit 60440cee authored by Joel Martin's avatar Joel Martin

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