UNPKG

sensorium

Version:

makeblock mainboards protocol api

389 lines (367 loc) 9.47 kB
/** * @private * @param {[type]} value [description] * @param {[type]} range [description] * @return {[type]} [description] */ function limitValue(value, range) { var newValue = value; range = range || [-255, 255]; if (value < range[0]) { newValue = range[0]; } if (value > range[1]) { newValue = range[1]; } return newValue; } /** * Convert array of int to ArrayBuffer. * @private * @param {[int]} data array of int * @return {ArrayBuffer} result array buffer * @private */ function arrayBufferFromArray(data) { var buffer = new ArrayBuffer(data.length); var result = new Int8Array(buffer); for (var i = 0; i < data.length; i++) { result[i] = data[i]; } return buffer; } /** * Convert ArrayBuffer from array of int * @private * @param {ArrayBuffer} buffer the source arraybuffer * @return {[int]} int array as the result; */ function arrayFromArrayBuffer(buffer) { var dataView = new Uint8Array(buffer); var result = []; for (var i = 0; i < dataView.length; i++) { result.push(dataView[i]); } return result; } /** * [buffer2string converts array buffer to string format] * @private * @param {ArrayBuffer} buf [the input array buffer] * @return {String} [the output string] */ function buffer2string(buf) { var buffer = new Uint8Array(buf); return Array.prototype.join.call(buffer, " "); } /** * [string2buffer converts string to array buffer format] * @private * @param {String} str [the input string] * @return {Uint8Array} [the output uint8 array buffer] */ function string2buffer(str) { var buffer = new Uint8Array(str.split(" ")); return buffer; } /** * 将十进制字符串数组转为16进制 * @private * @param {Array} data to be transformed data, such as: ["01", "55", "12"] * @param {Boolean} isUpperCase whether need output upperCase string. * @return {String} 16 进制字符串 */ function intStrToHexStr(data, isUpperCase) { var temp = []; for (var i = 0; i < data.length; i++) { if (data[i] != null) { var item = parseInt(data[i]).toString(16); if (isUpperCase) { item = parseInt(data[i]).toString(16).toUpperCase(); } if (item.length == 1) { item = "0" + item; } temp.push(item); } } return temp.join(" "); } /** * 十六进制字符串转成十进制 * @private * @param {[type]} str [description] * @return {[type]} [description] */ function hexStr2IntArray(str) { var a = str.split(" "); var arr = []; for (var i in a) { var num = parseInt(a[i], 16); arr.push(num); } arr.reverse(); return arr; } /** * Float to int then to bytes. * @private * @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; } /** * 整形转换成字节数组 * @private * @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; } /** * 32位整数转成字节,js最多只支持32位有符号整数,不支持64位,因此最多只能转成4byte * @private * @param {Number} float number * @return {Array} bytes array */ function longToBytes(value) { var bytes = []; var i = 4; do { bytes[--i] = value & (255); value = value >> 8; } while (i) return bytes; } /** * 将单词的第一个字母转成大写 * @private * @param {string} str string. * @return {string} target string. */ function upperCaseFirstLetter(str) { var reg = /\b(\w)|\s(\w)/g; // str = str.toLowerCase(); return str.replace(reg, function(m) { return m.toUpperCase(); }) } /** * n个byte转成int值 * @private * @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; } /** * transform int to ascii * @private * @param {Array} bytes int array * @return {String} str string */ function bytesToString(bytes) { var str = ""; for (var i = 0; i < bytes.length; i++) { str += String.fromCharCode(bytes[i]); } return str; } function hexToRgb(hex) { let validHexColorReg = /^#(?:[0-9a-f]{3}){1,2}$/i; if (!validHexColorReg.test(hex)) { throw Error(`${hex} is not a valid hex color`); } let r = parseInt(hex.substr(1, 2), 16), g = parseInt(hex.substr(3, 2), 16), b = parseInt(hex.substr(5, 2), 16); return [r, g, b]; } /** * commpose to call func(args) * @private * @param {!Function} func 方法 * @param {Array} args 方法的参数数组 * @return {*} 返回结果由方法决定 */ function composer(func, args) { if (!args) { args = []; } return func(...args); } /** * Continuous byte string to binary byte * 单元测试可参看以下: * 标准笑脸输入: "000000000000000000010000001000000100000000100000000100100000001 * 00000001000010010001000000100000000100000000100000000000000000000" * 最终发送协议: [255, 85, 23, 0, 2, 41, 1, 2, 0, 0, 0, 0, 16, 32, 64, 32, 18, 2, 2, 18, 32, 64, 32, 16, 0, 0] * @private * @param {String} byteStrs * @return {Array} */ function emotionByteString2binaryByte(byteStrs) { let byteResult = []; let len = byteStrs.length + 1; for (let i = 1; i < len; i++) { if (i % 8 === 0) { let byteStr = byteStrs.slice(i - 8, i); byteResult.push(parseInt(byteStr, 2)); } } return byteResult; } function getAllMethods(obj) { let props = [] do { const all = Object.getOwnPropertyNames(obj) .concat(Object.getOwnPropertySymbols(obj).map(s => s.toString())) .sort() .filter((p, i, arr) => { if ((i == 0 || p !== arr[i - 1]) && //not overriding in this prototype !props.includes(p)) { //not overridden in a child let desc = Object.getOwnPropertyDescriptor(obj, p); if (desc.get || desc.set) { //getter or setter return true; } else { return typeof obj[p] === 'function' && //only the methods p !== 'constructor' //not the constructor } } }) props = props.concat(all) } while ( (obj = Object.getPrototypeOf(obj)) && //walk-up the prototype chain Object.getPrototypeOf(obj) //not the the Object prototype methods (hasOwnProperty, etc...) ) return props; } /** * filter array with a binaried string * @private * @param {Array} arr an array like [1, 2, 3] * @param {String} bstr a binaried string like '10101011' * @return {Array} filtered array */ function fiterWithBinaryStr(arr, bstr) { let filter = function(val, index) { if (bstr[index] === '1') { return val; } } return arr.filter(filter); } /** * calculate value from data received: bytes -> int -> float * @private * @param {Array} intArray decimal array * @return {Number} result. */ function calculateResponseValue(intArray) { var result = null; // FIXME: int字节转浮点型 var intBitsToFloat = function(num) { /* s 为符号(sign);e 为指数(exponent);m 为有效位数(mantissa)*/ var 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); }; var intValue = bytesToInt(intArray); // TOFIX if (intValue < 100000 && intValue > 0) { result = intValue; } else { result = parseFloat(intBitsToFloat(intValue).toFixed(2)); } return result; } function stringToAsciiCode(string) { var result = []; var list = string.split(''); for (var i in list) { result.push(list[i].charCodeAt()); } return result; } /** * @fileOverview 工具类函数 */ export { limitValue, arrayBufferFromArray, arrayFromArrayBuffer, buffer2string, string2buffer, intStrToHexStr, hexStr2IntArray, float32ToBytes, bigIntToBytes, longToBytes, upperCaseFirstLetter, bytesToInt, bytesToString, hexToRgb, composer, emotionByteString2binaryByte, getAllMethods, fiterWithBinaryStr, calculateResponseValue, stringToAsciiCode }