@abaplint/runtime
Version:
Transpiler - Runtime
182 lines • 6.7 kB
JavaScript
"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