pws-formula
Version:
This is a formula execute the string or buffer format formula libray to get values from string or buffer.
235 lines (221 loc) • 5.98 kB
JavaScript
/**
* Project: pws-formula
* Created Date: Thursday, May 3rd 2018, 12:19:08 pm
* Author: Thomas.Li
* E-Mail: leeyinghui@hotmail.com
* Intro: Buffer operation methods
* -----
* Last Modified: Tue May 29 2018
* Modified By: Thomas.li
* -----
* Copyright (c) 2018 pareact
* ------------------------------------
* Always bet on Javascript!
*/
const getCRC = require('./crc').getCRC;
let buf; //temp buffer
/**
* get the Hex value of DEC
* @param {number} start
* @param {number} [length=2]
* @returns
*/
function hx(start, length = 2) {
if (length > 4 || length < 0) {
throw new RangeError('Out of Index Range');
}
return buf.readUIntBE(start, length);
}
/**
* get the Hex value of DEC (can read negative number)
* @param {number} start
* @param {number} [length=2]
* @returns
*/
function hxu(start, length = 2) {
if (length > 4 || length < 0) {
throw new RangeError('Out of Index Range');
}
return buf.readIntBE(start, length);
}
/**
* get the float value from 4 byte buffer
* @param {number} start
*/
function hp(start) {
if (start < 0 || start > buf.length - 4) {
throw new RangeError('Out of the range');
}
let result = [...Array(4).keys()].map(i =>
buf[start + i].toString(2).padStart(8, '0')
);
result = result.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 float value by ascii code (00 replaced to 30)
* @param {number} start
* @param {number} length
* @returns
* @memberof HexFormula
*/
function hc(start, length) {
let temp = buf.slice(start, start + length);
if (temp.length < length) {
throw new RangeError('Out of Index Range');
}
let result = temp.map(x => (x == 0 ? 48 : x));
if (result.some(x => x == 47 || x < 45 || x > 57)) {
throw new TypeError('The value is invalid');
} else {
return parseFloat(result.toString());
}
}
/**
* get the BCD Value
* @param {number} start
* @param {number} length
* @returns
* @memberof HexFormula
*/
function ht(start, length) {
let temp = buf.slice(start, start + length);
if (temp.length < length) {
throw new RangeError('Out of Index Range');
}
let result = temp.toString('hex');
let reg = /^[0-9]*$/;
if (reg.test(result)) {
return parseInt(result.toString());
} else {
throw new TypeError('The value is invalid');
}
}
/**
* get the bit value from index and order
*
* @param {mumber} index
* @param {number} order 0-7 from right to left 0xf0 = 0b11110000 (7-6-5-4-3-2-1-0)
* @returns
* @memberof HexFormula
*/
function hb(index, order) {
if (order >= 8 || order < 0) {
throw new TypeError('The value must be 0-7', 'hex.js', 40);
}
let temp = buf.readUInt8(index);
return (temp & (2 ** order)) >>> order;
}
/**
* 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 {Buffer} bf
* @param {string} formulas
* @returns
*/
function getBuffValue(bf, formulas) {
buf = bf;
return formulas.map(x => {
try {
let result = eval(x);
return { success: true, data: result };
} catch (e) {
return { success: false, data: e };
}
});
}
/**
* check if the buffer is valid by sort (crc,sum)
* @param {Buffer} bf
* @param {number} sort
* @returns
*/
function verifyBuffer(bf, sort) {
buf = bf;
if (buf.length < 3) {
return { success: false, data: 'The buffer is too short!' };
}
try {
//crc check
if (sort == 1) {
let originalValue = buf.readUInt16LE(buf.length - 2);
let tempBuf = buf.slice(0, buf.length - 2);
let checkValue = getCRC(tempBuf);
return {
success: originalValue == checkValue,
data: `${originalValue}-${checkValue}`
};
}
//sum
else if (sort == 3) {
let originalValue = buf.readUInt8(buf.length - 1);
let checkValue = buf.reduce((a, b) => a + b) - originalValue;
return {
success: checkValue % 256 == originalValue,
data: `${originalValue}-${checkValue}`
};
} 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 verified result from original buffer and sort(crc, sum)
* @param {Buffer} bf
* @param {number} sort
* @returns
*/
function getFullBuffer(bf, sort) {
buf = bf;
if (buf.length < 3) {
return { success: false, data: 'The buffer is too short!' };
}
try {
if (sort == 1) {
let checkValue = getCRC(buf);
let tempBuf = Buffer.alloc(2);
tempBuf.writeUInt16LE(checkValue, 0);
return {
success: true,
data: Buffer.concat([buf, tempBuf], buf.length + 2)
};
} else if (sort == 3) {
let checkValue = buf.reduce((a, b) => a + b) % 256;
let tempBuf = Buffer.alloc(1);
tempBuf.writeUInt8(checkValue, 0);
return {
success: true,
data: Buffer.concat([buf, tempBuf], buf.length + 1)
};
} else {
return { success: false, data: 'Sort value is invalid!' };
}
} catch (e) {
return { success: false, data: e };
}
}
module.exports = {
getBuffValue: getBuffValue,
verifyBuffer: verifyBuffer,
getFullBuffer: getFullBuffer
};