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