SmashMUGENWeb/Public/ecma/Utils/Tools.ecma.js
2026-07-20 07:23:37 +02:00

79 lines
2.1 KiB
JavaScript

"use strict";
import {BinaryStructureModel} from "../Models/BinaryStructureModel.ecma.js";
import {Check} from "http://localhost:18000/Public/ecma/Utils/Checks.ecma.js";
/**
* @class Tools
* @constructor
* @returns {void}
* @access public
* @static
*/
export const Tools = (function(){
/**
* @callback load_binary_type_callback
* @param {!Uint8Array|Array.<number>} data
* @param {!Object.<string, any|null>} object
* @returns {any|null}
*/
/**
* @callback load_binary_size_callback
* @param {!Object.<string, any|null>} object
* @returns {any|null}
*/
/**
* @constructs Tools
* @returns {void}
* @access private
* @static
*/
const Tools = function(){};
/**
* @param {!Uint8Array|Array.<number>} data
* @param {!Array.<Array.<[string, string|load_binary_type_callback, number|load_binary_size_callback]>>} structure
* @returns {Object.<string, any|null>}
* @access public
* @static
*/
Tools.load_binary = (data, structure) => {
/** @type {number} */
let i = 0;
return structure.reduce((object, [name, type, size]) => {
if(Check.is_function(size))
size = size(object);
if(Check.is_function(type))
object[name] = type(data.slice(i, i + size), object);
else{
/** @type {any} */
const value = data.slice(i, i + size);
object[name] = (
type == "string" ? String.fromCharCode(...value).replace(/\0/g, "") :
type == "integer" ? value.reduce((accurate, byte, j) => accurate | (byte << j * 8), 0) :
type == "boolean" ? !!value.reduce((accurate, byte, j) => accurate | (byte << j * 8), 0) :
type == "bytes" ? Array.from(value) :
value);
if(type == "integer" && size < 4 && object[name] >> size * 8 - 1)
object[name] -= 1 << size * 8;
};
i += size;
return object;
}, {});
};
return Tools;
})();