From ab01ea8c30ea1eacc83131588c74c336aabe0182 Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 21 Jul 2025 22:47:40 +0200 Subject: [PATCH] Mon 21 Jul 22:43:21 CEST 2025 --- js/dos/buf.js | 516 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 516 insertions(+) create mode 100644 js/dos/buf.js diff --git a/js/dos/buf.js b/js/dos/buf.js new file mode 100644 index 0000000..1286d1a --- /dev/null +++ b/js/dos/buf.js @@ -0,0 +1,516 @@ +/** + ** ============================== + ** 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-2018 bLAB + ** $CREATED: 29-4-15 by sbosse. + ** $RCS: $Id$ + ** $VERSION: 1.1.5 + ** + ** $INFO: + ** + ** DOS: Buffer Management + ** + ** $ENDOFINFO + */ +"use strict"; +var log = 0; + +var util = Require('util'); +var Io = Require('com/io'); +var Comp = Require('com/compat'); +var String = Comp.string; +var Array = Comp.array; +var Perv = Comp.pervasives; +var des48 = Require('dos/des48'); +var Rand = Comp.random; +var Net = Require('dos/network'); +var Status = Net.Status; +var Fs = Require('fs'); + + +var SIZEOF_INT16 = 2; +var SIZEOF_INT32 = 4; +var PORT_SIZE = 6; +var PRIV_SIZE = PORT_SIZE+SIZEOF_INT32; +var CAP_SIZE = PORT_SIZE+PRIV_SIZE; + +/** Generic buffer, union with rpcio object + ** Argument: optional, hex-ascci string or number (size), passed to Buffer instantiation + * + * + * @param {number|string|Buffer} [data] + * @constructor + */ +var buffer = function (data) { + var size; + this.pos=0; + if (Comp.isNumber(data)) { + this.data=new Buffer(data); + } else if (Comp.isString(data)) { + this.data=new Buffer(''); + buf_of_hex(this,data) + } else if (Comp.isArray(data)) { + this.data=new Buffer(data); + } else if (typeof data == "object" && data.constructor === Buffer) { + this.data=data; + } else this.data=new Buffer(''); +}; + +/** Extend a buffer to new size (buf.pos+off). + * + * @param buf + * @param off + */ +function buf_extend(buf,off) { + if (buf.data.length<(buf.pos+off)) { + buf.data=Buffer.concat([buf.data,new Buffer(off-(buf.data.length-buf.pos))]); + } +} + +/** Expand buffer to new size. + * + * @param buf + * @param size + */ +function buf_expand(buf,size) { + if (buf.data.lengthsize) { + buf.data=Buffer.slice(buf.data,size); + } +} + +/* + ** BUFFER encoding and decoding of native data types + ** Supported objects: rpcio, buffer. + ** Supported native data types: int16, int32, string, float, port, private, capability, ... + ** ALL buffer data is stored in byte buffers that extends automatically (buf_put_XX). + */ +function buf_put_string (buf,str) { + buf_extend(buf,str.length+1); + for(var i=0;i> 8) & 0xff; + buf.pos=buf.pos+2; +} + +function buf_get_int16 (buf) { + var n=0; + var end=buf.data.length; + if (buf.pos+2 <= end) { + n = buf.data[buf.pos]; + n = n | (buf.data[buf.pos+1] << 8); + buf.pos = buf.pos + 2; + if (n&0x8000) return (n-0x10000); else return (n); + } else throw Status.BUF_OVERFLOW; +} + +function buf_put_int32 (buf,n) { + buf_extend(buf,4); + buf.data[buf.pos]=n & 0xff; + buf.data[buf.pos+1]=(n >> 8) & 0xff; + buf.data[buf.pos+2]=(n >> 16) & 0xff; + buf.data[buf.pos+3]=(n >> 24) & 0xff; + buf.pos=buf.pos+4; +} + +function buf_get_int32 (buf) { + var n=0; + var end=buf.data.length; + if (buf.pos+4 <= end) { + n = buf.data[buf.pos]; + n = n | (buf.data[buf.pos+1] << 8); + n = n | (buf.data[buf.pos+2] << 16); + n = n | (buf.data[buf.pos+3] << 24); + buf.pos = buf.pos + 4; + // TBD: Sign check??? + return (n); + } else throw Status.BUF_OVERFLOW; +} + +function buf_put_port (buf,port) { + buf_extend(buf,Net.PORT_SIZE); + for(var i=0;i> 8) & 0xff; + buf.data[buf.pos+2]=(priv.prv_obj >> 16) & 0xff; + buf.data[buf.pos+3]=priv.prv_rights & 0xff; + buf.pos=buf.pos+4; + buf_put_port(buf,priv.prv_rand); +} + +function buf_get_priv (buf,priv) { + var n; + var end=buf.data.length; + if (buf.pos+(Net.PRIV_SIZE) <= end) { + if (priv == undefined) priv = Net.Private(); + n = buf.data[buf.pos]; + n = n | (buf.data[buf.pos+1] << 8); + n = n | (buf.data[buf.pos+2] << 16); + priv.prv_obj=n; + priv.prv_rights=buf.data[buf.pos+3]; + buf.pos=buf.pos+4; + priv.prv_rand=buf_get_port(buf); + return priv; + } else throw Status.BUF_OVERFLOW; +} + +function buf_put_cap (buf,cap) { + buf_put_port(buf,cap.cap_port); + buf_put_priv(buf,cap.cap_priv); +} + +function buf_get_cap (buf,cap) { + var end=buf.data.length; + if (buf.pos+(Net.CAP_SIZE) <= end) { + if (cap == undefined) cap = Net.Capability(); + cap.cap_port=buf_get_port(buf); + buf_get_priv(buf,cap.cap_priv); + return cap; + } else throw Status.BUF_OVERFLOW; +} + +function buf_put_hdr (buf,hdr) { + buf_put_port(buf,hdr.h_port); + buf_put_priv(buf,hdr.h_priv); + buf_put_int32(buf,hdr.h_command); + buf_put_int32(buf,hdr.h_status); +} + +function buf_get_hdr (buf,hdr) { + if (hdr==undefined) hdr=Net.Header(); + hdr.h_port=buf_get_port(buf); + buf_get_priv(buf,hdr.h_priv); + hdr.h_command=buf_get_int32(buf); + hdr.h_status=buf_get_int32(buf); + return hdr; +} + +/** TODO: buf blit + * + * @param buf + * @param bufsrc + * @param [srcoff] + * @param [len] + */ +function buf_put_buf (buf,bufsrc,srcoff,len) { + if (srcoff==undefined) srcoff=0; + if (len==undefined) len=bufsrc.data.length; + buf_extend(buf,len); + for(var i=0;i= buf.data.length) buf_expand(buf,off+1); + buf.pos=off; +} +/** + * @param {file} fd + * @param {buffer} buf + * @param {number} [off] file offset + * @param {number} [len] + * @returns {number} n + */ +function buf_write (fd,buf,off,len) { + var n; + if (off==undefined) n=Io.write_buf(fd,buf.data,0,buf.data.length); + else { + if (len==undefined) len=buf.data.length; + n=Io.write_buf(fd,buf.data,0,len,off); + } + return n; +} +/** + * @param {file} fd + * @param {buffer} buf + * @param {number} off file offset + * @param {number} len + * @returns {number} n + */ +function buf_read (fd,buf,off,len) { + var n; + buf_expand(buf,len); + n=Io.read_buf(fd,buf.data,0,len,off); + buf.pos=0; + return n; +} + +function buf_print(buf) { + var str='['; + for(var i=0;i0) str=str+','+buf.data[i]; + else str=str+buf.data[i]; + } + return str+']'+buf.pos+':'+buf.data.length; +} + +function buf_set (buf,off,byte) { + if (off >= buf.data.length) buf_expand(buf,off+1); + buf.data[off]=byte; +} + +function buf_get (buf,off) { + return buf.data[off]; +} + +/** Reset buffer + * + * @param buf + */ +function buf_init (buf) { + buf.data=new Buffer(''); + buf.pos=0; +} + +function buf_copy (dst,src) { + dst.data=new Buffer(src.data); + dst.pos=0; +} + +function buf_blit (dst,dstoff,src,srcoff,len) { + buf_expand(dst,dstoff+len); + src.data.copy(dst.data,dstoff,srcoff,srcoff+len); + dst.pos=0; +} + + +/** + * + * @type {{SIZEOF_INT16: number, SIZEOF_INT32: number, PORT_SIZE: number, PRIV_SIZE: number, CAP_SIZE: number, Buffer: Function, buf_put_string: buf_put_string, buf_put_int16: buf_put_int16, buf_put_int32: buf_put_int32, buf_put_port: buf_put_port, buf_put_priv: buf_put_priv, buf_put_cap: buf_put_cap, buf_put_hdr: buf_put_hdr, buf_put_buf: buf_put_buf, buf_put_bytes: buf_put_bytes, buf_get_string: buf_get_string, buf_get_int16: buf_get_int16, buf_get_int32: buf_get_int32, buf_get_port: buf_get_port, buf_get_priv: buf_get_priv, buf_get_cap: buf_get_cap, buf_get_hdr: buf_get_hdr, buf_get_buf: buf_get_buf, buf_get_bytes: buf_get_bytes, buf_pad: buf_pad, buf_set: buf_set, buf_get: buf_get, buf_set_pos: buf_set_pos, buf_init: buf_init, buf_blit: buf_blit, buf_copy: buf_copy, buf_extend: buf_extend, buf_expand: buf_expand, buf_shrink: buf_shrink, buf_read: buf_read, buf_write: buf_write, buf_print: buf_print, buf_to_hex: buf_to_hex, buf_of_hex: buf_of_hex, buf_to_str: buf_to_str, buf_of_str: buf_of_str}} + */ +module.exports = { + SIZEOF_INT16: SIZEOF_INT16, + SIZEOF_INT32: SIZEOF_INT32, + PORT_SIZE: PORT_SIZE, + PRIV_SIZE: PRIV_SIZE, + CAP_SIZE: CAP_SIZE, + /** + * + * @param {number|string|Buffer} [data] + * @returns {buffer} + */ + Buffer: function Buffer(data) { + var obj = new buffer(data); + Object.preventExtensions(obj); + return obj; + }, + // Buffer data operations + buf_put_string:buf_put_string, + buf_put_int16:buf_put_int16, + buf_put_int32:buf_put_int32, + buf_put_port:buf_put_port, + buf_put_priv:buf_put_priv, + buf_put_cap:buf_put_cap, + buf_put_hdr:buf_put_hdr, + buf_put_buf:buf_put_buf, + buf_put_bytes:buf_put_bytes, + buf_get_string:buf_get_string, + buf_get_int16:buf_get_int16, + buf_get_int32:buf_get_int32, + buf_get_port:buf_get_port, + buf_get_priv:buf_get_priv, + buf_get_cap:buf_get_cap, + buf_get_hdr:buf_get_hdr, + buf_get_buf:buf_get_buf, + buf_get_bytes:buf_get_bytes, + buf_pad:buf_pad, + buf_set:buf_set, + buf_get:buf_get, + buf_set_pos:buf_set_pos, + buf_init:buf_init, + buf_blit:buf_blit, + buf_copy:buf_copy, + buf_extend:buf_extend, + buf_expand:buf_expand, + buf_shrink:buf_shrink, + // Buffer IO + buf_read:buf_read, + buf_write:buf_write, + buf_print:buf_print, + // Conversion + buf_to_hex:buf_to_hex, + buf_of_hex:buf_of_hex, + buf_to_str:buf_to_str, + buf_of_str:buf_of_str, + + length: function(buf) { + if (buf.data==undefined) return 0; + else return buf.data.length; + } +};