You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
7.6 KiB
JavaScript
248 lines
7.6 KiB
JavaScript
const fsystem = require("./fileSystem").require();
|
|
const pth = require("path");
|
|
const Constants = require("./constants");
|
|
const Errors = require("./errors");
|
|
const isWin = typeof process === "object" && "win32" === process.platform;
|
|
|
|
const is_Obj = (obj) => obj && typeof obj === "object";
|
|
|
|
// generate CRC32 lookup table
|
|
const crcTable = new Uint32Array(256).map((t, c) => {
|
|
for (let k = 0; k < 8; k++) {
|
|
if ((c & 1) !== 0) {
|
|
c = 0xedb88320 ^ (c >>> 1);
|
|
} else {
|
|
c >>>= 1;
|
|
}
|
|
}
|
|
return c >>> 0;
|
|
});
|
|
|
|
// UTILS functions
|
|
|
|
function Utils(opts) {
|
|
this.sep = pth.sep;
|
|
this.fs = fsystem;
|
|
|
|
if (is_Obj(opts)) {
|
|
// custom filesystem
|
|
if (is_Obj(opts.fs) && typeof opts.fs.statSync === "function") {
|
|
this.fs = opts.fs;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Utils;
|
|
|
|
// INSTANCED functions
|
|
|
|
Utils.prototype.makeDir = function (/*String*/ folder) {
|
|
const self = this;
|
|
|
|
// Sync - make directories tree
|
|
function mkdirSync(/*String*/ fpath) {
|
|
let resolvedPath = fpath.split(self.sep)[0];
|
|
fpath.split(self.sep).forEach(function (name) {
|
|
if (!name || name.substr(-1, 1) === ":") return;
|
|
resolvedPath += self.sep + name;
|
|
var stat;
|
|
try {
|
|
stat = self.fs.statSync(resolvedPath);
|
|
} catch (e) {
|
|
self.fs.mkdirSync(resolvedPath);
|
|
}
|
|
if (stat && stat.isFile()) throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath);
|
|
});
|
|
}
|
|
|
|
mkdirSync(folder);
|
|
};
|
|
|
|
Utils.prototype.writeFileTo = function (/*String*/ path, /*Buffer*/ content, /*Boolean*/ overwrite, /*Number*/ attr) {
|
|
const self = this;
|
|
if (self.fs.existsSync(path)) {
|
|
if (!overwrite) return false; // cannot overwrite
|
|
|
|
var stat = self.fs.statSync(path);
|
|
if (stat.isDirectory()) {
|
|
return false;
|
|
}
|
|
}
|
|
var folder = pth.dirname(path);
|
|
if (!self.fs.existsSync(folder)) {
|
|
self.makeDir(folder);
|
|
}
|
|
|
|
var fd;
|
|
try {
|
|
fd = self.fs.openSync(path, "w", 438); // 0666
|
|
} catch (e) {
|
|
self.fs.chmodSync(path, 438);
|
|
fd = self.fs.openSync(path, "w", 438);
|
|
}
|
|
if (fd) {
|
|
try {
|
|
self.fs.writeSync(fd, content, 0, content.length, 0);
|
|
} finally {
|
|
self.fs.closeSync(fd);
|
|
}
|
|
}
|
|
self.fs.chmodSync(path, attr || 438);
|
|
return true;
|
|
};
|
|
|
|
Utils.prototype.writeFileToAsync = function (/*String*/ path, /*Buffer*/ content, /*Boolean*/ overwrite, /*Number*/ attr, /*Function*/ callback) {
|
|
if (typeof attr === "function") {
|
|
callback = attr;
|
|
attr = undefined;
|
|
}
|
|
|
|
const self = this;
|
|
|
|
self.fs.exists(path, function (exist) {
|
|
if (exist && !overwrite) return callback(false);
|
|
|
|
self.fs.stat(path, function (err, stat) {
|
|
if (exist && stat.isDirectory()) {
|
|
return callback(false);
|
|
}
|
|
|
|
var folder = pth.dirname(path);
|
|
self.fs.exists(folder, function (exists) {
|
|
if (!exists) self.makeDir(folder);
|
|
|
|
self.fs.open(path, "w", 438, function (err, fd) {
|
|
if (err) {
|
|
self.fs.chmod(path, 438, function () {
|
|
self.fs.open(path, "w", 438, function (err, fd) {
|
|
self.fs.write(fd, content, 0, content.length, 0, function () {
|
|
self.fs.close(fd, function () {
|
|
self.fs.chmod(path, attr || 438, function () {
|
|
callback(true);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
} else if (fd) {
|
|
self.fs.write(fd, content, 0, content.length, 0, function () {
|
|
self.fs.close(fd, function () {
|
|
self.fs.chmod(path, attr || 438, function () {
|
|
callback(true);
|
|
});
|
|
});
|
|
});
|
|
} else {
|
|
self.fs.chmod(path, attr || 438, function () {
|
|
callback(true);
|
|
});
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
Utils.prototype.findFiles = function (/*String*/ path) {
|
|
const self = this;
|
|
|
|
function findSync(/*String*/ dir, /*RegExp*/ pattern, /*Boolean*/ recursive) {
|
|
if (typeof pattern === "boolean") {
|
|
recursive = pattern;
|
|
pattern = undefined;
|
|
}
|
|
let files = [];
|
|
self.fs.readdirSync(dir).forEach(function (file) {
|
|
var path = pth.join(dir, file);
|
|
|
|
if (self.fs.statSync(path).isDirectory() && recursive) files = files.concat(findSync(path, pattern, recursive));
|
|
|
|
if (!pattern || pattern.test(path)) {
|
|
files.push(pth.normalize(path) + (self.fs.statSync(path).isDirectory() ? self.sep : ""));
|
|
}
|
|
});
|
|
return files;
|
|
}
|
|
|
|
return findSync(path, undefined, true);
|
|
};
|
|
|
|
Utils.prototype.getAttributes = function () {};
|
|
|
|
Utils.prototype.setAttributes = function () {};
|
|
|
|
// STATIC functions
|
|
|
|
// crc32 single update (it is part of crc32)
|
|
Utils.crc32update = function (crc, byte) {
|
|
return crcTable[(crc ^ byte) & 0xff] ^ (crc >>> 8);
|
|
};
|
|
|
|
Utils.crc32 = function (buf) {
|
|
if (typeof buf === "string") {
|
|
buf = Buffer.from(buf, "utf8");
|
|
}
|
|
// Generate crcTable
|
|
if (!crcTable.length) genCRCTable();
|
|
|
|
let len = buf.length;
|
|
let crc = ~0;
|
|
for (let off = 0; off < len; ) crc = Utils.crc32update(crc, buf[off++]);
|
|
// xor and cast as uint32 number
|
|
return ~crc >>> 0;
|
|
};
|
|
|
|
Utils.methodToString = function (/*Number*/ method) {
|
|
switch (method) {
|
|
case Constants.STORED:
|
|
return "STORED (" + method + ")";
|
|
case Constants.DEFLATED:
|
|
return "DEFLATED (" + method + ")";
|
|
default:
|
|
return "UNSUPPORTED (" + method + ")";
|
|
}
|
|
};
|
|
|
|
// removes ".." style path elements
|
|
Utils.canonical = function (/*string*/ path) {
|
|
if (!path) return "";
|
|
// trick normalize think path is absolute
|
|
var safeSuffix = pth.posix.normalize("/" + path.split("\\").join("/"));
|
|
return pth.join(".", safeSuffix);
|
|
};
|
|
|
|
// make abolute paths taking prefix as root folder
|
|
Utils.sanitize = function (/*string*/ prefix, /*string*/ name) {
|
|
prefix = pth.resolve(pth.normalize(prefix));
|
|
var parts = name.split("/");
|
|
for (var i = 0, l = parts.length; i < l; i++) {
|
|
var path = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep)));
|
|
if (path.indexOf(prefix) === 0) {
|
|
return path;
|
|
}
|
|
}
|
|
return pth.normalize(pth.join(prefix, pth.basename(name)));
|
|
};
|
|
|
|
// converts buffer, Uint8Array, string types to buffer
|
|
Utils.toBuffer = function toBuffer(/*buffer, Uint8Array, string*/ input) {
|
|
if (Buffer.isBuffer(input)) {
|
|
return input;
|
|
} else if (input instanceof Uint8Array) {
|
|
return Buffer.from(input);
|
|
} else {
|
|
// expect string all other values are invalid and return empty buffer
|
|
return typeof input === "string" ? Buffer.from(input, "utf8") : Buffer.alloc(0);
|
|
}
|
|
};
|
|
|
|
Utils.readBigUInt64LE = function (/*Buffer*/ buffer, /*int*/ index) {
|
|
var slice = Buffer.from(buffer.slice(index, index + 8));
|
|
slice.swap64();
|
|
|
|
return parseInt(`0x${slice.toString("hex")}`);
|
|
};
|
|
|
|
Utils.isWin = isWin; // Do we have windows system
|
|
Utils.crcTable = crcTable;
|