zip-js 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,541 +0,0 @@
1
- /*
2
- Copyright (c) 2013 Gildas Lormeau. All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are met:
6
-
7
- 1. Redistributions of source code must retain the above copyright notice,
8
- this list of conditions and the following disclaimer.
9
-
10
- 2. Redistributions in binary form must reproduce the above copyright
11
- notice, this list of conditions and the following disclaimer in
12
- the documentation and/or other materials provided with the distribution.
13
-
14
- 3. The names of the authors may not be used to endorse or promote products
15
- derived from this software without specific prior written permission.
16
-
17
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
18
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
20
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
21
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
- */
28
-
29
- (function() {
30
- "use strict";
31
-
32
- var CHUNK_SIZE = 512 * 1024;
33
-
34
- var TextWriter = zip.TextWriter, //
35
- BlobWriter = zip.BlobWriter, //
36
- Data64URIWriter = zip.Data64URIWriter, //
37
- Reader = zip.Reader, //
38
- TextReader = zip.TextReader, //
39
- BlobReader = zip.BlobReader, //
40
- Data64URIReader = zip.Data64URIReader, //
41
- createReader = zip.createReader, //
42
- createWriter = zip.createWriter;
43
-
44
- function ZipBlobReader(entry) {
45
- var that = this, blobReader;
46
-
47
- function init(callback) {
48
- that.size = entry.uncompressedSize;
49
- callback();
50
- }
51
-
52
- function getData(callback) {
53
- if (that.data)
54
- callback();
55
- else
56
- entry.getData(new BlobWriter(), function(data) {
57
- that.data = data;
58
- blobReader = new BlobReader(data);
59
- callback();
60
- }, null, that.checkCrc32);
61
- }
62
-
63
- function readUint8Array(index, length, callback, onerror) {
64
- getData(function() {
65
- blobReader.readUint8Array(index, length, callback, onerror);
66
- }, onerror);
67
- }
68
-
69
- that.size = 0;
70
- that.init = init;
71
- that.readUint8Array = readUint8Array;
72
- }
73
- ZipBlobReader.prototype = new Reader();
74
- ZipBlobReader.prototype.constructor = ZipBlobReader;
75
- ZipBlobReader.prototype.checkCrc32 = false;
76
-
77
- function getTotalSize(entry) {
78
- var size = 0;
79
-
80
- function process(entry) {
81
- size += entry.uncompressedSize || 0;
82
- entry.children.forEach(process);
83
- }
84
-
85
- process(entry);
86
- return size;
87
- }
88
-
89
- function initReaders(entry, onend, onerror) {
90
- var index = 0;
91
-
92
- function next() {
93
- index++;
94
- if (index < entry.children.length)
95
- process(entry.children[index]);
96
- else
97
- onend();
98
- }
99
-
100
- function process(child) {
101
- if (child.directory)
102
- initReaders(child, next, onerror);
103
- else {
104
- child.reader = new child.Reader(child.data, onerror);
105
- child.reader.init(function() {
106
- child.uncompressedSize = child.reader.size;
107
- next();
108
- });
109
- }
110
- }
111
-
112
- if (entry.children.length)
113
- process(entry.children[index]);
114
- else
115
- onend();
116
- }
117
-
118
- function detach(entry) {
119
- var children = entry.parent.children;
120
- children.forEach(function(child, index) {
121
- if (child.id == entry.id)
122
- children.splice(index, 1);
123
- });
124
- }
125
-
126
- function exportZip(zipWriter, entry, onend, onprogress, totalSize) {
127
- var currentIndex = 0;
128
-
129
- function process(zipWriter, entry, onend, onprogress, totalSize) {
130
- var childIndex = 0;
131
-
132
- function exportChild() {
133
- var child = entry.children[childIndex];
134
- if (child)
135
- zipWriter.add(child.getFullname(), child.reader, function() {
136
- currentIndex += child.uncompressedSize || 0;
137
- process(zipWriter, child, function() {
138
- childIndex++;
139
- exportChild();
140
- }, onprogress, totalSize);
141
- }, function(index) {
142
- if (onprogress)
143
- onprogress(currentIndex + index, totalSize);
144
- }, {
145
- directory : child.directory,
146
- version : child.zipVersion
147
- });
148
- else
149
- onend();
150
- }
151
-
152
- exportChild();
153
- }
154
-
155
- process(zipWriter, entry, onend, onprogress, totalSize);
156
- }
157
-
158
- function addFileEntry(zipEntry, fileEntry, onend, onerror) {
159
- function getChildren(fileEntry, callback) {
160
- if (fileEntry.isDirectory)
161
- fileEntry.createReader().readEntries(callback);
162
- if (fileEntry.isFile)
163
- callback([]);
164
- }
165
-
166
- function process(zipEntry, fileEntry, onend) {
167
- getChildren(fileEntry, function(children) {
168
- var childIndex = 0;
169
-
170
- function addChild(child) {
171
- function nextChild(childFileEntry) {
172
- process(childFileEntry, child, function() {
173
- childIndex++;
174
- processChild();
175
- });
176
- }
177
-
178
- if (child.isDirectory)
179
- nextChild(zipEntry.addDirectory(child.name));
180
- if (child.isFile)
181
- child.file(function(file) {
182
- var childZipEntry = zipEntry.addBlob(child.name, file);
183
- childZipEntry.uncompressedSize = file.size;
184
- nextChild(childZipEntry);
185
- }, onerror);
186
- }
187
-
188
- function processChild() {
189
- var child = children[childIndex];
190
- if (child)
191
- addChild(child);
192
- else
193
- onend();
194
- }
195
-
196
- processChild();
197
- });
198
- }
199
-
200
- if (fileEntry.isDirectory)
201
- process(zipEntry, fileEntry, onend);
202
- else
203
- fileEntry.file(function(file) {
204
- zipEntry.addBlob(fileEntry.name, file);
205
- onend();
206
- }, onerror);
207
- }
208
-
209
- function getFileEntry(fileEntry, entry, onend, onprogress, onerror, totalSize, checkCrc32) {
210
- var currentIndex = 0;
211
-
212
- function process(fileEntry, entry, onend, onprogress, onerror, totalSize) {
213
- var childIndex = 0;
214
-
215
- function addChild(child) {
216
- function nextChild(childFileEntry) {
217
- currentIndex += child.uncompressedSize || 0;
218
- process(childFileEntry, child, function() {
219
- childIndex++;
220
- processChild();
221
- }, onprogress, onerror, totalSize);
222
- }
223
-
224
- if (child.directory)
225
- fileEntry.getDirectory(child.name, {
226
- create : true
227
- }, nextChild, onerror);
228
- else
229
- fileEntry.getFile(child.name, {
230
- create : true
231
- }, function(file) {
232
- child.getData(new zip.FileWriter(file, zip.getMimeType(child.name)), nextChild, function(index) {
233
- if (onprogress)
234
- onprogress(currentIndex + index, totalSize);
235
- }, checkCrc32);
236
- }, onerror);
237
- }
238
-
239
- function processChild() {
240
- var child = entry.children[childIndex];
241
- if (child)
242
- addChild(child);
243
- else
244
- onend();
245
- }
246
-
247
- processChild();
248
- }
249
-
250
- if (entry.directory)
251
- process(fileEntry, entry, onend, onprogress, onerror, totalSize);
252
- else
253
- entry.getData(new zip.FileWriter(fileEntry, zip.getMimeType(entry.name)), onend, onprogress, checkCrc32);
254
- }
255
-
256
- function resetFS(fs) {
257
- fs.entries = [];
258
- fs.root = new ZipDirectoryEntry(fs);
259
- }
260
-
261
- function bufferedCopy(reader, writer, onend, onprogress, onerror) {
262
- var chunkIndex = 0;
263
-
264
- function stepCopy() {
265
- var index = chunkIndex * CHUNK_SIZE;
266
- if (onprogress)
267
- onprogress(index, reader.size);
268
- if (index < reader.size)
269
- reader.readUint8Array(index, Math.min(CHUNK_SIZE, reader.size - index), function(array) {
270
- writer.writeUint8Array(new Uint8Array(array), function() {
271
- chunkIndex++;
272
- stepCopy();
273
- });
274
- }, onerror);
275
- else
276
- writer.getData(onend);
277
- }
278
-
279
- stepCopy();
280
- }
281
-
282
- function addChild(parent, name, params, directory) {
283
- if (parent.directory)
284
- return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
285
- else
286
- throw "Parent entry is not a directory.";
287
- }
288
-
289
- function ZipEntry() {
290
- }
291
-
292
- ZipEntry.prototype = {
293
- init : function(fs, name, params, parent) {
294
- var that = this;
295
- if (fs.root && parent && parent.getChildByName(name))
296
- throw "Entry filename already exists.";
297
- if (!params)
298
- params = {};
299
- that.fs = fs;
300
- that.name = name;
301
- that.id = fs.entries.length;
302
- that.parent = parent;
303
- that.children = [];
304
- that.zipVersion = params.zipVersion || 0x14;
305
- that.uncompressedSize = 0;
306
- fs.entries.push(that);
307
- if (parent)
308
- that.parent.children.push(that);
309
- },
310
- getFileEntry : function(fileEntry, onend, onprogress, onerror, checkCrc32) {
311
- var that = this;
312
- initReaders(that, function() {
313
- getFileEntry(fileEntry, that, onend, onprogress, onerror, getTotalSize(that), checkCrc32);
314
- }, onerror);
315
- },
316
- moveTo : function(target) {
317
- var that = this;
318
- if (target.directory) {
319
- if (!target.isDescendantOf(that)) {
320
- if (that != target) {
321
- if (target.getChildByName(that.name))
322
- throw "Entry filename already exists.";
323
- detach(that);
324
- that.parent = target;
325
- target.children.push(that);
326
- }
327
- } else
328
- throw "Entry is a ancestor of target entry.";
329
- } else
330
- throw "Target entry is not a directory.";
331
- },
332
- getFullname : function() {
333
- var that = this, fullname = that.name, entry = that.parent;
334
- while (entry) {
335
- fullname = (entry.name ? entry.name + "/" : "") + fullname;
336
- entry = entry.parent;
337
- }
338
- return fullname;
339
- },
340
- isDescendantOf : function(ancestor) {
341
- var entry = this.parent;
342
- while (entry && entry.id != ancestor.id)
343
- entry = entry.parent;
344
- return !!entry;
345
- }
346
- };
347
- ZipEntry.prototype.constructor = ZipEntry;
348
-
349
- var ZipFileEntryProto;
350
-
351
- function ZipFileEntry(fs, name, params, parent) {
352
- var that = this;
353
- ZipEntry.prototype.init.call(that, fs, name, params, parent);
354
- that.Reader = params.Reader;
355
- that.Writer = params.Writer;
356
- that.data = params.data;
357
- if (params.getData) {
358
- that.getData = params.getData;
359
- }
360
- }
361
-
362
- ZipFileEntry.prototype = ZipFileEntryProto = new ZipEntry();
363
- ZipFileEntryProto.constructor = ZipFileEntry;
364
- ZipFileEntryProto.getData = function(writer, onend, onprogress, onerror) {
365
- var that = this;
366
- if (!writer || (writer.constructor == that.Writer && that.data))
367
- onend(that.data);
368
- else {
369
- if (!that.reader)
370
- that.reader = new that.Reader(that.data, onerror);
371
- that.reader.init(function() {
372
- writer.init(function() {
373
- bufferedCopy(that.reader, writer, onend, onprogress, onerror);
374
- }, onerror);
375
- });
376
- }
377
- };
378
-
379
- ZipFileEntryProto.getText = function(onend, onprogress, checkCrc32, encoding) {
380
- this.getData(new TextWriter(encoding), onend, onprogress, checkCrc32);
381
- };
382
- ZipFileEntryProto.getBlob = function(mimeType, onend, onprogress, checkCrc32) {
383
- this.getData(new BlobWriter(mimeType), onend, onprogress, checkCrc32);
384
- };
385
- ZipFileEntryProto.getData64URI = function(mimeType, onend, onprogress, checkCrc32) {
386
- this.getData(new Data64URIWriter(mimeType), onend, onprogress, checkCrc32);
387
- };
388
-
389
- var ZipDirectoryEntryProto;
390
-
391
- function ZipDirectoryEntry(fs, name, params, parent) {
392
- var that = this;
393
- ZipEntry.prototype.init.call(that, fs, name, params, parent);
394
- that.directory = true;
395
- }
396
-
397
- ZipDirectoryEntry.prototype = ZipDirectoryEntryProto = new ZipEntry();
398
- ZipDirectoryEntryProto.constructor = ZipDirectoryEntry;
399
- ZipDirectoryEntryProto.addDirectory = function(name) {
400
- return addChild(this, name, null, true);
401
- };
402
- ZipDirectoryEntryProto.addText = function(name, text) {
403
- return addChild(this, name, {
404
- data : text,
405
- Reader : TextReader,
406
- Writer : TextWriter
407
- });
408
- };
409
- ZipDirectoryEntryProto.addBlob = function(name, blob) {
410
- return addChild(this, name, {
411
- data : blob,
412
- Reader : BlobReader,
413
- Writer : BlobWriter
414
- });
415
- };
416
- ZipDirectoryEntryProto.addData64URI = function(name, dataURI) {
417
- return addChild(this, name, {
418
- data : dataURI,
419
- Reader : Data64URIReader,
420
- Writer : Data64URIWriter
421
- });
422
- };
423
- ZipDirectoryEntryProto.addFileEntry = function(fileEntry, onend, onerror) {
424
- addFileEntry(this, fileEntry, onend, onerror);
425
- };
426
- ZipDirectoryEntryProto.addData = function(name, params) {
427
- return addChild(this, name, params);
428
- };
429
- ZipDirectoryEntryProto.importBlob = function(blob, onend, onerror) {
430
- this.importZip(new BlobReader(blob), onend, onerror);
431
- };
432
- ZipDirectoryEntryProto.importText = function(text, onend, onerror) {
433
- this.importZip(new TextReader(text), onend, onerror);
434
- };
435
- ZipDirectoryEntryProto.importData64URI = function(dataURI, onend, onerror) {
436
- this.importZip(new Data64URIReader(dataURI), onend, onerror);
437
- };
438
- ZipDirectoryEntryProto.exportBlob = function(onend, onprogress, onerror) {
439
- this.exportZip(new BlobWriter("application/zip"), onend, onprogress, onerror);
440
- };
441
- ZipDirectoryEntryProto.exportText = function(onend, onprogress, onerror) {
442
- this.exportZip(new TextWriter(), onend, onprogress, onerror);
443
- };
444
- ZipDirectoryEntryProto.exportFileEntry = function(fileEntry, onend, onprogress, onerror) {
445
- this.exportZip(new zip.FileWriter(fileEntry, "application/zip"), onend, onprogress, onerror);
446
- };
447
- ZipDirectoryEntryProto.exportData64URI = function(onend, onprogress, onerror) {
448
- this.exportZip(new Data64URIWriter("application/zip"), onend, onprogress, onerror);
449
- };
450
- ZipDirectoryEntryProto.importZip = function(reader, onend, onerror) {
451
- var that = this;
452
- createReader(reader, function(zipReader) {
453
- zipReader.getEntries(function(entries) {
454
- entries.forEach(function(entry) {
455
- var parent = that, path = entry.filename.split("/"), name = path.pop();
456
- path.forEach(function(pathPart) {
457
- parent = parent.getChildByName(pathPart) || new ZipDirectoryEntry(that.fs, pathPart, null, parent);
458
- });
459
- if (!entry.directory)
460
- addChild(parent, name, {
461
- data : entry,
462
- Reader : ZipBlobReader
463
- });
464
- });
465
- onend();
466
- });
467
- }, onerror);
468
- };
469
- ZipDirectoryEntryProto.exportZip = function(writer, onend, onprogress, onerror) {
470
- var that = this;
471
- initReaders(that, function() {
472
- createWriter(writer, function(zipWriter) {
473
- exportZip(zipWriter, that, function() {
474
- zipWriter.close(onend);
475
- }, onprogress, getTotalSize(that));
476
- }, onerror);
477
- }, onerror);
478
- };
479
- ZipDirectoryEntryProto.getChildByName = function(name) {
480
- var childIndex, child, that = this;
481
- for (childIndex = 0; childIndex < that.children.length; childIndex++) {
482
- child = that.children[childIndex];
483
- if (child.name == name)
484
- return child;
485
- }
486
- };
487
-
488
- function FS() {
489
- resetFS(this);
490
- }
491
- FS.prototype = {
492
- remove : function(entry) {
493
- detach(entry);
494
- this.entries[entry.id] = null;
495
- },
496
- find : function(fullname) {
497
- var index, path = fullname.split("/"), node = this.root;
498
- for (index = 0; node && index < path.length; index++)
499
- node = node.getChildByName(path[index]);
500
- return node;
501
- },
502
- getById : function(id) {
503
- return this.entries[id];
504
- },
505
- importBlob : function(blob, onend, onerror) {
506
- resetFS(this);
507
- this.root.importBlob(blob, onend, onerror);
508
- },
509
- importText : function(text, onend, onerror) {
510
- resetFS(this);
511
- this.root.importText(text, onend, onerror);
512
- },
513
- importData64URI : function(dataURI, onend, onerror) {
514
- resetFS(this);
515
- this.root.importData64URI(dataURI, onend, onerror);
516
- },
517
- exportBlob : function(onend, onprogress, onerror) {
518
- this.root.exportBlob(onend, onprogress, onerror);
519
- },
520
- exportText : function(onend, onprogress, onerror) {
521
- this.root.exportText(onend, onprogress, onerror);
522
- },
523
- exportFileEntry : function(fileEntry, onend, onprogress, onerror) {
524
- this.root.exportFileEntry(fileEntry, onend, onprogress, onerror);
525
- },
526
- exportData64URI : function(onend, onprogress, onerror) {
527
- this.root.exportData64URI(onend, onprogress, onerror);
528
- }
529
- };
530
-
531
- zip.fs = {
532
- FS : FS,
533
- ZipDirectoryEntry : ZipDirectoryEntry,
534
- ZipFileEntry : ZipFileEntry
535
- };
536
-
537
- zip.getMimeType = function() {
538
- return "application/octet-stream";
539
- };
540
-
541
- })();