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
JavaScript
/**
* 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,
}