456 lines
9.2 KiB
JavaScript
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;
|
|
}
|
|
}
|