From 019279fcca0c8e660ce8233103991b9b6eba022f Mon Sep 17 00:00:00 2001 From: Deon George Date: Fri, 27 Mar 2020 16:14:33 +1100 Subject: [PATCH] created parse() for response frames with fields --- load/defs.js | 267 ++++++++++++++++++++++++++++++++++++++++++++++++-- load/funcs.js | 6 +- 2 files changed, 262 insertions(+), 11 deletions(-) diff --git a/load/defs.js b/load/defs.js index f29ca3a..244eaa9 100644 --- a/load/defs.js +++ b/load/defs.js @@ -43,23 +43,38 @@ function Frame() { this.type = FRAME_TYPE_INFO; this.key=[ null,null,null,null,null,null,null,null,null,null ]; + // Initialise frame array + this.frame_data = {}; + this.frame_content = {}; + for(x=0;x 80 ? '\n\r' : ''); + '\1W\1H'+this.page+' '.repeat(FRAME_PAGENUM-this.page.length)+' '+ + '\1G\1H'+' '.repeat(FRAME_COST-this.cost.toString().length)+this.cost+FRAME_COSTUNIT+ + (console.screen_columns > 80 ? '\n\r' : ''); + } - return header + base64_decode(this.content); - } + if ((this.type == FRAME_TYPE_LOGIN) || (this.type == FRAME_TYPE_RESPONSE)) { + return header+this.parse(this.content); + } else { + return header+this.content; + } + }; Object.defineProperty(this,'page', { get: function() { @@ -67,6 +82,12 @@ function Frame() { return this.frame+this.index; } }); + + Object.defineProperty(this,'fields', { + get: function() { + return this.frame_fields; + } + }); } // Load a frame from disk (.tex file) @@ -85,10 +106,240 @@ Frame.prototype.load = function(filename) { this[property] = load[property]; } + this.content = base64_decode(this.content); + } catch (error) { log(LOG_ERROR,'Frame error: '+error); return null; } log(LOG_DEBUG,'Loaded frame: ['+this.frame+']['+this.index+'] ('+this.page+')'); -} \ No newline at end of file +}; + +/** + * Parse the page text, and return the frame as 2 arrays: + * + First array is all the characters and the position on the frame + * + Second array is the array of the control codes that changes the color of the character + * + * The purpose of this function is to convert any special char sequences there are interpreted directly by Ansitex + * Currently they are: + * + ESC _ [;value] ESC \ + * + * Additionally, for response frames, if the cursor is moved to a field, its to determine what attributes (eg: color) + * should apply for that field. + * + * @todo This function could be advanced by looking for the next KEY_ESC char, instead of progressing 1 char at a time + * @param text + */ +Frame.prototype.parse = function(text) { + var c = 1; // column + var r = 1; // row + var output = ''; + + // Default Attributes + f = 39; + b = 49; + i = 0; + + for(p=0;p= 0 && csi[num] <= 8) { + i = csi[num]; + f = 39; + b = 49; + + // Forground Color + } else if (csi[num] >= 30 && csi[num] <= 39) { + f = csi[num]; + + // Background Color + } else if (csi[num] >= 40 && csi[num] <= 49) { + b = num; + } + } + break; + + // Advance characters + case 'C': + log(LOG_DEBUG,'CSI C ['+r+'x'+c+'] CHARS: '+matches[1]); + c += parseInt(matches[1]); // Advance our position + break; + + default: + dump('? CSI: '.matches[2]); + } + + break; + + case ' ': + log(LOG_DEBUG,'LOOSE ESC? ['+r+'x'+c+'] '+advance); + + break; + + // SOS + case '_': + log(LOG_DEBUG,'SOS ['+r+'x'+c+'] '+advance); + advance++; + + // Find our end ST param in the next 50 chars + matches = text.substring(p+advance,p+advance+50).match(/(([A-Z]+;[0-9a-z]+)([;]?.+)?)\x1b\\/); + log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', LENGTH: '+matches[0].length+', STRING: '+text.substring(p+advance,p+advance+50)); + + if (! matches) { + chars += nextbyte; + + break; + } + + advance += matches[0].length-1; + + // The last 2 chars of matches[0] are the ESC \ + sos = matches[0].substr(0,matches[0].length-2).split(';'); + log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', SOS: '+sos); + + var num = null; + var fieldlen = null; + for (num in sos) { + log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM: '+num+', SOS: '+sos[num]); + + switch (num) { + // First value is the field name + case '0': + field = sos[num]; + break; + + // Second value is the length/type of the field + case '1': + x = sos[num].match(/([0-9]+)([a-z])/); + if (! x) { + log(LOG_ERROR,'SOS FAILED PARSING FIELD LENGTH/TYPE. ['+r+'x'+c+'] '+sos[num]); + break; + } + + log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM CHARS: '+x[1]+', TYPE: '+x[2]); + fieldlen = x[1]; + fieldtype = x[2]; + break; + + // Third field is the char to to use + case '2': + fieldchar = sos[num]; + break; + + default: + log(LOG_ERROR,'IGNORING ADITIONAL SOS FIELDS. ['+r+'x'+c+'] '+sos[num]); + } + } + + if (fieldlen) { + chars = fieldchar.repeat(fieldlen); + } + + byte = ''; + + this.frame_fields.push({ + 'type': fieldtype, + 'length': fieldlen, + 'r': r, + 'c': c, + }); + + log(LOG_DEBUG,'SOS Field found at ['+r+'x'+(c-1)+'], Type: '+fieldtype+', Length: '+fieldlen); + + break; + + default: + log(LOG_DEBUG,'DEFAULT ['+r+'x'+c+'] '+advance); + } + + break; + + default: + this.frame_data[r][c] = {i:i,f:f,b:b}; + this.frame_content[r][c] = byte; + log(LOG_DEBUG,'ADD OUTPUT ['+r+'x'+c+'] for: '+byte); + c++; + } + + output += byte; + + if (advance) { + log(LOG_DEBUG,'ADVANCE P ['+r+'x'+c+'] '+advance+', NEXT CHAR: '+text.charAt(p+advance)+' ('+text.charCodeAt(p+advance)+')'); + output += chars; + p += advance; + } + + if (c>FRAME_WIDTH) { + c = 1; + r++; + } + + // @todo - If we are longer than FRAME_LENGTH, move the output into the next frame. + if (r>FRAME_LENGTH) { + break; + } + + // Debugging + if (false && r > 3) { + console.write(output); + bbs.hangup(); + exit(1); + } + + } + + return output; +}; \ No newline at end of file diff --git a/load/funcs.js b/load/funcs.js index 3c6c9ca..ea5b8a3 100644 --- a/load/funcs.js +++ b/load/funcs.js @@ -1,3 +1,4 @@ +// String repeat. if (!String.prototype.repeat) { String.prototype.repeat = function(count) { 'use strict'; @@ -51,8 +52,7 @@ function cursorOff() { * @param code * @returns {number | string|boolean} */ -function findMsgBase(code) -{ +function findMsgBase(code) { if (! code) code = "tex_data"; @@ -157,4 +157,4 @@ function sendBaseline(text,reposition) { if (! reposition) { console.popxy(); } -} +} \ No newline at end of file