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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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,
}