UNPKG

pws-formula

Version:

This is a formula execute the string or buffer format formula libray to get values from string or buffer.

283 lines (266 loc) 7.55 kB
/** * Project: pws-formula * Created Date: Thursday, May 3rd 2018, 8:39:13 pm * Author: Thomas.Li * E-Mail: leeyinghui@hotmail.com * Intro: String operation methods * ----- * Last Modified: Tue Jun 19 2018 * Modified By: Thomas.Li * ----- * Copyright (c) 2018 pareact * ------------------------------------ * Always bet on Javascript! */ let str; //temp string /** * get the dec value from the strings by the hex format * @param {number} start * @param {number} length must be even * @returns * @memberof AsciiFormula */ function ax(start, length) { if (length % 2 == 1) { throw new RangeError('The value must be even'); } if (length < 0 || length > 16) { throw new RangeError('The length must between 1-16'); } let bf = Buffer.from(str.slice(start, start + length), 'hex'); return bf.readUIntBE(0, length / 2); } /** * get the pmbus float value * * @param {number} start * @returns * @memberof AsciiFormula */ function ap(start) { if (start < 0 || start > (str.length - 8)) { throw new RangeError('Out of the range'); } let result = [...Array(4).keys()].map(i => parseInt(str.slice(start + i * 2, start + (i + 1) * 2), 16).toString(2).padStart(8, '0')); result = result.reverse().join(''); let reg = /^[0-1]*$/; if (!reg.test(result)) throw new TypeError('The value is invalid'); let mark = result[0] == '1' ? -1 : 1; let eMark = parseInt(result.slice(1, 9), 2); let mMark = parseInt(result.slice(9), 2); let r1 = 2 ** (eMark - 127); let r2 = mark * r1 * mMark * (2 ** -23); return Math.round((r1 + r2) * 100) / 100; } /** * get the dec or float value from asccii string * * @param {number} start * @param {number} length * @returns * @memberof AsciiFormula */ function ad(start, length) { if (start < 0 || start > (str.length - length)) { throw new RangeError('Out of the range'); } if (length > 16) { throw new RangeError('The length must <= 16'); } let result = str.slice(start, start + length); let reg1 = /^([+-]?\d+)(\.\d+)?$/; if (reg1.test(result)) { return parseFloat(result); } else { throw new TypeError('The value is invalid'); } } /** * get float value from hex format asccii string * * @param {number} start * @param {number} length * @returns * @memberof AsciiFormula */ function ac(start, length) { if (length % 2 == 1) { throw new RangeError('The value must be even'); } if (start < 0 || start > (str.length - length)) { throw new RangeError('Out of the range'); } let bf = Buffer.from(str.slice(start, start + length), 'hex'); let result = parseFloat(bf.toString()); if (Number.isNaN(result)) { throw new TypeError('Convert to float fault!'); } return result; } /** * get the float by eval() * * @returns * @memberof AsciiFormula */ function av() { let reg = /^([+-]?\d+)(\.\d+)?$/; if (reg.test(str)) { return parseFloat(str); } else { throw new TypeError('The value is invalid'); } } /** * return the bit value from ascii string (as hex) * * @param {number} start * @param {number} index * @returns * @memberof AsciiFormula */ function ab(start, index) { if (start < 0 || start > (str.length - 2) || index < 0 || index > 7) { throw new RangeError('Out of the range'); } let result = str.slice(start, start + 2); let reg = /^[0-9a-fA-F]*$/; if (reg.test(result)) { result = parseInt(str.slice(start, start + 2), 16); return (result & (2 ** index)) >>> index; } else { throw new TypeError('The value is invalid'); } } /** * Trinocular calculate * @param {string} condition * @param {string} a * @param {string} b * @returns */ function pif(condition, a, b) { return eval(condition) ? eval(a) : eval(b); } /** * outer method to call the inner formula by eval(str) * @param {string} st * @param {string} formulas * @returns */ function getStringValue(st, formulas) { str = st; return formulas.map(x => { try { let result = eval(x); return { 'success': true, 'data': result }; } catch (e) { return { 'success': false, 'data': e }; } }); } /** * check the string is valid by sort (lrc, sum, pmbus) * attention: there is no prefix and endchar * @param {string} st * @param {number} sort * @returns */ function verifyString(st, sort) { str = st; //remove not hex string let reg2 = /[^0-9a-fA-F]/gi; str = str.replace(reg2, ''); if (str.length < 3) { return { 'success': false, 'data': 'The string is too short!' }; } // if (str.length % 2 == 1) { // return { 'success': false, 'data': 'The value is invalid' }; // } let reg = /^[0-9a-fA-F]*$/; if (!reg.test(str)) { return { 'success': false, 'data': 'The string has invalid character!' }; } try { //lrc if (sort == 2) { let result = Buffer.from(str, 'hex'); let total = result.reduce((a, b) => a + b); return { 'success': total % 256 == 0, 'data': `${total}` }; } //sum else if (sort == 3) { let result = Buffer.from(str, 'hex'); let last = result.readUInt8(result.length - 1); let total = result.reduce((a, b) => a + b) - last; return { 'success': total % 256 == last, 'data': `${total}-${last}` }; } //pmbus else if (sort == 4) { let result = Buffer.from(str.slice(0, -4)); let checksum = parseInt(str.slice(-4), 16); let total = result.reduce((a, b) => a + b); return { 'success': (total + checksum) % 65536 == 0, 'data': `${total}- ${checksum}` }; } else if (sort == 0) { return { 'success': true, 'data': `no need to valid data` }; } else { return { 'success': false, 'data': 'Sort value is invalid!' }; } } catch (e) { return { 'success': false, 'data': e }; } } /** * get the fully string by check type(lrc, sum, pmbus) * @param {string} st * @param {number} sort * @returns */ function getFullString(st, sort) { str = st; if (str.length < 3) { return { 'success': false, 'data': 'The stringF is too short!' }; } if (str.length % 2 == 1) { return { 'success': false, 'data': 'The value is invalid' }; } let reg = /^[0-9a-fA-F]*$/; if (!reg.test(str)) { return { 'success': false, 'data': 'The string has invalid character!' }; } try { if (sort == 2) { let result = Buffer.from(str, 'hex'); let total = 256 - (result.reduce((a, b) => a + b) % 256); return { 'success': true, 'data': str + total.toString(16).toUpperCase() }; } else if (sort == 3) { let result = Buffer.from(str, 'hex'); let total = result.reduce((a, b) => a + b) % 256; return { 'success': true, 'data': str + total.toString(16).toUpperCase() }; } else if (sort == 4) { let result = Buffer.from(str); let total = 65536 - (result.reduce((a, b) => a + b) % 65536); return { 'success': true, 'data': str + total.toString(16).toUpperCase() }; } else { return { 'success': false, 'data': 'Sort value is invalid!' }; } } catch (e) { return { 'success': false, 'data': e }; } } module.exports = { getStringValue: getStringValue, verifyString: verifyString, getFullString: getFullString, }