* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const MSG_HEAD_LENGTH = 20;
const TYPT_LENGTH = 1;
const CMD_LENGTH = 2;
const SESSION_ID_LENGTH = 1;
const SESSION_LENGTH = 4;
export class Utils {
static encode(message: MessageParam): ArrayBuffer {
let splitUint64 = message.session ? Utils.splitUint64ToUint32s(BigInt(message.session!)) : { high32: 0, low32: 0 };
let totalByteLength = MSG_HEAD_LENGTH + (message.data_lenght ? message.data_lenght : 0);
let combinedBuffer = new ArrayBuffer(totalByteLength);
let headBuffer = new ArrayBuffer(MSG_HEAD_LENGTH);
let dataView = new DataView(headBuffer);
let index = 0;
dataView.setUint8(index, message.type!);
index += TYPT_LENGTH;
dataView.setUint16(index, message.cmd ? message.cmd : 0);
index += CMD_LENGTH;
dataView.setUint8(index, message.session_id ? message.session_id : 0);
index += SESSION_ID_LENGTH;
dataView.setUint32(index, splitUint64?.high32!);
index += SESSION_LENGTH;
dataView.setUint32(index, splitUint64?.low32!);
index += SESSION_LENGTH;
dataView.setUint32(index, message.data_lenght ? message.data_lenght : 0);
let existingArray = new Uint8Array(headBuffer);
let combinedArray = new Uint8Array(combinedBuffer);
combinedArray.set(existingArray, 0);
combinedArray.set(message.data ? message.data : new Uint8Array(0), headBuffer.byteLength);
return combinedBuffer;
}
public static decode(message: ArrayBuffer): MessageParam {
let decode: MessageParam | undefined;
let dataView = new DataView(message);
let sessionHigh = dataView.getUint32(4);
let sessionLow = dataView.getUint32(8);
let session = BigInt(sessionHigh) << BigInt(32) | BigInt(sessionLow);
let dataBytes = new Uint8Array(message, MSG_HEAD_LENGTH, message.byteLength - MSG_HEAD_LENGTH);
decode = {
type: dataView.getUint8(0),
cmd: dataView.getUint16(1),
session_id: dataView.getUint8(3),
session: session,
data_lenght: dataView.getUint32(12),
data: dataBytes
};
return decode;
}
public static splitUint64ToUint32s(bigInt: bigint): { high32: number, low32: number } {
const high32 = Number((bigInt >> BigInt(32)) & BigInt(0xFFFFFFFF));
const low32 = Number(bigInt & BigInt(0xFFFFFFFF));
return { high32, low32 };
}
}
export class MessageParam {
type: number | undefined;
cmd: number | undefined;
session_id?: number | undefined;
session?: bigint | undefined;
data_lenght?: number | undefined;
data?: Uint8Array | undefined;
}