UNPKG

@abaplint/runtime

Version:
182 lines 6.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HexUInt8 = void 0; /* eslint-disable no-bitwise */ const _parse_1 = require("../operators/_parse"); const float_1 = require("./float"); const xstring_1 = require("./xstring"); const throw_error_1 = require("../throw_error"); const integer8_1 = require("./integer8"); const REGEXP = /^(?![A-F0-9])/; const LUT_HEX_4b = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]; const LUT_HEX_8b = new Array(0x100); for (let n = 0; n < 0x100; n++) { LUT_HEX_8b[n] = `${LUT_HEX_4b[(n >>> 4) & 0xF]}${LUT_HEX_4b[n & 0xF]}`; } class HexUInt8 { value; length; qualifiedName; constructor(input) { this.length = input?.length ? input?.length : 1; this.qualifiedName = input?.qualifiedName; this.value = new Uint8Array(this.length); } getQualifiedName() { return this.qualifiedName; } clone() { const n = new HexUInt8({ length: this.length, qualifiedName: this.qualifiedName }); n.value = this.value.slice(0); return n; } setOffset(offset, value) { // caller must validate offset this.value[offset] = value; } getOffsetRaw(offset) { // caller must validate offset return this.value[offset]; } set(value) { let hexString = ""; if (typeof value === "string") { hexString = value; if (hexString.length < this.length * 2) { hexString = hexString.padEnd(this.length * 2, "0"); } } else if (typeof value === "number") { const maxVal = Math.pow(2, this.length * 8); if (value < 0) { hexString = Math.round(value + 0x100000000).toString(16).toUpperCase(); } else if (value >= maxVal) { const sub = value % maxVal; hexString = Math.round(sub).toString(16).toUpperCase(); } else { hexString = Math.round(value).toString(16).toUpperCase(); } if (hexString.length > this.length * 2) { hexString = hexString.substring(hexString.length - this.length * 2); } else if (hexString.length < this.length * 2) { hexString = hexString.padStart(this.length * 2, "0"); } } else if (value instanceof integer8_1.Integer8) { if (value.get() < 0) { hexString = (value.get() + 0x10000000000000000n).toString(16).toUpperCase(); } else { hexString = value.get().toString(16).toUpperCase(); } if (hexString.length > this.length * 2) { hexString = hexString.substring(hexString.length - this.length * 2); } else if (hexString.length < this.length * 2) { hexString = hexString.padStart(this.length * 2, "0"); } } else if (value instanceof HexUInt8 || value instanceof xstring_1.XString) { hexString = value.get(); if (hexString.length < this.length * 2) { hexString = hexString.padEnd(this.length * 2, "0"); } } else { const v = value.get(); if (value instanceof float_1.Float) { return this.set(value.getRaw()); } else if (typeof v === "number") { return this.set(v); } else { hexString = v; if (hexString.match(REGEXP)) { hexString = ""; } if (hexString.length < this.length * 2) { hexString = hexString.padEnd(this.length * 2, "0"); } } } if (hexString.length > this.length * 2) { hexString = hexString.substring(0, this.length * 2); } this.value = Uint8Array.from(Buffer.from(hexString, "hex")); return this; } getLength() { return this.length; } clear() { // optimize? https://gist.github.com/chrisj/872283d15e1bb460a4766a52f50ebcf6 for (let i = 0; i < this.value.length; i++) { this.value[i] = 0; } } get() { // return Buffer.from(this.value).toString("hex").toUpperCase(); let out = ""; // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let idx = 0; idx < this.value.length; idx++) { out += LUT_HEX_8b[this.value[idx]]; } return out; } getOffset(input) { let offset = input?.offset; if (offset) { if (offset instanceof integer8_1.Integer8) { offset = Number(offset.get()); } else { offset = (0, _parse_1.parse)(offset); } if (offset > this.length || offset < 0) { (0, throw_error_1.throwError)("CX_SY_RANGE_OUT_OF_BOUNDS"); } } else { offset = 0; } let length = input?.length; if (length) { if (length instanceof integer8_1.Integer8) { length = Number(length.get()); } else { length = (0, _parse_1.parse)(length); } if (length > this.length || length < 0) { (0, throw_error_1.throwError)("CX_SY_RANGE_OUT_OF_BOUNDS"); } } if (offset !== undefined && length !== undefined) { if (offset + length > this.length) { (0, throw_error_1.throwError)("CX_SY_RANGE_OUT_OF_BOUNDS"); } } // not sure how this works: without copying, https://nodejs.org/api/buffer.html#static-method-bufferfromarraybuffer-byteoffset-length /* console.dir(offset); console.dir(length); console.dir(this.value.subarray(offset, length ? offset + length : undefined)); console.dir(Buffer.from(this.value.subarray(offset, length ? offset + length : undefined))); */ // const str = Buffer.from(this.value.subarray(offset, length ? offset + length : undefined)).toString("hex").toUpperCase(); let str = ""; const until = length ? offset + length : this.value.length; for (let idx = offset; idx < until; idx++) { str += LUT_HEX_8b[this.value[idx]]; } return new xstring_1.XString().set(str); } } exports.HexUInt8 = HexUInt8; //# sourceMappingURL=hex_uint8.js.map