UNPKG

struffer

Version:
199 lines 5.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const os_1 = require("os"); var MemberEndianness; (function (MemberEndianness) { MemberEndianness[MemberEndianness["LittleEndian"] = 0] = "LittleEndian"; MemberEndianness[MemberEndianness["BigEndian"] = 1] = "BigEndian"; })(MemberEndianness = exports.MemberEndianness || (exports.MemberEndianness = {})); var MemberSignature; (function (MemberSignature) { MemberSignature[MemberSignature["Signed"] = 0] = "Signed"; MemberSignature[MemberSignature["Unsigned"] = 1] = "Unsigned"; })(MemberSignature = exports.MemberSignature || (exports.MemberSignature = {})); function totalBits(num) { return num.toString(2).length; } exports.totalBits = totalBits; function splitIntoBits(num, includeSign = false) { const bitCount = totalBits(num); let res = []; if (num < 0) { /* * two's complement is how to represent negatives * in binary. the following is true: * -x = tc(x) * x = tc(-x) * normally two's complement is: * tc(x) = ~x + 1 * but two's complement also works oppositely. * i.e. the following yields the same results: * tc(x) = ~(x - 1) * so we'll use the second method since it's easier * for us here. first, invert the number (e.g. -5 -> 5). * then, subtract 1 (e.g. 5 -> 4). next, split it * into bits (e.g. 4 -> [1, 0, 0]). finally, invert the * bits (e.g. [1, 0, 0] -> [0, 1, 1]). */ res = splitIntoBits((num * -1) - 1, false).map(i => (i === 0) ? 1 : 0); if (includeSign) { res.unshift(1); } } else { for (let i = 0; i < bitCount; i++) { res.unshift((num & (1 << i)) ? 1 : 0); } if (includeSign) { res.unshift(0); } } return res; } exports.splitIntoBits = splitIntoBits; function unsignedSplit(n, bitCount = totalBits(n)) { const bits = []; for (let i = 0; i < bitCount; i++) { bits.unshift((n & (1 << i)) ? 1 : 0); } return bits; } exports.unsignedSplit = unsignedSplit; function joinBits(bits) { let res = 0; let j = bits.length - 1; for (let i = 0; i < bits.length; i++) { if (bits[i]) res |= 1 << j; j--; } return res; } exports.joinBits = joinBits; function joinSignedBits(_bits) { let bits = _bits; /* * sign bit is always MSB (most significant bit) * thus, first bit on LE, last bit on BE */ // we tell istanbul to ignore the tenary because endianness is hardware dependent /* istanbul ignore next */ const negative = !!((os_1.endianness() === 'LE') ? bits.shift() : bits.pop()); let res = 0; if (negative) { bits = bits.map(i => (i === 0) ? 1 : 0); } let j = bits.length - 1; for (let i = 0; i < bits.length; i++) { if (bits[i]) res |= 1 << j; j--; } if (negative) { res = (res + 1) * -1; } return res; } exports.joinSignedBits = joinSignedBits; function parseType(_type) { let type = _type.toLowerCase(); const { BigEndian, LittleEndian } = MemberEndianness; const { Signed, Unsigned } = MemberSignature; const info = { endianness: LittleEndian, signature: Signed, bitSize: 0, }; const unwantedCharacter = /[^A-Za-z0-9]/; const numberCharacter = /[0-9]/; let signModifierFound = false; let lookingForModifiers = true; let shortsFound = 0; let longsFound = 0; const removeUnwantedCharacters = () => { while (unwantedCharacter.test(type[0])) type = type.slice(1); }; const remove = (len) => { type = type.slice(len); }; const is = (str) => type.startsWith(str); while (lookingForModifiers) { removeUnwantedCharacters(); if (is('unsigned')) { if (!signModifierFound) { signModifierFound = true; info.signature = Unsigned; } remove(8); continue; } if (is('signed')) { if (!signModifierFound) { signModifierFound = true; info.signature = Signed; } remove(6); continue; } if (is('short')) { shortsFound++; remove(5); continue; } if (is('long')) { longsFound++; remove(4); continue; } lookingForModifiers = false; } removeUnwantedCharacters(); if (is('int')) { info.bitSize = 32; remove(3); } else if (is('uint')) { if (!signModifierFound) info.signature = Unsigned; info.bitSize = 32; remove(4); } else if (is('i')) { info.bitSize = 32; remove(1); } else if (is('u')) { if (!signModifierFound) info.signature = Unsigned; info.bitSize = 32; remove(1); } else if (is('byte') || is('char')) { info.bitSize = 8; remove(4); } removeUnwantedCharacters(); let sizePart = ''; while (numberCharacter.test(type[0])) { sizePart += type[0]; type = type.slice(1).trim(); } if (sizePart !== '') { info.bitSize = Number(sizePart); } if (type.startsWith('be')) { info.endianness = BigEndian; } const divide = (longsFound > shortsFound) ? false : true; const times = (divide) ? (shortsFound - longsFound) : (longsFound - shortsFound); for (let i = 0; i < times; i++) { if (divide) { info.bitSize = info.bitSize / 2; } else { info.bitSize = info.bitSize * 2; } } return info; } exports.parseType = parseType; //# sourceMappingURL=common.js.map