@gjsify/string_decoder 0.3.12 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/index.js +399 -378
- package/package.json +4 -4
package/lib/esm/index.js
CHANGED
|
@@ -1,402 +1,423 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { base64Encode, checkEncoding, normalizeEncoding } from "@gjsify/utils";
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
2
4
|
function normalizeAndValidateEncoding(enc) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
if (enc) checkEncoding(enc);
|
|
6
|
+
return normalizeEncoding(enc);
|
|
5
7
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Decode a complete (non-streaming) chunk of UTF-8 bytes into a string,
|
|
10
|
+
* using the W3C "maximal subpart" replacement algorithm (Unicode 3.9 D93b).
|
|
11
|
+
*
|
|
12
|
+
* This avoids relying on TextDecoder which may produce incorrect replacement
|
|
13
|
+
* counts on older SpiderMonkey versions (e.g., GJS 1.80 / SpiderMonkey 115).
|
|
14
|
+
*
|
|
15
|
+
* Valid UTF-8 byte ranges per position:
|
|
16
|
+
* 1-byte: 00-7F
|
|
17
|
+
* 2-byte: C2-DF, 80-BF
|
|
18
|
+
* 3-byte: E0 A0-BF 80-BF | E1-EC 80-BF 80-BF | ED 80-9F 80-BF | EE-EF 80-BF 80-BF
|
|
19
|
+
* 4-byte: F0 90-BF 80-BF 80-BF | F1-F3 80-BF 80-BF 80-BF | F4 80-8F 80-BF 80-BF
|
|
20
|
+
*/
|
|
21
|
+
function utf8DecodeMaximalSubpart(bytes, start, end) {
|
|
22
|
+
let result = "";
|
|
23
|
+
let i = start;
|
|
24
|
+
while (i < end) {
|
|
25
|
+
const b0 = bytes[i];
|
|
26
|
+
if (b0 <= 127) {
|
|
27
|
+
result += String.fromCharCode(b0);
|
|
28
|
+
i++;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (b0 >= 194 && b0 <= 223) {
|
|
32
|
+
if (i + 1 < end && bytes[i + 1] >= 128 && bytes[i + 1] <= 191) {
|
|
33
|
+
result += String.fromCharCode((b0 & 31) << 6 | bytes[i + 1] & 63);
|
|
34
|
+
i += 2;
|
|
35
|
+
} else {
|
|
36
|
+
result += "�";
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (b0 >= 224 && b0 <= 239) {
|
|
42
|
+
let lo2, hi2;
|
|
43
|
+
if (b0 === 224) {
|
|
44
|
+
lo2 = 160;
|
|
45
|
+
hi2 = 191;
|
|
46
|
+
} else if (b0 === 237) {
|
|
47
|
+
lo2 = 128;
|
|
48
|
+
hi2 = 159;
|
|
49
|
+
} else {
|
|
50
|
+
lo2 = 128;
|
|
51
|
+
hi2 = 191;
|
|
52
|
+
}
|
|
53
|
+
if (i + 1 >= end) {
|
|
54
|
+
result += "�";
|
|
55
|
+
i++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const b1 = bytes[i + 1];
|
|
59
|
+
if (b1 < lo2 || b1 > hi2) {
|
|
60
|
+
result += "�";
|
|
61
|
+
i++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (i + 2 >= end) {
|
|
65
|
+
result += "�";
|
|
66
|
+
i += 2;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const b2 = bytes[i + 2];
|
|
70
|
+
if (b2 < 128 || b2 > 191) {
|
|
71
|
+
result += "�";
|
|
72
|
+
i += 2;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const cp = (b0 & 15) << 12 | (b1 & 63) << 6 | b2 & 63;
|
|
76
|
+
result += String.fromCharCode(cp);
|
|
77
|
+
i += 3;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (b0 >= 240 && b0 <= 244) {
|
|
81
|
+
let lo2, hi2;
|
|
82
|
+
if (b0 === 240) {
|
|
83
|
+
lo2 = 144;
|
|
84
|
+
hi2 = 191;
|
|
85
|
+
} else if (b0 === 244) {
|
|
86
|
+
lo2 = 128;
|
|
87
|
+
hi2 = 143;
|
|
88
|
+
} else {
|
|
89
|
+
lo2 = 128;
|
|
90
|
+
hi2 = 191;
|
|
91
|
+
}
|
|
92
|
+
if (i + 1 >= end) {
|
|
93
|
+
result += "�";
|
|
94
|
+
i++;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const b1 = bytes[i + 1];
|
|
98
|
+
if (b1 < lo2 || b1 > hi2) {
|
|
99
|
+
result += "�";
|
|
100
|
+
i++;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (i + 2 >= end) {
|
|
104
|
+
result += "�";
|
|
105
|
+
i += 2;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const b2 = bytes[i + 2];
|
|
109
|
+
if (b2 < 128 || b2 > 191) {
|
|
110
|
+
result += "�";
|
|
111
|
+
i += 2;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (i + 3 >= end) {
|
|
115
|
+
result += "�";
|
|
116
|
+
i += 3;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const b3 = bytes[i + 3];
|
|
120
|
+
if (b3 < 128 || b3 > 191) {
|
|
121
|
+
result += "�";
|
|
122
|
+
i += 3;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const cp = (b0 & 7) << 18 | (b1 & 63) << 12 | (b2 & 63) << 6 | b3 & 63;
|
|
126
|
+
result += String.fromCharCode(55296 + (cp - 65536 >> 10), 56320 + (cp - 65536 & 1023));
|
|
127
|
+
i += 4;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
result += "�";
|
|
131
|
+
i++;
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
122
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns the expected total byte length of a UTF-8 character given its first byte,
|
|
137
|
+
* and validates the lead byte is in a valid range.
|
|
138
|
+
* Returns 0 for invalid lead bytes.
|
|
139
|
+
*/
|
|
123
140
|
function utf8CharLength(byte) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
141
|
+
if ((byte & 128) === 0) return 1;
|
|
142
|
+
if (byte >= 194 && byte <= 223) return 2;
|
|
143
|
+
if (byte >= 224 && byte <= 239) return 3;
|
|
144
|
+
if (byte >= 240 && byte <= 244) return 4;
|
|
145
|
+
return 0;
|
|
129
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Check if a continuation byte is valid for its position in a multi-byte sequence.
|
|
149
|
+
* Returns true if the byte is in the expected range for that position.
|
|
150
|
+
*/
|
|
130
151
|
function isValidContinuation(leadByte, charLen, position, byte) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
152
|
+
if (position === 1) {
|
|
153
|
+
if (charLen === 3) {
|
|
154
|
+
if (leadByte === 224) return byte >= 160 && byte <= 191;
|
|
155
|
+
if (leadByte === 237) return byte >= 128 && byte <= 159;
|
|
156
|
+
return byte >= 128 && byte <= 191;
|
|
157
|
+
}
|
|
158
|
+
if (charLen === 4) {
|
|
159
|
+
if (leadByte === 240) return byte >= 144 && byte <= 191;
|
|
160
|
+
if (leadByte === 244) return byte >= 128 && byte <= 143;
|
|
161
|
+
return byte >= 128 && byte <= 191;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return byte >= 128 && byte <= 191;
|
|
144
165
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
/**
|
|
167
|
+
* StringDecoder provides an interface for efficiently decoding Buffer data
|
|
168
|
+
* into strings while preserving multi-byte characters that are split across
|
|
169
|
+
* Buffer boundaries.
|
|
170
|
+
*
|
|
171
|
+
* Implemented as a function constructor (not ES6 class) for compatibility
|
|
172
|
+
* with legacy CJS patterns that use StringDecoder.call(this, enc).
|
|
173
|
+
*/
|
|
174
|
+
const StringDecoder = function StringDecoder(encoding) {
|
|
175
|
+
this.encoding = normalizeAndValidateEncoding(encoding);
|
|
176
|
+
this._lastNeed = 0;
|
|
177
|
+
this._lastTotal = 0;
|
|
178
|
+
this._lastLeadByte = 0;
|
|
179
|
+
if (this.encoding === "utf8") {
|
|
180
|
+
this._lastChar = new Uint8Array(4);
|
|
181
|
+
} else if (this.encoding === "utf16le") {
|
|
182
|
+
this._lastChar = new Uint8Array(4);
|
|
183
|
+
} else if (this.encoding === "base64") {
|
|
184
|
+
this._lastChar = new Uint8Array(3);
|
|
185
|
+
} else {
|
|
186
|
+
this._lastChar = new Uint8Array(0);
|
|
187
|
+
}
|
|
159
188
|
};
|
|
160
189
|
StringDecoder.prototype.write = function write(buf) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
case "latin1":
|
|
172
|
-
return decodeLatin1(buf);
|
|
173
|
-
case "hex":
|
|
174
|
-
return decodeHex(buf);
|
|
175
|
-
default:
|
|
176
|
-
return decodeAscii(buf);
|
|
177
|
-
}
|
|
190
|
+
if (buf.length === 0) return "";
|
|
191
|
+
switch (this.encoding) {
|
|
192
|
+
case "utf8": return writeUtf8(this, buf);
|
|
193
|
+
case "utf16le": return writeUtf16le(this, buf);
|
|
194
|
+
case "base64": return writeBase64(this, buf);
|
|
195
|
+
case "ascii": return decodeAscii(buf);
|
|
196
|
+
case "latin1": return decodeLatin1(buf);
|
|
197
|
+
case "hex": return decodeHex(buf);
|
|
198
|
+
default: return decodeAscii(buf);
|
|
199
|
+
}
|
|
178
200
|
};
|
|
179
201
|
StringDecoder.prototype.end = function end(buf) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
let result = "";
|
|
203
|
+
if (buf && buf.length > 0) {
|
|
204
|
+
result = this.write(buf);
|
|
205
|
+
}
|
|
206
|
+
if (this.encoding === "utf8" && this._lastNeed > 0) {
|
|
207
|
+
result += "�";
|
|
208
|
+
this._lastNeed = 0;
|
|
209
|
+
this._lastTotal = 0;
|
|
210
|
+
} else if (this.encoding === "utf16le" && this._lastNeed > 0) {
|
|
211
|
+
const stored = this._lastTotal - this._lastNeed;
|
|
212
|
+
for (let i = 0; i + 1 < stored; i += 2) {
|
|
213
|
+
result += String.fromCharCode(this._lastChar[i] | this._lastChar[i + 1] << 8);
|
|
214
|
+
}
|
|
215
|
+
this._lastNeed = 0;
|
|
216
|
+
this._lastTotal = 0;
|
|
217
|
+
} else if (this.encoding === "base64" && this._lastNeed > 0) {
|
|
218
|
+
const remaining = this._lastChar.subarray(0, this._lastTotal - this._lastNeed);
|
|
219
|
+
result += base64Encode(remaining);
|
|
220
|
+
this._lastNeed = 0;
|
|
221
|
+
this._lastTotal = 0;
|
|
222
|
+
}
|
|
223
|
+
return result;
|
|
202
224
|
};
|
|
203
225
|
function writeUtf8(self, buf) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
226
|
+
let i = 0;
|
|
227
|
+
let result = "";
|
|
228
|
+
if (self._lastNeed > 0) {
|
|
229
|
+
while (i < buf.length && self._lastNeed > 0) {
|
|
230
|
+
const byte = buf[i];
|
|
231
|
+
const position = self._lastTotal - self._lastNeed;
|
|
232
|
+
if (isValidContinuation(self._lastLeadByte, self._lastTotal, position, byte)) {
|
|
233
|
+
self._lastChar[position] = byte;
|
|
234
|
+
self._lastNeed--;
|
|
235
|
+
i++;
|
|
236
|
+
} else {
|
|
237
|
+
result += "�";
|
|
238
|
+
self._lastNeed = 0;
|
|
239
|
+
self._lastTotal = 0;
|
|
240
|
+
self._lastLeadByte = 0;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (self._lastNeed === 0 && self._lastTotal > 0) {
|
|
245
|
+
result += utf8DecodeMaximalSubpart(self._lastChar, 0, self._lastTotal);
|
|
246
|
+
self._lastTotal = 0;
|
|
247
|
+
self._lastLeadByte = 0;
|
|
248
|
+
}
|
|
249
|
+
if (self._lastNeed > 0) {
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
let completeEnd = buf.length;
|
|
254
|
+
for (let j = 0; j < Math.min(4, buf.length - i); j++) {
|
|
255
|
+
const idx = buf.length - 1 - j;
|
|
256
|
+
if (idx < i) break;
|
|
257
|
+
const byte = buf[idx];
|
|
258
|
+
if ((byte & 192) !== 128) {
|
|
259
|
+
const charLen = utf8CharLength(byte);
|
|
260
|
+
if (charLen > 0 && byte >= 128) {
|
|
261
|
+
const available = buf.length - idx;
|
|
262
|
+
if (available < charLen) {
|
|
263
|
+
let allValid = true;
|
|
264
|
+
for (let k = 1; k < available; k++) {
|
|
265
|
+
if (!isValidContinuation(byte, charLen, k, buf[idx + k])) {
|
|
266
|
+
allValid = false;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (allValid) {
|
|
271
|
+
completeEnd = idx;
|
|
272
|
+
for (let k = 0; k < available; k++) {
|
|
273
|
+
self._lastChar[k] = buf[idx + k];
|
|
274
|
+
}
|
|
275
|
+
self._lastNeed = charLen - available;
|
|
276
|
+
self._lastTotal = charLen;
|
|
277
|
+
self._lastLeadByte = byte;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (completeEnd > i) {
|
|
285
|
+
result += utf8DecodeMaximalSubpart(buf, i, completeEnd);
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
266
288
|
}
|
|
267
289
|
function writeUtf16le(self, buf) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
290
|
+
let result = "";
|
|
291
|
+
let i = 0;
|
|
292
|
+
if (self._lastNeed > 0) {
|
|
293
|
+
const offset = self._lastTotal - self._lastNeed;
|
|
294
|
+
const needed = Math.min(self._lastNeed, buf.length);
|
|
295
|
+
for (let j = 0; j < needed; j++) {
|
|
296
|
+
self._lastChar[offset + j] = buf[j];
|
|
297
|
+
}
|
|
298
|
+
self._lastNeed -= needed;
|
|
299
|
+
i = needed;
|
|
300
|
+
if (self._lastNeed > 0) return "";
|
|
301
|
+
const stored = self._lastTotal;
|
|
302
|
+
let j = 0;
|
|
303
|
+
while (j + 1 < stored) {
|
|
304
|
+
const code = self._lastChar[j] | self._lastChar[j + 1] << 8;
|
|
305
|
+
j += 2;
|
|
306
|
+
if (code >= 55296 && code <= 56319) {
|
|
307
|
+
if (j + 1 < stored) {
|
|
308
|
+
const nextCode = self._lastChar[j] | self._lastChar[j + 1] << 8;
|
|
309
|
+
if (nextCode >= 56320 && nextCode <= 57343) {
|
|
310
|
+
result += String.fromCharCode(code, nextCode);
|
|
311
|
+
j += 2;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (i + 1 < buf.length) {
|
|
316
|
+
const nextCode = buf[i] | buf[i + 1] << 8;
|
|
317
|
+
if (nextCode >= 56320 && nextCode <= 57343) {
|
|
318
|
+
result += String.fromCharCode(code, nextCode);
|
|
319
|
+
i += 2;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
} else if (i >= buf.length) {
|
|
323
|
+
self._lastChar[0] = self._lastChar[j - 2];
|
|
324
|
+
self._lastChar[1] = self._lastChar[j - 1];
|
|
325
|
+
self._lastNeed = 2;
|
|
326
|
+
self._lastTotal = 4;
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
result += String.fromCharCode(code);
|
|
331
|
+
}
|
|
332
|
+
self._lastTotal = 0;
|
|
333
|
+
}
|
|
334
|
+
while (i + 1 < buf.length) {
|
|
335
|
+
const code = buf[i] | buf[i + 1] << 8;
|
|
336
|
+
i += 2;
|
|
337
|
+
if (code >= 55296 && code <= 56319) {
|
|
338
|
+
if (i + 1 < buf.length) {
|
|
339
|
+
const nextCode = buf[i] | buf[i + 1] << 8;
|
|
340
|
+
if (nextCode >= 56320 && nextCode <= 57343) {
|
|
341
|
+
result += String.fromCharCode(code, nextCode);
|
|
342
|
+
i += 2;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
} else if (i < buf.length) {
|
|
346
|
+
result += String.fromCharCode(code);
|
|
347
|
+
self._lastChar[0] = buf[i];
|
|
348
|
+
self._lastNeed = 1;
|
|
349
|
+
self._lastTotal = 2;
|
|
350
|
+
return result;
|
|
351
|
+
} else {
|
|
352
|
+
self._lastChar[0] = buf[i - 2];
|
|
353
|
+
self._lastChar[1] = buf[i - 1];
|
|
354
|
+
self._lastNeed = 2;
|
|
355
|
+
self._lastTotal = 4;
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
result += String.fromCharCode(code);
|
|
360
|
+
}
|
|
361
|
+
if (i < buf.length) {
|
|
362
|
+
self._lastChar[0] = buf[i];
|
|
363
|
+
self._lastNeed = 1;
|
|
364
|
+
self._lastTotal = 2;
|
|
365
|
+
}
|
|
366
|
+
return result;
|
|
345
367
|
}
|
|
346
368
|
function writeBase64(self, buf) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
369
|
+
let start = 0;
|
|
370
|
+
if (self._lastNeed > 0) {
|
|
371
|
+
const needed = Math.min(self._lastNeed, buf.length);
|
|
372
|
+
for (let i = 0; i < needed; i++) {
|
|
373
|
+
self._lastChar[self._lastTotal - self._lastNeed + i] = buf[i];
|
|
374
|
+
self._lastNeed--;
|
|
375
|
+
}
|
|
376
|
+
start = needed;
|
|
377
|
+
if (self._lastNeed > 0) return "";
|
|
378
|
+
}
|
|
379
|
+
const remaining = buf.length - start;
|
|
380
|
+
const complete = remaining - remaining % 3;
|
|
381
|
+
let result = "";
|
|
382
|
+
if (self._lastTotal > 0 && self._lastNeed === 0) {
|
|
383
|
+
result += base64Encode(self._lastChar.subarray(0, self._lastTotal));
|
|
384
|
+
self._lastTotal = 0;
|
|
385
|
+
}
|
|
386
|
+
if (complete > 0) {
|
|
387
|
+
result += base64Encode(buf.subarray(start, start + complete));
|
|
388
|
+
}
|
|
389
|
+
const leftover = remaining - complete;
|
|
390
|
+
if (leftover > 0) {
|
|
391
|
+
for (let i = 0; i < leftover; i++) {
|
|
392
|
+
self._lastChar[i] = buf[start + complete + i];
|
|
393
|
+
}
|
|
394
|
+
self._lastNeed = 3 - leftover;
|
|
395
|
+
self._lastTotal = 3;
|
|
396
|
+
}
|
|
397
|
+
return result;
|
|
376
398
|
}
|
|
377
399
|
function decodeAscii(buf) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
400
|
+
let result = "";
|
|
401
|
+
for (let i = 0; i < buf.length; i++) {
|
|
402
|
+
result += String.fromCharCode(buf[i] & 127);
|
|
403
|
+
}
|
|
404
|
+
return result;
|
|
383
405
|
}
|
|
384
406
|
function decodeLatin1(buf) {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
407
|
+
let result = "";
|
|
408
|
+
for (let i = 0; i < buf.length; i++) {
|
|
409
|
+
result += String.fromCharCode(buf[i]);
|
|
410
|
+
}
|
|
411
|
+
return result;
|
|
390
412
|
}
|
|
391
413
|
function decodeHex(buf) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
414
|
+
let result = "";
|
|
415
|
+
for (let i = 0; i < buf.length; i++) {
|
|
416
|
+
result += buf[i].toString(16).padStart(2, "0");
|
|
417
|
+
}
|
|
418
|
+
return result;
|
|
397
419
|
}
|
|
398
|
-
var
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
};
|
|
420
|
+
var src_default = { StringDecoder };
|
|
421
|
+
|
|
422
|
+
//#endregion
|
|
423
|
+
export { StringDecoder, src_default as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/string_decoder",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
4
4
|
"description": "Node.js string_decoder module for Gjs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"string_decoder"
|
|
31
31
|
],
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@gjsify/cli": "^0.3.
|
|
34
|
-
"@gjsify/unit": "^0.3.
|
|
33
|
+
"@gjsify/cli": "^0.3.14",
|
|
34
|
+
"@gjsify/unit": "^0.3.14",
|
|
35
35
|
"@types/node": "^25.6.0",
|
|
36
36
|
"typescript": "^6.0.3"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@gjsify/utils": "^0.3.
|
|
39
|
+
"@gjsify/utils": "^0.3.14"
|
|
40
40
|
}
|
|
41
41
|
}
|