1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciconst MSG_HEAD_LENGTH = 20;
17fb726d48Sopenharmony_ciconst TYPT_LENGTH = 1;
18fb726d48Sopenharmony_ciconst CMD_LENGTH = 2;
19fb726d48Sopenharmony_ciconst SESSION_ID_LENGTH = 1;
20fb726d48Sopenharmony_ciconst SESSION_LENGTH = 4;
21fb726d48Sopenharmony_ciexport class Utils {
22fb726d48Sopenharmony_ci    // 模块传进来的数据
23fb726d48Sopenharmony_ci    static encode(message: MessageParam) {
24fb726d48Sopenharmony_ci        let splitUint64 = message.session ? Utils.splitUint64ToUint32s(BigInt(message.session!)) : { high32: 0, low32: 0 };// 需处理64bit(session)
25fb726d48Sopenharmony_ci        let totalByteLength = MSG_HEAD_LENGTH + (message.data_lenght ? message.data_lenght : 0);
26fb726d48Sopenharmony_ci        let combinedBuffer = new ArrayBuffer(totalByteLength);// 一个更大的ArrayBuffer,合并前20个字节和data
27fb726d48Sopenharmony_ci        let headBuffer = new ArrayBuffer(MSG_HEAD_LENGTH);
28fb726d48Sopenharmony_ci        let dataView = new DataView(headBuffer);
29fb726d48Sopenharmony_ci        let index = 0;
30fb726d48Sopenharmony_ci        dataView.setUint8(index, message.type!);
31fb726d48Sopenharmony_ci        index += TYPT_LENGTH;
32fb726d48Sopenharmony_ci        dataView.setUint16(index, message.cmd ? message.cmd : 0);
33fb726d48Sopenharmony_ci        index += CMD_LENGTH;
34fb726d48Sopenharmony_ci        dataView.setUint8(index, message.session_id ? message.session_id : 0);
35fb726d48Sopenharmony_ci        index += SESSION_ID_LENGTH;
36fb726d48Sopenharmony_ci        dataView.setUint32(index, splitUint64?.high32!);
37fb726d48Sopenharmony_ci        index += SESSION_LENGTH;
38fb726d48Sopenharmony_ci        dataView.setUint32(index, splitUint64?.low32!);
39fb726d48Sopenharmony_ci        index += SESSION_LENGTH;
40fb726d48Sopenharmony_ci        dataView.setUint32(index, message.data_lenght ? message.data_lenght : 0);
41fb726d48Sopenharmony_ci        // 处理合并message.data
42fb726d48Sopenharmony_ci        let existingArray = new Uint8Array(headBuffer); // 将处理好的前20个字节 
43fb726d48Sopenharmony_ci        let combinedArray = new Uint8Array(combinedBuffer);
44fb726d48Sopenharmony_ci        // 分别将前20个字节和data对应的字节流set至combinedBuffer
45fb726d48Sopenharmony_ci        combinedArray.set(existingArray, 0);
46fb726d48Sopenharmony_ci        combinedArray.set(message.data ? message.data : new Uint8Array(0), headBuffer.byteLength);
47fb726d48Sopenharmony_ci        return combinedBuffer
48fb726d48Sopenharmony_ci    }
49fb726d48Sopenharmony_ci
50fb726d48Sopenharmony_ci    // onmessage接收到的数据解码
51fb726d48Sopenharmony_ci    public static decode(message: ArrayBuffer) {
52fb726d48Sopenharmony_ci        let decode: MessageParam | undefined;
53fb726d48Sopenharmony_ci        let dataView = new DataView(message);
54fb726d48Sopenharmony_ci        let sessionHigh = dataView.getUint32(4);
55fb726d48Sopenharmony_ci        let sessionLow = dataView.getUint32(8);
56fb726d48Sopenharmony_ci        // 将两个 32 位部分组合成一个 64 位的 BigInt  
57fb726d48Sopenharmony_ci        let session = BigInt(sessionHigh) << BigInt(32) | BigInt(sessionLow);
58fb726d48Sopenharmony_ci        // 先将data所需的字节截取出来
59fb726d48Sopenharmony_ci        let dataBytes = new Uint8Array(message, MSG_HEAD_LENGTH, message.byteLength - MSG_HEAD_LENGTH);
60fb726d48Sopenharmony_ci        // 解码 session 的两个 32 位部分  
61fb726d48Sopenharmony_ci        decode = {
62fb726d48Sopenharmony_ci            type: dataView.getUint8(0),
63fb726d48Sopenharmony_ci            cmd: dataView.getUint16(1),
64fb726d48Sopenharmony_ci            session_id: dataView.getUint8(3),
65fb726d48Sopenharmony_ci            session: session,
66fb726d48Sopenharmony_ci            data_lenght: dataView.getUint32(12),
67fb726d48Sopenharmony_ci            data: dataBytes
68fb726d48Sopenharmony_ci        }
69fb726d48Sopenharmony_ci        return decode
70fb726d48Sopenharmony_ci    }
71fb726d48Sopenharmony_ci
72fb726d48Sopenharmony_ci    // 处理64bit 需要拆分成两个32bit
73fb726d48Sopenharmony_ci    public static splitUint64ToUint32s(bigInt: bigint): { high32: number, low32: number } {
74fb726d48Sopenharmony_ci        // 使用位运算提取高32位和低32位  
75fb726d48Sopenharmony_ci        // 右移32位得到高32位,并与0xFFFFFFFF进行按位与操作以确保结果是32位无符号整数  
76fb726d48Sopenharmony_ci        const high32 = Number((bigInt >> BigInt(32)) & BigInt(0xFFFFFFFF));
77fb726d48Sopenharmony_ci        // 低32位可以直接与0xFFFFFFFF进行按位与操作  
78fb726d48Sopenharmony_ci        const low32 = Number(bigInt & BigInt(0xFFFFFFFF));
79fb726d48Sopenharmony_ci        return { high32, low32 };
80fb726d48Sopenharmony_ci    }
81fb726d48Sopenharmony_ci}
82fb726d48Sopenharmony_ciexport class MessageParam {
83fb726d48Sopenharmony_ci    type: number | undefined;
84fb726d48Sopenharmony_ci    cmd: number | undefined;
85fb726d48Sopenharmony_ci    session_id?: number | undefined;
86fb726d48Sopenharmony_ci    session?: bigint | undefined;
87fb726d48Sopenharmony_ci    data_lenght?: number | undefined;
88fb726d48Sopenharmony_ci    data?: Uint8Array | undefined
89fb726d48Sopenharmony_ci}