redesign type-handler
This commit is contained in:
parent
d1520baa61
commit
023e8e34f9
@ -1,455 +1,773 @@
|
||||
import { VirtualMethodNotImplementedError } from '@og/error-utils';
|
||||
import { UUID } from '@og/uuid';
|
||||
|
||||
/**
|
||||
* Represents the result of deserialization.
|
||||
* @class
|
||||
*/
|
||||
export class DeserializedResult {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {any} value - The deserialized value.
|
||||
* @param {number} offset - The offset after deserialization.
|
||||
*/
|
||||
constructor(value, offset) {
|
||||
this.value = value;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for handling basic data types.
|
||||
* @abstract
|
||||
* @class
|
||||
*/
|
||||
export class BasicTypeHandler {
|
||||
/**
|
||||
* Gets the size of the serialized value in bytes.
|
||||
* @abstract
|
||||
* @param {any} value - The value to be serialized.
|
||||
* @returns {number} - The size of the serialized value in bytes.
|
||||
*/
|
||||
sizeof(value) {
|
||||
throw new VirtualMethodNotImplementedError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the value and writes it to the DataView at the specified offset.
|
||||
* @abstract
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {any} value - The value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
throw new VirtualMethodNotImplementedError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the value from the DataView at the specified offset.
|
||||
* @abstract
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
throw new VirtualMethodNotImplementedError();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 8-bit signed integers (int8).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Int8Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* Gets the size of the serialized int8 value in bytes (always 1).
|
||||
* @param {number} _value - The int8 value.
|
||||
* @returns {number} - The size of the serialized int8 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Serializes the int8 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {number} value - The int8 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setInt8(offset, value);
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
* Deserializes the int8 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the int8 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getInt8(offset);
|
||||
return new DeserializedResult(view.getInt8(offset), offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 16-bit signed integers (int16).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Int16Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized int16 value in bytes (always 2).
|
||||
* @param {number} _value - The int16 value.
|
||||
* @returns {number} - The size of the serialized int16 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Serializes the int16 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {number} value - The int16 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setInt16(offset, value);
|
||||
return offset + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
* Deserializes the int16 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the int16 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getInt16(offset);
|
||||
return new DeserializedResult(view.getInt16(offset), offset + 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 32-bit signed integers (int32).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Int32Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized int32 value in bytes (always 4).
|
||||
* @param {number} _value - The int32 value.
|
||||
* @returns {number} - The size of the serialized int32 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Serializes the int32 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {number} value - The int32 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setInt32(offset, value);
|
||||
return offset + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
* Deserializes the int32 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the int32 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getInt32(offset);
|
||||
return new DeserializedResult(view.getInt32(offset), offset + 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 64-bit signed integers (int64).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Int64Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized int64 value in bytes (always 8).
|
||||
* @param {BigInt} _value - The int64 value.
|
||||
* @returns {number} - The size of the serialized int64 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {BigInt} value
|
||||
* Serializes the int64 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {BigInt} value - The int64 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setBigInt64(offset, value);
|
||||
return offset + 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {BigInt}
|
||||
* Deserializes the int64 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the int64 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getBigInt64(offset);
|
||||
return new DeserializedResult(view.getBigInt64(offset), offset + 8);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 8-bit unsigned integers (uint8).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Uint8Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized uint8 value in bytes (always 1).
|
||||
* @param {number} _value - The uint8 value.
|
||||
* @returns {number} - The size of the serialized uint8 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Serializes the uint8 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {number} value - The uint8 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setUint8(offset, value);
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
* Deserializes the uint8 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the uint8 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getUint8(offset);
|
||||
return new DeserializedResult(view.getUint8(offset), offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 16-bit unsigned integers (uint16).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Uint16Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized uint16 value in bytes (always 2).
|
||||
* @param {number} _value - The uint16 value.
|
||||
* @returns {number} - The size of the serialized uint16 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Serializes the uint16 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {number} value - The uint16 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setUint16(offset, value);
|
||||
return offset + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
* Deserializes the uint16 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the uint16 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getUint16(offset);
|
||||
return new DeserializedResult(view.getUint16(offset), offset + 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 32-bit unsigned integers (uint32).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Uint32Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized uint32 value in bytes (always 4).
|
||||
* @param {number} _value - The uint32 value.
|
||||
* @returns {number} - The size of the serialized uint32 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Serializes the uint32 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {number} value - The uint32 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setUint32(offset, value);
|
||||
return offset + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
* Deserializes the uint32 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the uint32 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getUint32(offset);
|
||||
return new DeserializedResult(view.getUint32(offset), offset + 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 64-bit unsigned integers (uint64).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class Uint64Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized uint64 value in bytes (always 8).
|
||||
* @param {BigInt} _value - The uint64 value.
|
||||
* @returns {number} - The size of the serialized uint64 value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {BigInt} value
|
||||
* Serializes the uint64 value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {BigInt} value - The uint64 value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setBigUint64(offset, value);
|
||||
return offset + 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {BigInt}
|
||||
* Deserializes the uint64 value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the uint64 value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getBigUint64(offset);
|
||||
return new DeserializedResult(view.getBigUint64(offset), offset + 8);
|
||||
}
|
||||
}
|
||||
|
||||
export class Float32Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
* Handles boolean values (bool).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setFloat32(offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getFloat32(offset);
|
||||
}
|
||||
}
|
||||
|
||||
export class Float64Handler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {number} _value
|
||||
* @returns {number}
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {number} value
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setFloat64(offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {number}
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getFloat64(offset);
|
||||
}
|
||||
}
|
||||
|
||||
export class BoolHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {boolean} _value
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized bool value in bytes (always 1).
|
||||
* @param {boolean} _value - The bool value.
|
||||
* @returns {number} - The size of the serialized bool value in bytes.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {boolean} value
|
||||
* Serializes the bool value and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {boolean} value - The bool value to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setUint8(offset, value ? 1 : 0);
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {boolean}
|
||||
* Deserializes the bool value from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the bool value and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
return view.getUint8(offset) !== 0;
|
||||
return new DeserializedResult(view.getUint8(offset) !== 0, offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles void values (void).
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class VoidHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* @returns {number}
|
||||
* Gets the size of the serialized void value in bytes (always 0).
|
||||
* @param {*} _value - The void value.
|
||||
* @returns {number} - The size of the serialized void value in bytes (always 0).
|
||||
*/
|
||||
sizeof() {
|
||||
sizeof(_value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} _view
|
||||
* @param {number} _offset
|
||||
* @param {undefined} _value
|
||||
* Serializes the void value (does nothing).
|
||||
* @param {DataView} _view - The DataView to write to (not used).
|
||||
* @param {number} offset - The offset to start writing at (not used).
|
||||
* @param {*} _value - The void value (not used).
|
||||
* @returns {number} - The offset unchanged.
|
||||
*/
|
||||
serialize(_view, _offset, _value) {
|
||||
// Do nothing for Void
|
||||
serialize(_view, offset, _value) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} _view
|
||||
* @param {number} _offset
|
||||
* @returns {undefined}
|
||||
* Deserializes the void value (does nothing).
|
||||
* @param {DataView} _view - The DataView to read from (not used).
|
||||
* @param {number} offset - The offset to start reading from (not used).
|
||||
* @returns {DeserializedResult} - The offset unchanged and undefined as the value.
|
||||
*/
|
||||
deserialize(_view, _offset) {
|
||||
// Do nothing for Void
|
||||
deserialize(_view, offset) {
|
||||
return new DeserializedResult(undefined, offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles array of a fixed length with elements of the same type.
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class FixedArrayHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* Constructor for FixedArrayHandler.
|
||||
* @param {number} n - The fixed length of the array.
|
||||
* @param {BasicTypeHandler} element_handler - The handler for individual elements of the array.
|
||||
*/
|
||||
constructor(n, element_handler) {
|
||||
super();
|
||||
this.n = n;
|
||||
this.element_handler = element_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the serialized fixed-length array in bytes.
|
||||
* @param {Array} value - The array to calculate the size for.
|
||||
* @returns {number} - The size of the serialized fixed-length array in bytes.
|
||||
*/
|
||||
sizeof(value) {
|
||||
let res = 0;
|
||||
for (let i = 0; i < this.n; i += 1) {
|
||||
res += this.element_handler.sizeof(value[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the fixed-length array and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {Array} value - The fixed-length array to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
for (let i = 0; i < this.n; i += 1) {
|
||||
offset = this.element_handler.serialize(view, offset, value[i]);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the fixed-length array from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the fixed-length array and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
let res = new Array(this.n);
|
||||
for (let i = 0; i < this.n; i += 1) {
|
||||
const tmp = this.element_handler.deserialize(view, offset);
|
||||
res[i] = tmp.value;
|
||||
offset = tmp.offset;
|
||||
}
|
||||
return new DeserializedResult(res, offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles dynamic arrays with elements of the same type.
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class DynamicArrayHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* Constructor for DynamicArrayHandler.
|
||||
* @param {BasicTypeHandler} element_handler - The handler for individual elements of the array.
|
||||
*/
|
||||
constructor(element_handler) {
|
||||
super();
|
||||
this.element_handler = element_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the serialized dynamic array in bytes.
|
||||
* @param {Array} value - The array to calculate the size for.
|
||||
* @returns {number} - The size of the serialized dynamic array in bytes.
|
||||
*/
|
||||
sizeof(value) {
|
||||
let size = 4; // For storing the length of the array
|
||||
for (const element of value) {
|
||||
size += this.element_handler.sizeof(element);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the dynamic array and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {Array} value - The dynamic array to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
view.setUint32(offset, value.length);
|
||||
offset += 4;
|
||||
for (const element of value) {
|
||||
offset = this.element_handler.serialize(view, offset, element);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the dynamic array from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the dynamic array and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
const length = view.getUint32(offset);
|
||||
offset += 4;
|
||||
const res = new Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
const tmp = this.element_handler.deserialize(view, offset);
|
||||
res[i] = tmp.value;
|
||||
offset = tmp.offset;
|
||||
}
|
||||
return new DeserializedResult(res, offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles storage and serialization of UUID objects using a 16-byte buffer.
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
export class UUIDHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {UUID} _value
|
||||
* @returns {number}
|
||||
*/
|
||||
sizeof(_value) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {UUID} value
|
||||
* Serializes the UUID object and writes it to the buffer at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {UUID} value - The UUID object to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
const buffer = value.buffer;
|
||||
for (let i = 0; i < buffer.length; i++) {
|
||||
view.setUint8(offset + i, buffer[i]);
|
||||
// Convert UUID to binary data (16 bytes)
|
||||
const binary_data = new Uint8Array(value.buffer);
|
||||
|
||||
// Write binary data to the buffer
|
||||
for (let i = 0; i < binary_data.length; i++) {
|
||||
view.setUint8(offset + i, binary_data[i]);
|
||||
}
|
||||
|
||||
return offset + 16; // Move offset to the next position after the UUID
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the UUID from the buffer at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result object.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
// Read 16 bytes from the buffer starting at the given offset
|
||||
const binary_data = new Uint8Array(16);
|
||||
for (let i = 0; i < 16; i++) {
|
||||
binary_data[i] = view.getUint8(offset + i);
|
||||
}
|
||||
|
||||
// Create a new UUID object from the binary data
|
||||
const uuid = new UUID(binary_data.buffer);
|
||||
return new DeserializedResult(uuid, offset + 16);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {UUID}
|
||||
* Handles storage and serialization of strings.
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
const buffer = new Uint8Array(16);
|
||||
for (let i = 0; i < 16; i++) {
|
||||
buffer[i] = view.getUint8(offset + i);
|
||||
}
|
||||
return new UUID(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
export class StringHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* @param {string} _value
|
||||
* @returns {number}
|
||||
* Constructs a StringHandler object.
|
||||
*/
|
||||
sizeof(_value) {
|
||||
// Calculate the size of string in bytes including the 4 bytes for length
|
||||
return 4 + this.utf8ByteLength(_value);
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @param {string} value
|
||||
* Gets the size of the serialized string in bytes.
|
||||
* @param {string} value - The string to calculate the size for.
|
||||
* @returns {number} - The size of the serialized string in bytes.
|
||||
*/
|
||||
sizeof(value) {
|
||||
// Convert the string to UTF-8 encoding and calculate its byte length
|
||||
const encoder = new TextEncoder();
|
||||
const encodedString = encoder.encode(value);
|
||||
|
||||
// Calculate the size of the string (length of UTF-8 encoding) plus 4 bytes for storing the length
|
||||
return encodedString.byteLength + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the string and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {string} value - The string to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
const utf8_bytes = this.encodeUTF8(value);
|
||||
// Write string length as 4-byte unsigned integer
|
||||
view.setUint32(offset, utf8_bytes.length, true);
|
||||
// Write UTF-8 bytes
|
||||
for (let i = 0; i < utf8_bytes.length; i++) {
|
||||
view.setUint8(offset + 4 + i, utf8_bytes[i]);
|
||||
// Convert the string to UTF-8 encoding
|
||||
const encoder = new TextEncoder();
|
||||
const encoded_string = encoder.encode(value);
|
||||
|
||||
// Write the length of the string as a uint32 at the specified offset
|
||||
view.setUint32(offset, encoded_string.length);
|
||||
offset += 4;
|
||||
|
||||
// Write the UTF-8 encoded string to the DataView starting at offset + 4 (after the length)
|
||||
for (let i = 0; i < encoded_string.length; i++) {
|
||||
view.setUint8(offset + i, encoded_string[i]);
|
||||
}
|
||||
|
||||
// Return the new offset after serialization
|
||||
return offset + encoded_string.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataView} view
|
||||
* @param {number} offset
|
||||
* @returns {string}
|
||||
* Deserializes the string from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the string and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
// Read string length as 4-byte unsigned integer
|
||||
const length = view.getUint32(offset, true);
|
||||
// Read UTF-8 bytes
|
||||
const utf8_bytes = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
utf8_bytes[i] = view.getUint8(offset + 4 + i);
|
||||
}
|
||||
// Decode UTF-8 bytes to string
|
||||
return this.decodeUTF8(utf8_bytes);
|
||||
}
|
||||
// Read the length of the string as a uint32 at the specified offset
|
||||
const length = view.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
/**
|
||||
* Encodes a string to UTF-8 bytes.
|
||||
* @param {string} str
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
encodeUTF8(str) {
|
||||
const encoder = new TextEncoder();
|
||||
return encoder.encode(str);
|
||||
}
|
||||
// Read the UTF-8 encoded string from the DataView starting at offset + 4 (after the length)
|
||||
const encoded_string = new Uint8Array(view.buffer, offset, length);
|
||||
|
||||
/**
|
||||
* Decodes UTF-8 bytes to a string.
|
||||
* @param {Uint8Array} bytes
|
||||
* @returns {string}
|
||||
*/
|
||||
decodeUTF8(bytes) {
|
||||
// Convert the UTF-8 encoded string to a JavaScript string
|
||||
const decoder = new TextDecoder();
|
||||
return decoder.decode(bytes);
|
||||
const decodedString = decoder.decode(encoded_string);
|
||||
|
||||
// Return the deserialized string and the new offset
|
||||
return new DeserializedResult(decodedString, offset + length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the byte length of a string encoded in UTF-8.
|
||||
* @param {string} str
|
||||
* @returns {number}
|
||||
* Handles the serialization and deserialization of a compound type composed of various fields.
|
||||
* @extends {BasicTypeHandler}
|
||||
* @class
|
||||
*/
|
||||
utf8ByteLength(str) {
|
||||
return new TextEncoder().encode(str).length;
|
||||
export class CompoundTypeHandler extends BasicTypeHandler {
|
||||
/**
|
||||
* Constructs a CompoundTypeHandler object for the specified type.
|
||||
* @param {Function} type - The class representing the compound type.
|
||||
* @example
|
||||
* // Define a class Point
|
||||
* class Point {
|
||||
* constructor(x, y) {
|
||||
* this.x = x;
|
||||
* this.y = y;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Define the type definition for Point
|
||||
* Point.prototype.typedef = [
|
||||
* {field: 'x', handler: new Float32Handler()},
|
||||
* {field: 'y', handler: new Float32Handler()}
|
||||
* ];
|
||||
*
|
||||
* // Create a CompoundTypeHandler for Point
|
||||
* const pointHandler = new CompoundTypeHandler(Point);
|
||||
*/
|
||||
constructor(type) {
|
||||
super();
|
||||
/**
|
||||
* The class representing the compound type.
|
||||
* @type {Function}
|
||||
* @private
|
||||
*/
|
||||
this.type = type;
|
||||
/**
|
||||
* The type definition specifying the fields and their handlers.
|
||||
* @type {Array<{field: string, handler: BasicTypeHandler}>}
|
||||
* @private
|
||||
*/
|
||||
this.typedef = type.typedef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the serialized compound type in bytes.
|
||||
* @param {Object} value - The instance of the compound type to calculate the size for.
|
||||
* @returns {number} - The size of the serialized compound type in bytes.
|
||||
*/
|
||||
sizeof(value) {
|
||||
let res = 0;
|
||||
for (let i = 0; i < this.typedef.length; i += 1) {
|
||||
const field_name = this.typedef[i].field;
|
||||
const field_handler = this.typedef[i].handler;
|
||||
res += field_handler.sizeof(value[field_name]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the compound type and writes it to the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to write to.
|
||||
* @param {number} offset - The offset to start writing at.
|
||||
* @param {Object} value - The instance of the compound type to be serialized.
|
||||
* @returns {number} - The new offset after serialization.
|
||||
*/
|
||||
serialize(view, offset, value) {
|
||||
for (let i = 0; i < this.typedef.length; i += 1) {
|
||||
const field_name = this.typedef[i].field;
|
||||
const field_handler = this.typedef[i].handler;
|
||||
offset = field_handler.serialize(view, offset, value[field_name]);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the compound type from the DataView at the specified offset.
|
||||
* @param {DataView} view - The DataView to read from.
|
||||
* @param {number} offset - The offset to start reading from.
|
||||
* @returns {DeserializedResult} - The deserialized result containing the compound type and a new offset.
|
||||
*/
|
||||
deserialize(view, offset) {
|
||||
let res = new this.type();
|
||||
for (let i = 0; i < this.typedef.length; i += 1) {
|
||||
const field_name = this.typedef[i].field;
|
||||
const field_handler = this.typedef[i].handler;
|
||||
const tmp = field_handler.deserialize(view, offset);
|
||||
res[field_name] = tmp.value;
|
||||
offset = tmp.offset;
|
||||
}
|
||||
return new DeserializedResult(res, offset);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user