1
2
3
4
5
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
122
123
124
125
126
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Ci, Cc } = require("chrome");
const { defer, all } = require("sdk/core/promise");
const PR_RDONLY = 0x01;
const PR_WRONLY = 0x02;
const PR_RDWR = 0x04;
const PR_CREATE_FILE = 0x08;
const PR_APPEND = 0x10;
const PR_TRUNCATE = 0x20;
const PR_SYNC = 0x40;
const PR_EXCL = 0x80;
// Default compression level:
const { COMPRESSION_DEFAULT } = Ci.nsIZipWriter;
function createNsFile(path) {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
try {
file.initWithPath(path);
} catch(e) {
throw new Error("This zip file path is not valid : " + path + "\n" + e);
}
return file;
}
exports.createNsFile = createNsFile;
const converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
function streamForData(data) {
return converter.convertToInputStream(data);
}
exports.ZipWriter = function (zipPath, mode) {
mode = mode ? mode : PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE;
let zw = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
zw.open(createNsFile(zipPath), mode);
// Create a directory entry.
// Returns true if the entry was created, or false if the entry already exists
this.mkdir = function mkdir(pathInZip) {
try {
zw.addEntryDirectory(pathInZip, 0, false);
}
catch(e) {
if (e.name === "NS_ERROR_FILE_ALREADY_EXISTS")
return false;
throw e
}
return true;
}
this.addFile = function addFile(pathInZip, filePath) {
let { promise, reject, resolve } = defer();
let nsfile = createNsFile(filePath);
if (!nsfile.exists()) {
reject(new Error("This file doesn't exist: " + nsfile.path));
return promise;
}
// Case 1/ Regular file
if (!nsfile.isDirectory()) {
try {
zw.addEntryFile(pathInZip, COMPRESSION_DEFAULT, nsfile, false);
resolve();
}
catch (e) {
reject(new Error("Unable to add following file in zip: " + nsfile.path + "\n" + e));
}
return promise;
}
// Case 2/ Directory
if (pathInZip.substr(-1) !== '/')
pathInZip += "/";
let entries = nsfile.directoryEntries;
let array = [];
zw.addEntryDirectory(pathInZip, nsfile.lastModifiedTime, false);
while(entries.hasMoreElements()) {
let file = entries.getNext().QueryInterface(Ci.nsIFile);
if (file.leafName === "." || file.leafName === "..")
continue;
let path = pathInZip + file.leafName;
if (path.substr(0, 1) == '/') {
path = path.substr(1);
}
this.addFile(path, file.path);
}
resolve();
return promise;
}
this.addData = function (pathInZip, data) {
let deferred = defer();
try {
let stream = streamForData(data);
zw.addEntryStream(pathInZip, 0, COMPRESSION_DEFAULT, stream, false);
} catch(e) {
throw new Error("Unable to add following data in zip: " +
data.substr(0, 20) + "\n" + e);
}
deferred.resolve();
return deferred.promise;
}
this.close = function close() {
let deferred = defer();
zw.close();
deferred.resolve();
return deferred.promise;
}
}
|