@zip.js/zip.js 2.5.2 → 2.5.5
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/dist/z-worker-fflate.js +1 -1
- package/dist/z-worker-pako.js +1 -1
- package/dist/z-worker.js +1 -1
- package/dist/zip-fs-full.js +460 -482
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +460 -482
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +460 -482
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +460 -482
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +1 -1
- package/index.d.ts +1 -1
- package/index.js +3 -3
- package/lib/core/codec-interface.js +89 -0
- package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +55 -29
- package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
- package/lib/core/configuration.js +10 -1
- package/lib/core/io.js +102 -100
- package/lib/core/{codecs → streams}/aes-crypto-stream.js +68 -54
- package/lib/core/{codecs → streams}/codec-stream.js +3 -6
- package/lib/core/{codecs → streams/codecs}/crc32.js +0 -0
- package/lib/core/{codecs → streams/codecs}/deflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/inflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/sjcl.js +0 -0
- package/lib/core/{codecs → streams}/crc32-stream.js +3 -4
- package/lib/core/{codecs → streams}/zip-crypto-stream.js +28 -32
- package/lib/core/streams/zip-entry-stream.js +178 -0
- package/lib/core/z-worker-core.js +30 -15
- package/lib/core/zip-fs-core.js +1 -1
- package/lib/core/zip-reader.js +21 -12
- package/lib/core/zip-writer.js +33 -22
- package/lib/z-worker-fflate.js +4 -1
- package/lib/z-worker-inline.js +1 -1
- package/lib/z-worker.js +2 -2
- package/lib/zip-fflate-shim.js +4 -1
- package/lib/zip-fs.js +6 -2
- package/lib/zip-full-fflate.js +6 -3
- package/lib/zip-full.js +8 -5
- package/lib/zip-no-worker-deflate.js +7 -3
- package/lib/zip-no-worker-fflate-deflate.js +6 -2
- package/lib/zip-no-worker-fflate-inflate.js +6 -3
- package/lib/zip-no-worker-fflate.js +6 -3
- package/lib/zip-no-worker-inflate.js +7 -4
- package/lib/zip-no-worker.js +8 -5
- package/lib/zip.js +6 -3
- package/package.json +2 -8
- package/tests/all/test-safe-closing.js +1 -1
- package/tests/node/package.json +2 -6
- package/tests/node/test-node.js +7 -11
- package/lib/core/codecs/codec.js +0 -230
- package/lib/core/engine.js +0 -89
|
@@ -26,9 +26,17 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Worker, URL */
|
|
30
|
-
|
|
31
|
-
import {
|
|
29
|
+
/* global Worker, URL, TransformStream */
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
createCodec,
|
|
33
|
+
MESSAGE_EVENT_TYPE,
|
|
34
|
+
MESSAGE_START,
|
|
35
|
+
MESSAGE_PULL,
|
|
36
|
+
MESSAGE_DATA,
|
|
37
|
+
MESSAGE_ABORT,
|
|
38
|
+
MESSAGE_CLOSE
|
|
39
|
+
} from "./codec-interface.js";
|
|
32
40
|
|
|
33
41
|
let classicWorkersSupported = true;
|
|
34
42
|
|
|
@@ -36,10 +44,12 @@ export {
|
|
|
36
44
|
getWorker
|
|
37
45
|
};
|
|
38
46
|
|
|
39
|
-
function getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts) {
|
|
47
|
+
function getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts) {
|
|
40
48
|
Object.assign(workerData, {
|
|
41
49
|
busy: true,
|
|
42
50
|
codecConstructor,
|
|
51
|
+
readable,
|
|
52
|
+
writable,
|
|
43
53
|
options: Object.assign({}, options),
|
|
44
54
|
scripts,
|
|
45
55
|
terminate() {
|
|
@@ -53,27 +63,50 @@ function getWorker(workerData, codecConstructor, options, config, onTaskFinished
|
|
|
53
63
|
onTaskFinished(workerData);
|
|
54
64
|
}
|
|
55
65
|
});
|
|
66
|
+
const { signal, onprogress, size } = streamOptions;
|
|
67
|
+
if (signal || onprogress) {
|
|
68
|
+
let chunkOffset = 0;
|
|
69
|
+
const transformer = {};
|
|
70
|
+
if (onprogress) {
|
|
71
|
+
transformer.transform = (chunk, controller) => {
|
|
72
|
+
chunkOffset += chunk.length;
|
|
73
|
+
try {
|
|
74
|
+
onprogress(chunkOffset, size());
|
|
75
|
+
} catch (_error) {
|
|
76
|
+
// ignored
|
|
77
|
+
}
|
|
78
|
+
controller.enqueue(chunk);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
workerData.readable = readable.pipeThrough(new TransformStream(transformer), { signal });
|
|
82
|
+
}
|
|
56
83
|
return webWorker ? createWebWorkerInterface(workerData, config) : createWorkerInterface(workerData, config);
|
|
57
84
|
}
|
|
58
85
|
|
|
59
86
|
function createWorkerInterface(workerData, config) {
|
|
60
|
-
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.options, config);
|
|
87
|
+
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.readable, workerData.writable, workerData.options, config);
|
|
61
88
|
const codec = {
|
|
62
89
|
abort() {
|
|
63
90
|
interfaceCodec.abort();
|
|
64
91
|
workerData.onTaskFinished();
|
|
65
92
|
},
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
run() {
|
|
94
|
+
const result = interfaceCodec.run();
|
|
95
|
+
workerData.onTaskFinished();
|
|
96
|
+
return result;
|
|
68
97
|
}
|
|
69
98
|
};
|
|
70
|
-
interfaceCodec.pull = () => codec.pull();
|
|
71
|
-
interfaceCodec.ondata = data => ondata(workerData, codec, data);
|
|
72
99
|
return codec;
|
|
73
100
|
}
|
|
74
101
|
|
|
75
102
|
function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
76
103
|
const workerOptions = { type: "module" };
|
|
104
|
+
workerData.reader = workerData.readable.getReader();
|
|
105
|
+
workerData.writer = workerData.writable.getWriter();
|
|
106
|
+
workerData.result = new Promise((resolve, reject) => {
|
|
107
|
+
workerData.resolveResult = resolve;
|
|
108
|
+
workerData.rejectResult = reject;
|
|
109
|
+
});
|
|
77
110
|
if (!workerData.interface) {
|
|
78
111
|
if (!classicWorkersSupported) {
|
|
79
112
|
workerData.worker = getWorker(workerOptions);
|
|
@@ -91,10 +124,11 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
91
124
|
sendMessage({ type: MESSAGE_ABORT });
|
|
92
125
|
workerData.onTaskFinished();
|
|
93
126
|
},
|
|
94
|
-
|
|
127
|
+
run() {
|
|
95
128
|
const options = workerData.options;
|
|
96
129
|
const scripts = workerData.scripts.slice(1);
|
|
97
130
|
sendMessage({ type: MESSAGE_START, scripts, options, config: { chunkSize } });
|
|
131
|
+
return workerData.result;
|
|
98
132
|
}
|
|
99
133
|
};
|
|
100
134
|
}
|
|
@@ -136,39 +170,31 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
136
170
|
async function onMessage(event) {
|
|
137
171
|
const message = event.data;
|
|
138
172
|
const reponseError = message.error;
|
|
139
|
-
const codec = workerData.interface;
|
|
140
173
|
try {
|
|
141
174
|
if (reponseError) {
|
|
142
175
|
const error = new Error(reponseError.message);
|
|
143
176
|
error.stack = reponseError.stack;
|
|
144
|
-
|
|
177
|
+
workerData.rejectResult(error);
|
|
145
178
|
workerData.onTaskFinished();
|
|
146
179
|
} else {
|
|
147
180
|
if (message.type == MESSAGE_PULL) {
|
|
148
|
-
const { value, done } = await
|
|
181
|
+
const { value, done } = await workerData.reader.read();
|
|
149
182
|
sendMessage({ type: MESSAGE_DATA, data: value, done, messageId: message.messageId });
|
|
150
183
|
}
|
|
151
184
|
if (message.type == MESSAGE_DATA) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
185
|
+
let { data } = message;
|
|
186
|
+
data = new Uint8Array(data);
|
|
187
|
+
await workerData.writer.ready;
|
|
188
|
+
workerData.writer.write(data);
|
|
189
|
+
}
|
|
190
|
+
if (message.type == MESSAGE_CLOSE) {
|
|
191
|
+
workerData.resolveResult(message.result);
|
|
192
|
+
workerData.onTaskFinished();
|
|
157
193
|
}
|
|
158
194
|
}
|
|
159
195
|
} catch (error) {
|
|
160
|
-
|
|
196
|
+
workerData.rejectResult(error);
|
|
161
197
|
workerData.onTaskFinished();
|
|
162
198
|
}
|
|
163
199
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async function ondata(workerData, codec, data) {
|
|
167
|
-
let { value, done } = data;
|
|
168
|
-
if (done) {
|
|
169
|
-
await codec.ondata({ value: { data: value.data, signature: value.signature }, done });
|
|
170
|
-
workerData.onTaskFinished();
|
|
171
|
-
} else if (value.data) {
|
|
172
|
-
await codec.ondata({ value: { data: value.data } });
|
|
173
|
-
}
|
|
174
200
|
}
|
|
@@ -28,47 +28,66 @@
|
|
|
28
28
|
|
|
29
29
|
/* global setTimeout, clearTimeout */
|
|
30
30
|
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
CODEC_INFLATE,
|
|
33
|
+
CODEC_DEFLATE,
|
|
34
|
+
ERR_INVALID_SIGNATURE,
|
|
35
|
+
ERR_INVALID_PASSWORD,
|
|
36
|
+
ERR_ABORT
|
|
37
|
+
} from "./codec-interface.js";
|
|
32
38
|
import { getWorker } from "./codec-pool-worker.js";
|
|
33
39
|
|
|
34
40
|
let pool = [];
|
|
35
41
|
const pendingRequests = [];
|
|
36
42
|
|
|
37
43
|
export {
|
|
38
|
-
|
|
44
|
+
runCodec,
|
|
39
45
|
terminateWorkers,
|
|
40
46
|
CODEC_DEFLATE,
|
|
41
47
|
CODEC_INFLATE,
|
|
42
48
|
ERR_INVALID_SIGNATURE,
|
|
43
|
-
ERR_INVALID_PASSWORD
|
|
49
|
+
ERR_INVALID_PASSWORD,
|
|
50
|
+
ERR_ABORT
|
|
44
51
|
};
|
|
45
52
|
|
|
46
53
|
let indexWorker = 0;
|
|
47
54
|
|
|
48
|
-
function
|
|
55
|
+
async function runCodec(codecConstructor, readable, writable, options, config, streamOptions) {
|
|
49
56
|
const streamCopy = !options.compressed && !options.signed && !options.encrypted;
|
|
50
57
|
const webWorker = !streamCopy && (options.useWebWorkers || (options.useWebWorkers === undefined && config.useWebWorkers));
|
|
51
58
|
const scripts = webWorker && config.workerScripts ? config.workerScripts[options.codecType] : [];
|
|
52
59
|
options.useCompressionStream = options.useCompressionStream === undefined ? config.useCompressionStream : options.useCompressionStream;
|
|
60
|
+
let codec;
|
|
53
61
|
if (pool.length < config.maxWorkers) {
|
|
54
62
|
const workerData = { indexWorker };
|
|
55
63
|
indexWorker++;
|
|
56
64
|
pool.push(workerData);
|
|
57
|
-
|
|
65
|
+
codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
|
|
58
66
|
} else {
|
|
59
67
|
const workerData = pool.find(workerData => !workerData.busy);
|
|
60
68
|
if (workerData) {
|
|
61
69
|
clearTerminateTimeout(workerData);
|
|
62
|
-
|
|
70
|
+
codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
|
|
71
|
+
} else {
|
|
72
|
+
codec = await new Promise(resolve => pendingRequests.push({ resolve, codecConstructor, readable, writable, options, webWorker, scripts }));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const { signal } = streamOptions;
|
|
76
|
+
try {
|
|
77
|
+
return await codec.run(signal);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (signal && signal.aborted && signal.reason == error) {
|
|
80
|
+
codec.abort();
|
|
81
|
+
throw new Error(ERR_ABORT);
|
|
63
82
|
} else {
|
|
64
|
-
|
|
83
|
+
throw error;
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
86
|
|
|
68
87
|
function onTaskFinished(workerData) {
|
|
69
88
|
if (pendingRequests.length) {
|
|
70
|
-
const [{ resolve, codecConstructor, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
|
|
71
|
-
resolve(getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts));
|
|
89
|
+
const [{ resolve, codecConstructor, readable, writable, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
|
|
90
|
+
resolve(getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts));
|
|
72
91
|
} else if (workerData.worker) {
|
|
73
92
|
clearTerminateTimeout(workerData);
|
|
74
93
|
if (Number.isFinite(config.terminateWorkerTimeout) && config.terminateWorkerTimeout >= 0) {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
/* global navigator */
|
|
30
30
|
|
|
31
|
+
const MINIMUM_CHUNK_SIZE = 64;
|
|
31
32
|
const DEFAULT_CONFIGURATION = {
|
|
32
33
|
chunkSize: 512 * 1024,
|
|
33
34
|
maxWorkers: (typeof navigator != "undefined" && navigator.hardwareConcurrency) || 2,
|
|
@@ -40,13 +41,18 @@ const config = Object.assign({}, DEFAULT_CONFIGURATION);
|
|
|
40
41
|
|
|
41
42
|
export {
|
|
42
43
|
configure,
|
|
43
|
-
getConfiguration
|
|
44
|
+
getConfiguration,
|
|
45
|
+
getChunkSize
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
function getConfiguration() {
|
|
47
49
|
return config;
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
function getChunkSize(config) {
|
|
53
|
+
return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
function configure(configuration) {
|
|
51
57
|
if (configuration.baseURL !== undefined) {
|
|
52
58
|
config.baseURL = configuration.baseURL;
|
|
@@ -60,6 +66,9 @@ function configure(configuration) {
|
|
|
60
66
|
if (configuration.terminateWorkerTimeout !== undefined) {
|
|
61
67
|
config.terminateWorkerTimeout = configuration.terminateWorkerTimeout;
|
|
62
68
|
}
|
|
69
|
+
if (configuration.useCompressionStream !== undefined) {
|
|
70
|
+
config.useCompressionStream = configuration.useCompressionStream;
|
|
71
|
+
}
|
|
63
72
|
if (configuration.useWebWorkers !== undefined) {
|
|
64
73
|
config.useWebWorkers = configuration.useWebWorkers;
|
|
65
74
|
}
|
package/lib/core/io.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Blob, FileReader, atob, btoa, XMLHttpRequest, document, fetch */
|
|
29
|
+
/* global Blob, FileReader, atob, btoa, XMLHttpRequest, document, fetch, ReadableStream, WritableStream */
|
|
30
30
|
|
|
31
31
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
32
32
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
@@ -40,6 +40,7 @@ const HTTP_HEADER_RANGE = "Range";
|
|
|
40
40
|
const HTTP_METHOD_HEAD = "HEAD";
|
|
41
41
|
const HTTP_METHOD_GET = "GET";
|
|
42
42
|
const HTTP_RANGE_UNIT = "bytes";
|
|
43
|
+
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
43
44
|
|
|
44
45
|
class Stream {
|
|
45
46
|
|
|
@@ -53,9 +54,39 @@ class Stream {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
class Reader extends Stream {
|
|
57
|
+
|
|
58
|
+
getStream({ offset, size, chunkSize } = { offset: 0, chunkSize: DEFAULT_CHUNK_SIZE }) {
|
|
59
|
+
const reader = this;
|
|
60
|
+
return new ReadableStream({
|
|
61
|
+
start() {
|
|
62
|
+
this.chunkOffset = 0;
|
|
63
|
+
},
|
|
64
|
+
async pull(controller) {
|
|
65
|
+
const { chunkOffset } = this;
|
|
66
|
+
controller.enqueue(await reader.readUint8Array(offset + chunkOffset, Math.min(chunkSize, size() - chunkOffset)));
|
|
67
|
+
if (chunkOffset + chunkSize > size()) {
|
|
68
|
+
controller.close();
|
|
69
|
+
} else {
|
|
70
|
+
this.chunkOffset += chunkSize;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
class WriterStream extends Stream {
|
|
78
|
+
|
|
79
|
+
getStream() {
|
|
80
|
+
const writer = this;
|
|
81
|
+
return new WritableStream({
|
|
82
|
+
write(chunk) {
|
|
83
|
+
return writer.writeUint8Array(chunk);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
56
87
|
}
|
|
57
88
|
|
|
58
|
-
class Writer extends
|
|
89
|
+
class Writer extends WriterStream {
|
|
59
90
|
|
|
60
91
|
writeUint8Array(array) {
|
|
61
92
|
this.size += array.length;
|
|
@@ -70,9 +101,10 @@ class TextReader extends Reader {
|
|
|
70
101
|
}
|
|
71
102
|
|
|
72
103
|
init() {
|
|
104
|
+
const reader = this;
|
|
73
105
|
super.init();
|
|
74
|
-
|
|
75
|
-
|
|
106
|
+
reader.blobReader.init();
|
|
107
|
+
reader.size = reader.blobReader.size;
|
|
76
108
|
}
|
|
77
109
|
|
|
78
110
|
readUint8Array(offset, length) {
|
|
@@ -94,14 +126,15 @@ class TextWriter extends Writer {
|
|
|
94
126
|
}
|
|
95
127
|
|
|
96
128
|
getData() {
|
|
97
|
-
|
|
98
|
-
|
|
129
|
+
const writer = this;
|
|
130
|
+
if (writer.blob.text) {
|
|
131
|
+
return writer.blob.text();
|
|
99
132
|
} else {
|
|
100
133
|
const reader = new FileReader();
|
|
101
134
|
return new Promise((resolve, reject) => {
|
|
102
135
|
reader.onload = event => resolve(event.target.result);
|
|
103
136
|
reader.onerror = () => reject(reader.error);
|
|
104
|
-
reader.readAsText(
|
|
137
|
+
reader.readAsText(writer.blob, writer.encoding);
|
|
105
138
|
});
|
|
106
139
|
}
|
|
107
140
|
}
|
|
@@ -111,19 +144,21 @@ class Data64URIReader extends Reader {
|
|
|
111
144
|
|
|
112
145
|
constructor(dataURI) {
|
|
113
146
|
super();
|
|
114
|
-
|
|
147
|
+
const reader = this;
|
|
148
|
+
reader.dataURI = dataURI;
|
|
115
149
|
let dataEnd = dataURI.length;
|
|
116
150
|
while (dataURI.charAt(dataEnd - 1) == "=") {
|
|
117
151
|
dataEnd--;
|
|
118
152
|
}
|
|
119
|
-
|
|
120
|
-
|
|
153
|
+
reader.dataStart = dataURI.indexOf(",") + 1;
|
|
154
|
+
reader.size = Math.floor((dataEnd - reader.dataStart) * 0.75);
|
|
121
155
|
}
|
|
122
156
|
|
|
123
157
|
readUint8Array(offset, length) {
|
|
124
158
|
const dataArray = new Uint8Array(length);
|
|
125
159
|
const start = Math.floor(offset / 3) * 4;
|
|
126
|
-
const
|
|
160
|
+
const dataStart = this.dataStart;
|
|
161
|
+
const bytes = atob(this.dataURI.substring(start + dataStart, Math.ceil((offset + length) / 3) * 4 + dataStart));
|
|
127
162
|
const delta = offset - Math.floor(start / 4) * 3;
|
|
128
163
|
for (let indexByte = delta; indexByte < delta + length; indexByte++) {
|
|
129
164
|
dataArray[indexByte - delta] = bytes.charCodeAt(indexByte);
|
|
@@ -142,20 +177,21 @@ class Data64URIWriter extends Writer {
|
|
|
142
177
|
|
|
143
178
|
writeUint8Array(array) {
|
|
144
179
|
super.writeUint8Array(array);
|
|
180
|
+
const writer = this;
|
|
145
181
|
let indexArray = 0;
|
|
146
|
-
let dataString =
|
|
147
|
-
const delta =
|
|
148
|
-
|
|
182
|
+
let dataString = writer.pending;
|
|
183
|
+
const delta = writer.pending.length;
|
|
184
|
+
writer.pending = "";
|
|
149
185
|
for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
|
|
150
186
|
dataString += String.fromCharCode(array[indexArray]);
|
|
151
187
|
}
|
|
152
188
|
for (; indexArray < array.length; indexArray++) {
|
|
153
|
-
|
|
189
|
+
writer.pending += String.fromCharCode(array[indexArray]);
|
|
154
190
|
}
|
|
155
191
|
if (dataString.length > 2) {
|
|
156
|
-
|
|
192
|
+
writer.data += btoa(dataString);
|
|
157
193
|
} else {
|
|
158
|
-
|
|
194
|
+
writer.pending = dataString;
|
|
159
195
|
}
|
|
160
196
|
}
|
|
161
197
|
|
|
@@ -173,14 +209,15 @@ class BlobReader extends Reader {
|
|
|
173
209
|
}
|
|
174
210
|
|
|
175
211
|
async readUint8Array(offset, length) {
|
|
176
|
-
|
|
177
|
-
|
|
212
|
+
const reader = this;
|
|
213
|
+
if (reader.blob.arrayBuffer) {
|
|
214
|
+
return new Uint8Array(await reader.blob.slice(offset, offset + length).arrayBuffer());
|
|
178
215
|
} else {
|
|
179
216
|
const reader = new FileReader();
|
|
180
217
|
return new Promise((resolve, reject) => {
|
|
181
218
|
reader.onload = event => resolve(new Uint8Array(event.target.result));
|
|
182
219
|
reader.onerror = () => reject(reader.error);
|
|
183
|
-
reader.readAsArrayBuffer(
|
|
220
|
+
reader.readAsArrayBuffer(reader.blob.slice(offset, offset + length));
|
|
184
221
|
});
|
|
185
222
|
}
|
|
186
223
|
}
|
|
@@ -197,21 +234,23 @@ class BlobWriter extends Writer {
|
|
|
197
234
|
|
|
198
235
|
writeUint8Array(array) {
|
|
199
236
|
super.writeUint8Array(array);
|
|
200
|
-
|
|
201
|
-
|
|
237
|
+
const writer = this;
|
|
238
|
+
if (writer.arrayBuffers.length == writer.arrayBuffersMaxlength) {
|
|
239
|
+
flushArrayBuffers(writer);
|
|
202
240
|
}
|
|
203
|
-
|
|
241
|
+
writer.arrayBuffers.push(array.buffer);
|
|
204
242
|
}
|
|
205
243
|
|
|
206
244
|
getData() {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
245
|
+
const writer = this;
|
|
246
|
+
if (!writer.blob) {
|
|
247
|
+
if (writer.arrayBuffers.length) {
|
|
248
|
+
flushArrayBuffers(writer);
|
|
210
249
|
}
|
|
211
|
-
|
|
212
|
-
initArrayBuffers(
|
|
250
|
+
writer.blob = writer.pendingBlob;
|
|
251
|
+
initArrayBuffers(writer);
|
|
213
252
|
}
|
|
214
|
-
return
|
|
253
|
+
return writer.blob;
|
|
215
254
|
}
|
|
216
255
|
}
|
|
217
256
|
|
|
@@ -229,78 +268,38 @@ class ReadableStreamReader {
|
|
|
229
268
|
|
|
230
269
|
constructor(readableStream) {
|
|
231
270
|
this.readableStream = readableStream;
|
|
232
|
-
this.reader = readableStream.getReader();
|
|
233
271
|
this.size = Infinity;
|
|
234
|
-
this.index = 0;
|
|
235
|
-
this.currentSize = 0;
|
|
236
|
-
this.pendingValue = new Uint8Array();
|
|
237
272
|
}
|
|
238
273
|
|
|
239
|
-
init() {
|
|
274
|
+
init(size) {
|
|
275
|
+
this.size = size;
|
|
240
276
|
this.initialized = true;
|
|
241
277
|
}
|
|
242
278
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
throw new Error(ERR_NOT_SEEKABLE_READER);
|
|
246
|
-
}
|
|
247
|
-
let data = new Uint8Array(length);
|
|
248
|
-
let size = 0, done;
|
|
249
|
-
do {
|
|
250
|
-
const result = await this.reader.read();
|
|
251
|
-
let { value } = result;
|
|
252
|
-
done = result.done;
|
|
253
|
-
if (value) {
|
|
254
|
-
this.currentSize += value.length;
|
|
255
|
-
} else {
|
|
256
|
-
value = this.pendingValue;
|
|
257
|
-
this.pendingValue = new Uint8Array();
|
|
258
|
-
}
|
|
259
|
-
if (this.pendingValue.length) {
|
|
260
|
-
const newValue = new Uint8Array(this.pendingValue.length + value.length);
|
|
261
|
-
newValue.set(this.pendingValue);
|
|
262
|
-
newValue.set(value, this.pendingValue.length);
|
|
263
|
-
this.pendingValue = new Uint8Array();
|
|
264
|
-
value = newValue;
|
|
265
|
-
}
|
|
266
|
-
if (size + value.length > length) {
|
|
267
|
-
data.set(value.subarray(0, length), size);
|
|
268
|
-
this.pendingValue = value.subarray(length);
|
|
269
|
-
size += length;
|
|
270
|
-
} else {
|
|
271
|
-
data.set(value, size);
|
|
272
|
-
size += value.length;
|
|
273
|
-
}
|
|
274
|
-
} while (size < length && !done);
|
|
275
|
-
if (done && this.size == Infinity) {
|
|
276
|
-
this.size = this.currentSize;
|
|
277
|
-
}
|
|
278
|
-
if (this.size < length) {
|
|
279
|
-
data = data.slice(0, this.size);
|
|
280
|
-
length = this.size;
|
|
281
|
-
}
|
|
282
|
-
this.index += length;
|
|
283
|
-
return data;
|
|
279
|
+
getStream() {
|
|
280
|
+
return this.readableStream;
|
|
284
281
|
}
|
|
285
282
|
}
|
|
286
283
|
|
|
287
284
|
class WritableStreamWriter extends Writer {
|
|
288
285
|
|
|
289
|
-
constructor(
|
|
286
|
+
constructor(writable) {
|
|
290
287
|
super();
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
const writer = this;
|
|
289
|
+
writer.writable = writable;
|
|
293
290
|
}
|
|
294
291
|
|
|
295
292
|
async writeUint8Array(array) {
|
|
296
293
|
await this.writer.ready;
|
|
297
|
-
return this.
|
|
294
|
+
return this.writable.getWriter().write(array);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
getStream() {
|
|
298
|
+
return this.writable;
|
|
298
299
|
}
|
|
299
300
|
|
|
300
301
|
async getData() {
|
|
301
|
-
|
|
302
|
-
await this.writer.close();
|
|
303
|
-
return this.writableStream;
|
|
302
|
+
return this.writable;
|
|
304
303
|
}
|
|
305
304
|
}
|
|
306
305
|
|
|
@@ -308,15 +307,16 @@ class FetchReader extends Reader {
|
|
|
308
307
|
|
|
309
308
|
constructor(url, options) {
|
|
310
309
|
super();
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
delete
|
|
318
|
-
delete
|
|
319
|
-
delete
|
|
310
|
+
const reader = this;
|
|
311
|
+
reader.url = url;
|
|
312
|
+
reader.preventHeadRequest = options.preventHeadRequest;
|
|
313
|
+
reader.useRangeHeader = options.useRangeHeader;
|
|
314
|
+
reader.forceRangeRequests = options.forceRangeRequests;
|
|
315
|
+
reader.options = Object.assign({}, options);
|
|
316
|
+
delete reader.options.preventHeadRequest;
|
|
317
|
+
delete reader.options.useRangeHeader;
|
|
318
|
+
delete reader.options.forceRangeRequests;
|
|
319
|
+
delete reader.options.useXHR;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
async init() {
|
|
@@ -333,11 +333,12 @@ class XHRReader extends Reader {
|
|
|
333
333
|
|
|
334
334
|
constructor(url, options) {
|
|
335
335
|
super();
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
336
|
+
const reader = this;
|
|
337
|
+
reader.url = url;
|
|
338
|
+
reader.preventHeadRequest = options.preventHeadRequest;
|
|
339
|
+
reader.useRangeHeader = options.useRangeHeader;
|
|
340
|
+
reader.forceRangeRequests = options.forceRangeRequests;
|
|
341
|
+
reader.options = options;
|
|
341
342
|
}
|
|
342
343
|
|
|
343
344
|
async init() {
|
|
@@ -540,10 +541,11 @@ class Uint8ArrayWriter extends Writer {
|
|
|
540
541
|
|
|
541
542
|
writeUint8Array(array) {
|
|
542
543
|
super.writeUint8Array(array);
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
544
|
+
const writer = this;
|
|
545
|
+
const previousArray = writer.array;
|
|
546
|
+
writer.array = new Uint8Array(previousArray.length + array.length);
|
|
547
|
+
writer.array.set(previousArray);
|
|
548
|
+
writer.array.set(array, previousArray.length);
|
|
547
549
|
}
|
|
548
550
|
|
|
549
551
|
getData() {
|