1/* 2* Copyright (c) 2022 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'); 16 17function utf8ArrayToStr(array) { 18 let out; 19 let i; 20 let len; 21 let c; 22 let char2; 23 let char3; 24 25 out = ''; 26 len = array.length; 27 i = 0; 28 while (i < len) { 29 c = array[i++]; 30 switch (c >> 4) { 31 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 32 // 0xxxxxxx 33 out += String.fromCharCode(c); 34 break; 35 case 12: case 13: 36 // 110x xxxx 10xx xxxx 37 char2 = array[i++]; 38 out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); 39 break; 40 case 14: 41 // 1110 xxxx 10xx xxxx 10xx xxxx 42 char2 = array[i++]; 43 char3 = array[i++]; 44 out += String.fromCharCode(((c & 0x0F) << 12) | 45 ((char2 & 0x3F) << 6) | 46 ((char3 & 0x3F) << 0)); 47 break; 48 } 49 } 50 51 return out; 52} 53 54function stringToUint8Array(string, options = { stream: false }) { 55 if (options.stream) { 56 throw new Error(`Failed to encode: the 'stream' option is unsupported.`); 57 } 58 let pos = 0; 59 const len = string.length; 60 let at = 0; // output position 61 let tlen = Math.max(32, len + (len >> 1) + 7); // 1.5x size 62 let target = new Uint8Array((tlen >> 3) << 3); // ... but at 8 byte offset 63 64 while (pos < len) { 65 let value = string.charCodeAt(pos++); 66 let isContinue = false; 67 if (value >= 0xd800 && value <= 0xdbff) { 68 if (pos < len) {// high surrogate 69 const extra = string.charCodeAt(pos); 70 if ((extra & 0xfc00) === 0xdc00) { 71 ++pos; 72 value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000; 73 } 74 } 75 if (value >= 0xd800 && value <= 0xdbff) { 76 isContinue = true; // drop lone surrogate 77 } 78 } 79 80 if (!isContinue) { 81 // expand the buffer if we couldn't write 4 bytes 82 if (at + 4 > target.length) { 83 tlen += 8; // minimum extra 84 tlen *= (1.0 + (pos / string.length) * 2); // take 2x the remaining 85 tlen = (tlen >> 3) << 3; // 8 byte offset 86 87 target = uint8Array(tlen, target); 88 } 89 90 let calculateResult = calculate(value, target, at); 91 isContinue = calculateResult[0]; 92 target = calculateResult[1]; 93 at = calculateResult[2]; 94 } 95 } 96 return target.slice(0, at); 97} 98 99function calculate(value, target, at) { 100 let isContinue = false; 101 if ((value & 0xffffff80) === 0) { // 1-byte 102 target[at++] = value; // ASCII 103 isContinue = true; 104 } else if ((value & 0xfffff800) === 0) { // 2-byte 105 target[at++] = ((value >> 6) & 0x1f) | 0xc0; 106 } else if ((value & 0xffff0000) === 0) { // 3-byte 107 target[at++] = ((value >> 12) & 0x0f) | 0xe0; 108 target[at++] = ((value >> 6) & 0x3f) | 0x80; 109 } else if ((value & 0xffe00000) === 0) { // 4-byte 110 target[at++] = ((value >> 18) & 0x07) | 0xf0; 111 target[at++] = ((value >> 12) & 0x3f) | 0x80; 112 target[at++] = ((value >> 6) & 0x3f) | 0x80; 113 } else { 114 isContinue = true; 115 } 116 if (!isContinue) { 117 target[at++] = (value & 0x3f) | 0x80; 118 } 119 return [isContinue, target, at]; 120} 121 122function uint8Array(tlen, target) { 123 const update = new Uint8Array(tlen); 124 update.set(target); 125 return update; 126} 127 128function readFile(fn) { 129 if (!fs.existsSync(fn)) { 130 return ''; 131 } 132 let data = fs.readFileSync(fn); 133 data = utf8ArrayToStr(data); 134 return data; 135} 136function writeFile(fn, str) { 137 let data = stringToUint8Array(str); 138 fs.writeFileSync(fn, data); 139} 140 141function createFolder(path) { 142 if (fs.existsSync(path)) { 143 return; 144 } 145 fs.mkdirSync(path); 146} 147 148module.exports = { 149 readFile, 150 writeFile, 151 createFolder 152}; 153