meoser
Version:
meos protocol engine
290 lines (273 loc) • 7.09 kB
JavaScript
/**
* data is bytesarray
* @param {[type]} data [description]
*/
function calcFileCheckSum(data) {
let checksum = [0, 0, 0, 0];
let extraNum = data.length % 4;
for (let k = 0; k < extraNum; k++) {
data.push(0);
}
let len = Math.ceil(data.length/4);
for (let i = 0; i < len; i++) {
checksum[0] = checksum[0] ^ data[i * 4 + 0];
checksum[1] = checksum[1] ^ data[i * 4 + 1];
checksum[2] = checksum[2] ^ data[i * 4 + 2];
checksum[3] = checksum[3] ^ data[i * 4 + 3];
}
return checksum;
}
/**
* data is bytesarray
* @param {[type]} data [description]
*/
function calcFrameCheckSum(data) {
let sum = 0;
for (let val of data) {
sum += val;
}
return sum & 0xff;
}
function stringToAsciiCode(string) {
var result = [];
var list = string.split('');
for (var i in list) {
result.push(list[i].charCodeAt());
}
return result;
}
function bytesToString(bytes) {
var str = "";
for (var i = 0; i < bytes.length; i++) {
str += String.fromCharCode(bytes[i]);
}
return str;
}
/**
* [ascii2Str description]
* @param {String|Array} ascList ascii string or array
* @return {String}
*/
function ascii2Str(ascList) {
let arr;
if (ascList instanceof Array) {
arr = ascList;
} else if (typeof ascList === 'string') {
arr = ascList.split(',');
}
let b = '';
for (let val of arr) {
b += String.fromCharCode(val);
}
return b;
}
/**
* n个byte转成int值
* @param {Array} bytes 传入的bytes数组
* @return {Number} 返回的int数值
*/
function bytesToInt(bytes) {
var val = 0;
for (var i = bytes.length - 1; i >= 0; i--) {
val += (bytes[bytes.length - i - 1] << (i * 8));
}
return val;
}
function longToBytes(value) {
var bytes = [];
var i = 4;
do {
bytes[--i] = value & (255);
value = value >> 8;
} while (i);
return bytes;
}
/**
* Float to bytes.
* 现将float转成整形,再将整形转成字节表示
* @param {float} float number
* @return {bytes}
*/
function float32ToBytes(value) {
// TOFIX: hack
if (value == 0) {
return [0, 0, 0, 0];
}
var bytesInt = 0;
switch (value) {
case Number.POSITIVE_INFINITY:
bytesInt = 0x7F800000;
break;
case Number.NEGATIVE_INFINITY:
bytesInt = 0xFF800000;
break;
case +0.0:
bytesInt = 0x40000000;
break;
case -0.0:
bytesInt = 0xC0000000;
break;
default:
// if (Number.isNaN(value)) { bytesInt = 0x7FC00000; break; }
if (value <= -0.0) {
bytesInt = 0x80000000;
value = -value;
}
var exponent = Math.floor(Math.log(value) / Math.log(2));
var significand = ((value / Math.pow(2, exponent)) * 0x00800000) | 0;
exponent += 127;
if (exponent >= 0xFF) {
exponent = 0xFF;
significand = 0;
} else if (exponent < 0) exponent = 0;
bytesInt = bytesInt | (exponent << 23);
bytesInt = bytesInt | (significand & ~(-1 << 23));
break;
}
var bytesArray = bigIntToBytes(bytesInt);
return bytesArray;
}
/**
* 整形转换成字节数组
* @param {number} value 整形
* @return {array} array数组
*/
function bigIntToBytes(value) {
var bytesArray = [];
var b1 = (value & 0xff);
var b2 = ((value >> 8) & 0xff);
var b3 = ((value >> 16) & 0xff);
var b4 = ((value >> 24) & 0xff);
bytesArray.push(b1);
bytesArray.push(b2);
bytesArray.push(b3);
bytesArray.push(b4);
return bytesArray;
}
function intArrayToHexArray(data) {
var temp = [];
for (var i = 0; i < data.length; i++) {
if (data[i] !== null) {
var item = parseInt(data[i], 10).toString(16);
if (item.length === 1) {
item = '0' + item;
}
temp.push(item);
}
}
return temp;
}
/**
* Convert ArrayBuffer from array of int
* @param {ArrayBuffer} buffer the source arraybuffer
* @return {[int]} int array as the result;
* @private
*/
function arrayFromArrayBuffer(buffer) {
var dataView = new Uint8Array(buffer);
var result = [];
for (var i = 0; i < dataView.length; i++) {
result.push(dataView[i]);
}
return result;
}
const redoAsync = async function(fn, num) {
let result;
for(let i = 0; i < num; i++) {
// console.log('第', i+1, '次重试');
result = await fn();
if(!result.err) {
break;
}
}
return Promise.resolve(result);
}
/**
* convert bytes to length
* @param {Number} low 低位
* @param {Number} high 高位
*/
function convertByte2Len(low, high) {
let small = low || 0;
let big = high || 0;
return (big << 8) | small; //big*256+small
}
/**
* convert length to bytes
* @param {Number} len 长度
*/
function convertLen2Byte(len) {
return [len & 0xff, len >> 8 & 0xff];
}
/**
* calculate value from data received: bytes -> int -> float
* @param {Array} intArray decimal array
* @return {Number} result.
*/
function calculateResponseValue(intArray) {
let result = null;
// FIXME: int字节转浮点型
let intBitsToFloat = function(num) {
/* s 为符号(sign);e 为指数(exponent);m 为有效位数(mantissa)*/
let s = (num >> 31) == 0 ? 1 : -1,
e = (num >> 23) & 0xff,
m = (e == 0) ?
(num & 0x7fffff) << 1 :
(num & 0x7fffff) | 0x800000;
return s * m * Math.pow(2, e - 150);
};
let intValue = bytesToInt(intArray);
// TOFIX
if (intValue < 100000 && intValue > 0) {
result = intValue;
} else {
result = parseFloat(intBitsToFloat(intValue).toFixed(2));
}
return result;
}
function floatArrayFixed (arr, level=2) {
let newArr = [];
if(Array.isArray(arr)) {
newArr = arr.map( i => {
if(typeof i === 'number' && i != parseInt(i)) { // float number
return Number(i.toFixed(level));
}else {
return i;
}
})
}
return newArr;
}
/**
* [checkArrayDiff description]
* @param {Array} prev [description]
* @param {Array} next [description]
* @return {[type]} [description]
*/
function checkArrayDiff(prev, next) {
for(let i = 0, p; p = prev[i]; i++) {
if(p != next[i]) { // there is no difference between null, 0, undefined
return true;
}
}
return false;
}
export {
calcFileCheckSum,
calcFrameCheckSum,
stringToAsciiCode,
bytesToString,
ascii2Str,
bytesToInt,
longToBytes,
float32ToBytes,
bigIntToBytes,
intArrayToHexArray,
arrayFromArrayBuffer,
convertByte2Len,
convertLen2Byte,
calculateResponseValue,
redoAsync,
floatArrayFixed,
checkArrayDiff
}