You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

694 lines
18 KiB
JavaScript

import Long from './Long.js';
//const Long = require('./Long.js')
//import Long from '@/static/js/Long.js'
/**
* short所占byte的最大位数
*/
const SHORT_MAX_LENGTH = 2;
/**
* int所占byte的最大位数
*/
const INT_MAX_LENGTH = 4;
/**
* float所占byte的最大位数
*/
const FLOAT_MAX_LENGTH = 4;
/**
* long所占byte的最大位数
*/
const LONG_MAX_LENGTH = 8;
/**
* 一位byte所能表示的最大无符号整数是255
*/
const MAX_ARRAY_LENGTH = 255;
/**
* 两位byte所能表示的最大无符号整数是65535
*/
const MAX_LARGE_ARRAY_LENGTH = 65535;
const BigEndian = 0;
const LittleEndian = 1;
let int8 = new Int8Array(4);
let int32 = new Int32Array(int8.buffer, 0, 1);
let float32 = new Float32Array(int8.buffer, 0, 1);
function stringToChars(_s) {
// _s = _s.replace(/(^\s*)|(\s*$)/g, "");
let _r = [];
for (let i = 0; i < _s.length; i++) {
_r[i] = _s.charAt(i);
}
return _r;
}
/***
* byte[] 转16进制字符串
* @param src
* @return
*/
function bytesToHexString(src) {
let stringBuilder = "";
if (src == null || src.length <= 0) {
return null;
}
for (let i = 0; i < src.length; i++) {
let v = src[i] & 0xFF;
let hv = Number(v).toString(16);
if (hv.length < 2) {
stringBuilder += "0"
}
stringBuilder += hv;
}
return stringBuilder;
}
/***
* byte[] 转16进制字符串[空格隔开]
* @param src
* @return
*/
function bytesToHex(src) {
let stringBuilder = "";
if (src == null || src.length <= 0) {
return null;
}
for (let i = 0; i < src.length; i++) {
let v = src[i] & 0xFF;
let hv = Number(v).toString(16);
if (hv.length < 2) {
stringBuilder.concat(0);
}
stringBuilder.concat(hv).concat("");
}
return stringBuilder;
}
/**
* hexString转byteArr
*
* @param hexString
* @return
*/
function hexStringToBytes(hexString) {
if (hexString == null || "" === hexString) {
return null;
}
hexString = hexString.toUpperCase();
let length = hexString.length / 2;
let hexChars = stringToChars(hexString);
let d = [length];
for (let i = 0; i < length; i++) {
let pos = i * 2;
d[i] = (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* char to byte
* @param c
* @return
*/
function charToByte(c) {
return "0123456789ABCDEF".indexOf(c);
}
/**
* 一位byte转int无符号
*
* @param b
* @return 0 ~ 255
*/
function byteToIntUnSigned(b) {
return b & 0xFF;
}
/**
* int byte 4
* @param n
* @return
*/
function intToBytes(n) {
let b = [];
b[3] = (n & 0xff);
b[2] = (n >> 8 & 0xff);
b[1] = (n >> 16 & 0xff);
b[0] = (n >> 24 & 0xff);
return b;
}
/**
* byte 4 byte 1
* @param bytes
* @return
*/
function byte4ToByte1(bytes) {
let byte1 = [];
byte1[0] = bytes[3];
return byte1;
}
/**
*
* @param bytes
* @return
*/
function bytesReverse(bytes) {
let b = bytes[0];
b = ~b;
return b;
}
// ======================【通用方法】=====================================//
/**
* 按照指定的存储方式来依次读取byte数据
*
* @param mode 存储方式
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return
*/
function readBytes(mode, src, offset, length) {
let value = 0;
//从低位开始读
if (LittleEndian === mode) {
for (let i = 0; i < length; i++) {
value |= (src[offset + i] & 0xFF) << (8 * i);
}
} else {
for (let i = 0; i < length; i++) {
value |= (src[offset + length - i - 1] & 0xFF) << (8 * i);
}
}
return value;
}
/**
* 填充数值到byte数组中
*
* @param mode 存储方式
* @param value 数值
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 数值的长度
*/
function fillValueToBytes(mode, value, src, offset, length) {
if (LittleEndian === mode) {
for (let i = 0; i < length; i++) {
src[offset + i] = ((value >> (i * 8)) & 0xFF);
}
} else {
for (let i = 0; i < length; i++) {
src[offset + length - i - 1] = ((value >> (i * 8)) & 0xFF);
}
}
}
/**
* 将值转化为byte数组
*
* @param mode 存储方式
* @param value 数值
* @param length 数值的长度
*/
function valueToBytes(mode, value, length) {
let bytes = [];
if (LittleEndian === mode) {
for (let i = 0; i < length; i++) {
bytes[i] = ((value >> (i * 8)) & 0xFF);
}
} else {
for (let i = 0; i < length; i++) {
bytes[length - i - 1] = ((value >> (i * 8)) & 0xFF);
}
}
return bytes;
}
// ======================【byte数组<-->无符号short】=====================================//
/**
* byte数组中取short数值
*
* @param mode 存储方式
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return short 数值
*/
function bytesToShort(mode, src, offset, length) {
if (length < 1 || length > SHORT_MAX_LENGTH) { //纠正错误的长度
length = SHORT_MAX_LENGTH;
}
return readBytes(mode, src, offset, length);
}
/**
* byte数组中取short数值
*
* @param mode 存储方式
* @param src byte数组
* @param offset 从数组的第offset位开始
* @return short 数值
*/
// function bytesToShort(mode, src, offset) {
// return readBytes(mode, src, offset, SHORT_MAX_LENGTH);
// }
/**
* 将short填充至byte数组中
*
* @param mode 存储方式
* @param value 数值
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return short数值
*/
function fillShortToBytes(mode, value, src, offset, length) {
if (length < 1 || length > SHORT_MAX_LENGTH) { //纠正错误的长度
length = SHORT_MAX_LENGTH;
}
fillValueToBytes(mode, value, src, offset, length);
return offset + length;
}
/**
* 将short填充至byte数组中
*
* @param mode 存储方式
* @param value 数值
* @param src byte数组
* @param offset 从数组的第offset位开始
* @return short数值
*/
// function fillShortToBytes(mode, value, src, offset) {
// fillValueToBytes(mode, value, src, offset, SHORT_MAX_LENGTH);
// return offset + SHORT_MAX_LENGTH;
// }
// ======================【byte数组<-->无符号int】=====================================//
/**
* byte数组中取int数值
*
* @param mode 存储方式
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return short数值
*/
function bytesToInt(mode, src, offset, length) {
if (length < 1 || length > INT_MAX_LENGTH) { //纠正错误的长度
length = INT_MAX_LENGTH;
}
return readBytes(mode, src, offset, length);
}
/**
* 将Int填充至byte数组中
*
* @param mode 存储方式
* @param value 数值
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return short数值
*/
function fillIntToBytes(mode, value, src, offset, length) {
if (length < 1 || length > INT_MAX_LENGTH) { //纠正错误的长度
length = INT_MAX_LENGTH;
}
fillValueToBytes(mode, value, src, offset, length);
return offset + length;
}
// ======================【byte数组<-->无符号long】=====================================//
/**
* byte数组中取long数值
*
* @param mode 存储方式
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return short数值
*/
function bytesToLong(mode, src, offset, length) {
if (length < 1 || length > LONG_MAX_LENGTH) { //纠正错误的长度
length = LONG_MAX_LENGTH;
}
let value = Long.fromNumber(0);
let bt = []
for (let i = 0; i < length; i++) {
bt[i] = src[offset + i]
}
//从低位开始读
if (LittleEndian === mode) {
value = Long.fromBytesLE(bt).toNumber();
} else {
value = Long.fromBytesBE(bt).toNumber();
}
return value;
}
/**
* 将long填充至byte数组中
*
* @param mode 存储方式
* @param value 数值
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return short数值
*/
function fillLongToBytes(mode, value, src, offset, length) {
if (length < 1 || length > LONG_MAX_LENGTH) { //纠正错误的长度
length = LONG_MAX_LENGTH;
}
let bt = []
if (LittleEndian === mode) {
bt = Long.fromValue(value).toBytesLE()
} else {
bt = Long.fromValue(value).toBytesBE()
}
for (let i = 0; i < length; i++) {
src[offset + i] = bt[i]
}
return offset + length;
}
// ======================【byte数组<--> String】=====================================//
/**
* byte数组中取String数值
*
* @param mode 存储方式
* @param src byte数组
* @param offset 从数组的第offset位开始
* @param length 长度
* @return String
*/
function bytesToString(src, offset, length) {
let arr = []
for (let i = 0; i < length; i++) {
let value = src[offset + i];
if (value !== 0) {
arr[i] = value
}
}
let str = '',
_arr = arr;
for (let i = 0; i < _arr.length; i++) {
let one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/);
if (v && one.length === 8) {
let bytesLength = v[0].length;
let store = _arr[i].toString(2).slice(7 - bytesLength);
for (let st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2);
}
str += String.fromCharCode(parseInt(store, 2));
i += bytesLength - 1;
} else {
str += String.fromCharCode(_arr[i]);
}
}
return str.trim();
}
function fillStringToBytes(value, src, offset, length) {
let bytes = [];
let c;
for (let i = 0; i < value.length; i++) {
c = value.charCodeAt(i);
if (c >= 0x010000 && c <= 0x10FFFF) {
bytes.push(((c >> 18) & 0x07) | 0xF0);
bytes.push(((c >> 12) & 0x3F) | 0x80);
bytes.push(((c >> 6) & 0x3F) | 0x80);
bytes.push((c & 0x3F) | 0x80);
} else if (c >= 0x000800 && c <= 0x00FFFF) {
bytes.push(((c >> 12) & 0x0F) | 0xE0);
bytes.push(((c >> 6) & 0x3F) | 0x80);
bytes.push((c & 0x3F) | 0x80);
} else if (c >= 0x000080 && c <= 0x0007FF) {
bytes.push(((c >> 6) & 0x1F) | 0xC0);
bytes.push((c & 0x3F) | 0x80);
} else {
bytes.push(c & 0xFF);
}
}
for (let i = 0; i < length; i++) {
src[offset + i] = bytes[i]
}
return bytes;
}
// ======================【大小端转化】=====================================//
/**
* 大端值转小端
*
* @param value
* @param length
* @return
*/
function bigEndianToLittleEndian(value, length) {
let src = valueToBytes(BigEndian, value, length);
return readBytes(LittleEndian, src, 0, length);
}
/**
* 小端值转大端
*
* @param value
* @param length
* @return
*/
function littleEndianToBigEndian(value, length) {
let src = valueToBytes(LittleEndian, value, length);
return readBytes(BigEndian, src, 0, length);
}
/**
* byte hex
* @param b
* @return
*/
function byteToHex(b) {
let hex = Integer.toHexString(b & 0xFF);
if (hex.length() < 2) {
hex = "0" + hex;
}
return hex;
}
function byteToBit(a) {
let temp = new byte[8];
for (let i = 7; i >= 0; i--) {
temp[i] = ((a >> i) & 1);
}
return temp;
}
function bitToByte(a) {
let temp = 0;
for (let i = 0; i < a.length; i++) {
temp = (temp | a[i] << i);
}
return temp;
}
function intBitsToFloat(i) {
int32[0] = i;
return float32[0];
}
function floatToIntBits(f) {
float32[0] = f;
return int32[0];
}
/////////////////////////////////////////////测试/////////////////////////////////////////////////////////
//测试 61850 静态图谱文件 小端模式
let hexStr = "";
// let bytes = hexStringToBytes(hexStr);
// normVersion = intBitsToFloat(bytesToInt(LittleEndian, bytes, 0, 4))
// fileVersion = intBitsToFloat(bytesToInt(LittleEndian, bytes, 4, 4))
// atlasType = bytesToShort(LittleEndian, bytes, 8, 2)
// atlasTime = bytesToLong(LittleEndian, bytes, 10, 8)
// testFileFlag = bytes[18]
// chName = bytesToString(bytes, 19, 32)
// dischargeType = bytes[51]
// alarmLevel = bytes[52]
// dischargeFlag = bytes[53]
// dischargeTypeBability = []
// for (let i = 0, offset = 54; i < 7; i++, offset += 4) {
// dischargeTypeBability[i] = intBitsToFloat(bytesToInt(LittleEndian, bytes, offset, 4))
// }
// phase = bytesToInt(LittleEndian, bytes, 82, 4)
// amplitude = bytesToInt(LittleEndian, bytes, 86, 4)
// periodicity = bytesToInt(LittleEndian, bytes, 90, 4)
// correlation50Hz = bytesToInt(LittleEndian, bytes, 94, 4)
// correlation100Hz = bytesToInt(LittleEndian, bytes, 98, 4)
// atlasFlag = bytes[102]
// dBmUnit = bytes[103]
// dBmMin = intBitsToFloat(bytesToInt(LittleEndian, bytes, 104, 4))
// dBmMax = intBitsToFloat(bytesToInt(LittleEndian, bytes, 108, 4))
// decollator = bytesToString(bytes, 112, 4)
// dBmData = []
// for (let i = 0, offset = 116; i < 6400; i++, offset += 4) {
// dBmData[i] = intBitsToFloat(bytesToInt(LittleEndian, bytes, offset, 4))
// }
// console.log(normVersion, fileVersion, atlasType, atlasTime, testFileFlag, chName, dischargeType, alarmLevel, dischargeFlag, dischargeTypeBability, phase
// , amplitude, periodicity, correlation50Hz, correlation100Hz, atlasFlag, dBmUnit, dBmMin, dBmMax, decollator, dBmData)
// //转字节
// let data = []
// fillIntToBytes(LittleEndian , floatToIntBits(normVersion), data , 0 , 4)
// fillIntToBytes(LittleEndian , floatToIntBits(fileVersion), data , 4 , 4)
// fillShortToBytes(LittleEndian , atlasType , data, 8 , 2)
// fillLongToBytes(LittleEndian , atlasTime , data , 10 , 8)
// data[18] = testFileFlag
// fillStringToBytes(chName , data , 19,32)
// data[51] = dischargeType
// data[52] = alarmLevel
// data[53] = dischargeFlag
// for(let i = 0 , offset = 54 ; i< 7 ; i++ ,offset+=4 ){
// fillIntToBytes(LittleEndian , floatToIntBits(dischargeTypeBability[i]), data , offset , 4)
// }
// fillIntToBytes(LittleEndian , phase , data , 82 , 4)
// fillIntToBytes(LittleEndian , amplitude , data , 86 , 4)
// fillIntToBytes(LittleEndian , periodicity , data , 90 , 4)
// fillIntToBytes(LittleEndian , correlation50Hz , data , 94 , 4)
// fillIntToBytes(LittleEndian , correlation100Hz , data , 98 , 4)
// data[102] = atlasFlag
// data[103] = dBmUnit
// fillIntToBytes(LittleEndian , floatToIntBits(dBmMin), data , 104 , 4)
// fillIntToBytes(LittleEndian , floatToIntBits(dBmMax), data , 108 , 4)
// fillStringToBytes(decollator , data , 112,4)
// for(let i = 0 , offset = 116 ; i< 6400 ; i++ ,offset+=4 ){
// fillIntToBytes(LittleEndian , floatToIntBits(dBmData[i]), data , offset , 4)
// }
// console.log(bytesToHexString(data) === hexStr)
///测试大端模式
let bigHexStr = ""
// bytes = hexStringToBytes(bigHexStr);
// normVersion = intBitsToFloat(bytesToInt(BigEndian,bytes,0,4))
// fileVersion = intBitsToFloat(bytesToInt(BigEndian,bytes,4,4))
// atlasType = bytesToShort(BigEndian,bytes,8,2)
// atlasTime = bytesToLong(BigEndian , bytes , 10 , 8)
// testFileFlag = bytes[18]
// chName = bytesToString(bytes,19,32)
// dischargeType = bytes[51]
// alarmLevel = bytes[52]
// dischargeFlag = bytes[53]
// dischargeTypeBability = []
// for(let i = 0 , offset = 54 ; i< 7 ; i++ ,offset+=4 ){
// dischargeTypeBability[i] = intBitsToFloat(bytesToInt(BigEndian,bytes,offset,4))
// }
// phase = bytesToInt(BigEndian , bytes , 82 , 4)
// amplitude = bytesToInt(BigEndian , bytes , 86 , 4)
// periodicity = bytesToInt(BigEndian , bytes , 90 , 4)
// correlation50Hz = bytesToInt(BigEndian , bytes , 94 , 4)
// correlation100Hz = bytesToInt(BigEndian , bytes , 98 , 4)
// atlasFlag = bytes[102]
// dBmUnit = bytes[103]
// dBmMin = intBitsToFloat(bytesToInt(BigEndian,bytes,104,4))
// dBmMax = intBitsToFloat(bytesToInt(BigEndian,bytes,108,4))
// decollator = bytesToString(bytes, 112 ,4)
// dBmData = []
// for(let i = 0 , offset = 116 ; i< 6400 ; i++ ,offset+=4 ){
// dBmData[i] = intBitsToFloat(bytesToInt(BigEndian,bytes,offset,4))
// }
// console.log(normVersion,fileVersion,atlasType,atlasTime,testFileFlag,chName,dischargeType,alarmLevel,dischargeFlag,dischargeTypeBability,phase
// ,amplitude,periodicity,correlation50Hz,correlation100Hz,atlasFlag,dBmUnit,dBmMin,dBmMax,decollator,dBmData)
// //转字节
// fillIntToBytes(BigEndian , floatToIntBits(normVersion), data , 0 , 4)
// fillIntToBytes(BigEndian , floatToIntBits(fileVersion), data , 4 , 4)
// fillShortToBytes(BigEndian , atlasType , data, 8 , 2)
// fillLongToBytes(BigEndian , atlasTime , data , 10 , 8)
// data[18] = testFileFlag
// fillStringToBytes(chName , data , 19,32)
// data[51] = dischargeType
// data[52] = alarmLevel
// data[53] = dischargeFlag
// for(let i = 0 , offset = 54 ; i< 7 ; i++ ,offset+=4 ){
// fillIntToBytes(BigEndian , floatToIntBits(dischargeTypeBability[i]), data , offset , 4)
// }
// fillIntToBytes(BigEndian , phase , data , 82 , 4)
// fillIntToBytes(BigEndian , amplitude , data , 86 , 4)
// fillIntToBytes(BigEndian , periodicity , data , 90 , 4)
// fillIntToBytes(BigEndian , correlation50Hz , data , 94 , 4)
// fillIntToBytes(BigEndian , correlation100Hz , data , 98 , 4)
// data[102] = atlasFlag
// data[103] = dBmUnit
// fillIntToBytes(BigEndian , floatToIntBits(dBmMin), data , 104 , 4)
// fillIntToBytes(BigEndian , floatToIntBits(dBmMax), data , 108 , 4)
// fillStringToBytes(decollator , data , 112,4)
// for(let i = 0 , offset = 116 ; i< 6400 ; i++ ,offset+=4 ){
// fillIntToBytes(BigEndian , floatToIntBits(dBmData[i]), data , offset , 4)
// }
// console.log(bytesToHexString(data) === bigHexStr)
export {
LittleEndian,
BigEndian,
hexStringToBytes,
intBitsToFloat,
bytesToShort,
bytesToLong,
bytesToInt,
bytesToString,
fillIntToBytes,
fillShortToBytes,
fillLongToBytes,
fillStringToBytes,
bytesToHexString,
}