1/* 2* Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15const fs = require('fs'); 16const MOVE_EIGHTEEN = 18; 17const MOVE_TWELVE = 12; 18const MOVE_SIX = 6; 19 20function utf8ArrayToStr(array) { 21 let char2 = ''; 22 let char3 = ''; 23 24 let outStr = ''; 25 let len = array.length; 26 let i = 0; 27 while (i < len) { 28 let ch = array[i++]; 29 switch (ch >> 4) { 30 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 31 // 0xxxxxxx 32 outStr += String.fromCharCode(ch); 33 break; 34 case 12: case 13: 35 // 110x xxxx 10xx xxxx 36 char2 = array[i++]; 37 outStr += String.fromCharCode(((ch & 0x1F) << 6) | (char2 & 0x3F)); 38 break; 39 case 14: 40 // 1110 xxxx 10xx xxxx 10xx xxxx 41 char2 = array[i++]; 42 char3 = array[i++]; 43 outStr += String.fromCharCode(((ch & 0x0F) << 12) | 44 ((char2 & 0x3F) << 6) | 45 ((char3 & 0x3F) << 0)); 46 break; 47 } 48 } 49 50 return outStr; 51} 52 53function stringToUint8Array(string, option = { streamBool: false }) { 54 if (option.streamBool) { 55 throw new Error(`Failed to encode: the 'streamBool' option is unsupported.`); 56 } 57 const len = string.length; 58 let position = 0; 59 // output position 60 let atPos = 0; 61 // 1.5x size 62 let tlength = Math.max(32, len + (len >> 1) + 7); 63 // ... but atPos 8 byte offset 64 let target = new Uint8Array((tlength >> 3) << 3); 65 66 while (position < len) { 67 let value = string.charCodeAt(position++); 68 let isContinue = false; 69 if (value >= 0xd800 && value <= 0xdbff) { 70 if (position < len) {// high surrogate 71 const extra = string.charCodeAt(position); 72 if ((extra & 0xfc00) === 0xdc00) { 73 ++position; 74 value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000; 75 } 76 } 77 if (value >= 0xd800 && value <= 0xdbff) { 78 isContinue = true; // drop lone surrogate 79 } 80 } 81 82 if (!isContinue) { 83 // expand the buffer if we couldn't write 4 bytes 84 if (atPos + 4 > target.length) { 85 tlength += 8; // minimum extra 86 tlength *= (1.0 + (position / string.length) * 2); // take 2x the remaining 87 tlength = (tlength >> 3) << 3; // 8 byte offset 88 89 target = uint8Array(tlength, target); 90 } 91 92 let calculateResult = calculate(value, target, atPos); 93 isContinue = calculateResult[0]; 94 target = calculateResult[1]; 95 atPos = calculateResult[2]; 96 } 97 } 98 return target.slice(0, atPos); 99} 100 101function calculate(val, target, at) { 102 let isContinue = false; 103 if ((val & 0xffffff80) === 0) { // 1-byte 104 target[at++] = val; // ASCII 105 isContinue = true; 106 } else if ((val & 0xffe00000) === 0) { // 4-byte 107 target[at++] = ((val >> MOVE_EIGHTEEN) & 0x07) | 0xf0; 108 target[at++] = ((val >> MOVE_TWELVE) & 0x3f) | 0x80; 109 target[at++] = ((val >> MOVE_SIX) & 0x3f) | 0x80; 110 } else if ((val & 0xffff0000) === 0) { // 3-byte 111 target[at++] = ((val >> MOVE_TWELVE) & 0x0f) | 0xe0; 112 target[at++] = ((val >> MOVE_SIX) & 0x3f) | 0x80; 113 } else if ((val & 0xfffff800) === 0) { // 2-byte 114 target[at++] = ((val >> MOVE_SIX) & 0x1f) | 0xc0; 115 } else { 116 isContinue = true; 117 } 118 if (!isContinue) { 119 target[at++] = (val & 0x3f) | 0x80; 120 } 121 return [isContinue, target, at]; 122} 123 124function uint8Array(tlen, target) { 125 const update = new Uint8Array(tlen); 126 update.set(target); 127 return update; 128} 129 130function readFile(fn) { 131 if (!fs.existsSync(fn)) { 132 return ''; 133 } 134 let data = fs.readFileSync(fn); 135 data = utf8ArrayToStr(data); 136 return data; 137} 138 139function writeFile(fn, str) { 140 fs.writeFileSync(fn, str, { encoding: 'utf8' }); 141} 142 143function appendWriteFile(fn, str) { 144 fs.appendFile(fn, str, 'utf8', err => { 145 if (err) { 146 console.error(err); 147 return; 148 } 149 }); 150} 151 152// 随机生成整数 153function generateRandomInteger(min, max) { 154 min = Math.ceil(min); 155 max = Math.floor(max); 156 return Math.floor(Math.random() * (max - min + 1)) + min; 157} 158 159/** 160 * 获取Json文件内容 161 * @returns 162 */ 163function getJsonCfg(jsonFilePath) { 164 let jsonCfg = null; // json 配置文件 165 let jsonFile = fs.readFileSync(jsonFilePath, { encoding: 'utf8' }); 166 jsonCfg = JSON.parse(jsonFile); 167 return jsonCfg; 168} 169 170module.exports = { 171 readFile, 172 writeFile, 173 appendWriteFile, 174 generateRandomInteger, 175 getJsonCfg 176}; 177