Mon 21 Jul 22:43:21 CEST 2025

This commit is contained in:
sbosse 2025-07-21 23:14:07 +02:00
parent f5789cdc38
commit 6ac708f826

549
js/com/io.app.js Normal file
View File

@ -0,0 +1,549 @@
/**
** ==============================
** O O O OOOO
** O O O O O O
** O O O O O O
** OOOO OOOO O OOO OOOO
** O O O O O O O
** O O O O O O O
** OOOO OOOO O O OOOO
** ==============================
** Dr. Stefan Bosse http://www.bsslab.de
**
** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED
** BY THE AUTHOR(S).
** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED,
** MODIFIED, OR OTHERWISE USED IN A CONTEXT
** OUTSIDE OF THE SOFTWARE SYSTEM.
**
** $AUTHORS: Stefan Bosse
** $INITIAL: (C) 2006-2020 bLAB
** $CREATED: sbosse on 28-3-15.
** $VERSION: 1.11.1
**
** $INFO:
*
* This module encapsulates all IO operations (except networking) supporting
* jvm applications.
*
** $ENDOFINFO
*/
/*
************
** JVM (node.js,jxcore)
************
*/
var util = Require('util');
var GetEnv = Require('os/getenv');
var Base64 = Require('os/base64');
var Fs = Require('fs');
Require('os/polyfill')
var stderr_fun = function (str) { process.stderr.write(str); };
var stdout_fun = function (str) { process.stdout.write(str); };
/*
** node.js specific
*/
var tracefile = undefined;
var tracing = false;
var timestamp = false;
/**
* Open a module and append all exported properties to the current global object.
* (top-level scope)
*/
global.open = function(name,context,as) {
var module = Require(name);
if (!context) context=global;
for (var p in module) {
context[p] = module[p];
};
if (as) context[as]=module;
}
global.print = console.log;
global.checkOptions = function(options,defaultOptions) {
return Object.assign({}, defaultOptions||{}, options) };
global.checkOption = function (option,defaultOption) {
return option==undefined? defaultOption:option };
var io = {
options: {
columns:undefined,
rows:undefined,
log:console.log,
err:console.err,
warn:console.warn,
},
/**
*
* @param fd
*/
close: function (fd) {
Fs.closeSync(fd);
},
/**
** Return current date in year-month-day format
*/
Date: function ()
{
var now = new Date();
var year = "" + now.getFullYear();
var month = "0" + (now.getMonth()+1);
month = month.substring(month.length-2);
var date = "0" + now.getDate();
date = date.substring(date.length-2);
return year + "-" + month + "-" + date;
},
/**
*
* @param msg
*/
debug: function (msg) {
this.options.err('Debug: ' + msg);
},
/**
*
* @param path
*/
exists: function (path) {
return Fs.existsSync(path);
},
error: undefined,
/**
*
* @param msg
*/
err: function (msg) {
this.options.err('Error: ' + msg);
throw Error(msg);
},
exit: function (n) {
process.exit(n);
},
/**
*
* @param msg
*/
fail: function (msg) {
this.options.err('Fatal Error: ' + msg);
process.exit(0);
},
/**
*
* @param path
*/
file_exists: function (path) {
return Fs.existsSync(path);
},
/** Search a file by iterating global PATH variable.
*
* @param name File name or partial (relative) path
*/
file_search: function (name) {
// Expecting global PATH variable !?
if (this.file_exists(name)) return name;
else if (typeof PATH !== 'undefined') {
for (var p in PATH) {
if (this.file_exists(PATH[p]+'/'+name)) return (PATH[p]+'/'+name);
}
return undefined;
} else return undefined;
},
/**
*
* @param path
* @returns {number}
*/
file_size: function (path) {
var stat = Fs.statSync(path);
if (stat != undefined)
return stat.size;
else
return -1;
},
/**
*
* @param path
* @param timekind a c m
* @returns {number}
*/
file_time: function (path,timekind) {
var stat = Fs.statSync(path);
if (stat != undefined)
switch (timekind) {
case 'a': return stat.atime.getTime()/1000;
case 'c': return stat.ctime.getTime()/1000;
case 'm': return stat.mtime.getTime()/1000;
default: return stat.mtime.getTime()/1000;
}
else
return -1;
},
/**
* @return {string []}
*/
getargs: function () {
return process.argv;
},
getenv: function (name, def) {
return GetEnv(name, def);
},
/**
*
* @param obj
*/
inspect: function (obj) {
return util&&util.inspect?util.inspect(obj):(typeof obj)
},
/**
*
* @param {boolean|string} condmsg conditional message var log=X; log((log lt. N)||(msg))
*/
log: function (condmsg) {
if (condmsg==true) return;
if (!timestamp) console.warn(condmsg);
else {
var date = new Date();
var time = Math.floor(date.getTime());
console.warn('['+process.pid+':'+time+']'+condmsg);
}
},
/**
*
* @returns {*} RSS HEAP in kBytes {data,heap}
*/
mem: function () {
var mem = process.memoryUsage();
return {data:(mem.rss/1024)|0,heap:(mem.heapUsed/1024)|0};
},
/**
*
* @param path
* @param mode
* @returns {*}
*/
open: function (path, mode) {
return Fs.openSync(path, mode);
},
/**
*
* @param msg
*/
out: function (msg) {
this.options.log(msg)
},
/**
*
* @param e
* @param where
*/
printstack: function (e,where) {
if (!e.stack) e=new Error(e);
if (!e.stack) e.stack ='empty stack';
var stack = e.stack //.replace(/^[^\(]+?[\n$]/gm, '')
.replace(/^\s+at\s+/gm, '')
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@')
.split('\n');
if (where==undefined) this.out(e);
else this.out(where+': '+e);
this.out('Stack Trace');
this.out('--------------------------------');
for(var i in stack) {
if (i>0) {
var line = stack[i];
if(line.indexOf('Module.',0)>=0) break;
this.out(' at '+line);
}
}
this.out('--------------------------------');
},
/**
*
* @param fd
* @param len
* @param foff
*/
read: function (fd, len, foff) {
// TODO
},
/**
*
* @param path
* @returns {string|undefined}
*/
read_file: function (path) {
try {
return Fs.readFileSync(path,'utf8');
} catch (e) {
this.error=e;
return undefined;
}
},
/**
*
* @param path
* @returns {*}
*/
read_file_bin: function (path) {
try {
return Fs.readFileSync(path);
} catch (e) {
this.error=e;
return undefined;
}
},
/**
*
* @param fd
*/
read_line: function (fd) {
// TODO
},
/**
*
* @param fd
* @param buf
* @param boff
* @param len
* @param [foff]
* @returns {number}
*/
read_buf: function (fd, buf, boff, len, foff) {
return Fs.readSync(fd, buf, boff, len, foff);
},
/**
*
* @param e
* @param where
*/
sprintstack: function (e) {
var str='';
if (e==_ || !e.stack) e=new Error(e);
if (!e.stack) e.stack ='empty stack';
var stack = e.stack //.replace(/^[^\(]+?[\n$]/gm, '')
.replace(/^\s+at\s+/gm, '')
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@')
.replace(/^Object.eval\s*\(/gm, '')
.split('\n');
for(var i in stack) {
if (i>0) {
var line = stack[i];
if(line.indexOf('Module.',0)>=0) break;
if (str!='') str += '\n';
str += ' at '+line;
}
}
return str;
},
/**
*
*/
stacktrace: function () {
var e = new Error('dummy');
if (!e.stack) e.stack ='empty stack';
var stack = e.stack.replace(/^[^\(]+?[\n$]/gm, '')
.replace(/^\s+at\s+/gm, '')
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@')
.split('\n');
this.out('Stack Trace');
this.out('--------------------------------');
for(var i in stack) {
if (i>0) {
var line = stack[i];
if(line.indexOf('Module.',0)>=0) break;
this.out(' at '+line);
}
}
this.out('--------------------------------');
},
/**
*
* @param fun
*/
set_stderr: function(fun) {
stderr_fun=fun;
},
/**
*
* @param fun
*/
set_stdout: function(fun) {
stdout_fun=fun;
},
/**
*
* @param msg
*/
stderr: function (msg) {
stderr_fun(msg);
},
// sleep(ms)
sleep: function(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
},
/**
*
* @param msg
*/
stdout: function (msg) {
stdout_fun(msg);
},
/**
*
* @param fd
*/
sync: function (fd) {
Fs.fsyncSync(fd);
},
date: function () {
var date = Date();
return date.split(' ').slice(1,5).join(' ');
},
/** Return system time in milliseconds
*/
time: function () {
var date = new Date();
return Math.floor(date.getTime());
},
/**
** Return current time in hour:minute:second format
*/
Time: function ()
{
var now = new Date();
var hour = "0" + now.getHours();
hour = hour.substring(hour.length-2);
var minute = "0" + now.getMinutes();
minute = minute.substring(minute.length-2);
var second = "0" + now.getSeconds();
second = second.substring(second.length-2);
var milli = "0" + Math.floor(now.getMilliseconds()/10);
milli = milli.substring(milli.length-2);
return hour + ":" + minute + ":" + second+':'+milli;
},
/** Write a message with a time stamp written to the trace file.
*
* @param {boolean|string} condmsg conditional message var trace=Io.tracing; trace(trace||(msg))
*/
trace: function (condmsg) {
if (condmsg != true && tracefile != undefined) {
var date = new Date();
var time = Math.floor(date.getTime());
Fs.writeSync(tracefile, '[' + time + '] ' + condmsg + '\n');
}
},
tracing: tracing,
/**
*
* @param {string} path
*/
trace_open: function (path) {
tracefile = Fs.openSync(path, 'w+');
if (tracefile != undefined) this.tracing = false;
},
/**
*
* @param msg
*/
warn: function (msg) {
if (!timestamp) this.options.warn('Warning: ' + msg);
else {
var date = new Date();
var time = Math.floor(date.getTime());
console.warn('['+process.pid+':'+time+'] Warning: '+msg);
}
},
workdir: function () {
return this.getenv('PWD',this.getenv('CWD',''));
},
/**
*
* @param fd
* @param data
* @param [foff]
* @returns {number}
*/
write: function (fd, data, foff) {
return Fs.writeSync(fd, data, foff);
},
/**
*
* @param fd
* @param buf
* @param bpos
* @param blen
* @param [foff]
* @returns {number}
*/
write_buf: function (fd, buf, bpos, blen, foff) {
return Fs.writeSync(fd, buf, bpos, blen, foff);
},
/**
*
* @param path
* @param {string} buf
*/
write_file: function (path,str) {
try {
Fs.writeFileSync(path, str, 'utf8');
return str.length;
} catch (e) {
return -1;
}
},
/**
*
* @param path
* @param buf
* @returns {*}
*/
write_file_bin: function (path,buf) {
try {
Fs.writeFileSync(path, buf, 'binary');
return buf.length;
} catch (e) {
this.error=e;
return -1;
}
},
/**
*
* @param fd
* @param {string} str
* @returns {number}
*/
write_line: function (fd, str) {
return Fs.writeSync(fd, str+NL);
},
/**
* Process management
*/
fork: undefined,
exec: undefined,
execSync: undefined,
spawn: undefined,
/**
* OS
*/
hostname: function () {return 'localhost'}
};
module.exports = io;