2
0
mirror of https://github.com/esiur/esiur-js.git synced 2025-06-27 15:23:11 +00:00
This commit is contained in:
2022-03-13 11:28:38 +03:00
parent 7b1b844753
commit 15eb1453e7
55 changed files with 24308 additions and 4587 deletions

View File

@ -26,8 +26,7 @@
"use strict";
import DataType from './DataType.js';
import DC from './DataConverter.js';
import DC from './DC.js';
export default class BinaryList
{
@ -35,216 +34,198 @@ export default class BinaryList
constructor()
{
this.list = [];
//this.data = [];
}
addRange(bl)
{
for(var i = 0; i < bl.list.length; i++)
this.list.push(bl.list[i]);
addDateTime(value, endian) {
this.addDC(DC.dateTimeToBytes(value, endian));
return this;
}
add(typedValue, position)
{
if (position !== undefined)
this.list.splice(position, 0, typedValue);
else
this.list.push(typedValue);
insertDateTime(position, value, endian) {
this.insertDC(position, DC.dateTimeToBytes(value, endian));
return this;
}
addDateTimeArray(value, endian) {
this.addDC(DC.dateTimeArrayToBytes(value, endian));
return this;
}
insertDateTimeArray(position, value, endian) {
this.insertDC(position, DC.dateTimeArrayToBytes(value, endian));
return this;
}
addGuid(value) {
this.addDC(DC.guidToBytes(value));
return this;
}
insertGuid(position, value) {
this.insertDC(position, DC.guidToBytes(value));
return this;
}
addUint8Array(value) {
this.addDC(value);
return this;
}
addDC(value) {
this.list.push(...value);
return this;
}
insertUint8Array(position, value) {
this.insertDC(position, value);
return this;
}
addString(value) {
this.addDC(DC.stringToBytes(value));
return this;
}
insertString(position, value) {
this.insertDC(position, DC.stringToBytes(value));
return this;
}
insertUint8(position, value) {
this.list.splice(position, 0, value);
return this;
}
addUint8(value) {
this.list.push(value);
return this;
}
addInt8(value) {
this.list.push(value);
return this;
}
insertInt8(position, value) {
this.list.splice(position, 0, value);
return this;
}
addChar(value) {
this.addDC(DC.charToBytes(value));
return this;
}
insertChar(position, value) {
this.insertDC(position, DC.charToBytes(value));
return this;
}
addBoolean(value) {
this.addDC(DC.boolToBytes(value));
return this;
}
insertBoolean(position, value) {
this.insertDC(position, DC.boolToBytes(value));
return this;
}
addUint16(value, endian) {
this.addDC(DC.uint16ToBytes(value, endian));
return this;
}
insertUint16(position, value, endian) {
this.insertDC(position, DC.uint16ToBytes(value, endian));
return this;
}
addInt16(value, endian) {
this.addDC(DC.int16ToBytes(value, endian));
return this;
}
insertInt16(position, value, endian) {
this.insertDC(position, DC.int16ToBytes(value, endian));
return this;
}
addUint32(value, endian) {
this.addDC(DC.uint32ToBytes(value, endian));
return this;
}
insertUint32(position, value, endian ) {
this.insertDC(position, DC.uint32ToBytes(value, endian));
return this;
}
addInt32(value, endian) {
this.addDC(DC.int32ToBytes(value, endian));
return this;
}
insertInt32(position, value, endian) {
this.insertDC(position, DC.int32ToBytes(value, endian));
return this;
}
addUint64(value, endian) {
this.addDC(DC.uint64ToBytes(value, endian));
return this;
}
insertUint64( position, value, endian) {
this.insertDC(position, DC.uint64ToBytes(value, endian));
return this;
}
addInt64(value, endian) {
this.addDC(DC.int64ToBytes(value, endian));
return this;
}
insertInt64(position, value, endian) {
this.insertDC(position, DC.int64ToBytes(value, endian));
return this;
}
addFloat32(value, endian) {
this.addDC(DC.float32ToBytes(value, endian));
return this;
}
insertFloat32(position, value, endian ) {
this.insertDC(position, DC.float32ToBytes(value, endian));
return this;
}
addFloat64(value, endian) {
this.addDC(DC.float64ToBytes(value, endian));
return this;
}
insertFloat64(position, value, endian) {
this.insertDC(position, DC.float64ToBytes(value, endian));
return this;
}
get length()
{
return this.toArray().length;
return this.list.length;
}
toArray()
{
var ars = [];
// calculate length
for(var i = 0; i < this.list.length; i++)
{
switch (this.list[i].type)
{
case DataType.Bool:
ars.push(DC.boolToBytes(this.list[i].value));
break;
case DataType.UInt8:
ars.push(DC.uint8ToBytes(this.list[i].value));
break;
case DataType.Int8:
ars.push(DC.int8ToBytes(this.list[i].value));
break;
case DataType.Char:
ars.push(DC.charToBytes(this.list[i].value));
break;
case DataType.UInt16:
ars.push(DC.uint16ToBytes(this.list[i].value));
break;
case DataType.Int16:
ars.push(DC.int16ToBytes(this.list[i].value));
break;
case DataType.UInt32:
ars.push(DC.uint32ToBytes(this.list[i].value));
break;
case DataType.Int32:
ars.push(DC.int32ToBytes(this.list[i].value));
break;
case DataType.UInt64:
ars.push(DC.uint64ToBytes(this.list[i].value));
break;
case DataType.Int64:
ars.push(DC.int64ToBytes(this.list[i].value));
break;
case DataType.Float32:
ars.push(DC.float32ToBytes(this.list[i].value));
break;
case DataType.Float64:
ars.push(DC.float64ToBytes(this.list[i].value));
break;
case DataType.String:
ars.push(DC.stringToBytes(this.list[i].value));
break;
case DataType.DateTime:
ars.push(DC.dateTimeToBytes(this.list[i].value));
break;
case DataType.UInt8Array:
ars.push(this.list[i].value);
break;
case DataType.UInt16Array:
ars.push(DC.uint16ArrayToBytes(this.list[i].value));
break;
case DataType.UInt32Array:
ars.push(DC.uint32ArrayToBytes(this.list[i].value));
break;
case DataType.Int16Array:
ars.push(DC.int16ArrayToBytes(this.list[i].value));
break;
case DataType.Int32Array:
ars.push(DC.int32ArrayToBytes(this.list[i].value));
break;
case DataType.Float32Array:
ars.push(DC.float32ArrayToBytes(this.list[i].value));
break;
case DataType.Float64Array:
ars.push(DC.float64ArrayToBytes(this.list[i].value));
break;
//case DataType.Resource:
// ars.push(DC.uint32ToBytes(this.list[i].value.instance.id));
// break;
//case DataType.DistributedResource:
// ars.push(DC.int8ToBytes(this.list[i].value));
// break;
}
}
var length = 0;
ars.forEach(function(a){
length += a.length ;//?? a.byteLength;
});
var rt = new Uint8Array(length);
var offset = 0;
for(var i = 0; i < ars.length; i++) {
rt.set(ars[i], offset);
offset+=ars[i].length;// ?? ars[i].byteLength;
}
return rt;
return new Uint8Array(this.list);
}
toDC()
{
return new DC(this.toArray());
return new DC(this.list);
}
addDateTime(value, position)
{
return this.add({type: DataType.DateTime, value: value}, position);
}
addUint8Array(value, position)
{
return this.add({type: DataType.UInt8Array, value: value}, position);
}
addHex(value, position)
{
return this.addUint8Array(DC.hexToBytes(value), position);
}
addString(value, position)
{
return this.add({type: DataType.String, value: value}, position);
}
addUint8(value, position)
{
return this.add({type: DataType.UInt8, value: value}, position);
}
addInt8(value, position)
{
return this.add({type: DataType.Int8, value: value}, position);
}
addChar(value, position)
{
return this.add({type: DataType.Char, value: value}, position);
}
addUint16(value, position)
{
return this.add({type: DataType.UInt16, value: value}, position);
}
addInt16(value, position)
{
return this.add({type: DataType.Int16, value: value}, position);
}
addUint32(value, position)
{
return this.add({type: DataType.UInt32, value: value}, position);
}
addInt32(value, position)
{
return this.add({type: DataType.Int32, value: value}, position);
}
addUint64(value, position)
{
return this.add({type: DataType.UInt64, value: value}, position);
}
addInt64(value, position)
{
return this.add({type: DataType.Int64, value: value}, position);
}
addFloat32(value, position)
{
return this.add({type: DataType.Float32, value: value}, position);
}
addFloat64(value, position)
{
return this.add({type: DataType.Float64, value: value}, position);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,11 @@ import Guid from './Guid.js';
export const UNIX_EPOCH = 621355968000000000;
export const TWO_PWR_32 = (1 << 16) * (1 << 16);
export const Endian = {
Big: 0,
Little: 1
}
export default class DC extends Uint8Array
{
constructor(bufferOrSize) {
@ -63,6 +68,10 @@ export default class DC extends Uint8Array
return rt;
}
static fromList(list){
return new DC(list);
}
static hexToBytes(value)
{
// convert hex to Uint8Array
@ -79,73 +88,73 @@ export default class DC extends Uint8Array
return rt;
}
static charToBytes(value)
static charToBytes(value, endian)
{
var rt = new DC(2);
rt.setChar(0, value);
rt.setChar(0, value, endian);
return rt;
}
static int16ToBytes(value)
static int16ToBytes(value, endian)
{
var rt = new DC(2);
rt.setInt16(0, value);
rt.setInt16(0, value, endian);
return rt;
}
static uint16ToBytes(value)
static uint16ToBytes(value, endian)
{
var rt = new DC(2);
rt.setUint16(0, value);
rt.setUint16(0, value, endian);
return rt;
}
static int32ToBytes(value)
static int32ToBytes(value, endian)
{
var rt = new DC(4);
rt.setInt32(0, value);
rt.setInt32(0, value, endian);
return rt;
}
static uint32ToBytes(value)
static uint32ToBytes(value, endian)
{
var rt = new DC(4);
rt.setUint32(0, value);
rt.setUint32(0, value, endian);
return rt;
}
static float32ToBytes(value)
static float32ToBytes(value, endian)
{
var rt = new DC(4);
rt.setFloat32(0, value);
rt.setFloat32(0, value, endian);
return rt;
}
static int64ToBytes(value)
static int64ToBytes(value, endian)
{
var rt = new DC(8);
rt.setInt64(0, value);
rt.setInt64(0, value, endian);
return rt;
}
static uint64ToBytes(value)
static uint64ToBytes(value, endian)
{
var rt = new DC(8);
rt.setUint64(0, value);
rt.setUint64(0, value, endian);
return rt;
}
static float64ToBytes(value)
static float64ToBytes(value, endian)
{
var rt = new DC(8);
rt.setFloat64(0, value);
rt.setFloat64(0, value, endian);
return rt;
}
static dateTimeToBytes(value)
static dateTimeToBytes(value, endian)
{
var rt = new DC(8);
rt.setDateTime(0, value);
rt.setDateTime(0, value, endian);
return rt;
}
@ -172,68 +181,68 @@ export default class DC extends Uint8Array
return list.toArray();
}
static uint16ArrayToBytes(values)
static uint16ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 2);
for(var i = 0; i < values.length; i++)
rt.setUint16(i * 2, values[i]);
rt.setUint16(i * 2, values[i], endian);
return rt;
}
static int16ArrayToBytes(values)
static int16ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 2);
for(var i = 0; i < values.length; i++)
rt.setInt16(i * 2, values[i]);
rt.setInt16(i * 2, values[i], endian);
return rt;
}
static uint32ArrayToBytes(values)
static uint32ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 4);
for(var i = 0; i < values.length; i++)
rt.setUint32(i * 4, values[i]);
rt.setUint32(i * 4, values[i], endian);
return rt;
}
static int32ArrayToBytes(values)
static int32ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 4);
for(var i = 0; i < values.length; i++)
rt.setInt32(i * 4, values[i]);
rt.setInt32(i * 4, values[i], endian);
return rt;
}
static int64ArrayToBytes(values)
static int64ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 8);
for(var i = 0; i < values.length; i++)
rt.setInt64(i * 8, values[i]);
rt.setInt64(i * 8, values[i], endian);
return rt;
}
static uint64ArrayToBytes(values)
static uint64ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 8);
for(var i = 0; i < values.length; i++)
rt.setUint64(i * 8, values[i]);
rt.setUint64(i * 8, values[i], endian);
return rt;
}
static float32ArrayToBytes(values)
static float32ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 4);
for(var i = 0; i < values.length; i++)
rt.setFloat32(i * 4, values[i]);
rt.setFloat32(i * 4, values[i], endian);
return rt;
}
static float64ArrayToBytes(values)
static float64ArrayToBytes(values, endian)
{
var rt = new DC(values.length * 8);
for(var i = 0; i < values.length; i++)
rt.setFloat64(i * 8, values[i]);
rt.setFloat64(i * 8, values[i], endian);
return rt;
}
@ -280,39 +289,34 @@ export default class DC extends Uint8Array
return this[offset];// this.dv.getUint8(offset);
}
getInt16(offset)
getInt16(offset, endian)
{
return this.dv.getInt16(offset);
return this.dv.getInt16(offset, endian != Endian.Big);
}
getUint16(offset)
getUint16(offset, endian)
{
return this.dv.getUint16(offset);
return this.dv.getUint16(offset, endian != Endian.Big);
}
getInt32(offset)
getInt32(offset, endian)
{
return this.dv.getInt32(offset);
return this.dv.getInt32(offset, endian != Endian.Big);
}
getInt32Little(offset)
getUint32(offset, endian)
{
return this.dv.getInt32(offset, true);
return this.dv.getUint32(offset, endian != Endian.Big);
}
getUint32(offset)
getFloat32(offset, endian)
{
return this.dv.getUint32(offset);
return this.dv.getFloat32(offset, endian != Endian.Big);
}
getFloat32(offset)
getFloat64(offset, endian)
{
return this.dv.getFloat32(offset);
}
getFloat64(offset)
{
return this.dv.getFloat64(offset);
return this.dv.getFloat64(offset, endian != Endian.Big);
}
setInt8(offset, value)
@ -325,34 +329,34 @@ export default class DC extends Uint8Array
return this.dv.setUint8(offset, value);
}
setInt16(offset, value)
setInt16(offset, value, endian)
{
return this.dv.setInt16(offset, value);
return this.dv.setInt16(offset, value, endian != Endian.Big);
}
setUint16(offset, value)
setUint16(offset, value, endian)
{
return this.dv.setUint16(offset, value);
return this.dv.setUint16(offset, value, endian != Endian.Big);
}
setInt32(offset, value)
setInt32(offset, value, endian)
{
return this.dv.setInt32(offset, value);
return this.dv.setInt32(offset, value, endian != Endian.Big);
}
setUint32(offset, value)
setUint32(offset, value, endian)
{
return this.dv.setUint32(offset, value);
return this.dv.setUint32(offset, value, endian != Endian.Big);
}
setFloat32(offset, value)
setFloat32(offset, value, endian)
{
return this.dv.setFloat32(offset, value);
return this.dv.setFloat32(offset, value, endian != Endian.Big);
}
setFloat64(offset, value)
setFloat64(offset, value, endian)
{
return this.dv.setFloat64(offset, value);
return this.dv.setFloat64(offset, value, endian != Endian.Big);
}
getInt8Array(offset, length)
@ -365,12 +369,12 @@ export default class DC extends Uint8Array
return new Uint8Array(this.buffer, offset, length);
}
copy(offset, length, elementSize, func, dstType)
copy(offset, length, elementSize, func, dstType, endian)
{
let rt = new dstType(length / elementSize);
let d = 0, end = offset + length;
for (let i = offset; i < end; i += elementSize)
rt[d++] = func.call(this, i);
rt[d++] = func.call(this, i, endian);
return rt;
}
@ -384,55 +388,47 @@ export default class DC extends Uint8Array
}
getInt16Array(offset, length)
getInt16Array(offset, length, endian)
{
return this.copy(offset, length, 2, this.getInt16, Int16Array);
return this.copy(offset, length, 2, this.getInt16, Int16Array, endian);
//return new Int16Array(this.clip(offset, length).buffer);
}
getUint16Array(offset, length)
getUint16Array(offset, length, endian)
{
return this.copy(offset, length, 2, this.getUint16, Uint16Array);
//return new Uint16Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 2, this.getUint16, Uint16Array, endian);
}
getInt32Array(offset, length)
getInt32Array(offset, length, endian)
{
return this.copy(offset, length, 4, this.getInt32, Int32Array);
//return new Int32Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 4, this.getInt32, Int32Array, endian);
}
getUint32Array(offset, length)
getUint32Array(offset, length, endian)
{
return this.copy(offset, length, 4, this.getUint32, Uint32Array);
//return new Uint32Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 4, this.getUint32, Uint32Array, endian);
}
getFloat32Array(offset, length)
getFloat32Array(offset, length, endian)
{
return this.copy(offset, length, 4, this.getFloat32, Float32Array);
//return new Float32Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 4, this.getFloat32, Float32Array, endian);
}
getFloat64Array(offset, length)
getFloat64Array(offset, length, endian)
{
return this.copy(offset, length, 8, this.getFloat64, Float64Array);
// return new Float64Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 8, this.getFloat64, Float64Array, endian);
}
getInt64Array(offset, length)
getInt64Array(offset, length, endian)
{
return this.copy(offset, length, 8, this.getInt64, Float64Array);//BigInt64Array);
//return new Int64Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 8, this.getInt64, Float64Array, endian);
}
getUint64Array(offset, length)
getUint64Array(offset, length, endian)
{
return this.copy(offset, length, 8, this.getUint64, Float64Array);//BigUint64Array);
//return new Uint64Array(this.clip(offset, length).buffer);
return this.copy(offset, length, 8, this.getUint64, Float64Array, endian);
}
getBoolean(offset)
@ -453,21 +449,21 @@ export default class DC extends Uint8Array
return rt;
}
getChar(offset)
getChar(offset, endian)
{
return String.fromCharCode(this.getUint16(offset));
return String.fromCharCode(this.getUint16(offset, endian));
}
setChar(offset, value)
setChar(offset, value, endian)
{
this.setUint16(offset, value.charCodeAt(0));
this.setUint16(offset, value.charCodeAt(0), endian);
}
getCharArray(offset, length)
getCharArray(offset, length, endian)
{
var rt = [];
for(var i = 0; i < length; i+=2)
rt.push(this.getChar(offset+i));
rt.push(this.getChar(offset+i, endian));
return rt;
}
@ -495,14 +491,14 @@ export default class DC extends Uint8Array
}
}
getStringArray(offset, length)
getStringArray(offset, length, endian)
{
var rt = [];
var i = 0;
while (i < length)
{
var cl = this.getUint32(offset + i);
var cl = this.getUint32(offset + i, endian);
i += 4;
rt.push(this.getString(offset + i, cl));
i += cl;
@ -512,55 +508,160 @@ export default class DC extends Uint8Array
}
// @TODO: Test numbers with bit 7 of h = 1
getInt64(offset)
getInt64(offset, endian)
{
var h = this.getInt32(offset);
var l = this.getInt32(offset + 4);
if (endian == Endian.Big) {
let bi = BigInt(0);
bi |= BigInt(this[offset++]) << 56n;
bi |= BigInt(this[offset++]) << 48n;
bi |= BigInt(this[offset++]) << 40n;
bi |= BigInt(this[offset++]) << 32n;
bi |= BigInt(this[offset++]) << 24n;
bi |= BigInt(this[offset++]) << 16n;
bi |= BigInt(this[offset++]) << 8n;
bi |= BigInt(this[offset++]);
return parseInt(bi);
} else {
let bi = BigInt(0);
bi |= BigInt(this[offset++]);
bi |= BigInt(this[offset++]) << 8n;
bi |= BigInt(this[offset++]) << 16n;
bi |= BigInt(this[offset++]) << 24n;
bi |= BigInt(this[offset++]) << 32n;
bi |= BigInt(this[offset++]) << 40n;
bi |= BigInt(this[offset++]) << 48n;
bi |= BigInt(this[offset++]) << 56n;
return parseInt(bi);
}
// var h = this.getInt32(offset);
// var l = this.getInt32(offset + 4);
return h * TWO_PWR_32 + ((l >= 0) ? l : TWO_PWR_32 + l);
// return h * TWO_PWR_32 + ((l >= 0) ? l : TWO_PWR_32 + l);
}
getUint64(offset)
getUint64(offset, endian)
{
var h = this.getUint32(offset);
var l = this.getUint32(offset + 4);
return h * TWO_PWR_32 + ((l >= 0) ? l : TWO_PWR_32 + l);
if (endian == Endian.Big) {
let bi = BigInt(0);
bi |= BigInt(this[offset++]) << 56n;
bi |= BigInt(this[offset++]) << 48n;
bi |= BigInt(this[offset++]) << 40n;
bi |= BigInt(this[offset++]) << 32n;
bi |= BigInt(this[offset++]) << 24n;
bi |= BigInt(this[offset++]) << 16n;
bi |= BigInt(this[offset++]) << 8n;
bi |= BigInt(this[offset++]);
return parseInt(bi);
} else {
let bi = BigInt(0);
bi |= BigInt(this[offset++]);
bi |= BigInt(this[offset++]) << 8n;
bi |= BigInt(this[offset++]) << 16n;
bi |= BigInt(this[offset++]) << 24n;
bi |= BigInt(this[offset++]) << 32n;
bi |= BigInt(this[offset++]) << 40n;
bi |= BigInt(this[offset++]) << 48n;
bi |= BigInt(this[offset++]) << 56n;
return parseInt(bi);
}
//var h = this.getUint32(offset);
//var l = this.getUint32(offset + 4);
//return h * TWO_PWR_32 + ((l >= 0) ? l : TWO_PWR_32 + l);
}
setInt64(offset, value)
setInt64(offset, value, endian)
{
var l = (value % TWO_PWR_32) | 0;
var h = (value / TWO_PWR_32) | 0;
this.setInt32(offset, h);
this.setInt32(offset + 4, l);
var bi = BigInt(value);
var byte = BigInt(0xFF);
if (endian == Endian.Big) {
this[offset++] = parseInt((bi >> 56n) & byte);
this[offset++] = parseInt((bi >> 48n) & byte);
this[offset++] = parseInt((bi >> 40n) & byte);
this[offset++] = parseInt((bi >> 32n) & byte);
this[offset++] = parseInt((bi >> 24n) & byte);
this[offset++] = parseInt((bi >> 16n) & byte);
this[offset++] = parseInt((bi >> 8n) & byte);
this[offset++] = parseInt(bi & byte);
} else {
this[offset++] = parseInt(bi & byte);
this[offset++] = parseInt((bi >> 8n) & byte);
this[offset++] = parseInt((bi >> 16n) & byte);
this[offset++] = parseInt((bi >> 24n) & byte);
this[offset++] = parseInt((bi >> 32n) & byte);
this[offset++] = parseInt((bi >> 40n) & byte);
this[offset++] = parseInt((bi >> 48n) & byte);
this[offset++] = parseInt((bi >> 56n) & byte);
}
//var l = (value % TWO_PWR_32) | 0;
//var h = (value / TWO_PWR_32) | 0;
//this.setInt32(offset, h);
//this.setInt32(offset + 4, l);
}
setUint64(offset, value)
setUint64(offset, value, endian)
{
var l = (value % TWO_PWR_32) | 0;
var h = (value / TWO_PWR_32) | 0;
this.setInt32(offset, h);
this.setInt32(offset + 4, l);
var bi = BigInt(value);
var byte = BigInt(0xFF);
if (endian == Endian.Big) {
this[offset++] = parseInt((bi >> 56n) & byte);
this[offset++] = parseInt((bi >> 48n) & byte);
this[offset++] = parseInt((bi >> 40n) & byte);
this[offset++] = parseInt((bi >> 32n) & byte);
this[offset++] = parseInt((bi >> 24n) & byte);
this[offset++] = parseInt((bi >> 16n) & byte);
this[offset++] = parseInt((bi >> 8n) & byte);
this[offset++] = parseInt(bi & byte);
} else {
this[offset++] = parseInt(bi & byte);
this[offset++] = parseInt((bi >> 8n) & byte);
this[offset++] = parseInt((bi >> 16n) & byte);
this[offset++] = parseInt((bi >> 24n) & byte);
this[offset++] = parseInt((bi >> 32n) & byte);
this[offset++] = parseInt((bi >> 40n) & byte);
this[offset++] = parseInt((bi >> 48n) & byte);
this[offset++] = parseInt((bi >> 56n) & byte);
}
// var l = (value % TWO_PWR_32) | 0;
// var h = (value / TWO_PWR_32) | 0;
// this.setInt32(offset, h);
// this.setInt32(offset + 4, l);
}
setDateTime(offset, value)
setDateTime(offset, value, endian)
{
// Unix Epoch
var ticks = 621355968000000000 + (value.getTime() * 10000);
this.setUint64(offset, ticks);
this.setUint64(offset, ticks, endian);
}
getDateTime(offset)
getDateTime(offset, endian)
{
var ticks = this.getUint64(offset);
var ticks = this.getUint64(offset, endian);
return new Date(Math.round((ticks-UNIX_EPOCH)/10000));
}
getDateTimeArray(offset)
getDateTimeArray(offset, endian)
{
var rt = [];
for(var i = 0; i < length; i+=8)
rt.push(this.getDateTime(offset+i));
rt.push(this.getDateTime(offset+i, endian));
return rt;
}

View File

@ -0,0 +1,510 @@
import IEnum from './IEnum.js';
import Tuple from './Tuple.js';
import TemplateType from '../Resource/Template/TemplateType.js';
import Warehouse from '../Resource/Warehouse.js';
import AsyncBag from '../Core/AsyncBag.js';
import AsyncReply from '../Core/AsyncReply.js';
import DC from './DC.js';
import DistributedConnection from '../Net/IIP/DistributedConnection.js';
import NotModified from './NotModified.js';
import RepresentationType from './RepresentationType.js';
import Codec from './Codec.js';
import TypedMap from './TypedMap.js';
import PropertyValueArray from './PropertyValueArray.js';
import PropertyValue from './PropertyValue.js';
import Record from './Record.js';
export class PropertyValueParserResults {
//final int size;
///final AsyncReply<PropertyValue> reply;
constructor(size, reply){
this.size = size;
this.reply = reply;
}
}
export default class DataDeserializer {
static nullParser(data, offset, length, connection) {
return new AsyncReply(null);
}
static booleanTrueParser(
data, offset, length, connection) {
return new AsyncReply(true);
}
static booleanFalseParser(
data, offset, length, connection) {
return new AsyncReply(false);
}
static notModifiedParser(
data, offset, length, connection) {
return new AsyncReply(NotModified());
}
static byteParser(
data, offset, length, connection) {
return new AsyncReply(data[offset]);
}
static sByteParser(
data, offset, length, connection) {
return new AsyncReply(
data[offset] > 127 ? data[offset] - 256 : data[offset]);
}
static char16Parser(
data, offset, length, connection) {
return new AsyncReply(data.getChar(offset));
}
static char8Parser(
data, offset, length, connection) {
return new AsyncReply(String.fromCharCode(data[offset]));
}
static int16Parser(
data, offset, length, connection) {
return new AsyncReply(data.getInt16(offset));
}
static uInt16Parser(
data, offset, length, connection) {
return new AsyncReply(data.getUint16(offset));
}
static int32Parser(
data, offset, length, connection) {
return new AsyncReply(data.getInt32(offset));
}
static uInt32Parser(
data, offset, length, connection) {
return new AsyncReply(data.getUint32(offset));
}
static float32Parser(
data, offset, length, connection) {
return new AsyncReply(data.getFloat32(offset));
}
static float64Parser(
data, offset, length, connection) {
return new AsyncReply(data.getFloat64(offset));
}
static float128Parser(
data, offset, length, connection) {
// @TODO
return new AsyncReply(data.getFloat64(offset));
}
static int128Parser(
data, offset, length, connection) {
// @TODO
return new AsyncReply(data.getInt64(offset));
}
static uInt128Parser(
data, offset, length, connection) {
return new AsyncReply(data.getUint64(offset));
}
static int64Parser(
data, offset, length, connection) {
return new AsyncReply(data.getInt64(offset));
}
static uInt64Parser(
data, offset, length, connection) {
return new AsyncReply(data.getUint64(offset));
}
static dateTimeParser(
data, offset, length, connection) {
return new AsyncReply(data.getDateTime(offset));
}
static resourceParser(
data, offset, length, connection) {
if (connection != null) {
var id = data.getUint32(offset);
return connection.fetch(id);
}
throw Error("Can't parse resource with no connection");
}
static localResourceParser(
data, offset, length, connection) {
var id = data.getUint32(offset);
return Warehouse.getById(id);
}
static rawDataParser(
data, offset, length, connection) {
return new AsyncReply(data.clip(offset, length));
}
static stringParser(
data, offset, length, connection) {
return new AsyncReply(data.getString(offset, length));
}
static recordParser(
data, offset, length, connection) {
var reply = new AsyncReply();
var classId = data.getGuid(offset);
offset += 16;
length -= 16;
var template = Warehouse.getTemplateByClassId(classId, TemplateType.Record);
if (template != null) {
listParser(data, offset, length, connection).then((ar) => {
let record;
if (template.definedType != null) {
record = Warehouse.createInstance(template.definedType);
} else {
record = Record();
}
var kv = new Map();
for (var i = 0; i < template.properties.length; i++)
kv[template.properties[i].name] = ar[i];
record.deserialize(kv);
reply.trigger(record);
});
} else {
if (connection == null)
throw Error("Can't parse record with no connection");
connection.getTemplate(classId).then((tmp) => {
if (tmp == null)
reply.triggerError(new Error("Couldn't fetch record template."));
DataDeserializer.listParser(data, offset, length, connection).then((ar) => {
var record = new Record();
//var kv = new Map();
for (var i = 0; i < tmp.properties.length; i++)
record[tmp.properties[i].name] = ar[i];
//record.deserialize(kv);
reply.trigger(record);
});
}).error((x) => reply.triggerError(x));
}
return reply;
}
static constantParser(
data, offset, length, connection) {
throw Error("NotImplementedException");
}
static enumParser(data, offset, length, connection) {
var classId = data.getGuid(offset);
offset += 16;
var index = data[offset++];
var template = Warehouse.getTemplateByClassId(classId, TemplateType.Enum);
if (template != null) {
if (template.definedType != null) {
var enumVal = Warehouse.createInstance(template.definedType);
enumVal.index = index;
enumVal.name = template.constants[index].name;
enumVal.value = template.constants[index].value;
return new AsyncReply.ready(enumVal);
} else {
return AsyncReply.ready(IEnum(index, template.constants[index].value,
template.constants[index].name));
}
} else {
var reply = new AsyncReply();
if (connection == null)
throw Error("Can't parse enum with no connection");
connection.getTemplate(classId).then((tmp) => {
if (tmp != null) {
if (tmp.definedType != null) {
var enumVal = Warehouse.createInstance(tmp.definedType);
enumVal.index = index;
enumVal.name = tmp.constants[index].name;
enumVal.value = tmp.constants[index].value;
reply.trigger(enumVal);
} else {
reply.trigger(new IEnum(
index, tmp.constants[index].value, tmp.constants[index].name));
}
} else
reply.triggerError(new Error("Template not found for enum"));
}).error((x) => reply.triggerError(x));
return reply;
}
}
static recordListParser(
data, offset, length, connection) {
var rt = new AsyncBag();
while (length > 0) {
var parsed = Codec.parse(data, offset, connection);
rt.add(parsed.reply);
if (parsed.size > 0) {
offset += parsed.size;
length -= parsed.size;
} else
throw new Error("Error while parsing structured data");
}
rt.seal();
return rt;
}
static resourceListParser(
data, offset, length, connection) {
var rt = new AsyncBag();
while (length > 0) {
var parsed = Codec.parse(data, offset, connection);
rt.add(parsed.reply);
if (parsed.size > 0) {
offset += parsed.size;
length -= parsed.size;
} else
throw new Error("Error while parsing structured data");
}
rt.seal();
return rt;
}
static listParser(
data, offset, length, connection) {
var rt = new AsyncBag();
while (length > 0) {
var parsed = Codec.parse(data, offset, connection);
rt.add(parsed.reply);
if (parsed.size > 0) {
offset += parsed.size;
length -= parsed.size;
} else
throw new Error("Error while parsing structured data");
}
rt.seal();
return rt;
}
static typedMapParser(
data, offset, length, connection) {
// get key type
var keyRep = RepresentationType.parse(data, offset);
offset += keyRep.size;
length -= keyRep.size;
var valueRep = RepresentationType.parse(data, offset);
offset += valueRep.size;
length -= valueRep.size;
var map = new TypedMap();
var rt = new AsyncReply();
var results = new AsyncBag();
while (length > 0) {
var parsed = Codec.parse(data, offset, connection);
results.add(parsed.reply);
if (parsed.size > 0) {
offset += parsed.size;
length -= parsed.size;
} else
throw new Error("Error while parsing structured data");
}
results.seal();
results.then((ar) => {
for (var i = 0; i < ar.length; i += 2)
map.set(ar[i], ar[i + 1]);
rt.trigger(map);
});
return rt;
}
static tupleParser(
data, offset, length, connection) {
var results = new AsyncBag();
var rt = new AsyncReply();
var tupleSize = data[offset++];
length--;
var types = [];
for (var i = 0; i < tupleSize; i++) {
var rep = RepresentationType.parse(data, offset);
if (rep.type != null)
types.push(rep.type.getRuntimeType() ?? Object);
offset += rep.size;
length -= rep.size;
}
while (length > 0) {
var parsed = Codec.parse(data, offset, connection);
results.add(parsed.reply);
if (parsed.size > 0) {
offset += parsed.size;
length -= parsed.size;
} else
throw new Error("Error while parsing structured data");
}
results.seal();
results.then((ar) => {
rt.trigger(new (Tuple.of(...types))(...ar));
});
return rt;
}
static typedListParser(
data, offset, length, connection) {
var rt = new AsyncBag();
// get the type
var rep = RepresentationType.parse(data, offset);
offset += rep.size;
length -= rep.size;
var runtimeType = rep.type.getRuntimeType();
rt.arrayType = runtimeType;
while (length > 0) {
var parsed = Codec.parse(data, offset, connection);
rt.add(parsed.reply);
if (parsed.size > 0) {
offset += parsed.size;
length -= parsed.size;
} else
throw new Error("Error while parsing structured data");
}
rt.seal();
return rt;
}
static PropertyValueArrayParser(
data,
offset,
length,
connection) //, bool ageIncluded = true)
{
var rt = new AsyncBag();
DataDeserializer.listParser(data, offset, length, connection).then((x) => {
var pvs = new PropertyValueArray();
for (var i = 0; i < x.length; i += 3)
pvs.push(new PropertyValue(x[2], x[0], x[1]));
rt.trigger(pvs);
});
return rt;
}
static propertyValueParser(data, offset,
connection) //, bool ageIncluded = true)
{
let reply = new AsyncReply();
let age = data.getUint64(offset);
offset += 8;
let date = data.getDateTime(offset);
offset += 8;
let parsed = Codec.parse(data, offset, connection);
parsed.reply.then((value) => {
reply.trigger(new PropertyValue(value, age, date));
});
return new PropertyValueParserResults(16 + parsed.size, reply);
}
static
historyParser(data, offset, length, resource,
connection) {
throw new Error("Not implemented");
// @TODO
// var list = new KeyList<PropertyTemplate, List<PropertyValue>>();
// var reply = new AsyncReply<KeyList<PropertyTemplate, List<PropertyValue[]>>>();
// var bagOfBags = new AsyncBag<PropertyValue[]>();
// var ends = offset + length;
// while (offset < ends)
// {
// var index = data[offset++];
// var pt = resource.Instance.Template.GetPropertyTemplateByIndex(index);
// list.Add(pt, null);
// var cs = data.GetUInt32(offset);
// offset += 4;
// var (len, pv) = PropertyValueParser(data, offset, connection);
// bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
// offset += len;
// }
// bagOfBags.Seal();
// bagOfBags.Then(x =>
// {
// for (var i = 0; i < list.Count; i++)
// list[list.Keys.ElementAt(i)] = x[i];
// reply.Trigger(list);
// });
// return reply;
}
}

418
src/Data/DataSerializer.js Normal file
View File

@ -0,0 +1,418 @@
import BinaryList from './BinaryList.js';
import Codec from './Codec.js';
//import IRecord from './IRecord.js';
//import DistributedResource from '../Net/IIP/DistributedResource.js';
//import IResource from '../Resource/IResource.js';
import Warehouse from '../Resource/Warehouse.js';
//import PropertyTemplate from '../Resource/Template/PropertyTemplate.js';
//import PropertyValue from './PropertyValue.js';
import { TransmissionTypeIdentifier} from './TransmissionType.js';
//import DistributedConnection from '../Net/IIP/DistributedConnection.js';
import DC, { BL } from './DC.js';
import RepresentationType from './RepresentationType.js';
import Tuple from './Tuple.js';
export class DataSerializerComposeResults {
// int identifier;
//DC data;
constructor(identifier, data){
this.identifier = identifier;
this.data = data;
}
}
export default class DataSerializer {
//public delegate byte[] Serializer(object value);
static historyComposer(history, connection, prependLength = false) {
throw new Error("Not implemented");
}
static int32Composer(
value, connection) {
var rt = new DC(4);
rt.setInt32(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Int32, rt);
}
static uInt32Composer(
value, connection) {
var rt = new DC(4);
rt.setUint32(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.UInt32, rt);
}
static int16Composer(
value, connection) {
var rt = new DC(2);
rt.setInt16(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Int16, rt);
}
static uInt16Composer(
value, connection) {
var rt = new DC(2);
rt.setUint16(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.UInt16, rt);
}
static float32Composer(
value, connection) {
var rt = new DC(4);
rt.setFloat32(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Float32, rt);
}
static float64Composer(value, connection) {
var rt = new DC(8);
rt.setFloat64(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Float64, rt);
}
static int64Composer(
value, connection) {
var rt = new DC(8);
rt.setInt64(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Int64, rt);
}
static numberComposer(value, connection) {
var rt = new DC(8);
if (Number.isInteger(value)){
rt.setInt64(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Int64, rt);
}
else {
rt.setFloat64(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Float64, rt);
}
}
static uInt64Composer(
value, connection) {
var rt = new DC(8);
rt.setUint64(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.UInt64, rt);
}
static dateTimeComposer(
value, connection) {
var rt = new DC(8);
rt.setDateTime(0, value);
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.DateTime, rt);
}
static float128Composer(
value, connection) {
//@TODO: implement decimal
var rt = new DC(16);
rt.setFloat64(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Float64, rt);
}
static stringComposer(
value, connection) {
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.String, DC.stringToBytes(value));
}
static enumComposer(
value, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var template = Warehouse.getTemplateByType(value.runtimeType);
if (template == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var cts = template.constants.where((x) => x.value == value);
if (cts.isEmpty)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var rt = BinaryList();
rt.addGuid(template.classId);
rt.addUint8(cts.first.index);
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Enum, rt.toDC());
}
static uInt8Composer(
value, connection) {
var rt = new DC(1);
rt[0] = value;
return new DataSerializerComposeResults(TransmissionTypeIdentifier.UInt8, rt);
}
static int8Composer(
value, connection) {
var rt = new DC(1);
rt[0] = value;
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Int8, rt);
}
static char8Composer(
value, connection) {
var rt = new DC(1);
rt[0] = value;
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Char8, rt);
}
static char16Composer(
value, connection) {
var rt = new DC(2);
rt.setUint16(0, value);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Char16, rt);
}
static boolComposer(
value, connection) {
return new DataSerializerComposeResults(
value
? TransmissionTypeIdentifier.True
: TransmissionTypeIdentifier.False,
new DC(0));
}
static notModifiedComposer(
value, connection) {
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.NotModified, new DC(0));
}
static rawDataComposer(
value, connection) {
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.RawData, value);
}
static listComposer(
value, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
else
return new DataSerializerComposeResults(TransmissionTypeIdentifier.List,
DataSerializer.arrayComposer(value , connection));
//var rt = new List<byte>();
//var list = (IEnumerable)value;// ((List<object>)value);
//foreach (var o in list)
// rt.AddRange(Codec.Compose(o, connection));
//return (TransmissionTypeIdentifier.List, rt.ToArray());
}
static typedListComposer(
value, type, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var composed = DataSerializer.arrayComposer(value, connection);
var header =
(RepresentationType.fromType(type) ?? RepresentationType.Dynamic)
.compose();
var rt = new BinaryList()
.addDC(header)
.addDC(composed);
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.TypedList, rt.toDC());
}
static propertyValueArrayComposer(
value, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var rt = BL();
for (var i = 0; i < value.length; i ++){
rt.addDC(Codec.compose(value[i].age, connection));
rt.addDC(Codec.compose(value[i].date, connection));
rt.addDC(Codec.compose(value[i].value, connection));
}
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.List, rt.toDC());
}
static typedMapComposer(
value, keyType, valueType, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var kt =
(RepresentationType.fromType(keyType) ?? RepresentationType.Dynamic)
.compose();
var vt =
(RepresentationType.fromType(valueType) ?? RepresentationType.Dynamic)
.compose();
var rt = new BinaryList();
rt.addDC(kt);
rt.addDC(vt);
//@TODO
for(let [k, v] of value)
{
rt.addDC(Codec.compose(k, connection));
rt.addDC(Codec.compose(v, connection));
}
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.TypedMap, rt.toDC());
}
static arrayComposer(value, connection) {
var rt = new BinaryList();
for (var i of value)
rt.addDC(Codec.compose(i, connection));
return rt.toDC();
}
static resourceListComposer(
value, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
return new DataSerializerComposeResults(TransmissionTypeIdentifier.ResourceList,
DataSerializer.arrayComposer(value, connection));
}
static recordListComposer(
value, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
return new DataSerializerComposeResults(TransmissionTypeIdentifier.RecordList,
DataSerializer.arrayComposer(value, connection));
}
static resourceComposer(
value, connection) {
var resource = value;
var rt = new DC(4);
if (Codec.isLocalResource(resource, connection)) {
rt.setUint32(0, resource.id ?? 0);
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.ResourceLocal, rt);
} else {
// @TODO: connection.cache.Add(value as IResource, DateTime.UtcNow);
rt.setUint32(0, resource.instance?.id ?? 0);
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Resource, rt);
}
}
static mapComposer(
value, connection) {
if (value == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
var rt = BinaryList();
for (var el in value) {
rt.addDC(Codec.compose(el.key, connection));
rt.addDC(Codec.compose(el.value, connection));
}
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Map, rt.toDC());
}
static recordComposer(
value, connection) {
var rt = BinaryList();
var template = Warehouse.getTemplateByType(value.runtimeType);
if (template == null)
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Null, new DC(0));
rt.addDC(DC.guidToBytes(template.classId));
var recordData = value.serialize();
for (var pt in template.properties) {
var propValue = recordData[pt.name];
rt.addDC(Codec.compose(propValue, connection));
}
return new DataSerializerComposeResults(
TransmissionTypeIdentifier.Record, rt.toDC());
}
// TODO:
// static DataSerializerComposeResults historyComposer(KeyList<PropertyTemplate, PropertyValue[]> history,
// DistributedConnection connection, bool prependLength = false)
// {
// //@TODO:Test
// var rt = new BinaryList();
// for (var i = 0; i < history.Count; i++)
// rt.AddUInt8(history.Keys.ElementAt(i).Index)
// .AddUInt8Array(Codec.Compose(history.Values.ElementAt(i), connection));
// if (prependLength)
// rt.InsertInt32(0, rt.Length);
// return rt.ToArray();
// }
static tupleComposer(value, connection) {
if (value == null)
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Null, new DC(0));
var rt = BL();
var fields = Tuple.getTypes(value);
var types = fields.map(x => RepresentationType.fromType(x).compose());
rt.Add(value.length);
for (var t of types)
rt.addUint8Array(t);
var composed = DataSerializer.arrayComposer(value, connection);
if (composed == null)
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Null, new DC(0));
else
{
rt.addUint8Array(composed);
return new DataSerializerComposeResults(TransmissionTypeIdentifier.Tuple, rt.toArray());
}
}
}

28
src/Data/ExtendedTypes.js Normal file
View File

@ -0,0 +1,28 @@
class Num extends Number {
toString() { return super.toString()}
constructor(value) {
super(value);
}
}
export class Int128 extends Num {}
export class Int64 extends Num { }
export class Int32 extends Num { }
export class Int16 extends Num { }
export class Int8 extends Num { }
export class UInt128 extends Num {}
export class UInt64 extends Num { }
export class UInt32 extends Num { }
export class UInt16 extends Num { }
export class UInt8 extends Num { }
export class Float32 extends Num{}
export class Float64 extends Num{}
export class Float128 extends Num{}
export class Char16 extends String {}
export class Char8 extends String {}

View File

@ -24,8 +24,8 @@
* Created by Ahmed Zamil on 02/09/2017.
*/
"use strict";
import DC from './DC.js';
export default class Guid
{
constructor(dc)
@ -38,6 +38,14 @@ export default class Guid
return this.value.getHex(0, 16);
}
static fromString(data) {
this.value = DC.fromHex(data, '');
}
toString() {
return this.vlue.toHex('');
}
// [Symbol.toPrimitive](hint){
// console.log(hint);
// }

18
src/Data/IEnum.js Normal file
View File

@ -0,0 +1,18 @@
//import TemplateDescriber from '../Resource/Template/TemplateDescriber.js';
export default class IEnum {
IEnum(index, value, name){
this.index = index;
this.value = value;
this.name = name;
}
get template () {
//return new TemplateDescriber("IEnum");
}
toString() {
return `${this.name}<${this.value}>`;
}
}

View File

@ -1,3 +1,6 @@
export default class IRecord {
toString() {
//return serialize().toString();
}
}

7
src/Data/ParseResult.js Normal file
View File

@ -0,0 +1,7 @@
export default class ParseResult {
constructor (size, value){
this.size = size;
this.value = value;
}
}

View File

@ -0,0 +1,3 @@
export default class PropertyValueArray extends Array {
}

View File

@ -28,5 +28,5 @@ import IRecord from './IRecord.js';
export default class Record extends IRecord
{
}

40
src/Data/RecordArray.js Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017-2022 Ahmed Kh. Zamil
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* Created by Ahmed Zamil on 26/08/2017.
*/
"use strict";
import IRecord from "./IRecord.js";
export default class RecordArray extends Array
{
push(value)
{
if (value instanceof IRecord)
super.push(value);
else
return;
}
}

View File

@ -0,0 +1,197 @@
import TemplateType from '../Resource/Template/TemplateType.js';
import IRecord from './IRecord.js';
import IResource from '../Resource/IResource.js';
import BinaryList from './BinaryList.js';
import DC from './DC.js';
import Warehouse from '../Resource/Warehouse.js';
import {Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128, Char8, Char16, Float32, Float64, Float128} from './ExtendedTypes.js';
export const RepresentationTypeIdentifier = {
Void: 0x0,
Dynamic : 0x1,
Bool : 0x2,
UInt8 : 0x3,
Int8 : 0x4,
Char : 0x5,
Int16 : 0x6,
UInt16 : 0x7,
Int32 : 0x8,
UInt32 : 0x9,
Float32 : 0xA,
Int64 : 0xB,
UInt64 : 0xC,
Float64 : 0xD,
DateTime : 0xE,
Int128 : 0xF,
UInt128 : 0x10,
Decimal : 0x11,
String : 0x12,
RawData : 0x13,
Resource : 0x14,
Record : 0x15,
List : 0x16,
Map : 0x17,
Enum : 0x18,
TypedResource : 0x45, // Followed by UUID
TypedRecord : 0x46, // Followed by UUID
TypedList : 0x48, // Followed by element type
Tuple2 : 0x50, // Followed by element type
TypedMap : 0x51, // Followed by key type and value type
Tuple3 : 0x58,
Tuple4 : 0x60,
Tuple5 : 0x68,
Tuple6 : 0x70,
Tuple7 : 0x78
}
let RuntimeTypes = {};
RuntimeTypes[RepresentationTypeIdentifier.Void] = [Object, Object];
RuntimeTypes[RepresentationTypeIdentifier.Bool] = [Boolean, Object];
RuntimeTypes[RepresentationTypeIdentifier.Char] = [Char8, Object];
RuntimeTypes[RepresentationTypeIdentifier.Char16] = [Char16, Object];
RuntimeTypes[RepresentationTypeIdentifier.UInt8] = [UInt8, UInt8];
RuntimeTypes[RepresentationTypeIdentifier.Int8] = [Int8, Object];
RuntimeTypes[RepresentationTypeIdentifier.Int16] = [Int16, Object];
RuntimeTypes[RepresentationTypeIdentifier.UInt16] = [UInt16, Object];
RuntimeTypes[RepresentationTypeIdentifier.Int32] = [Int32, Object];
RuntimeTypes[RepresentationTypeIdentifier.UInt32] = [UInt32, Object];
RuntimeTypes[RepresentationTypeIdentifier.Int64] = [Int64, Object];
RuntimeTypes[RepresentationTypeIdentifier.UInt64] = [UInt64, Object];
RuntimeTypes[RepresentationTypeIdentifier.Int128] = [Int128, Object];
RuntimeTypes[RepresentationTypeIdentifier.UInt128] = [UInt128, Object];
RuntimeTypes[RepresentationTypeIdentifier.Float32] = [Float32, Object];
RuntimeTypes[RepresentationTypeIdentifier.Float64] = [Float64, Object];
RuntimeTypes[RepresentationTypeIdentifier.Decimal] = [Float128, Object];
RuntimeTypes[RepresentationTypeIdentifier.String] = [String, Object];
RuntimeTypes[RepresentationTypeIdentifier.DateTime] = [Date, Object];
RuntimeTypes[RepresentationTypeIdentifier.Resource] = [IResource, IResource];
RuntimeTypes[RepresentationTypeIdentifier.Record] = [IRecord, IRecord];
export class RepresentationTypeParseResults {
//RepresentationType type;
//int size;
constructor(size, type){
this.size= size;
this.type = type;
}
}
export default class RepresentationType {
// static getTypeFromName(name) {
// const types = {
// "int": int,
// "bool": bool,
// "double": double,
// "String": String,
// "IResource": IResource,
// "IRecord": IRecord,
// "IEnum": IEnum,
// "DC": DC,
// };
// if (types[name] != null) {
// return types[name];
// } else
// return Object().runtimeType;
// }
toNullable() {
return new RepresentationType(this.identifier, true, this.guid, this.subTypes);
}
static get Void () { return new RepresentationType(RepresentationTypeIdentifier.Void, true, null, null);}
static get Dynamic() { return new RepresentationType(RepresentationTypeIdentifier.Dynamic, true, null, null);}
static fromType(type) {
return Warehouse.typesFactory[type]?.representationType;
}
getRuntimeType() {
if (RuntimeTypes[this.identifier])
return this.nullable
? RuntimeTypes[this.identifier][1]
: RuntimeTypes[this.identifier][0];
if (this.identifier == RepresentationTypeIdentifier.TypedRecord)
return Warehouse.getTemplateByClassId(this.guid, TemplateType.Record)
?.definedType;
else if (this.identifier == RepresentationTypeIdentifier.TypedResource)
return Warehouse.getTemplateByClassId(this.guid, TemplateType.Unspecified)
?.definedType;
else if (this.identifier == RepresentationTypeIdentifier.Enum)
return Warehouse.getTemplateByClassId(this.guid, TemplateType.Enum)
?.definedType;
return null;
}
constructor(identifier, nullable, guid, subTypes) {
this.identifier = identifier;
this.nullable = nullable;
this.guid = guid;
this.subTypes = subTypes;
}
compose() {
var rt = new BinaryList();
if (this.nullable)
rt.addUint8(0x80 | this.identifier);
else
rt.addUint8(this.identifier);
if (this.guid != null) rt.addDC(DC.guidToBytes(this.guid));
if (this.subTypes != null)
for (var i = 0; i < this.subTypes.length; i++)
rt.addDC(this.subTypes[i].compose());
return rt.toDC();
}
//public override string ToString() => Identifier.ToString() + (Nullable ? "?" : "")
// + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
static parse(data, offset) {
let oOffset = offset;
let header = data[offset++];
let nullable = (header & 0x80) > 0;
let identifier = (header & 0x7F);
if ((header & 0x40) > 0) {
let hasGUID = (header & 0x4) > 0;
let subsCount = (header >> 3) & 0x7;
let guid = null;
if (hasGUID) {
guid = data.getGuid(offset);
offset += 16;
}
let subs = [];
for (let i = 0; i < subsCount; i++) {
let parsed = RepresentationType.parse(data, offset);
subs.push(parsed.type);
offset += parsed.size;
}
return new RepresentationTypeParseResults(offset - oOffset,
new RepresentationType(identifier, nullable, guid, subs));
} else {
return new RepresentationTypeParseResults(
1, new RepresentationType(identifier, nullable, null, null));
}
}
}
export {RepresentationType};

View File

@ -26,6 +26,7 @@
"use strict";
import IResource from "../Resource/IResource.js";
export default class ResourceArray extends Array
{
push(value)

View File

@ -0,0 +1,196 @@
import DC from './DC.js';
export const TransmissionTypeIdentifier = {
Null : 0x0,
False : 0x1,
True : 0x2,
NotModified : 0x3,
UInt8 : 0x8,
Int8 : 0x9,
Char8 : 0xA,
Int16 : 0x10,
UInt16 : 0x11,
Char16 : 0x12,
Int32 : 0x18,
UInt32 : 0x19,
Float32 : 0x1A,
Resource : 0x1B,
ResourceLocal : 0x1C,
Int64 : 0x20,
UInt64 : 0x21,
Float64 : 0x22,
DateTime : 0x23,
Int128 : 0x28,
UInt128 : 0x29,
Float128 : 0x2A,
RawData : 0x40,
String : 0x41,
List : 0x42,
ResourceList : 0x43,
RecordList : 0x44,
Map : 0x45,
MapList : 0x46,
//Tuple = 0x47,
Record : 0x80,
TypedList : 0x81,
TypedMap : 0x82,
Tuple : 0x83,
Enum : 0x84,
Constant : 0x85
};
export let TransmissionTypeClass = {
Fixed : 0,
Dynamic : 1,
Typed : 2
}
export class TransmissionTypeParseResults {
constructor(size, type) {
this.size = size;
this.type = type;
}
}
export default class TransmissionType {
// final int identifier;
// final int index;
// final int classType;
// final int offset;
// final int contentLength;
// final int exponent;
static get Null() { return new
TransmissionType(TransmissionTypeIdentifier.Null, 0, 0, 0, 0);}
constructor(identifier, classType, index, offset, contentLength, exponent = 0){
this.identifier = identifier;
this.classType = classType;
this.index = index;
this.offset = offset;
this.contentLength = contentLength;
this.exponent = exponent;
}
static compose(identifier, data) {
if (data.length == 0) return DC.fromList([identifier]);
var cls = identifier >> 6;
if (cls == TransmissionTypeClass.Fixed) {
return DC.combine([identifier], 0, 1, data, 0, data.length);
} else {
var len = data.length;
if (len == 0) {
return DC.fromList([identifier]);
} else if (len <= 0xFF) {
let rt = new DC(2 + len);
rt[0] = identifier | 0x8;
rt[1] = len;
rt.set(data, 2);
return rt;
} else if (len <= 0xFFFF) {
let rt = new DC(3 + len);
rt[0] = identifier | 0x10;
rt[1] = (len >> 8) & 0xFF;
rt[2] = len & 0xFF;
rt.set(data, 3);
return rt;
} else if (len <= 0xFFFFFF) {
let rt = new DC(4 + len);
rt[0] = identifier | 0x18;
rt[1] = (len >> 16) & 0xFF;
rt[2] = (len >> 8) & 0xFF;
rt[3] = len & 0xFF;
rt.set(data, 4);
return rt;
} else if (len <= 0xFFFFFFFF) {
let rt = new DC(5 + len);
rt[0] = (identifier | 0x20);
rt[1] = ((len >> 24) & 0xFF);
rt[2] = ((len >> 16) & 0xFF);
rt[3] = ((len >> 8) & 0xFF);
rt[4] = (len & 0xFF);
rt.set(data, 5);
return rt;
} else if (len <= 0xFFFFFFFFFF) {
let rt = new DC(6 + len);
rt[0] = identifier | 0x28;
rt[1] = ((len >> 32) & 0xFF);
rt[2] = ((len >> 24) & 0xFF);
rt[3] = ((len >> 16) & 0xFF);
rt[4] = ((len >> 8) & 0xFF);
rt[5] = (len & 0xFF);
rt.set(data, 6);
return rt;
} else if (len <= 0xFFFFFFFFFFFF) {
let rt = new DC(7 + len);
rt[0] = identifier | 0x30;
rt[1] = (len >> 40) & 0xFF;
rt[2] = (len >> 32) & 0xFF;
rt[3] = (len >> 24) & 0xFF;
rt[4] = (len >> 16) & 0xFF;
rt[5] = (len >> 8) & 0xFF;
rt[6] = len & 0xFF;
rt.set(data, 7);
return rt;
} else //if (len <= 0xFF_FF_FF_FF_FF_FF_FF)
{
let rt = new DC(8 + len);
rt[0] = identifier | 0x38;
rt[1] = (len >> 48) & 0xFF;
rt[2] = (len >> 40) & 0xFF;
rt[3] = (len >> 32) & 0xFF;
rt[4] = (len >> 24) & 0xFF;
rt[5] = (len >> 16) & 0xFF;
rt[6] = (len >> 8) & 0xFF;
rt[7] = len & 0xFF;
data.set(data, 8);
return rt;
}
}
}
static parse(data, offset, ends) {
var h = data[offset++];
var cls = h >> 6;
if (cls == TransmissionTypeClass.Fixed) {
var exp = (h & 0x38) >> 3;
if (exp == 0)
return new TransmissionTypeParseResults(
1, new TransmissionType(h, cls, h & 0x7, 0, exp));
let cl = (1 << (exp - 1));
if (ends - offset < cl)
return new TransmissionTypeParseResults(ends - offset - cl, null);
return new TransmissionTypeParseResults(
1 + cl, new TransmissionType(h, cls, h & 0x7, offset, cl, exp));
} else {
let cll = (h >> 3) & 0x7;
if (ends - offset < cll)
return new TransmissionTypeParseResults(ends - offset - cll, null);
let cl = 0;
for (var i = 0; i < cll; i++) cl = cl << 8 | data[offset++];
return new TransmissionTypeParseResults(
1 + cl + cll, new TransmissionType((h & 0xC7), cls, h & 0x7, offset, cl));
}
}
}
export {TransmissionType}

26
src/Data/Tuple.js Normal file
View File

@ -0,0 +1,26 @@
export default class Tuple extends Array {
static cache = {};
static getTypes(tuple){
return tuple.constructor.types;
}
static of(){
let types = [];
for(let i =0 ; i < arguments.length; i++){
types.push(arguments[i]);
}
if (Tuple.cache[types] != null)
return Tuple.cache[types];
let c = class extends Tuple{}
Object.defineProperty(c, "name", {value: types.map(x => x.name).join('') + "Tuple"});
Object.defineProperty(c, "types", {value: types});
Tuple.cache[types] = c;
return c;
}
}

36
src/Data/TypedList.js Normal file
View File

@ -0,0 +1,36 @@
import IResource from "../Resource/IResource.js";
import PropertyValue from "./PropertyValue.js";
import PropertyValueArray from "./PropertyValueArray.js";
import ResourceArray from "./ResourceArray.js";
export default class TypedList extends Array
{
// constructor(data)
// {
// if (data != undefined && data instanceof Array)
// for(var i = 0; i < data.length; i++)
// this.push(data[i]);
// }
static cache = { [IResource] : ResourceArray,
[PropertyValue] : PropertyValueArray
};
static getType(typedList){
return typedList.constructor.type;
}
static of(type){
if (TypedList.cache[type] != null)
return TypedList.cache[type];
let c = class extends TypedList{}
Object.defineProperty(c, "name", {value: type.name + "List"});
Object.defineProperty(c, "type", {value: type});
TypedList.cache[type] = c;
return c;
}
}

43
src/Data/TypedMap.js Normal file
View File

@ -0,0 +1,43 @@
export default class TypedMap extends Map {
constructor(data)
{
super();
if (data instanceof Object)
for(var i in data)
this.set(i, data[i]);
}
static getTypes(typedMap){
return [typedMap.constructor.keyType ?? Object, typedMap.constructor.valueType ?? Object];
}
static cache = {};
static of(keyType, valueType){
if (TypedMap.cache[[keyType, valueType]] != null)
return TypedMap.cache[[keyType, valueType]];
//if (TypedMap.cache[keyType] != null)
// if (TypedMap.cache[keyType][valueType] != null)
// return TypedMap.cache[keyType][valueType];
let c = class extends TypedMap{}
Object.defineProperty(c, "name", {value: keyType.name + valueType.name + "Map"});
Object.defineProperty(c, "keyType", {value: keyType});
Object.defineProperty(c, "valueType", {value: valueType});
//if (TypedMap.cache[keyType] == null)
// TypedMap.cache[keyType] = {[valueType]: c};
//else
// TypedMap.cache[keyType][valueType] = c;
TypedMap.cache[[keyType, valueType]] = c;
return c;
}
}