opengenerals/shared/bstruct/type-handler.mjs
szdytom a03cf1b2a1
[js] add UUID and type-handlers
Signed-off-by: szdytom <szdytom@qq.com>
2024-02-10 14:16:27 +08:00

456 lines
9.2 KiB
JavaScript

import { VirtualMethodNotImplementedError } from '@og/error-utils';
export class BasicTypeHandler {
sizeof(value) {
throw new VirtualMethodNotImplementedError();
}
serialize(view, offset, value) {
throw new VirtualMethodNotImplementedError();
}
deserialize(view, offset) {
throw new VirtualMethodNotImplementedError();
}
};
export class Int8Handler extends BasicTypeHandler {
sizeof(_value) {
return 1;
}
/**
*
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
serialize(view, offset, value) {
view.setInt8(offset, value);
}
/**
*
* @param {DataView} view
* @param {number} offset
* @returns {number}
*/
deserialize(view, offset) {
return view.getInt8(offset);
}
}
export class Int16Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 2;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
serialize(view, offset, value) {
view.setInt16(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {number}
*/
deserialize(view, offset) {
return view.getInt16(offset);
}
}
export class Int32Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 4;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
serialize(view, offset, value) {
view.setInt32(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {number}
*/
deserialize(view, offset) {
return view.getInt32(offset);
}
}
export class Int64Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 8;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {BigInt} value
*/
serialize(view, offset, value) {
view.setBigInt64(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {BigInt}
*/
deserialize(view, offset) {
return view.getBigInt64(offset);
}
}
export class Uint8Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 1;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
serialize(view, offset, value) {
view.setUint8(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {number}
*/
deserialize(view, offset) {
return view.getUint8(offset);
}
}
export class Uint16Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 2;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
serialize(view, offset, value) {
view.setUint16(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {number}
*/
deserialize(view, offset) {
return view.getUint16(offset);
}
}
export class Uint32Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 4;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
serialize(view, offset, value) {
view.setUint32(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {number}
*/
deserialize(view, offset) {
return view.getUint32(offset);
}
}
export class Uint64Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 8;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {BigInt} value
*/
serialize(view, offset, value) {
view.setBigUint64(offset, value);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {BigInt}
*/
deserialize(view, offset) {
return view.getBigUint64(offset);
}
}
export class Float32Handler extends BasicTypeHandler {
/**
* @param {number} _value
* @returns {number}
*/
sizeof(_value) {
return 4;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {number} value
*/
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}
*/
sizeof(_value) {
return 1;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {boolean} value
*/
serialize(view, offset, value) {
view.setUint8(offset, value ? 1 : 0);
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {boolean}
*/
deserialize(view, offset) {
return view.getUint8(offset) !== 0;
}
}
export class VoidHandler extends BasicTypeHandler {
/**
* @returns {number}
*/
sizeof() {
return 0;
}
/**
* @param {DataView} _view
* @param {number} _offset
* @param {undefined} _value
*/
serialize(_view, _offset, _value) {
// Do nothing for Void
}
/**
* @param {DataView} _view
* @param {number} _offset
* @returns {undefined}
*/
deserialize(_view, _offset) {
// Do nothing for Void
}
}
export class UUIDHandler extends BasicTypeHandler {
/**
* @param {UUID} _value
* @returns {number}
*/
sizeof(_value) {
return 16;
}
/**
* @param {DataView} view
* @param {number} offset
* @param {UUID} value
*/
serialize(view, offset, value) {
const buffer = value.buffer;
for (let i = 0; i < buffer.length; i++) {
view.setUint8(offset + i, buffer[i]);
}
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {UUID}
*/
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}
*/
sizeof(_value) {
// Calculate the size of string in bytes including the 4 bytes for length
return 4 + this.utf8ByteLength(_value);
}
/**
* @param {DataView} view
* @param {number} offset
* @param {string} value
*/
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]);
}
}
/**
* @param {DataView} view
* @param {number} offset
* @returns {string}
*/
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);
}
/**
* Encodes a string to UTF-8 bytes.
* @param {string} str
* @returns {Uint8Array}
*/
encodeUTF8(str) {
const encoder = new TextEncoder();
return encoder.encode(str);
}
/**
* Decodes UTF-8 bytes to a string.
* @param {Uint8Array} bytes
* @returns {string}
*/
decodeUTF8(bytes) {
const decoder = new TextDecoder();
return decoder.decode(bytes);
}
/**
* Calculates the byte length of a string encoded in UTF-8.
* @param {string} str
* @returns {number}
*/
utf8ByteLength(str) {
return new TextEncoder().encode(str).length;
}
}