@node-projects/jszip 4.0.0

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/utf8.js ADDED
@@ -0,0 +1,276 @@
1
+ import utils from "./utils.js";
2
+ import support from "./support.js";
3
+ import nodejsUtils from "./nodejsUtils.js";
4
+ import { GenericWorker } from "./stream/GenericWorker.js";
5
+
6
+ /**
7
+ * The following functions come from pako, from pako/lib/utils/strings
8
+ * released under the MIT license, see pako https://github.com/nodeca/pako/
9
+ */
10
+
11
+ // Table with utf8 lengths (calculated by first byte of sequence)
12
+ // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
13
+ // because max possible codepoint is 0x10ffff
14
+ var _utf8len = new Array(256);
15
+ for (var i = 0; i < 256; i++) {
16
+ _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1);
17
+ }
18
+ _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
19
+
20
+ // convert string to array (typed, when possible)
21
+ var string2buf = function (str) {
22
+ var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
23
+
24
+ // count binary size
25
+ for (m_pos = 0; m_pos < str_len; m_pos++) {
26
+ c = str.charCodeAt(m_pos);
27
+ if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
28
+ c2 = str.charCodeAt(m_pos + 1);
29
+ if ((c2 & 0xfc00) === 0xdc00) {
30
+ c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
31
+ m_pos++;
32
+ }
33
+ }
34
+ buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
35
+ }
36
+
37
+ // allocate buffer
38
+ if (support.uint8array) {
39
+ buf = new Uint8Array(buf_len);
40
+ } else {
41
+ buf = new Array(buf_len);
42
+ }
43
+
44
+ // convert
45
+ for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
46
+ c = str.charCodeAt(m_pos);
47
+ if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
48
+ c2 = str.charCodeAt(m_pos + 1);
49
+ if ((c2 & 0xfc00) === 0xdc00) {
50
+ c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
51
+ m_pos++;
52
+ }
53
+ }
54
+ if (c < 0x80) {
55
+ /* one byte */
56
+ buf[i++] = c;
57
+ } else if (c < 0x800) {
58
+ /* two bytes */
59
+ buf[i++] = 0xC0 | (c >>> 6);
60
+ buf[i++] = 0x80 | (c & 0x3f);
61
+ } else if (c < 0x10000) {
62
+ /* three bytes */
63
+ buf[i++] = 0xE0 | (c >>> 12);
64
+ buf[i++] = 0x80 | (c >>> 6 & 0x3f);
65
+ buf[i++] = 0x80 | (c & 0x3f);
66
+ } else {
67
+ /* four bytes */
68
+ buf[i++] = 0xf0 | (c >>> 18);
69
+ buf[i++] = 0x80 | (c >>> 12 & 0x3f);
70
+ buf[i++] = 0x80 | (c >>> 6 & 0x3f);
71
+ buf[i++] = 0x80 | (c & 0x3f);
72
+ }
73
+ }
74
+
75
+ return buf;
76
+ };
77
+
78
+ // Calculate max possible position in utf8 buffer,
79
+ // that will not break sequence. If that's not possible
80
+ // - (very small limits) return max size as is.
81
+ //
82
+ // buf[] - utf8 bytes array
83
+ // max - length limit (mandatory);
84
+ var utf8border = function (buf, max) {
85
+ var pos;
86
+
87
+ max = max || buf.length;
88
+ if (max > buf.length) { max = buf.length; }
89
+
90
+ // go back from last position, until start of sequence found
91
+ pos = max - 1;
92
+ while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
93
+
94
+ // Fuckup - very small and broken sequence,
95
+ // return max, because we should return something anyway.
96
+ if (pos < 0) { return max; }
97
+
98
+ // If we came to start of buffer - that means vuffer is too small,
99
+ // return max too.
100
+ if (pos === 0) { return max; }
101
+
102
+ return (pos + _utf8len[buf[pos]] > max) ? pos : max;
103
+ };
104
+
105
+ // convert array to string
106
+ var buf2string = function (buf) {
107
+ var i, out, c, c_len;
108
+ var len = buf.length;
109
+
110
+ // Reserve max possible length (2 words per char)
111
+ // NB: by unknown reasons, Array is significantly faster for
112
+ // String.fromCharCode.apply than Uint16Array.
113
+ var utf16buf = new Array(len * 2);
114
+
115
+ for (out = 0, i = 0; i < len;) {
116
+ c = buf[i++];
117
+ // quick process ascii
118
+ if (c < 0x80) { utf16buf[out++] = c; continue; }
119
+
120
+ c_len = _utf8len[c];
121
+ // skip 5 & 6 byte codes
122
+ if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }
123
+
124
+ // apply mask on first byte
125
+ c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
126
+ // join the rest
127
+ while (c_len > 1 && i < len) {
128
+ c = (c << 6) | (buf[i++] & 0x3f);
129
+ c_len--;
130
+ }
131
+
132
+ // terminated by end of string?
133
+ if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
134
+
135
+ if (c < 0x10000) {
136
+ utf16buf[out++] = c;
137
+ } else {
138
+ c -= 0x10000;
139
+ utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
140
+ utf16buf[out++] = 0xdc00 | (c & 0x3ff);
141
+ }
142
+ }
143
+
144
+ // shrinkBuf(utf16buf, out)
145
+ if (utf16buf.length !== out) {
146
+ if (utf16buf.subarray) {
147
+ utf16buf = utf16buf.subarray(0, out);
148
+ } else {
149
+ utf16buf.length = out;
150
+ }
151
+ }
152
+
153
+ // return String.fromCharCode.apply(null, utf16buf);
154
+ return utils.applyFromCharCode(utf16buf);
155
+ };
156
+
157
+
158
+ // That's all for the pako functions.
159
+
160
+
161
+ /**
162
+ * Transform a javascript string into an array (typed if possible) of bytes,
163
+ * UTF-8 encoded.
164
+ * @param {String} str the string to encode
165
+ * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string.
166
+ */
167
+ export function utf8encode(str) {
168
+ if (support.nodebuffer) {
169
+ return nodejsUtils.newBufferFrom(str, "utf-8");
170
+ }
171
+
172
+ return string2buf(str);
173
+ };
174
+
175
+ /**
176
+ * Transform a bytes array (or a representation) representing an UTF-8 encoded
177
+ * string into a javascript string.
178
+ * @param {Array|Uint8Array|Buffer} buf the data de decode
179
+ * @return {String} the decoded string.
180
+ */
181
+ export function utf8decode(buf) {
182
+ if (support.nodebuffer) {
183
+ return utils.transformTo("nodebuffer", buf).toString("utf-8");
184
+ }
185
+
186
+ buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf);
187
+
188
+ return buf2string(buf);
189
+ };
190
+
191
+ export class Utf8DecodeWorker extends GenericWorker {
192
+ /**
193
+ * A worker to decode utf8 encoded binary chunks into string chunks.
194
+ * @constructor
195
+ */
196
+ constructor() {
197
+ super("utf-8 decode");
198
+ // the last bytes if a chunk didn't end with a complete codepoint.
199
+ this.leftOver = null;
200
+ }
201
+
202
+ /**
203
+ * @see GenericWorker.processChunk
204
+ */
205
+ processChunk(chunk) {
206
+
207
+ var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data);
208
+
209
+ // 1st step, re-use what's left of the previous chunk
210
+ if (this.leftOver && this.leftOver.length) {
211
+ if (support.uint8array) {
212
+ var previousData = data;
213
+ data = new Uint8Array(previousData.length + this.leftOver.length);
214
+ data.set(this.leftOver, 0);
215
+ data.set(previousData, this.leftOver.length);
216
+ } else {
217
+ data = this.leftOver.concat(data);
218
+ }
219
+ this.leftOver = null;
220
+ }
221
+
222
+ var nextBoundary = utf8border(data);
223
+ var usableData = data;
224
+ if (nextBoundary !== data.length) {
225
+ if (support.uint8array) {
226
+ usableData = data.subarray(0, nextBoundary);
227
+ this.leftOver = data.subarray(nextBoundary, data.length);
228
+ } else {
229
+ usableData = data.slice(0, nextBoundary);
230
+ this.leftOver = data.slice(nextBoundary, data.length);
231
+ }
232
+ }
233
+
234
+ this.push({
235
+ data: exports.utf8decode(usableData),
236
+ meta: chunk.meta
237
+ });
238
+ };
239
+
240
+ /**
241
+ * @see GenericWorker.flush
242
+ */
243
+ flush() {
244
+ if (this.leftOver && this.leftOver.length) {
245
+ this.push({
246
+ data: exports.utf8decode(this.leftOver),
247
+ meta: {}
248
+ });
249
+ this.leftOver = null;
250
+ }
251
+ };
252
+ }
253
+
254
+ export class Utf8EncodeWorker extends GenericWorker {
255
+ /**
256
+ * A worker to endcode string chunks into utf8 encoded binary chunks.
257
+ * @constructor
258
+ */
259
+ constructor() {
260
+ super("utf-8 encode");
261
+ }
262
+
263
+ /**
264
+ * @see GenericWorker.processChunk
265
+ */
266
+ processChunk(chunk) {
267
+ this.push({
268
+ data: utf8encode(chunk.data),
269
+ meta: chunk.meta
270
+ });
271
+ };
272
+ }
273
+
274
+ export default {
275
+ utf8encode, utf8decode, Utf8DecodeWorker, Utf8EncodeWorker
276
+ }